@walkeros/server-destination-aws 4.8.2 → 4.8.3-next-1793115089237
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 +28 -3
- package/dist/dev.d.mts +15 -2
- package/dist/dev.d.ts +15 -2
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.d.mts +15 -2
- package/dist/examples/index.d.ts +15 -2
- package/dist/examples/index.js +86 -46
- package/dist/examples/index.mjs +79 -39
- package/dist/walkerOS.json +1121 -1074
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @walkeros/server-destination-aws
|
|
2
2
|
|
|
3
|
+
## 4.8.3-next-1793115089237
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5313635: The Firehose and SNS step examples carry event timestamps in
|
|
8
|
+
milliseconds, as the walkerOS event model defines them, so the published
|
|
9
|
+
records and messages show realistic dates. The delivery hint describes the
|
|
10
|
+
dead letter queue without promising a later replay.
|
|
11
|
+
- 34fd225: The Firehose step examples now state their expected record bytes as
|
|
12
|
+
literals instead of computing them with the destination's own encoder, so the
|
|
13
|
+
examples check the delivered record rather than agree with the code by
|
|
14
|
+
construction. Published behavior is unchanged.
|
|
15
|
+
- 5313635: The package publishes a minimal example: a stream name for Firehose
|
|
16
|
+
and a topic ARN for SNS, one example per export, with the region and
|
|
17
|
+
credentials taken from the AWS environment. The docs page renders the install
|
|
18
|
+
line, the integrated code and the flow from it, and the package test runs the
|
|
19
|
+
same settings.
|
|
20
|
+
- Updated dependencies [34fd225]
|
|
21
|
+
- Updated dependencies [5313635]
|
|
22
|
+
- Updated dependencies [5313635]
|
|
23
|
+
- Updated dependencies [5313635]
|
|
24
|
+
- Updated dependencies [5313635]
|
|
25
|
+
- Updated dependencies [5313635]
|
|
26
|
+
- Updated dependencies [34fd225]
|
|
27
|
+
- Updated dependencies [5313635]
|
|
28
|
+
- @walkeros/core@4.8.3-next-1793115089237
|
|
29
|
+
- @walkeros/server-core@4.8.3-next-1793115089237
|
|
30
|
+
|
|
3
31
|
## 4.8.2
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -286,9 +314,6 @@
|
|
|
286
314
|
and `event.context` remain required.
|
|
287
315
|
- Each source self-registers via TypeScript module augmentation of `SourceMap`
|
|
288
316
|
in `@walkeros/core`.
|
|
289
|
-
- App-side coordination (`/workspaces/developer/app`) is a follow-up plan, not
|
|
290
|
-
part of this release. Telemetry from v4 CLI/MCP will not validate against
|
|
291
|
-
the existing app schema until that follow-up ships.
|
|
292
317
|
- `Mapping.Rule.skip` is renamed to `Mapping.Rule.silent`. Customer flow.json
|
|
293
318
|
configs using `skip: true` in mapping rules must rename to `silent: true`.
|
|
294
319
|
Hard cut: no legacy alias, the field is gone.
|
package/dist/dev.d.mts
CHANGED
|
@@ -58,8 +58,14 @@ declare namespace step$1 {
|
|
|
58
58
|
export { step$1_firehoseRecord as firehoseRecord, init$1 as init, step$1_mappedRecord as mappedRecord, orderEvent$1 as orderEvent, silentRule$1 as silentRule, step$1_userSignupEvent as userSignupEvent };
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* The setting Firehose needs to deliver: the stream name. The region and the
|
|
63
|
+
* credentials come from the AWS environment.
|
|
64
|
+
*/
|
|
65
|
+
declare const minimal$1: Flow.MinimalExample;
|
|
66
|
+
|
|
61
67
|
declare namespace firehoseExamplesNs {
|
|
62
|
-
export { env$1 as env, step$1 as step };
|
|
68
|
+
export { env$1 as env, minimal$1 as minimal, step$1 as step };
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
/** An AWS SDK v3 command class, as far as this destination builds one. */
|
|
@@ -115,10 +121,17 @@ declare namespace step {
|
|
|
115
121
|
export { step_attributedPublish as attributedPublish, step_init as init, step_mappedMessage as mappedMessage, step_orderEvent as orderEvent, step_pageView as pageView, step_silentRule as silentRule };
|
|
116
122
|
}
|
|
117
123
|
|
|
124
|
+
/**
|
|
125
|
+
* The setting SNS needs to deliver: the topic ARN. The credentials come from
|
|
126
|
+
* the AWS environment.
|
|
127
|
+
*/
|
|
128
|
+
declare const minimal: Flow.MinimalExample;
|
|
129
|
+
|
|
118
130
|
declare const snsExamplesNs_env: typeof env;
|
|
131
|
+
declare const snsExamplesNs_minimal: typeof minimal;
|
|
119
132
|
declare const snsExamplesNs_step: typeof step;
|
|
120
133
|
declare namespace snsExamplesNs {
|
|
121
|
-
export { snsExamplesNs_env as env, snsExamplesNs_step as step };
|
|
134
|
+
export { snsExamplesNs_env as env, snsExamplesNs_minimal as minimal, snsExamplesNs_step as step };
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
declare const settings$1: _walkeros_core_dev.JSONSchema;
|
package/dist/dev.d.ts
CHANGED
|
@@ -58,8 +58,14 @@ declare namespace step$1 {
|
|
|
58
58
|
export { step$1_firehoseRecord as firehoseRecord, init$1 as init, step$1_mappedRecord as mappedRecord, orderEvent$1 as orderEvent, silentRule$1 as silentRule, step$1_userSignupEvent as userSignupEvent };
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* The setting Firehose needs to deliver: the stream name. The region and the
|
|
63
|
+
* credentials come from the AWS environment.
|
|
64
|
+
*/
|
|
65
|
+
declare const minimal$1: Flow.MinimalExample;
|
|
66
|
+
|
|
61
67
|
declare namespace firehoseExamplesNs {
|
|
62
|
-
export { env$1 as env, step$1 as step };
|
|
68
|
+
export { env$1 as env, minimal$1 as minimal, step$1 as step };
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
/** An AWS SDK v3 command class, as far as this destination builds one. */
|
|
@@ -115,10 +121,17 @@ declare namespace step {
|
|
|
115
121
|
export { step_attributedPublish as attributedPublish, step_init as init, step_mappedMessage as mappedMessage, step_orderEvent as orderEvent, step_pageView as pageView, step_silentRule as silentRule };
|
|
116
122
|
}
|
|
117
123
|
|
|
124
|
+
/**
|
|
125
|
+
* The setting SNS needs to deliver: the topic ARN. The credentials come from
|
|
126
|
+
* the AWS environment.
|
|
127
|
+
*/
|
|
128
|
+
declare const minimal: Flow.MinimalExample;
|
|
129
|
+
|
|
118
130
|
declare const snsExamplesNs_env: typeof env;
|
|
131
|
+
declare const snsExamplesNs_minimal: typeof minimal;
|
|
119
132
|
declare const snsExamplesNs_step: typeof step;
|
|
120
133
|
declare namespace snsExamplesNs {
|
|
121
|
-
export { snsExamplesNs_env as env, snsExamplesNs_step as step };
|
|
134
|
+
export { snsExamplesNs_env as env, snsExamplesNs_minimal as minimal, snsExamplesNs_step as step };
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
declare const settings$1: _walkeros_core_dev.JSONSchema;
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,i=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,r=(e,i)=>{for(var s in i)t(e,s,{get:i[s],enumerable:!0})},o={};r(o,{examples:()=>fe,exportExamples:()=>Ae,exportSchemas:()=>we,hints:()=>ye,schemas:()=>ve}),module.exports=(e=o,((e,r,o,a)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let c of s(r))n.call(e,c)||c===o||t(e,c,{get:()=>r[c],enumerable:!(a=i(r,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};r(a,{env:()=>c,step:()=>u});var c={};r(c,{push:()=>l,simulation:()=>p});var d=class{input;constructor(e){this.input=e}get[Symbol.toStringTag](){return"PutRecordBatchCommand"}},l={AWS:{FirehoseClient:class{config;constructor(e){this.config=e}async send(e){const t="input"in e?e.input:void 0;var i;return{FailedPutCount:0,Encrypted:!1,RequestResponses:("object"==typeof(i=t)&&null!==i&&"Records"in i&&Array.isArray(i.Records)?t.Records:[]).map((e,t)=>({RecordId:`mock-record-id-${t}`}))}}destroy(){}},PutRecordBatchCommand:d}},p=["call:AWS.FirehoseClient.send"],u={};r(u,{firehoseRecord:()=>w,init:()=>S,mappedRecord:()=>C,orderEvent:()=>b,silentRule:()=>N,userSignupEvent:()=>E});var m=require("@walkeros/core");require("@walkeros/core");function g(e,t=!0){const i=JSON.stringify(e);if("string"!=typeof i)throw new TypeError("The payload does not serialize to JSON.");return Buffer.from(t?`${i}\n`:i)}var h="walkeros-events",S={title:"Initialization",description:"Init builds one FirehoseClient for the stream region with the credentials from config.credentials and a 2500 ms per-attempt timeout. Nothing is sent until the first event.",in:{settings:{streamName:h,region:"eu-central-1"},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new FirehoseClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},v=(0,m.getEvent)("page view",{id:"ev-1700001000",timestamp:1700001e3,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),f=(0,m.getEvent)("order complete",{id:"ev-1700001001",timestamp:1700001001,data:{id:"ORD-400",value:99.99,currency:"EUR"},source:{type:"express",platform:"server"}}),y=(0,m.createEvent)({name:"user signup",id:"ev-1700001002",timestamp:1700001002,data:{plan:"pro",source:"landing-page"},user:{id:"usr-789",email:"new@example.com"},source:{type:"express",platform:"server"}});function A(e){return[["client.send",{DeliveryStreamName:h,Records:[{Data:g(e)}]}]]}var w={title:"Page view record",description:"A page view is sent to Firehose as one record: the full event as JSON followed by a newline.",in:v,mapping:void 0,out:A(v)},b={title:"Order record",description:"An order complete event is serialized and delivered to Firehose as one newline-terminated record.",in:f,mapping:void 0,out:A(f)},E={title:"User signup record",description:"A user signup event including user fields is streamed to Firehose as a JSON record.",in:y,mapping:void 0,out:A(y)},C={title:"Mapped record",description:"A mapping that produces an object sends that object as the record instead of the full event. Keep the event id in it for deduplication.",in:f,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:A({id:"ev-1700001001",name:"order complete",order_id:"ORD-400",total:99.99})},N={public:!1,description:"A rule with silent: true sends no record to Firehose.",in:v,mapping:{silent:!0},out:[]},_={};r(_,{env:()=>T,step:()=>W});var T={};r(T,{push:()=>x,simulation:()=>D});var z=class{constructor(e){this.input=e}input},k=class extends z{get[Symbol.toStringTag](){return"CreateTopicCommand"}},R=class extends z{get[Symbol.toStringTag](){return"PublishCommand"}},I=class extends z{get[Symbol.toStringTag](){return"GetTopicAttributesCommand"}},O=class extends z{get[Symbol.toStringTag](){return"SubscribeCommand"}},K=class extends z{get[Symbol.toStringTag](){return"GetCallerIdentityCommand"}},x={AWS:{SNSClient:class{constructor(e){this.config=e}config;async send(e){return e instanceof k?{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events"}:e instanceof R?{MessageId:"mock-message-id"}:{}}destroy(){}},CreateTopicCommand:k,PublishCommand:R,GetTopicAttributesCommand:I,SubscribeCommand:O,STSClient:class{constructor(e){this.config=e}config;async send(){return{Account:"123456789012",Arn:"arn:aws:iam::123456789012:user/walkeros"}}destroy(){}},GetCallerIdentityCommand:K}},D=["call:AWS.SNSClient.send"],W={};r(W,{attributedPublish:()=>J,init:()=>j,mappedMessage:()=>U,orderEvent:()=>G,pageView:()=>Y,silentRule:()=>B});var q=require("@walkeros/core"),F="arn:aws:sns:eu-central-1:123456789012:walkeros-events",j={title:"Initialization",description:"Init builds one SNSClient in the region of the topic ARN with the credentials from config.credentials and a 2500 ms per-attempt timeout. No topic is created and nothing is sent until the first event.",in:{settings:{topicArn:F},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new SNSClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},M=(0,q.getEvent)("page view",{id:"ev-1700001000",timestamp:1700001e3,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),P=(0,q.getEvent)("order complete",{id:"ev-1700001001",timestamp:1700001001,data:{id:"ORD-400",value:99.99,currency:"EUR"},user:{id:"usr-789"},source:{type:"express",platform:"server"}}),$=(0,q.getEvent)("product view",{id:"ev-1700001002",timestamp:1700001002,data:{id:"SKU-1",tenant_id:"acme"},source:{type:"express",platform:"server"}}),Y={title:"Page view publish",description:"A page view event is JSON-stringified and published as the Message of an SNS Publish call.",in:M,mapping:void 0,out:[["client.send",{TopicArn:F,Message:JSON.stringify(M)}]]},G={title:"Order publish with FIFO group (path-resolved)",description:'An order complete event is published to a FIFO topic with a messageGroupId resolved from the event via the mapping path "user.id". The deduplication id defaults to the event id.',in:P,mapping:{settings:{messageGroupId:"user.id"}},out:[["client.send",{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events.fifo",Message:JSON.stringify(P),MessageGroupId:"usr-789",MessageDeduplicationId:"ev-1700001001"}]]},J={title:"Publish with per-event message attributes",description:"Demonstrates `messageAttributes` as `Mapping.Map`: each attribute value resolves per event. Operators express the SDK shape (`{ DataType, StringValue }`) per entry.",in:$,mapping:{settings:{messageAttributes:{schema_version:{value:{DataType:"String",StringValue:"v4"}},tenant:{value:{DataType:"String",StringValue:"acme"}}}}},out:[["client.send",{TopicArn:F,Message:JSON.stringify($),MessageAttributes:{schema_version:{DataType:"String",StringValue:"v4"},tenant:{DataType:"String",StringValue:"acme"}}}]]},U={title:"Mapped message",description:"A mapping that produces an object publishes that object as the Message instead of the full event. Keep the event id in it for deduplication.",in:P,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:[["client.send",{TopicArn:F,Message:JSON.stringify({id:"ev-1700001001",name:"order complete",order_id:"ORD-400",total:99.99})}]]},B={public:!1,description:"A rule with silent: true publishes no message to SNS.",in:M,mapping:{silent:!0},out:[]},L=require("@walkeros/core/dev"),V=require("@walkeros/core/dev"),H=V.z.string().min(1).describe("Name of the Firehose stream (like walkeros-events). Required.").optional(),Q=V.z.string().describe("AWS region of the stream (like eu-central-1). Default: AWS_REGION or the active profile, else eu-central-1."),X=V.z.any().describe("A FirehoseClient of your own. Used as is and never closed by the destination."),Z=V.z.any().describe("Raw FirehoseClient options passed to the SDK (like { endpoint, maxAttempts }). Put keys in config.credentials instead."),ee=V.z.object({streamName:H,client:X.optional(),region:Q.optional(),config:Z.optional()}),te=V.z.object({streamName:H,region:Q.optional(),newline:V.z.boolean().describe("Append a newline to every record (default true). Set false when the stream adds its own new line delimiter.").optional(),config:Z.optional(),client:X.optional(),firehose:ee.describe("Deprecated: use the flat fields streamName, region, config and client.").optional()}).refine(e=>void 0!==e.streamName||void 0!==e.firehose?.streamName,{message:"Set settings.streamName"}).meta({anyOf:[{required:["streamName"]},{required:["firehose"],properties:{firehose:{required:["streamName"]}}}]}),ie=require("@walkeros/core/dev").z.object({}),se=(0,L.zodToSchema)(te),ne=(0,L.zodToSchema)(ie),re=(0,L.zodToSchema)(ee),oe=require("@walkeros/core/dev"),ae=require("@walkeros/core/dev"),ce=ae.z.object({topicArn:ae.z.string().describe("Topic ARN (like arn:aws:sns:eu-central-1:123456789012:walkeros-events). Region and topic name derive from it. Required unless topicName is set.").optional(),topicName:ae.z.string().min(1).describe("Topic name (like walkeros-events). Used by walkeros setup; without topicArn the ARN is completed with the account id at the first publish.").optional(),region:ae.z.string().describe("AWS region (like eu-central-1). Default: the region in topicArn, AWS_REGION or the active profile, else eu-central-1.").optional(),client:ae.z.any().describe("An SNSClient of your own. Used as is and never closed by the destination.").optional(),config:ae.z.any().describe("Raw SNSClient options passed to the SDK. Put keys in config.credentials instead.").optional()}).refine(e=>void 0!==e.topicArn||void 0!==e.topicName,{message:"Set settings.topicArn or settings.topicName"}).meta({anyOf:[{required:["topicArn"]},{required:["topicName"]}]}),de=require("@walkeros/core/dev"),le=de.z.object({messageAttributes:de.z.record(de.z.string(),de.z.unknown()).optional(),messageGroupId:de.z.unknown().optional(),messageDeduplicationId:de.z.unknown().optional()}),pe=require("@walkeros/core/dev"),ue=pe.z.object({protocol:pe.z.enum(["sqs","lambda","https","http","email","sms"]),endpoint:pe.z.string().min(1),rawMessageDelivery:pe.z.boolean().optional(),filterPolicy:pe.z.record(pe.z.string(),pe.z.unknown()).optional(),deadLetterTargetArn:pe.z.string().optional()}),me=pe.z.object({region:pe.z.string().optional(),displayName:pe.z.string().optional(),fifoTopic:pe.z.boolean().optional(),kmsMasterKeyId:pe.z.string().optional(),tags:pe.z.record(pe.z.string(),pe.z.string()).optional(),subscriptions:pe.z.array(ue).optional()}),ge=(0,oe.zodToSchema)(ce),he=(0,oe.zodToSchema)(le),Se=(0,oe.zodToSchema)(me),ve={};r(ve,{firehose:()=>re,firehoseMapping:()=>ne,firehoseSettings:()=>se,mapping:()=>ne,settings:()=>se,snsMapping:()=>he,snsSettings:()=>ge,snsSetup:()=>Se});var fe={};r(fe,{env:()=>c,firehose:()=>a,sns:()=>_,step:()=>u});var ye={"minimal-config":{text:"Firehose needs settings.streamName (plus settings.region when the stream is not in AWS_REGION or eu-central-1). SNS needs settings.topicArn; region and topic name derive from it. Off AWS, add config.credentials. Nothing is sent and no credentials are loaded until the first event.",code:[{lang:"json",code:'{ "settings": { "streamName": "walkeros-events", "region": "eu-central-1" }, "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'},{lang:"json",code:'{ "settings": { "topicArn": "arn:aws:sns:eu-central-1:123456789012:walkeros-events" } }'}]},"auth-credentials":{text:"On AWS compute an attached IAM role needs no config at all. Elsewhere, config.credentials ({ accessKeyId, secretAccessKey, sessionToken? }, or the same as a JSON string) wins over settings.config.credentials, which wins over the AWS default chain (AWS_* variables, AWS_PROFILE, ECS, EC2 and web identity roles; Kubernetes can go keyless with AWS_ROLE_ARN plus AWS_WEB_IDENTITY_TOKEN_FILE). Back every value with $secret; never write a literal key. Credentials are shape-checked at init and loaded only at the first send.",code:[{lang:"json",code:'{ "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'}]},"firehose-records":{text:"Each record is the mapped data object, or the full event when the mapping produced none, followed by a newline. Set settings.newline: false when the stream adds its own new line delimiter. Batching is on by default (500 records or 1 s); calls carry at most 500 records and 2,900,000 bytes, and a record over 1,000,000 bytes fails as RecordTooLarge without being sent."},"delivery-guarantee":{text:"Delivery is at least once: deduplicate downstream on event.id, and keep id in mapped data. A record AWS rejects is reported as failed with code, status and retryable. There is no retry beyond the built-in AWS SDK retry: a rejected record goes to the in-memory dead letter queue of the collector, which nothing replays yet. On SNS FIFO topics MessageDeduplicationId defaults to event.id."},"troubleshoot-errors":{text:"Every failure carries code, status and retryable, and its message names the stream or topic and the region; the AWS error itself stays on the error as its cause. ResourceNotFoundException: wrong settings.streamName or region. AccessDeniedException / AuthorizationErrorException: the credentials lack firehose:PutRecordBatch or sns:Publish. UnrecognizedClientException, InvalidSignatureException, ExpiredTokenException or no credentials found: check config.credentials or the environment. SNS NotFoundException: the topic does not exist; run walkeros setup or set settings.topicArn. NULL rows in Athena: the stream adds its own new line delimiter too, so set newline: false. Code config at start: a missing or conflicting setting, named in the message."}},Ae={destinationFirehose:a,destinationSNS:_},we={destinationFirehose:{settings:se,mapping:ne},destinationSNS:{settings:ge,mapping:he,setup:Se}};//# sourceMappingURL=dev.js.map
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,s=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,r=(e,s)=>{for(var i in s)t(e,i,{get:s[i],enumerable:!0})},o={};r(o,{examples:()=>fe,exportExamples:()=>be,exportSchemas:()=>we,hints:()=>ye,schemas:()=>ve}),module.exports=(e=o,((e,r,o,a)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let c of i(r))n.call(e,c)||c===o||t(e,c,{get:()=>r[c],enumerable:!(a=s(r,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};r(a,{env:()=>c,minimal:()=>C,step:()=>u});var c={};r(c,{push:()=>l,simulation:()=>p});var d=class{input;constructor(e){this.input=e}get[Symbol.toStringTag](){return"PutRecordBatchCommand"}},l={AWS:{FirehoseClient:class{config;constructor(e){this.config=e}async send(e){const t="input"in e?e.input:void 0;var s;return{FailedPutCount:0,Encrypted:!1,RequestResponses:("object"==typeof(s=t)&&null!==s&&"Records"in s&&Array.isArray(s.Records)?t.Records:[]).map((e,t)=>({RecordId:`mock-record-id-${t}`}))}}destroy(){}},PutRecordBatchCommand:d}},p=["call:AWS.FirehoseClient.send"],u={};r(u,{firehoseRecord:()=>y,init:()=>h,mappedRecord:()=>A,orderEvent:()=>b,silentRule:()=>E,userSignupEvent:()=>w});var m=require("@walkeros/core"),g="walkeros-events",h={title:"Initialization",description:"Init builds one FirehoseClient for the stream region with the credentials from config.credentials and a 2500 ms per-attempt timeout. Nothing is sent until the first event.",in:{settings:{streamName:g,region:"eu-central-1"},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new FirehoseClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},S=(0,m.getEvent)("page view",{id:"ev-1700001000",timestamp:1700001e6,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),v=(0,m.getEvent)("order complete",{id:"ev-1700001001",timestamp:1700001001e3,data:{id:"ORD-400",value:99.99,currency:"EUR"},source:{type:"express",platform:"server"}}),f=(0,m.createEvent)({name:"user signup",id:"ev-1700001002",timestamp:1700001002e3,data:{plan:"pro",source:"landing-page"},user:{id:"usr-789",email:"new@example.com"},source:{type:"express",platform:"server"}}),y={title:"Page view record",description:"A page view is sent to Firehose as one record: the full event as JSON followed by a newline.",in:S,mapping:void 0,out:[["client.send",{DeliveryStreamName:g,Records:[{Data:Buffer.from('{"name":"page view","data":{"title":"Home","url":"https://example.com/"},"context":{"dev":["test",1]},"globals":{"pagegroup":"docs"},"custom":{"completely":"random"},"user":{"id":"us3r","device":"c00k13","session":"s3ss10n"},"nested":[{"entity":"child","data":{"is":"subordinated"}}],"consent":{"functional":true},"id":"ev-1700001000","trigger":"load","entity":"page","action":"view","timestamp":1700001000000,"timing":3.14,"source":{"count":1,"trace":"0a1b2c3d4e5f60718293a4b5c6d7e8f9","type":"express","platform":"server"}}\n')}]}]]},b={title:"Order record",description:"An order complete event is serialized and delivered to Firehose as one newline-terminated record.",in:v,mapping:void 0,out:[["client.send",{DeliveryStreamName:g,Records:[{Data:Buffer.from('{"name":"order complete","data":{"id":"ORD-400","value":99.99,"currency":"EUR"},"context":{"shopping":["complete",0]},"globals":{"pagegroup":"shop"},"custom":{"completely":"random"},"user":{"id":"us3r","device":"c00k13","session":"s3ss10n"},"nested":[{"entity":"product","data":{"id":"ers","name":"Everyday Ruck Snack","color":"black","size":"l","price":420},"context":{"shopping":["complete",0]},"nested":[]},{"entity":"product","data":{"id":"cc","name":"Cool Cap","size":"one size","price":42},"context":{"shopping":["complete",0]},"nested":[]},{"entity":"gift","data":{"name":"Surprise"},"context":{"shopping":["complete",0]},"nested":[]}],"consent":{"functional":true},"id":"ev-1700001001","trigger":"load","entity":"order","action":"complete","timestamp":1700001001000,"timing":3.14,"source":{"count":1,"trace":"0a1b2c3d4e5f60718293a4b5c6d7e8f9","type":"express","platform":"server"}}\n')}]}]]},w={title:"User signup record",description:"A user signup event including user fields is streamed to Firehose as a JSON record.",in:f,mapping:void 0,out:[["client.send",{DeliveryStreamName:g,Records:[{Data:Buffer.from('{"name":"user signup","data":{"plan":"pro","source":"landing-page"},"context":{"dev":["test",1]},"globals":{"lang":"elb"},"custom":{"completely":"random"},"user":{"id":"usr-789","email":"new@example.com"},"nested":[{"entity":"child","data":{"is":"subordinated"}}],"consent":{"functional":true},"id":"ev-1700001002","trigger":"test","entity":"user","action":"signup","timestamp":1700001002000,"timing":3.14,"source":{"count":1,"trace":"0a1b2c3d4e5f60718293a4b5c6d7e8f9","type":"express","platform":"server"}}\n')}]}]]},A={title:"Mapped record",description:"A mapping that produces an object sends that object as the record instead of the full event. Keep the event id in it for deduplication.",in:v,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:[["client.send",{DeliveryStreamName:g,Records:[{Data:Buffer.from('{"id":"ev-1700001001","name":"order complete","order_id":"ORD-400","total":99.99}\n')}]}]]},E={public:!1,description:"A rule with silent: true sends no record to Firehose.",in:S,mapping:{silent:!0},out:[]},C={settings:{streamName:"walkeros-events"}},N={};r(N,{env:()=>_,minimal:()=>J,step:()=>K});var _={};r(_,{push:()=>D,simulation:()=>O});var k=class{constructor(e){this.input=e}input},z=class extends k{get[Symbol.toStringTag](){return"CreateTopicCommand"}},R=class extends k{get[Symbol.toStringTag](){return"PublishCommand"}},T=class extends k{get[Symbol.toStringTag](){return"GetTopicAttributesCommand"}},x=class extends k{get[Symbol.toStringTag](){return"SubscribeCommand"}},I=class extends k{get[Symbol.toStringTag](){return"GetCallerIdentityCommand"}},D={AWS:{SNSClient:class{constructor(e){this.config=e}config;async send(e){return e instanceof z?{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events"}:e instanceof R?{MessageId:"mock-message-id"}:{}}destroy(){}},CreateTopicCommand:z,PublishCommand:R,GetTopicAttributesCommand:T,SubscribeCommand:x,STSClient:class{constructor(e){this.config=e}config;async send(){return{Account:"123456789012",Arn:"arn:aws:iam::123456789012:user/walkeros"}}destroy(){}},GetCallerIdentityCommand:I}},O=["call:AWS.SNSClient.send"],K={};r(K,{attributedPublish:()=>G,init:()=>F,mappedMessage:()=>B,orderEvent:()=>Y,pageView:()=>$,silentRule:()=>U});var W=require("@walkeros/core"),q="arn:aws:sns:eu-central-1:123456789012:walkeros-events",F={title:"Initialization",description:"Init builds one SNSClient in the region of the topic ARN with the credentials from config.credentials and a 2500 ms per-attempt timeout. No topic is created and nothing is sent until the first event.",in:{settings:{topicArn:q},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new SNSClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},j=(0,W.getEvent)("page view",{id:"ev-1700001000",timestamp:1700001e6,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),M=(0,W.getEvent)("order complete",{id:"ev-1700001001",timestamp:1700001001e3,data:{id:"ORD-400",value:99.99,currency:"EUR"},user:{id:"usr-789"},source:{type:"express",platform:"server"}}),P=(0,W.getEvent)("product view",{id:"ev-1700001002",timestamp:1700001002e3,data:{id:"SKU-1",tenant_id:"acme"},source:{type:"express",platform:"server"}}),$={title:"Page view publish",description:"A page view event is JSON-stringified and published as the Message of an SNS Publish call.",in:j,mapping:void 0,out:[["client.send",{TopicArn:q,Message:JSON.stringify(j)}]]},Y={title:"Order publish with FIFO group (path-resolved)",description:'An order complete event is published to a FIFO topic with a messageGroupId resolved from the event via the mapping path "user.id". The deduplication id defaults to the event id.',in:M,mapping:{settings:{messageGroupId:"user.id"}},out:[["client.send",{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events.fifo",Message:JSON.stringify(M),MessageGroupId:"usr-789",MessageDeduplicationId:"ev-1700001001"}]]},G={title:"Publish with per-event message attributes",description:"Demonstrates `messageAttributes` as `Mapping.Map`: each attribute value resolves per event. Operators express the SDK shape (`{ DataType, StringValue }`) per entry.",in:P,mapping:{settings:{messageAttributes:{schema_version:{value:{DataType:"String",StringValue:"v4"}},tenant:{value:{DataType:"String",StringValue:"acme"}}}}},out:[["client.send",{TopicArn:q,Message:JSON.stringify(P),MessageAttributes:{schema_version:{DataType:"String",StringValue:"v4"},tenant:{DataType:"String",StringValue:"acme"}}}]]},B={title:"Mapped message",description:"A mapping that produces an object publishes that object as the Message instead of the full event. Keep the event id in it for deduplication.",in:M,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:[["client.send",{TopicArn:q,Message:JSON.stringify({id:"ev-1700001001",name:"order complete",order_id:"ORD-400",total:99.99})}]]},U={public:!1,description:"A rule with silent: true publishes no message to SNS.",in:j,mapping:{silent:!0},out:[]},J={settings:{topicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events"}},L=require("@walkeros/core/dev"),V=require("@walkeros/core/dev"),H=V.z.string().min(1).describe("Name of the Firehose stream (like walkeros-events). Required.").optional(),Q=V.z.string().describe("AWS region of the stream (like eu-central-1). Default: AWS_REGION or the active profile, else eu-central-1."),X=V.z.any().describe("A FirehoseClient of your own. Used as is and never closed by the destination."),Z=V.z.any().describe("Raw FirehoseClient options passed to the SDK (like { endpoint, maxAttempts }). Put keys in config.credentials instead."),ee=V.z.object({streamName:H,client:X.optional(),region:Q.optional(),config:Z.optional()}),te=V.z.object({streamName:H,region:Q.optional(),newline:V.z.boolean().describe("Append a newline to every record (default true). Set false when the stream adds its own new line delimiter.").optional(),config:Z.optional(),client:X.optional(),firehose:ee.describe("Deprecated: use the flat fields streamName, region, config and client.").optional()}).refine(e=>void 0!==e.streamName||void 0!==e.firehose?.streamName,{message:"Set settings.streamName"}).meta({anyOf:[{required:["streamName"]},{required:["firehose"],properties:{firehose:{required:["streamName"]}}}]}),se=require("@walkeros/core/dev").z.object({}),ie=(0,L.zodToSchema)(te),ne=(0,L.zodToSchema)(se),re=(0,L.zodToSchema)(ee),oe=require("@walkeros/core/dev"),ae=require("@walkeros/core/dev"),ce=ae.z.object({topicArn:ae.z.string().describe("Topic ARN (like arn:aws:sns:eu-central-1:123456789012:walkeros-events). Region and topic name derive from it. Required unless topicName is set.").optional(),topicName:ae.z.string().min(1).describe("Topic name (like walkeros-events). Used by walkeros setup; without topicArn the ARN is completed with the account id at the first publish.").optional(),region:ae.z.string().describe("AWS region (like eu-central-1). Default: the region in topicArn, AWS_REGION or the active profile, else eu-central-1.").optional(),client:ae.z.any().describe("An SNSClient of your own. Used as is and never closed by the destination.").optional(),config:ae.z.any().describe("Raw SNSClient options passed to the SDK. Put keys in config.credentials instead.").optional()}).refine(e=>void 0!==e.topicArn||void 0!==e.topicName,{message:"Set settings.topicArn or settings.topicName"}).meta({anyOf:[{required:["topicArn"]},{required:["topicName"]}]}),de=require("@walkeros/core/dev"),le=de.z.object({messageAttributes:de.z.record(de.z.string(),de.z.unknown()).optional(),messageGroupId:de.z.unknown().optional(),messageDeduplicationId:de.z.unknown().optional()}),pe=require("@walkeros/core/dev"),ue=pe.z.object({protocol:pe.z.enum(["sqs","lambda","https","http","email","sms"]),endpoint:pe.z.string().min(1),rawMessageDelivery:pe.z.boolean().optional(),filterPolicy:pe.z.record(pe.z.string(),pe.z.unknown()).optional(),deadLetterTargetArn:pe.z.string().optional()}),me=pe.z.object({region:pe.z.string().optional(),displayName:pe.z.string().optional(),fifoTopic:pe.z.boolean().optional(),kmsMasterKeyId:pe.z.string().optional(),tags:pe.z.record(pe.z.string(),pe.z.string()).optional(),subscriptions:pe.z.array(ue).optional()}),ge=(0,oe.zodToSchema)(ce),he=(0,oe.zodToSchema)(le),Se=(0,oe.zodToSchema)(me),ve={};r(ve,{firehose:()=>re,firehoseMapping:()=>ne,firehoseSettings:()=>ie,mapping:()=>ne,settings:()=>ie,snsMapping:()=>he,snsSettings:()=>ge,snsSetup:()=>Se});var fe={};r(fe,{env:()=>c,firehose:()=>a,sns:()=>N,step:()=>u});var ye={"minimal-config":{text:"Firehose needs settings.streamName (plus settings.region when the stream is not in AWS_REGION or eu-central-1). SNS needs settings.topicArn; region and topic name derive from it. Off AWS, add config.credentials. Nothing is sent and no credentials are loaded until the first event.",code:[{lang:"json",code:'{ "settings": { "streamName": "walkeros-events", "region": "eu-central-1" }, "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'},{lang:"json",code:'{ "settings": { "topicArn": "arn:aws:sns:eu-central-1:123456789012:walkeros-events" } }'}]},"auth-credentials":{text:"On AWS compute an attached IAM role needs no config at all. Elsewhere, config.credentials ({ accessKeyId, secretAccessKey, sessionToken? }, or the same as a JSON string) wins over settings.config.credentials, which wins over the AWS default chain (AWS_* variables, AWS_PROFILE, ECS, EC2 and web identity roles; Kubernetes can go keyless with AWS_ROLE_ARN plus AWS_WEB_IDENTITY_TOKEN_FILE). Back every value with $secret; never write a literal key. Credentials are shape-checked at init and loaded only at the first send.",code:[{lang:"json",code:'{ "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'}]},"firehose-records":{text:"Each record is the mapped data object, or the full event when the mapping produced none, followed by a newline. Set settings.newline: false when the stream adds its own new line delimiter. Batching is on by default (500 records or 1 s); calls carry at most 500 records and 2,900,000 bytes, and a record over 1,000,000 bytes fails as RecordTooLarge without being sent."},"delivery-guarantee":{text:"Delivery is at least once: deduplicate downstream on event.id, and keep id in mapped data. A record AWS rejects is reported as failed with code, status and retryable. There is no retry beyond the built-in AWS SDK retry: a rejected record goes to the in-memory dead letter queue of the collector, which nothing replays. On SNS FIFO topics MessageDeduplicationId defaults to event.id."},"troubleshoot-errors":{text:"Every failure carries code, status and retryable, and its message names the stream or topic and the region; the AWS error itself stays on the error as its cause. ResourceNotFoundException: wrong settings.streamName or region. AccessDeniedException / AuthorizationErrorException: the credentials lack firehose:PutRecordBatch or sns:Publish. UnrecognizedClientException, InvalidSignatureException, ExpiredTokenException or no credentials found: check config.credentials or the environment. SNS NotFoundException: the topic does not exist; run walkeros setup or set settings.topicArn. NULL rows in Athena: the stream adds its own new line delimiter too, so set newline: false. Code config at start: a missing or conflicting setting, named in the message."}},be={destinationFirehose:a,destinationSNS:N},we={destinationFirehose:{settings:ie,mapping:ne},destinationSNS:{settings:ge,mapping:he,setup:Se}};//# sourceMappingURL=dev.js.map
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev.ts","../src/firehose/examples/index.ts","../src/firehose/examples/env.ts","../src/firehose/examples/step.ts","../src/lib/payload.ts","../src/firehose/lib/records.ts","../src/sns/examples/index.ts","../src/sns/examples/env.ts","../src/sns/examples/step.ts","../src/firehose/schemas/index.ts","../src/firehose/schemas/settings.ts","../src/firehose/schemas/mapping.ts","../src/sns/schemas/index.ts","../src/sns/schemas/settings.ts","../src/sns/schemas/mapping.ts","../src/sns/schemas/setup.ts","../src/schemas.ts","../src/examples/index.ts","../src/hints.ts"],"sourcesContent":["import * as firehoseExamplesNs from './firehose/examples';\nimport * as snsExamplesNs from './sns/examples';\nimport * as firehoseSchemasNs from './firehose/schemas';\nimport * as snsSchemasNs from './sns/schemas';\n\nexport * as schemas from './schemas';\nexport * as examples from './examples';\nexport { hints } from './hints';\n\n/** Dev examples per export, keyed by the export names in package.json. */\nexport const exportExamples = {\n destinationFirehose: firehoseExamplesNs,\n destinationSNS: snsExamplesNs,\n};\n\n/** Schemas per export, keyed by the export names in package.json. */\nexport const exportSchemas = {\n destinationFirehose: {\n settings: firehoseSchemasNs.settings,\n mapping: firehoseSchemasNs.mapping,\n },\n destinationSNS: {\n settings: snsSchemasNs.settings,\n mapping: snsSchemasNs.mapping,\n setup: snsSchemasNs.setup,\n },\n};\n","export * as env from './env';\nexport * as step from './step';\n","import type { PutRecordBatchCommandInput } from '@aws-sdk/client-firehose';\nimport type { Env, SendClient } from '../types';\n\n/**\n * Example environment for the AWS Firehose destination.\n *\n * `push` is the mock env simulate injects: the client answers every `send`\n * locally, so nothing reaches AWS. Each command keeps its `input`, so a\n * recorded `send` shows the request.\n */\n\ninterface RecordsInput {\n Records: unknown[];\n}\n\nfunction hasRecords(value: unknown): value is RecordsInput {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'Records' in value &&\n Array.isArray(value.Records)\n );\n}\n\n// Mock FirehoseClient class: every record is accepted.\nclass MockFirehoseClient implements SendClient {\n config: unknown;\n\n constructor(config?: unknown) {\n this.config = config;\n }\n\n async send(command: object) {\n const input = 'input' in command ? command.input : undefined;\n const records = hasRecords(input) ? input.Records : [];\n return {\n FailedPutCount: 0,\n Encrypted: false,\n RequestResponses: records.map((_, index) => ({\n RecordId: `mock-record-id-${index}`,\n })),\n };\n }\n\n destroy(): void {}\n}\n\n// Mock PutRecordBatchCommand class. The build minifies class names; the tag\n// keeps the SDK command name in printed simulate output.\nclass MockPutRecordBatchCommand {\n readonly input: PutRecordBatchCommandInput;\n\n constructor(input: PutRecordBatchCommandInput) {\n this.input = input;\n }\n\n get [Symbol.toStringTag](): string {\n return 'PutRecordBatchCommand';\n }\n}\n\nexport const push: Env = {\n AWS: {\n FirehoseClient: MockFirehoseClient,\n PutRecordBatchCommand: MockPutRecordBatchCommand,\n },\n};\n\nexport const simulation = ['call:AWS.FirehoseClient.send'];\n","import type { Flow } from '@walkeros/core';\nimport { createEvent, getEvent } from '@walkeros/core';\nimport { toRecordData } from '../lib/records';\n\n/**\n * Firehose step examples. Each `out` is the recorded\n * `client.send(new PutRecordBatchCommand(input))` call. A record is the full\n * event as JSON plus a newline, or the mapped `data` when a mapping produced\n * an object.\n */\n\nconst STREAM = 'walkeros-events';\n\n/**\n * The copy-paste config: the stream, its region, and keys from `$secret`.\n * `init` builds one client from it, offline, with a per-attempt timeout of a\n * quarter of the collector's 10 s race, so the SDK's three attempts end\n * before the collector stops waiting.\n */\nexport const init: Flow.StepExample = {\n title: 'Initialization',\n description:\n 'Init builds one FirehoseClient for the stream region with the credentials from config.credentials and a 2500 ms per-attempt timeout. Nothing is sent until the first event.',\n in: {\n settings: { streamName: STREAM, region: 'eu-central-1' },\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n },\n out: [\n [\n 'new FirehoseClient',\n {\n region: 'eu-central-1',\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n requestHandler: { requestTimeout: 2500, throwOnRequestTimeout: true },\n },\n ],\n ],\n};\n\nconst pageEvent = getEvent('page view', {\n id: 'ev-1700001000',\n timestamp: 1700001000,\n data: { title: 'Home', url: 'https://example.com/' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst orderEvt = getEvent('order complete', {\n id: 'ev-1700001001',\n timestamp: 1700001001,\n data: { id: 'ORD-400', value: 99.99, currency: 'EUR' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst signupEvt = createEvent({\n name: 'user signup',\n id: 'ev-1700001002',\n timestamp: 1700001002,\n data: { plan: 'pro', source: 'landing-page' },\n user: { id: 'usr-789', email: 'new@example.com' },\n source: { type: 'express', platform: 'server' },\n});\n\nfunction sent(payload: unknown): Flow.StepExample['out'] {\n return [\n [\n 'client.send',\n {\n DeliveryStreamName: STREAM,\n Records: [{ Data: toRecordData(payload) }],\n },\n ],\n ];\n}\n\nexport const firehoseRecord: Flow.StepExample = {\n title: 'Page view record',\n description:\n 'A page view is sent to Firehose as one record: the full event as JSON followed by a newline.',\n in: pageEvent,\n mapping: undefined,\n out: sent(pageEvent),\n};\n\nexport const orderEvent: Flow.StepExample = {\n title: 'Order record',\n description:\n 'An order complete event is serialized and delivered to Firehose as one newline-terminated record.',\n in: orderEvt,\n mapping: undefined,\n out: sent(orderEvt),\n};\n\nexport const userSignupEvent: Flow.StepExample = {\n title: 'User signup record',\n description:\n 'A user signup event including user fields is streamed to Firehose as a JSON record.',\n in: signupEvt,\n mapping: undefined,\n out: sent(signupEvt),\n};\n\nexport const mappedRecord: Flow.StepExample = {\n title: 'Mapped record',\n description:\n 'A mapping that produces an object sends that object as the record instead of the full event. Keep the event id in it for deduplication.',\n in: orderEvt,\n mapping: {\n data: {\n map: {\n id: 'id',\n name: 'name',\n order_id: 'data.id',\n total: 'data.value',\n },\n },\n },\n out: sent({\n id: 'ev-1700001001',\n name: 'order complete',\n order_id: 'ORD-400',\n total: 99.99,\n }),\n};\n\n/** A silent rule sends no record to Firehose. */\nexport const silentRule: Flow.StepExample = {\n public: false,\n description: 'A rule with silent: true sends no record to Firehose.',\n in: pageEvent,\n mapping: { silent: true },\n out: [],\n};\n","import type { WalkerOS } from '@walkeros/core';\nimport { isObject } from '@walkeros/core';\n\n/**\n * What one record or message carries: the mapped `data` when the mapping\n * produced an object, else the full event.\n */\nexport function toPayload(event: WalkerOS.Event, data?: unknown): object {\n return isObject(data) ? data : event;\n}\n","export { toPayload } from '../../lib/payload';\n\n/** Most records one `PutRecordBatch` call accepts. */\nexport const MAX_RECORDS_PER_CALL = 500;\n\n/**\n * Raw bytes per call, kept below the documented 4 MiB request limit with room\n * for the base64 encoding and the JSON envelope of the request.\n */\nexport const MAX_BYTES_PER_CALL = 2_900_000;\n\n/** Largest record Firehose accepts, newline included. */\nexport const MAX_RECORD_BYTES = 1_000_000;\n\n/** The record bytes: the payload as JSON, plus `\\n` unless `newline` is false. */\nexport function toRecordData(payload: unknown, newline = true): Buffer {\n const json = JSON.stringify(payload);\n if (typeof json !== 'string')\n throw new TypeError('The payload does not serialize to JSON.');\n return Buffer.from(newline ? `${json}\\n` : json);\n}\n\n/** One record on its way out, with its index in the delivery. */\nexport interface PlannedRecord {\n index: number;\n data: Buffer;\n}\n\n/** A record refused before sending; it is never sent. */\nexport interface RefusedRecord {\n index: number;\n code: 'RecordTooLarge' | 'InvalidRecord';\n detail: string;\n cause?: unknown;\n}\n\nexport interface Plan {\n chunks: PlannedRecord[][];\n refused: RefusedRecord[];\n}\n\n/**\n * Turns payloads into records and splits them into calls of at most\n * `MAX_RECORDS_PER_CALL` records and `MAX_BYTES_PER_CALL` bytes, in order.\n * A record that cannot be serialized or is too large is refused on its own,\n * so it never fails its neighbours.\n */\nexport function planChunks(\n payloads: readonly unknown[],\n newline: boolean,\n): Plan {\n const chunks: PlannedRecord[][] = [];\n const refused: RefusedRecord[] = [];\n let current: PlannedRecord[] = [];\n let currentBytes = 0;\n\n payloads.forEach((payload, index) => {\n let data: Buffer;\n try {\n data = toRecordData(payload, newline);\n } catch (error) {\n refused.push({\n index,\n code: 'InvalidRecord',\n detail: `Record ${index} does not serialize to JSON.`,\n cause: error,\n });\n return;\n }\n\n if (data.byteLength > MAX_RECORD_BYTES) {\n refused.push({\n index,\n code: 'RecordTooLarge',\n detail: `Record ${index} is ${data.byteLength} bytes, over the ${MAX_RECORD_BYTES} byte limit.`,\n });\n return;\n }\n\n if (\n current.length >= MAX_RECORDS_PER_CALL ||\n currentBytes + data.byteLength > MAX_BYTES_PER_CALL\n ) {\n chunks.push(current);\n current = [];\n currentBytes = 0;\n }\n\n current.push({ index, data });\n currentBytes += data.byteLength;\n });\n\n if (current.length > 0) chunks.push(current);\n return { chunks, refused };\n}\n","export * as env from './env';\nexport * as step from './step';\n","import type {\n CreateTopicCommandInput,\n GetTopicAttributesCommandInput,\n PublishCommandInput,\n SubscribeCommandInput,\n} from '@aws-sdk/client-sns';\nimport type { GetCallerIdentityCommandInput } from '@aws-sdk/client-sts';\nimport type { Env, SendClient } from '../types';\n\n/**\n * Example environment for the AWS SNS destination.\n *\n * `push` is the mock env simulate injects: the SNS and STS clients answer\n * every `send` locally, so nothing reaches AWS. Each command keeps its\n * `input`, so a recorded `send` shows the request (`Publish` per event).\n * Unit tests still substitute the SDK module-wide via\n * `jest.mock('@aws-sdk/client-sns')`.\n */\n\nconst TOPIC_ARN = 'arn:aws:sns:eu-central-1:123456789012:walkeros-events';\n\n// The build minifies class names; the tag keeps the SDK command name in\n// printed simulate output (`{\"PublishCommand\":{\"input\":...}}`).\nclass MockCommand<Input> {\n constructor(public readonly input: Input) {}\n}\n\nclass MockCreateTopicCommand extends MockCommand<CreateTopicCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'CreateTopicCommand';\n }\n}\nclass MockPublishCommand extends MockCommand<PublishCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'PublishCommand';\n }\n}\nclass MockGetTopicAttributesCommand extends MockCommand<GetTopicAttributesCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'GetTopicAttributesCommand';\n }\n}\nclass MockSubscribeCommand extends MockCommand<SubscribeCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'SubscribeCommand';\n }\n}\nclass MockGetCallerIdentityCommand extends MockCommand<GetCallerIdentityCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'GetCallerIdentityCommand';\n }\n}\n\nclass MockSNSClient implements SendClient {\n constructor(public config?: object) {}\n async send(command: object): Promise<unknown> {\n if (command instanceof MockCreateTopicCommand)\n return { TopicArn: TOPIC_ARN };\n if (command instanceof MockPublishCommand)\n return { MessageId: 'mock-message-id' };\n return {};\n }\n destroy(): void {}\n}\n\nclass MockSTSClient implements SendClient {\n constructor(public config?: object) {}\n async send(): Promise<unknown> {\n return {\n Account: '123456789012',\n Arn: 'arn:aws:iam::123456789012:user/walkeros',\n };\n }\n destroy(): void {}\n}\n\nexport const push: Env = {\n AWS: {\n SNSClient: MockSNSClient,\n CreateTopicCommand: MockCreateTopicCommand,\n PublishCommand: MockPublishCommand,\n GetTopicAttributesCommand: MockGetTopicAttributesCommand,\n SubscribeCommand: MockSubscribeCommand,\n STSClient: MockSTSClient,\n GetCallerIdentityCommand: MockGetCallerIdentityCommand,\n },\n};\n\n/** Every request goes through `send`; the command in `args[0]` names it. */\nexport const simulation = ['call:AWS.SNSClient.send'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\n\n/**\n * SNS step examples. Each example's `out` is the array of recorded mock\n * calls produced by `push()`. The recording shape is:\n * ['client.send', commandInput]\n *\n * The destination JSON-stringifies the event (or the mapped `data` object)\n * into the Publish call's Message field. Mapping entries (messageGroupId,\n * messageDeduplicationId, messageAttributes) resolve per event via\n * getMappingValue. On a FIFO topic the deduplication id defaults to the\n * event id.\n */\n\nconst TOPIC_ARN = 'arn:aws:sns:eu-central-1:123456789012:walkeros-events';\nconst FIFO_ARN = 'arn:aws:sns:eu-central-1:123456789012:walkeros-events.fifo';\n\n/**\n * The copy-paste config: the topic ARN, which also names the region, and\n * keys from `$secret`. `init` builds one client from it, offline; nothing is\n * sent until the first event.\n */\nexport const init: Flow.StepExample = {\n title: 'Initialization',\n description:\n 'Init builds one SNSClient in the region of the topic ARN with the credentials from config.credentials and a 2500 ms per-attempt timeout. No topic is created and nothing is sent until the first event.',\n in: {\n settings: { topicArn: TOPIC_ARN },\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n },\n out: [\n [\n 'new SNSClient',\n {\n region: 'eu-central-1',\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n requestHandler: { requestTimeout: 2500, throwOnRequestTimeout: true },\n },\n ],\n ],\n};\n\nconst pageEvent = getEvent('page view', {\n id: 'ev-1700001000',\n timestamp: 1700001000,\n data: { title: 'Home', url: 'https://example.com/' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst orderEvt = getEvent('order complete', {\n id: 'ev-1700001001',\n timestamp: 1700001001,\n data: { id: 'ORD-400', value: 99.99, currency: 'EUR' },\n user: { id: 'usr-789' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst productViewEvt = getEvent('product view', {\n id: 'ev-1700001002',\n timestamp: 1700001002,\n data: { id: 'SKU-1', tenant_id: 'acme' },\n source: { type: 'express', platform: 'server' },\n});\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view publish',\n description:\n 'A page view event is JSON-stringified and published as the Message of an SNS Publish call.',\n in: pageEvent,\n mapping: undefined,\n out: [\n [\n 'client.send',\n {\n TopicArn: TOPIC_ARN,\n Message: JSON.stringify(pageEvent),\n },\n ],\n ],\n};\n\nexport const orderEvent: Flow.StepExample = {\n title: 'Order publish with FIFO group (path-resolved)',\n description:\n 'An order complete event is published to a FIFO topic with a messageGroupId resolved from the event via the mapping path \"user.id\". The deduplication id defaults to the event id.',\n in: orderEvt,\n mapping: { settings: { messageGroupId: 'user.id' } },\n out: [\n [\n 'client.send',\n {\n TopicArn: FIFO_ARN,\n Message: JSON.stringify(orderEvt),\n MessageGroupId: 'usr-789',\n MessageDeduplicationId: 'ev-1700001001',\n },\n ],\n ],\n};\n\nexport const attributedPublish: Flow.StepExample = {\n title: 'Publish with per-event message attributes',\n description:\n 'Demonstrates `messageAttributes` as `Mapping.Map`: each attribute value resolves per event. Operators express the SDK shape (`{ DataType, StringValue }`) per entry.',\n in: productViewEvt,\n mapping: {\n settings: {\n messageAttributes: {\n schema_version: { value: { DataType: 'String', StringValue: 'v4' } },\n tenant: { value: { DataType: 'String', StringValue: 'acme' } },\n },\n },\n },\n out: [\n [\n 'client.send',\n {\n TopicArn: TOPIC_ARN,\n Message: JSON.stringify(productViewEvt),\n MessageAttributes: {\n schema_version: { DataType: 'String', StringValue: 'v4' },\n tenant: { DataType: 'String', StringValue: 'acme' },\n },\n },\n ],\n ],\n};\n\nexport const mappedMessage: Flow.StepExample = {\n title: 'Mapped message',\n description:\n 'A mapping that produces an object publishes that object as the Message instead of the full event. Keep the event id in it for deduplication.',\n in: orderEvt,\n mapping: {\n data: {\n map: { id: 'id', name: 'name', order_id: 'data.id', total: 'data.value' },\n },\n },\n out: [\n [\n 'client.send',\n {\n TopicArn: TOPIC_ARN,\n Message: JSON.stringify({\n id: 'ev-1700001001',\n name: 'order complete',\n order_id: 'ORD-400',\n total: 99.99,\n }),\n },\n ],\n ],\n};\n\n/** A silent rule publishes no message to SNS. */\nexport const silentRule: Flow.StepExample = {\n public: false,\n description: 'A rule with silent: true publishes no message to SNS.',\n in: pageEvent,\n mapping: { silent: true },\n out: [],\n};\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema, FirehoseConfigSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport {\n SettingsSchema,\n type Settings,\n FirehoseConfigSchema,\n} from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n\n// Nested JSON Schema for Firehose subpage\nexport const firehose = zodToSchema(FirehoseConfigSchema);\n","import { z } from '@walkeros/core/dev';\n\nconst streamName = z\n .string()\n .min(1)\n .describe('Name of the Firehose stream (like walkeros-events). Required.')\n .optional();\n\nconst region = z\n .string()\n .describe(\n 'AWS region of the stream (like eu-central-1). Default: AWS_REGION or the active profile, else eu-central-1.',\n );\n\nconst client = z\n .any()\n .describe(\n 'A FirehoseClient of your own. Used as is and never closed by the destination.',\n );\n\nconst config = z\n .any()\n .describe(\n 'Raw FirehoseClient options passed to the SDK (like { endpoint, maxAttempts }). Put keys in config.credentials instead.',\n );\n\n/** @deprecated The nested form, still read as an alias of the flat fields. */\nexport const FirehoseConfigSchema = z.object({\n streamName,\n client: client.optional(),\n region: region.optional(),\n config: config.optional(),\n});\n\nexport const SettingsSchema = z\n .object({\n // Optional in the schema only so the deprecated alias still validates;\n // init throws when neither form names a stream.\n streamName,\n region: region.optional(),\n newline: z\n .boolean()\n .describe(\n 'Append a newline to every record (default true). Set false when the stream adds its own new line delimiter.',\n )\n .optional(),\n config: config.optional(),\n client: client.optional(),\n firehose: FirehoseConfigSchema.describe(\n 'Deprecated: use the flat fields streamName, region, config and client.',\n ).optional(),\n })\n .refine(\n (settings) =>\n settings.streamName !== undefined ||\n settings.firehose?.streamName !== undefined,\n { message: 'Set settings.streamName' },\n )\n // The same rule in JSON Schema: the stream is named in one of both forms.\n .meta({\n anyOf: [\n { required: ['streamName'] },\n {\n required: ['firehose'],\n properties: { firehose: { required: ['streamName'] } },\n },\n ],\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * AWS Firehose Mapping Schema\n * Firehose has no rule-level settings: a rule's `data` becomes the record.\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\nimport { SetupSchema } from './setup';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\nexport {\n SetupSchema,\n SetupSubscriptionSchema,\n type Setup,\n type SetupSubscription,\n} from './setup';\n\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\nexport const setup = zodToSchema(SetupSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z\n .object({\n topicArn: z\n .string()\n .describe(\n 'Topic ARN (like arn:aws:sns:eu-central-1:123456789012:walkeros-events). Region and topic name derive from it. Required unless topicName is set.',\n )\n .optional(),\n topicName: z\n .string()\n .min(1)\n .describe(\n 'Topic name (like walkeros-events). Used by walkeros setup; without topicArn the ARN is completed with the account id at the first publish.',\n )\n .optional(),\n region: z\n .string()\n .describe(\n 'AWS region (like eu-central-1). Default: the region in topicArn, AWS_REGION or the active profile, else eu-central-1.',\n )\n .optional(),\n client: z\n .any()\n .describe(\n 'An SNSClient of your own. Used as is and never closed by the destination.',\n )\n .optional(),\n config: z\n .any()\n .describe(\n 'Raw SNSClient options passed to the SDK. Put keys in config.credentials instead.',\n )\n .optional(),\n })\n .refine(\n (settings) =>\n settings.topicArn !== undefined || settings.topicName !== undefined,\n { message: 'Set settings.topicArn or settings.topicName' },\n )\n // The same rule in JSON Schema: one of both names the topic.\n .meta({\n anyOf: [{ required: ['topicArn'] }, { required: ['topicName'] }],\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * SNS Mapping Schema.\n *\n * `messageAttributes` is `Mapping.Map`: each value resolves per event to the\n * SDK's `{ DataType, StringValue }` shape. Schema accepts any structure;\n * runtime mapping resolution coerces shape via `getMappingValue`.\n *\n * `messageGroupId` and `messageDeduplicationId` are `Mapping.Value`: a string\n * path or a value-config object.\n */\nexport const MappingSchema = z.object({\n messageAttributes: z.record(z.string(), z.unknown()).optional(),\n messageGroupId: z.unknown().optional(),\n messageDeduplicationId: z.unknown().optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const SetupSubscriptionSchema = z.object({\n protocol: z.enum(['sqs', 'lambda', 'https', 'http', 'email', 'sms']),\n endpoint: z.string().min(1),\n rawMessageDelivery: z.boolean().optional(),\n filterPolicy: z.record(z.string(), z.unknown()).optional(),\n deadLetterTargetArn: z.string().optional(),\n});\n\nexport const SetupSchema = z.object({\n region: z.string().optional(),\n displayName: z.string().optional(),\n fifoTopic: z.boolean().optional(),\n kmsMasterKeyId: z.string().optional(),\n tags: z.record(z.string(), z.string()).optional(),\n subscriptions: z.array(SetupSubscriptionSchema).optional(),\n});\n\nexport type Setup = z.infer<typeof SetupSchema>;\nexport type SetupSubscription = z.infer<typeof SetupSubscriptionSchema>;\n","// Browser-safe schema-only exports\n// This file exports ONLY schemas without any Node.js dependencies\n\nexport {\n settings as firehoseSettings,\n mapping as firehoseMapping,\n firehose,\n} from './firehose/schemas';\n\nexport {\n settings as snsSettings,\n mapping as snsMapping,\n setup as snsSetup,\n} from './sns/schemas';\n\n// Backwards-compatible aliases (firehose is the package's default sub-destination).\nexport { settings, mapping } from './firehose/schemas';\n","export * as firehose from '../firehose/examples';\nexport * as sns from '../sns/examples';\n// Re-export env at top level for env-loader compatibility (matches web pattern)\nexport * as env from '../firehose/examples/env';\nexport * as step from '../firehose/examples/step';\n","import type { Hint } from '@walkeros/core';\n\nexport const hints: Hint.Hints = {\n 'minimal-config': {\n text: 'Firehose needs settings.streamName (plus settings.region when the stream is not in AWS_REGION or eu-central-1). SNS needs settings.topicArn; region and topic name derive from it. Off AWS, add config.credentials. Nothing is sent and no credentials are loaded until the first event.',\n code: [\n {\n lang: 'json',\n code: '{ \"settings\": { \"streamName\": \"walkeros-events\", \"region\": \"eu-central-1\" }, \"credentials\": { \"accessKeyId\": \"$secret.AWS_ACCESS_KEY_ID\", \"secretAccessKey\": \"$secret.AWS_SECRET_ACCESS_KEY\" } }',\n },\n {\n lang: 'json',\n code: '{ \"settings\": { \"topicArn\": \"arn:aws:sns:eu-central-1:123456789012:walkeros-events\" } }',\n },\n ],\n },\n 'auth-credentials': {\n text: 'On AWS compute an attached IAM role needs no config at all. Elsewhere, config.credentials ({ accessKeyId, secretAccessKey, sessionToken? }, or the same as a JSON string) wins over settings.config.credentials, which wins over the AWS default chain (AWS_* variables, AWS_PROFILE, ECS, EC2 and web identity roles; Kubernetes can go keyless with AWS_ROLE_ARN plus AWS_WEB_IDENTITY_TOKEN_FILE). Back every value with $secret; never write a literal key. Credentials are shape-checked at init and loaded only at the first send.',\n code: [\n {\n lang: 'json',\n code: '{ \"credentials\": { \"accessKeyId\": \"$secret.AWS_ACCESS_KEY_ID\", \"secretAccessKey\": \"$secret.AWS_SECRET_ACCESS_KEY\" } }',\n },\n ],\n },\n 'firehose-records': {\n text: 'Each record is the mapped data object, or the full event when the mapping produced none, followed by a newline. Set settings.newline: false when the stream adds its own new line delimiter. Batching is on by default (500 records or 1 s); calls carry at most 500 records and 2,900,000 bytes, and a record over 1,000,000 bytes fails as RecordTooLarge without being sent.',\n },\n 'delivery-guarantee': {\n text: 'Delivery is at least once: deduplicate downstream on event.id, and keep id in mapped data. A record AWS rejects is reported as failed with code, status and retryable. There is no retry beyond the built-in AWS SDK retry: a rejected record goes to the in-memory dead letter queue of the collector, which nothing replays yet. On SNS FIFO topics MessageDeduplicationId defaults to event.id.',\n },\n 'troubleshoot-errors': {\n text: 'Every failure carries code, status and retryable, and its message names the stream or topic and the region; the AWS error itself stays on the error as its cause. ResourceNotFoundException: wrong settings.streamName or region. AccessDeniedException / AuthorizationErrorException: the credentials lack firehose:PutRecordBatch or sns:Publish. UnrecognizedClientException, InvalidSignatureException, ExpiredTokenException or no credentials found: check config.credentials or the environment. SNS NotFoundException: the topic does not exist; run walkeros setup or set settings.topicArn. NULL rows in Athena: the stream adds its own new line delimiter too, so set newline: false. Code config at start: a missing or conflicting setting, named in the message.',\n },\n};\n"],"mappings":"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","names":["examples_exports","config","import_core","examples_exports","env_exports","step_exports","env_exports","push","simulation","config","step_exports","init","orderEvent","silentRule","import_core","TOPIC_ARN","pageEvent","orderEvt","import_dev","settings","import_dev","import_dev","import_dev","SettingsSchema","settings","import_dev","MappingSchema","import_dev","settings","SettingsSchema","mapping","MappingSchema","mapping","settings","examples_exports","examples_exports","settings","mapping"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/firehose/examples/index.ts","../src/firehose/examples/env.ts","../src/firehose/examples/step.ts","../src/firehose/examples/minimal.ts","../src/sns/examples/index.ts","../src/sns/examples/env.ts","../src/sns/examples/step.ts","../src/sns/examples/minimal.ts","../src/firehose/schemas/index.ts","../src/firehose/schemas/settings.ts","../src/firehose/schemas/mapping.ts","../src/sns/schemas/index.ts","../src/sns/schemas/settings.ts","../src/sns/schemas/mapping.ts","../src/sns/schemas/setup.ts","../src/schemas.ts","../src/examples/index.ts","../src/hints.ts"],"sourcesContent":["import * as firehoseExamplesNs from './firehose/examples';\nimport * as snsExamplesNs from './sns/examples';\nimport * as firehoseSchemasNs from './firehose/schemas';\nimport * as snsSchemasNs from './sns/schemas';\n\nexport * as schemas from './schemas';\nexport * as examples from './examples';\nexport { hints } from './hints';\n\n/** Dev examples per export, keyed by the export names in package.json. */\nexport const exportExamples = {\n destinationFirehose: firehoseExamplesNs,\n destinationSNS: snsExamplesNs,\n};\n\n/** Schemas per export, keyed by the export names in package.json. */\nexport const exportSchemas = {\n destinationFirehose: {\n settings: firehoseSchemasNs.settings,\n mapping: firehoseSchemasNs.mapping,\n },\n destinationSNS: {\n settings: snsSchemasNs.settings,\n mapping: snsSchemasNs.mapping,\n setup: snsSchemasNs.setup,\n },\n};\n","export * as env from './env';\nexport * as step from './step';\nexport { minimal } from './minimal';\n","import type { PutRecordBatchCommandInput } from '@aws-sdk/client-firehose';\nimport type { Env, SendClient } from '../types';\n\n/**\n * Example environment for the AWS Firehose destination.\n *\n * `push` is the mock env simulate injects: the client answers every `send`\n * locally, so nothing reaches AWS. Each command keeps its `input`, so a\n * recorded `send` shows the request.\n */\n\ninterface RecordsInput {\n Records: unknown[];\n}\n\nfunction hasRecords(value: unknown): value is RecordsInput {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'Records' in value &&\n Array.isArray(value.Records)\n );\n}\n\n// Mock FirehoseClient class: every record is accepted.\nclass MockFirehoseClient implements SendClient {\n config: unknown;\n\n constructor(config?: unknown) {\n this.config = config;\n }\n\n async send(command: object) {\n const input = 'input' in command ? command.input : undefined;\n const records = hasRecords(input) ? input.Records : [];\n return {\n FailedPutCount: 0,\n Encrypted: false,\n RequestResponses: records.map((_, index) => ({\n RecordId: `mock-record-id-${index}`,\n })),\n };\n }\n\n destroy(): void {}\n}\n\n// Mock PutRecordBatchCommand class. The build minifies class names; the tag\n// keeps the SDK command name in printed simulate output.\nclass MockPutRecordBatchCommand {\n readonly input: PutRecordBatchCommandInput;\n\n constructor(input: PutRecordBatchCommandInput) {\n this.input = input;\n }\n\n get [Symbol.toStringTag](): string {\n return 'PutRecordBatchCommand';\n }\n}\n\nexport const push: Env = {\n AWS: {\n FirehoseClient: MockFirehoseClient,\n PutRecordBatchCommand: MockPutRecordBatchCommand,\n },\n};\n\nexport const simulation = ['call:AWS.FirehoseClient.send'];\n","import type { Flow } from '@walkeros/core';\nimport { createEvent, getEvent } from '@walkeros/core';\n\n/**\n * Firehose step examples. Each `out` is the recorded\n * `client.send(new PutRecordBatchCommand(input))` call. A record is the full\n * event as JSON plus a newline, or the mapped `data` when a mapping produced\n * an object; each record's bytes are written out below.\n */\n\nconst STREAM = 'walkeros-events';\n\n/**\n * The copy-paste config: the stream, its region, and keys from `$secret`.\n * `init` builds one client from it, offline, with a per-attempt timeout of a\n * quarter of the collector's 10 s race, so the SDK's three attempts end\n * before the collector stops waiting.\n */\nexport const init: Flow.StepExample = {\n title: 'Initialization',\n description:\n 'Init builds one FirehoseClient for the stream region with the credentials from config.credentials and a 2500 ms per-attempt timeout. Nothing is sent until the first event.',\n in: {\n settings: { streamName: STREAM, region: 'eu-central-1' },\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n },\n out: [\n [\n 'new FirehoseClient',\n {\n region: 'eu-central-1',\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n requestHandler: { requestTimeout: 2500, throwOnRequestTimeout: true },\n },\n ],\n ],\n};\n\nconst pageEvent = getEvent('page view', {\n id: 'ev-1700001000',\n timestamp: 1700001000000,\n data: { title: 'Home', url: 'https://example.com/' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst orderEvt = getEvent('order complete', {\n id: 'ev-1700001001',\n timestamp: 1700001001000,\n data: { id: 'ORD-400', value: 99.99, currency: 'EUR' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst signupEvt = createEvent({\n name: 'user signup',\n id: 'ev-1700001002',\n timestamp: 1700001002000,\n data: { plan: 'pro', source: 'landing-page' },\n user: { id: 'usr-789', email: 'new@example.com' },\n source: { type: 'express', platform: 'server' },\n});\n\nexport const firehoseRecord: Flow.StepExample = {\n title: 'Page view record',\n description:\n 'A page view is sent to Firehose as one record: the full event as JSON followed by a newline.',\n in: pageEvent,\n mapping: undefined,\n out: [\n [\n 'client.send',\n {\n DeliveryStreamName: STREAM,\n Records: [\n {\n Data: Buffer.from(\n '{\"name\":\"page view\",\"data\":{\"title\":\"Home\",\"url\":\"https://example.com/\"},\"context\":{\"dev\":[\"test\",1]},\"globals\":{\"pagegroup\":\"docs\"},\"custom\":{\"completely\":\"random\"},\"user\":{\"id\":\"us3r\",\"device\":\"c00k13\",\"session\":\"s3ss10n\"},\"nested\":[{\"entity\":\"child\",\"data\":{\"is\":\"subordinated\"}}],\"consent\":{\"functional\":true},\"id\":\"ev-1700001000\",\"trigger\":\"load\",\"entity\":\"page\",\"action\":\"view\",\"timestamp\":1700001000000,\"timing\":3.14,\"source\":{\"count\":1,\"trace\":\"0a1b2c3d4e5f60718293a4b5c6d7e8f9\",\"type\":\"express\",\"platform\":\"server\"}}\\n',\n ),\n },\n ],\n },\n ],\n ],\n};\n\nexport const orderEvent: Flow.StepExample = {\n title: 'Order record',\n description:\n 'An order complete event is serialized and delivered to Firehose as one newline-terminated record.',\n in: orderEvt,\n mapping: undefined,\n out: [\n [\n 'client.send',\n {\n DeliveryStreamName: STREAM,\n Records: [\n {\n Data: Buffer.from(\n '{\"name\":\"order complete\",\"data\":{\"id\":\"ORD-400\",\"value\":99.99,\"currency\":\"EUR\"},\"context\":{\"shopping\":[\"complete\",0]},\"globals\":{\"pagegroup\":\"shop\"},\"custom\":{\"completely\":\"random\"},\"user\":{\"id\":\"us3r\",\"device\":\"c00k13\",\"session\":\"s3ss10n\"},\"nested\":[{\"entity\":\"product\",\"data\":{\"id\":\"ers\",\"name\":\"Everyday Ruck Snack\",\"color\":\"black\",\"size\":\"l\",\"price\":420},\"context\":{\"shopping\":[\"complete\",0]},\"nested\":[]},{\"entity\":\"product\",\"data\":{\"id\":\"cc\",\"name\":\"Cool Cap\",\"size\":\"one size\",\"price\":42},\"context\":{\"shopping\":[\"complete\",0]},\"nested\":[]},{\"entity\":\"gift\",\"data\":{\"name\":\"Surprise\"},\"context\":{\"shopping\":[\"complete\",0]},\"nested\":[]}],\"consent\":{\"functional\":true},\"id\":\"ev-1700001001\",\"trigger\":\"load\",\"entity\":\"order\",\"action\":\"complete\",\"timestamp\":1700001001000,\"timing\":3.14,\"source\":{\"count\":1,\"trace\":\"0a1b2c3d4e5f60718293a4b5c6d7e8f9\",\"type\":\"express\",\"platform\":\"server\"}}\\n',\n ),\n },\n ],\n },\n ],\n ],\n};\n\nexport const userSignupEvent: Flow.StepExample = {\n title: 'User signup record',\n description:\n 'A user signup event including user fields is streamed to Firehose as a JSON record.',\n in: signupEvt,\n mapping: undefined,\n out: [\n [\n 'client.send',\n {\n DeliveryStreamName: STREAM,\n Records: [\n {\n Data: Buffer.from(\n '{\"name\":\"user signup\",\"data\":{\"plan\":\"pro\",\"source\":\"landing-page\"},\"context\":{\"dev\":[\"test\",1]},\"globals\":{\"lang\":\"elb\"},\"custom\":{\"completely\":\"random\"},\"user\":{\"id\":\"usr-789\",\"email\":\"new@example.com\"},\"nested\":[{\"entity\":\"child\",\"data\":{\"is\":\"subordinated\"}}],\"consent\":{\"functional\":true},\"id\":\"ev-1700001002\",\"trigger\":\"test\",\"entity\":\"user\",\"action\":\"signup\",\"timestamp\":1700001002000,\"timing\":3.14,\"source\":{\"count\":1,\"trace\":\"0a1b2c3d4e5f60718293a4b5c6d7e8f9\",\"type\":\"express\",\"platform\":\"server\"}}\\n',\n ),\n },\n ],\n },\n ],\n ],\n};\n\nexport const mappedRecord: Flow.StepExample = {\n title: 'Mapped record',\n description:\n 'A mapping that produces an object sends that object as the record instead of the full event. Keep the event id in it for deduplication.',\n in: orderEvt,\n mapping: {\n data: {\n map: {\n id: 'id',\n name: 'name',\n order_id: 'data.id',\n total: 'data.value',\n },\n },\n },\n out: [\n [\n 'client.send',\n {\n DeliveryStreamName: STREAM,\n Records: [\n {\n Data: Buffer.from(\n '{\"id\":\"ev-1700001001\",\"name\":\"order complete\",\"order_id\":\"ORD-400\",\"total\":99.99}\\n',\n ),\n },\n ],\n },\n ],\n ],\n};\n\n/** A silent rule sends no record to Firehose. */\nexport const silentRule: Flow.StepExample = {\n public: false,\n description: 'A rule with silent: true sends no record to Firehose.',\n in: pageEvent,\n mapping: { silent: true },\n out: [],\n};\n","import type { Flow } from '@walkeros/core';\n\n/**\n * The setting Firehose needs to deliver: the stream name. The region and the\n * credentials come from the AWS environment.\n */\nexport const minimal: Flow.MinimalExample = {\n settings: { streamName: 'walkeros-events' },\n};\n","export * as env from './env';\nexport * as step from './step';\nexport { minimal } from './minimal';\n","import type {\n CreateTopicCommandInput,\n GetTopicAttributesCommandInput,\n PublishCommandInput,\n SubscribeCommandInput,\n} from '@aws-sdk/client-sns';\nimport type { GetCallerIdentityCommandInput } from '@aws-sdk/client-sts';\nimport type { Env, SendClient } from '../types';\n\n/**\n * Example environment for the AWS SNS destination.\n *\n * `push` is the mock env simulate injects: the SNS and STS clients answer\n * every `send` locally, so nothing reaches AWS. Each command keeps its\n * `input`, so a recorded `send` shows the request (`Publish` per event).\n * Unit tests still substitute the SDK module-wide via\n * `jest.mock('@aws-sdk/client-sns')`.\n */\n\nconst TOPIC_ARN = 'arn:aws:sns:eu-central-1:123456789012:walkeros-events';\n\n// The build minifies class names; the tag keeps the SDK command name in\n// printed simulate output (`{\"PublishCommand\":{\"input\":...}}`).\nclass MockCommand<Input> {\n constructor(public readonly input: Input) {}\n}\n\nclass MockCreateTopicCommand extends MockCommand<CreateTopicCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'CreateTopicCommand';\n }\n}\nclass MockPublishCommand extends MockCommand<PublishCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'PublishCommand';\n }\n}\nclass MockGetTopicAttributesCommand extends MockCommand<GetTopicAttributesCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'GetTopicAttributesCommand';\n }\n}\nclass MockSubscribeCommand extends MockCommand<SubscribeCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'SubscribeCommand';\n }\n}\nclass MockGetCallerIdentityCommand extends MockCommand<GetCallerIdentityCommandInput> {\n get [Symbol.toStringTag](): string {\n return 'GetCallerIdentityCommand';\n }\n}\n\nclass MockSNSClient implements SendClient {\n constructor(public config?: object) {}\n async send(command: object): Promise<unknown> {\n if (command instanceof MockCreateTopicCommand)\n return { TopicArn: TOPIC_ARN };\n if (command instanceof MockPublishCommand)\n return { MessageId: 'mock-message-id' };\n return {};\n }\n destroy(): void {}\n}\n\nclass MockSTSClient implements SendClient {\n constructor(public config?: object) {}\n async send(): Promise<unknown> {\n return {\n Account: '123456789012',\n Arn: 'arn:aws:iam::123456789012:user/walkeros',\n };\n }\n destroy(): void {}\n}\n\nexport const push: Env = {\n AWS: {\n SNSClient: MockSNSClient,\n CreateTopicCommand: MockCreateTopicCommand,\n PublishCommand: MockPublishCommand,\n GetTopicAttributesCommand: MockGetTopicAttributesCommand,\n SubscribeCommand: MockSubscribeCommand,\n STSClient: MockSTSClient,\n GetCallerIdentityCommand: MockGetCallerIdentityCommand,\n },\n};\n\n/** Every request goes through `send`; the command in `args[0]` names it. */\nexport const simulation = ['call:AWS.SNSClient.send'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\n\n/**\n * SNS step examples. Each example's `out` is the array of recorded mock\n * calls produced by `push()`. The recording shape is:\n * ['client.send', commandInput]\n *\n * The destination JSON-stringifies the event (or the mapped `data` object)\n * into the Publish call's Message field. Mapping entries (messageGroupId,\n * messageDeduplicationId, messageAttributes) resolve per event via\n * getMappingValue. On a FIFO topic the deduplication id defaults to the\n * event id.\n */\n\nconst TOPIC_ARN = 'arn:aws:sns:eu-central-1:123456789012:walkeros-events';\nconst FIFO_ARN = 'arn:aws:sns:eu-central-1:123456789012:walkeros-events.fifo';\n\n/**\n * The copy-paste config: the topic ARN, which also names the region, and\n * keys from `$secret`. `init` builds one client from it, offline; nothing is\n * sent until the first event.\n */\nexport const init: Flow.StepExample = {\n title: 'Initialization',\n description:\n 'Init builds one SNSClient in the region of the topic ARN with the credentials from config.credentials and a 2500 ms per-attempt timeout. No topic is created and nothing is sent until the first event.',\n in: {\n settings: { topicArn: TOPIC_ARN },\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n },\n out: [\n [\n 'new SNSClient',\n {\n region: 'eu-central-1',\n credentials: {\n accessKeyId: '$secret.AWS_ACCESS_KEY_ID',\n secretAccessKey: '$secret.AWS_SECRET_ACCESS_KEY',\n },\n requestHandler: { requestTimeout: 2500, throwOnRequestTimeout: true },\n },\n ],\n ],\n};\n\nconst pageEvent = getEvent('page view', {\n id: 'ev-1700001000',\n timestamp: 1700001000000,\n data: { title: 'Home', url: 'https://example.com/' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst orderEvt = getEvent('order complete', {\n id: 'ev-1700001001',\n timestamp: 1700001001000,\n data: { id: 'ORD-400', value: 99.99, currency: 'EUR' },\n user: { id: 'usr-789' },\n source: { type: 'express', platform: 'server' },\n});\n\nconst productViewEvt = getEvent('product view', {\n id: 'ev-1700001002',\n timestamp: 1700001002000,\n data: { id: 'SKU-1', tenant_id: 'acme' },\n source: { type: 'express', platform: 'server' },\n});\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view publish',\n description:\n 'A page view event is JSON-stringified and published as the Message of an SNS Publish call.',\n in: pageEvent,\n mapping: undefined,\n out: [\n [\n 'client.send',\n {\n TopicArn: TOPIC_ARN,\n Message: JSON.stringify(pageEvent),\n },\n ],\n ],\n};\n\nexport const orderEvent: Flow.StepExample = {\n title: 'Order publish with FIFO group (path-resolved)',\n description:\n 'An order complete event is published to a FIFO topic with a messageGroupId resolved from the event via the mapping path \"user.id\". The deduplication id defaults to the event id.',\n in: orderEvt,\n mapping: { settings: { messageGroupId: 'user.id' } },\n out: [\n [\n 'client.send',\n {\n TopicArn: FIFO_ARN,\n Message: JSON.stringify(orderEvt),\n MessageGroupId: 'usr-789',\n MessageDeduplicationId: 'ev-1700001001',\n },\n ],\n ],\n};\n\nexport const attributedPublish: Flow.StepExample = {\n title: 'Publish with per-event message attributes',\n description:\n 'Demonstrates `messageAttributes` as `Mapping.Map`: each attribute value resolves per event. Operators express the SDK shape (`{ DataType, StringValue }`) per entry.',\n in: productViewEvt,\n mapping: {\n settings: {\n messageAttributes: {\n schema_version: { value: { DataType: 'String', StringValue: 'v4' } },\n tenant: { value: { DataType: 'String', StringValue: 'acme' } },\n },\n },\n },\n out: [\n [\n 'client.send',\n {\n TopicArn: TOPIC_ARN,\n Message: JSON.stringify(productViewEvt),\n MessageAttributes: {\n schema_version: { DataType: 'String', StringValue: 'v4' },\n tenant: { DataType: 'String', StringValue: 'acme' },\n },\n },\n ],\n ],\n};\n\nexport const mappedMessage: Flow.StepExample = {\n title: 'Mapped message',\n description:\n 'A mapping that produces an object publishes that object as the Message instead of the full event. Keep the event id in it for deduplication.',\n in: orderEvt,\n mapping: {\n data: {\n map: { id: 'id', name: 'name', order_id: 'data.id', total: 'data.value' },\n },\n },\n out: [\n [\n 'client.send',\n {\n TopicArn: TOPIC_ARN,\n Message: JSON.stringify({\n id: 'ev-1700001001',\n name: 'order complete',\n order_id: 'ORD-400',\n total: 99.99,\n }),\n },\n ],\n ],\n};\n\n/** A silent rule publishes no message to SNS. */\nexport const silentRule: Flow.StepExample = {\n public: false,\n description: 'A rule with silent: true publishes no message to SNS.',\n in: pageEvent,\n mapping: { silent: true },\n out: [],\n};\n","import type { Flow } from '@walkeros/core';\n\n/**\n * The setting SNS needs to deliver: the topic ARN. The credentials come from\n * the AWS environment.\n */\nexport const minimal: Flow.MinimalExample = {\n settings: {\n topicArn: 'arn:aws:sns:eu-central-1:123456789012:walkeros-events',\n },\n};\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema, FirehoseConfigSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport {\n SettingsSchema,\n type Settings,\n FirehoseConfigSchema,\n} from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n\n// Nested JSON Schema for Firehose subpage\nexport const firehose = zodToSchema(FirehoseConfigSchema);\n","import { z } from '@walkeros/core/dev';\n\nconst streamName = z\n .string()\n .min(1)\n .describe('Name of the Firehose stream (like walkeros-events). Required.')\n .optional();\n\nconst region = z\n .string()\n .describe(\n 'AWS region of the stream (like eu-central-1). Default: AWS_REGION or the active profile, else eu-central-1.',\n );\n\nconst client = z\n .any()\n .describe(\n 'A FirehoseClient of your own. Used as is and never closed by the destination.',\n );\n\nconst config = z\n .any()\n .describe(\n 'Raw FirehoseClient options passed to the SDK (like { endpoint, maxAttempts }). Put keys in config.credentials instead.',\n );\n\n/** @deprecated The nested form, still read as an alias of the flat fields. */\nexport const FirehoseConfigSchema = z.object({\n streamName,\n client: client.optional(),\n region: region.optional(),\n config: config.optional(),\n});\n\nexport const SettingsSchema = z\n .object({\n // Optional in the schema only so the deprecated alias still validates;\n // init throws when neither form names a stream.\n streamName,\n region: region.optional(),\n newline: z\n .boolean()\n .describe(\n 'Append a newline to every record (default true). Set false when the stream adds its own new line delimiter.',\n )\n .optional(),\n config: config.optional(),\n client: client.optional(),\n firehose: FirehoseConfigSchema.describe(\n 'Deprecated: use the flat fields streamName, region, config and client.',\n ).optional(),\n })\n .refine(\n (settings) =>\n settings.streamName !== undefined ||\n settings.firehose?.streamName !== undefined,\n { message: 'Set settings.streamName' },\n )\n // The same rule in JSON Schema: the stream is named in one of both forms.\n .meta({\n anyOf: [\n { required: ['streamName'] },\n {\n required: ['firehose'],\n properties: { firehose: { required: ['streamName'] } },\n },\n ],\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * AWS Firehose Mapping Schema\n * Firehose has no rule-level settings: a rule's `data` becomes the record.\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\nimport { SetupSchema } from './setup';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\nexport {\n SetupSchema,\n SetupSubscriptionSchema,\n type Setup,\n type SetupSubscription,\n} from './setup';\n\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\nexport const setup = zodToSchema(SetupSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z\n .object({\n topicArn: z\n .string()\n .describe(\n 'Topic ARN (like arn:aws:sns:eu-central-1:123456789012:walkeros-events). Region and topic name derive from it. Required unless topicName is set.',\n )\n .optional(),\n topicName: z\n .string()\n .min(1)\n .describe(\n 'Topic name (like walkeros-events). Used by walkeros setup; without topicArn the ARN is completed with the account id at the first publish.',\n )\n .optional(),\n region: z\n .string()\n .describe(\n 'AWS region (like eu-central-1). Default: the region in topicArn, AWS_REGION or the active profile, else eu-central-1.',\n )\n .optional(),\n client: z\n .any()\n .describe(\n 'An SNSClient of your own. Used as is and never closed by the destination.',\n )\n .optional(),\n config: z\n .any()\n .describe(\n 'Raw SNSClient options passed to the SDK. Put keys in config.credentials instead.',\n )\n .optional(),\n })\n .refine(\n (settings) =>\n settings.topicArn !== undefined || settings.topicName !== undefined,\n { message: 'Set settings.topicArn or settings.topicName' },\n )\n // The same rule in JSON Schema: one of both names the topic.\n .meta({\n anyOf: [{ required: ['topicArn'] }, { required: ['topicName'] }],\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * SNS Mapping Schema.\n *\n * `messageAttributes` is `Mapping.Map`: each value resolves per event to the\n * SDK's `{ DataType, StringValue }` shape. Schema accepts any structure;\n * runtime mapping resolution coerces shape via `getMappingValue`.\n *\n * `messageGroupId` and `messageDeduplicationId` are `Mapping.Value`: a string\n * path or a value-config object.\n */\nexport const MappingSchema = z.object({\n messageAttributes: z.record(z.string(), z.unknown()).optional(),\n messageGroupId: z.unknown().optional(),\n messageDeduplicationId: z.unknown().optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const SetupSubscriptionSchema = z.object({\n protocol: z.enum(['sqs', 'lambda', 'https', 'http', 'email', 'sms']),\n endpoint: z.string().min(1),\n rawMessageDelivery: z.boolean().optional(),\n filterPolicy: z.record(z.string(), z.unknown()).optional(),\n deadLetterTargetArn: z.string().optional(),\n});\n\nexport const SetupSchema = z.object({\n region: z.string().optional(),\n displayName: z.string().optional(),\n fifoTopic: z.boolean().optional(),\n kmsMasterKeyId: z.string().optional(),\n tags: z.record(z.string(), z.string()).optional(),\n subscriptions: z.array(SetupSubscriptionSchema).optional(),\n});\n\nexport type Setup = z.infer<typeof SetupSchema>;\nexport type SetupSubscription = z.infer<typeof SetupSubscriptionSchema>;\n","// Browser-safe schema-only exports\n// This file exports ONLY schemas without any Node.js dependencies\n\nexport {\n settings as firehoseSettings,\n mapping as firehoseMapping,\n firehose,\n} from './firehose/schemas';\n\nexport {\n settings as snsSettings,\n mapping as snsMapping,\n setup as snsSetup,\n} from './sns/schemas';\n\n// Backwards-compatible aliases (firehose is the package's default sub-destination).\nexport { settings, mapping } from './firehose/schemas';\n","export * as firehose from '../firehose/examples';\nexport * as sns from '../sns/examples';\n// Re-export env at top level for env-loader compatibility (matches web pattern)\nexport * as env from '../firehose/examples/env';\nexport * as step from '../firehose/examples/step';\n","import type { Hint } from '@walkeros/core';\n\nexport const hints: Hint.Hints = {\n 'minimal-config': {\n text: 'Firehose needs settings.streamName (plus settings.region when the stream is not in AWS_REGION or eu-central-1). SNS needs settings.topicArn; region and topic name derive from it. Off AWS, add config.credentials. Nothing is sent and no credentials are loaded until the first event.',\n code: [\n {\n lang: 'json',\n code: '{ \"settings\": { \"streamName\": \"walkeros-events\", \"region\": \"eu-central-1\" }, \"credentials\": { \"accessKeyId\": \"$secret.AWS_ACCESS_KEY_ID\", \"secretAccessKey\": \"$secret.AWS_SECRET_ACCESS_KEY\" } }',\n },\n {\n lang: 'json',\n code: '{ \"settings\": { \"topicArn\": \"arn:aws:sns:eu-central-1:123456789012:walkeros-events\" } }',\n },\n ],\n },\n 'auth-credentials': {\n text: 'On AWS compute an attached IAM role needs no config at all. Elsewhere, config.credentials ({ accessKeyId, secretAccessKey, sessionToken? }, or the same as a JSON string) wins over settings.config.credentials, which wins over the AWS default chain (AWS_* variables, AWS_PROFILE, ECS, EC2 and web identity roles; Kubernetes can go keyless with AWS_ROLE_ARN plus AWS_WEB_IDENTITY_TOKEN_FILE). Back every value with $secret; never write a literal key. Credentials are shape-checked at init and loaded only at the first send.',\n code: [\n {\n lang: 'json',\n code: '{ \"credentials\": { \"accessKeyId\": \"$secret.AWS_ACCESS_KEY_ID\", \"secretAccessKey\": \"$secret.AWS_SECRET_ACCESS_KEY\" } }',\n },\n ],\n },\n 'firehose-records': {\n text: 'Each record is the mapped data object, or the full event when the mapping produced none, followed by a newline. Set settings.newline: false when the stream adds its own new line delimiter. Batching is on by default (500 records or 1 s); calls carry at most 500 records and 2,900,000 bytes, and a record over 1,000,000 bytes fails as RecordTooLarge without being sent.',\n },\n 'delivery-guarantee': {\n text: 'Delivery is at least once: deduplicate downstream on event.id, and keep id in mapped data. A record AWS rejects is reported as failed with code, status and retryable. There is no retry beyond the built-in AWS SDK retry: a rejected record goes to the in-memory dead letter queue of the collector, which nothing replays. On SNS FIFO topics MessageDeduplicationId defaults to event.id.',\n },\n 'troubleshoot-errors': {\n text: 'Every failure carries code, status and retryable, and its message names the stream or topic and the region; the AWS error itself stays on the error as its cause. ResourceNotFoundException: wrong settings.streamName or region. AccessDeniedException / AuthorizationErrorException: the credentials lack firehose:PutRecordBatch or sns:Publish. UnrecognizedClientException, InvalidSignatureException, ExpiredTokenException or no credentials found: check config.credentials or the environment. SNS NotFoundException: the topic does not exist; run walkeros setup or set settings.topicArn. NULL rows in Athena: the stream adds its own new line delimiter too, so set newline: false. Code config at start: a missing or conflicting setting, named in the message.',\n },\n};\n"],"mappings":"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","names":["examples_exports","config","examples_exports","env_exports","minimal","step_exports","env_exports","push","simulation","config","step_exports","init","orderEvent","silentRule","import_core","TOPIC_ARN","pageEvent","orderEvt","minimal","import_dev","settings","import_dev","import_dev","import_dev","SettingsSchema","settings","import_dev","MappingSchema","import_dev","settings","SettingsSchema","mapping","MappingSchema","mapping","settings","examples_exports","examples_exports","settings","mapping"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire as e}from"module";e(import.meta.url);var t=Object.defineProperty,i=(e,i)=>{for(var s in i)t(e,s,{get:i[s],enumerable:!0})},s={};i(s,{env:()=>r,step:()=>c});var r={};i(r,{push:()=>o,simulation:()=>a});var n=class{input;constructor(e){this.input=e}get[Symbol.toStringTag](){return"PutRecordBatchCommand"}},o={AWS:{FirehoseClient:class{config;constructor(e){this.config=e}async send(e){const t="input"in e?e.input:void 0;var i;return{FailedPutCount:0,Encrypted:!1,RequestResponses:("object"==typeof(i=t)&&null!==i&&"Records"in i&&Array.isArray(i.Records)?t.Records:[]).map((e,t)=>({RecordId:`mock-record-id-${t}`}))}}destroy(){}},PutRecordBatchCommand:n}},a=["call:AWS.FirehoseClient.send"],c={};i(c,{firehoseRecord:()=>y,init:()=>g,mappedRecord:()=>b,orderEvent:()=>A,silentRule:()=>E,userSignupEvent:()=>w});import{createEvent as d,getEvent as l}from"@walkeros/core";import{isObject as p}from"@walkeros/core";function m(e,t=!0){const i=JSON.stringify(e);if("string"!=typeof i)throw new TypeError("The payload does not serialize to JSON.");return Buffer.from(t?`${i}\n`:i)}var u="walkeros-events",g={title:"Initialization",description:"Init builds one FirehoseClient for the stream region with the credentials from config.credentials and a 2500 ms per-attempt timeout. Nothing is sent until the first event.",in:{settings:{streamName:u,region:"eu-central-1"},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new FirehoseClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},h=l("page view",{id:"ev-1700001000",timestamp:1700001e3,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),S=l("order complete",{id:"ev-1700001001",timestamp:1700001001,data:{id:"ORD-400",value:99.99,currency:"EUR"},source:{type:"express",platform:"server"}}),f=d({name:"user signup",id:"ev-1700001002",timestamp:1700001002,data:{plan:"pro",source:"landing-page"},user:{id:"usr-789",email:"new@example.com"},source:{type:"express",platform:"server"}});function v(e){return[["client.send",{DeliveryStreamName:u,Records:[{Data:m(e)}]}]]}var y={title:"Page view record",description:"A page view is sent to Firehose as one record: the full event as JSON followed by a newline.",in:h,mapping:void 0,out:v(h)},A={title:"Order record",description:"An order complete event is serialized and delivered to Firehose as one newline-terminated record.",in:S,mapping:void 0,out:v(S)},w={title:"User signup record",description:"A user signup event including user fields is streamed to Firehose as a JSON record.",in:f,mapping:void 0,out:v(f)},b={title:"Mapped record",description:"A mapping that produces an object sends that object as the record instead of the full event. Keep the event id in it for deduplication.",in:S,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:v({id:"ev-1700001001",name:"order complete",order_id:"ORD-400",total:99.99})},E={public:!1,description:"A rule with silent: true sends no record to Firehose.",in:h,mapping:{silent:!0},out:[]},C={};i(C,{env:()=>N,step:()=>D});var N={};i(N,{push:()=>O,simulation:()=>x});var _=class{constructor(e){this.input=e}input},k=class extends _{get[Symbol.toStringTag](){return"CreateTopicCommand"}},T=class extends _{get[Symbol.toStringTag](){return"PublishCommand"}},R=class extends _{get[Symbol.toStringTag](){return"GetTopicAttributesCommand"}},I=class extends _{get[Symbol.toStringTag](){return"SubscribeCommand"}},K=class extends _{get[Symbol.toStringTag](){return"GetCallerIdentityCommand"}},O={AWS:{SNSClient:class{constructor(e){this.config=e}config;async send(e){return e instanceof k?{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events"}:e instanceof T?{MessageId:"mock-message-id"}:{}}destroy(){}},CreateTopicCommand:k,PublishCommand:T,GetTopicAttributesCommand:R,SubscribeCommand:I,STSClient:class{constructor(e){this.config=e}config;async send(){return{Account:"123456789012",Arn:"arn:aws:iam::123456789012:user/walkeros"}}destroy(){}},GetCallerIdentityCommand:K}},x=["call:AWS.SNSClient.send"],D={};i(D,{attributedPublish:()=>z,init:()=>M,mappedMessage:()=>G,orderEvent:()=>Y,pageView:()=>$,silentRule:()=>J});import{getEvent as W}from"@walkeros/core";var F="arn:aws:sns:eu-central-1:123456789012:walkeros-events",M={title:"Initialization",description:"Init builds one SNSClient in the region of the topic ARN with the credentials from config.credentials and a 2500 ms per-attempt timeout. No topic is created and nothing is sent until the first event.",in:{settings:{topicArn:F},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new SNSClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},j=W("page view",{id:"ev-1700001000",timestamp:1700001e3,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),P=W("order complete",{id:"ev-1700001001",timestamp:1700001001,data:{id:"ORD-400",value:99.99,currency:"EUR"},user:{id:"usr-789"},source:{type:"express",platform:"server"}}),q=W("product view",{id:"ev-1700001002",timestamp:1700001002,data:{id:"SKU-1",tenant_id:"acme"},source:{type:"express",platform:"server"}}),$={title:"Page view publish",description:"A page view event is JSON-stringified and published as the Message of an SNS Publish call.",in:j,mapping:void 0,out:[["client.send",{TopicArn:F,Message:JSON.stringify(j)}]]},Y={title:"Order publish with FIFO group (path-resolved)",description:'An order complete event is published to a FIFO topic with a messageGroupId resolved from the event via the mapping path "user.id". The deduplication id defaults to the event id.',in:P,mapping:{settings:{messageGroupId:"user.id"}},out:[["client.send",{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events.fifo",Message:JSON.stringify(P),MessageGroupId:"usr-789",MessageDeduplicationId:"ev-1700001001"}]]},z={title:"Publish with per-event message attributes",description:"Demonstrates `messageAttributes` as `Mapping.Map`: each attribute value resolves per event. Operators express the SDK shape (`{ DataType, StringValue }`) per entry.",in:q,mapping:{settings:{messageAttributes:{schema_version:{value:{DataType:"String",StringValue:"v4"}},tenant:{value:{DataType:"String",StringValue:"acme"}}}}},out:[["client.send",{TopicArn:F,Message:JSON.stringify(q),MessageAttributes:{schema_version:{DataType:"String",StringValue:"v4"},tenant:{DataType:"String",StringValue:"acme"}}}]]},G={title:"Mapped message",description:"A mapping that produces an object publishes that object as the Message instead of the full event. Keep the event id in it for deduplication.",in:P,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:[["client.send",{TopicArn:F,Message:JSON.stringify({id:"ev-1700001001",name:"order complete",order_id:"ORD-400",total:99.99})}]]},J={public:!1,description:"A rule with silent: true publishes no message to SNS.",in:j,mapping:{silent:!0},out:[]};import{zodToSchema as U}from"@walkeros/core/dev";import{z as B}from"@walkeros/core/dev";var L=B.string().min(1).describe("Name of the Firehose stream (like walkeros-events). Required.").optional(),V=B.string().describe("AWS region of the stream (like eu-central-1). Default: AWS_REGION or the active profile, else eu-central-1."),H=B.any().describe("A FirehoseClient of your own. Used as is and never closed by the destination."),Q=B.any().describe("Raw FirehoseClient options passed to the SDK (like { endpoint, maxAttempts }). Put keys in config.credentials instead."),X=B.object({streamName:L,client:H.optional(),region:V.optional(),config:Q.optional()}),Z=B.object({streamName:L,region:V.optional(),newline:B.boolean().describe("Append a newline to every record (default true). Set false when the stream adds its own new line delimiter.").optional(),config:Q.optional(),client:H.optional(),firehose:X.describe("Deprecated: use the flat fields streamName, region, config and client.").optional()}).refine(e=>void 0!==e.streamName||void 0!==e.firehose?.streamName,{message:"Set settings.streamName"}).meta({anyOf:[{required:["streamName"]},{required:["firehose"],properties:{firehose:{required:["streamName"]}}}]});import{z as ee}from"@walkeros/core/dev";var te=ee.object({}),ie=U(Z),se=U(te),re=U(X);import{zodToSchema as ne}from"@walkeros/core/dev";import{z as oe}from"@walkeros/core/dev";var ae=oe.object({topicArn:oe.string().describe("Topic ARN (like arn:aws:sns:eu-central-1:123456789012:walkeros-events). Region and topic name derive from it. Required unless topicName is set.").optional(),topicName:oe.string().min(1).describe("Topic name (like walkeros-events). Used by walkeros setup; without topicArn the ARN is completed with the account id at the first publish.").optional(),region:oe.string().describe("AWS region (like eu-central-1). Default: the region in topicArn, AWS_REGION or the active profile, else eu-central-1.").optional(),client:oe.any().describe("An SNSClient of your own. Used as is and never closed by the destination.").optional(),config:oe.any().describe("Raw SNSClient options passed to the SDK. Put keys in config.credentials instead.").optional()}).refine(e=>void 0!==e.topicArn||void 0!==e.topicName,{message:"Set settings.topicArn or settings.topicName"}).meta({anyOf:[{required:["topicArn"]},{required:["topicName"]}]});import{z as ce}from"@walkeros/core/dev";var de=ce.object({messageAttributes:ce.record(ce.string(),ce.unknown()).optional(),messageGroupId:ce.unknown().optional(),messageDeduplicationId:ce.unknown().optional()});import{z as le}from"@walkeros/core/dev";var pe=le.object({protocol:le.enum(["sqs","lambda","https","http","email","sms"]),endpoint:le.string().min(1),rawMessageDelivery:le.boolean().optional(),filterPolicy:le.record(le.string(),le.unknown()).optional(),deadLetterTargetArn:le.string().optional()}),me=le.object({region:le.string().optional(),displayName:le.string().optional(),fifoTopic:le.boolean().optional(),kmsMasterKeyId:le.string().optional(),tags:le.record(le.string(),le.string()).optional(),subscriptions:le.array(pe).optional()}),ue=ne(ae),ge=ne(de),he=ne(me),Se={};i(Se,{firehose:()=>re,firehoseMapping:()=>se,firehoseSettings:()=>ie,mapping:()=>se,settings:()=>ie,snsMapping:()=>ge,snsSettings:()=>ue,snsSetup:()=>he});var fe={};i(fe,{env:()=>r,firehose:()=>s,sns:()=>C,step:()=>c});var ve={"minimal-config":{text:"Firehose needs settings.streamName (plus settings.region when the stream is not in AWS_REGION or eu-central-1). SNS needs settings.topicArn; region and topic name derive from it. Off AWS, add config.credentials. Nothing is sent and no credentials are loaded until the first event.",code:[{lang:"json",code:'{ "settings": { "streamName": "walkeros-events", "region": "eu-central-1" }, "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'},{lang:"json",code:'{ "settings": { "topicArn": "arn:aws:sns:eu-central-1:123456789012:walkeros-events" } }'}]},"auth-credentials":{text:"On AWS compute an attached IAM role needs no config at all. Elsewhere, config.credentials ({ accessKeyId, secretAccessKey, sessionToken? }, or the same as a JSON string) wins over settings.config.credentials, which wins over the AWS default chain (AWS_* variables, AWS_PROFILE, ECS, EC2 and web identity roles; Kubernetes can go keyless with AWS_ROLE_ARN plus AWS_WEB_IDENTITY_TOKEN_FILE). Back every value with $secret; never write a literal key. Credentials are shape-checked at init and loaded only at the first send.",code:[{lang:"json",code:'{ "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'}]},"firehose-records":{text:"Each record is the mapped data object, or the full event when the mapping produced none, followed by a newline. Set settings.newline: false when the stream adds its own new line delimiter. Batching is on by default (500 records or 1 s); calls carry at most 500 records and 2,900,000 bytes, and a record over 1,000,000 bytes fails as RecordTooLarge without being sent."},"delivery-guarantee":{text:"Delivery is at least once: deduplicate downstream on event.id, and keep id in mapped data. A record AWS rejects is reported as failed with code, status and retryable. There is no retry beyond the built-in AWS SDK retry: a rejected record goes to the in-memory dead letter queue of the collector, which nothing replays yet. On SNS FIFO topics MessageDeduplicationId defaults to event.id."},"troubleshoot-errors":{text:"Every failure carries code, status and retryable, and its message names the stream or topic and the region; the AWS error itself stays on the error as its cause. ResourceNotFoundException: wrong settings.streamName or region. AccessDeniedException / AuthorizationErrorException: the credentials lack firehose:PutRecordBatch or sns:Publish. UnrecognizedClientException, InvalidSignatureException, ExpiredTokenException or no credentials found: check config.credentials or the environment. SNS NotFoundException: the topic does not exist; run walkeros setup or set settings.topicArn. NULL rows in Athena: the stream adds its own new line delimiter too, so set newline: false. Code config at start: a missing or conflicting setting, named in the message."}},ye={destinationFirehose:s,destinationSNS:C},Ae={destinationFirehose:{settings:ie,mapping:se},destinationSNS:{settings:ue,mapping:ge,setup:he}};export{fe as examples,ye as exportExamples,Ae as exportSchemas,ve as hints,Se as schemas};//# sourceMappingURL=dev.mjs.map
|
|
1
|
+
import{createRequire as e}from"module";e(import.meta.url);var t=Object.defineProperty,s=(e,s)=>{for(var i in s)t(e,i,{get:s[i],enumerable:!0})},i={};s(i,{env:()=>n,minimal:()=>b,step:()=>c});var n={};s(n,{push:()=>o,simulation:()=>a});var r=class{input;constructor(e){this.input=e}get[Symbol.toStringTag](){return"PutRecordBatchCommand"}},o={AWS:{FirehoseClient:class{config;constructor(e){this.config=e}async send(e){const t="input"in e?e.input:void 0;var s;return{FailedPutCount:0,Encrypted:!1,RequestResponses:("object"==typeof(s=t)&&null!==s&&"Records"in s&&Array.isArray(s.Records)?t.Records:[]).map((e,t)=>({RecordId:`mock-record-id-${t}`}))}}destroy(){}},PutRecordBatchCommand:r}},a=["call:AWS.FirehoseClient.send"],c={};s(c,{firehoseRecord:()=>v,init:()=>m,mappedRecord:()=>y,orderEvent:()=>f,silentRule:()=>A,userSignupEvent:()=>S});import{createEvent as d,getEvent as l}from"@walkeros/core";var p="walkeros-events",m={title:"Initialization",description:"Init builds one FirehoseClient for the stream region with the credentials from config.credentials and a 2500 ms per-attempt timeout. Nothing is sent until the first event.",in:{settings:{streamName:p,region:"eu-central-1"},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new FirehoseClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},u=l("page view",{id:"ev-1700001000",timestamp:1700001e6,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),g=l("order complete",{id:"ev-1700001001",timestamp:1700001001e3,data:{id:"ORD-400",value:99.99,currency:"EUR"},source:{type:"express",platform:"server"}}),h=d({name:"user signup",id:"ev-1700001002",timestamp:1700001002e3,data:{plan:"pro",source:"landing-page"},user:{id:"usr-789",email:"new@example.com"},source:{type:"express",platform:"server"}}),v={title:"Page view record",description:"A page view is sent to Firehose as one record: the full event as JSON followed by a newline.",in:u,mapping:void 0,out:[["client.send",{DeliveryStreamName:p,Records:[{Data:Buffer.from('{"name":"page view","data":{"title":"Home","url":"https://example.com/"},"context":{"dev":["test",1]},"globals":{"pagegroup":"docs"},"custom":{"completely":"random"},"user":{"id":"us3r","device":"c00k13","session":"s3ss10n"},"nested":[{"entity":"child","data":{"is":"subordinated"}}],"consent":{"functional":true},"id":"ev-1700001000","trigger":"load","entity":"page","action":"view","timestamp":1700001000000,"timing":3.14,"source":{"count":1,"trace":"0a1b2c3d4e5f60718293a4b5c6d7e8f9","type":"express","platform":"server"}}\n')}]}]]},f={title:"Order record",description:"An order complete event is serialized and delivered to Firehose as one newline-terminated record.",in:g,mapping:void 0,out:[["client.send",{DeliveryStreamName:p,Records:[{Data:Buffer.from('{"name":"order complete","data":{"id":"ORD-400","value":99.99,"currency":"EUR"},"context":{"shopping":["complete",0]},"globals":{"pagegroup":"shop"},"custom":{"completely":"random"},"user":{"id":"us3r","device":"c00k13","session":"s3ss10n"},"nested":[{"entity":"product","data":{"id":"ers","name":"Everyday Ruck Snack","color":"black","size":"l","price":420},"context":{"shopping":["complete",0]},"nested":[]},{"entity":"product","data":{"id":"cc","name":"Cool Cap","size":"one size","price":42},"context":{"shopping":["complete",0]},"nested":[]},{"entity":"gift","data":{"name":"Surprise"},"context":{"shopping":["complete",0]},"nested":[]}],"consent":{"functional":true},"id":"ev-1700001001","trigger":"load","entity":"order","action":"complete","timestamp":1700001001000,"timing":3.14,"source":{"count":1,"trace":"0a1b2c3d4e5f60718293a4b5c6d7e8f9","type":"express","platform":"server"}}\n')}]}]]},S={title:"User signup record",description:"A user signup event including user fields is streamed to Firehose as a JSON record.",in:h,mapping:void 0,out:[["client.send",{DeliveryStreamName:p,Records:[{Data:Buffer.from('{"name":"user signup","data":{"plan":"pro","source":"landing-page"},"context":{"dev":["test",1]},"globals":{"lang":"elb"},"custom":{"completely":"random"},"user":{"id":"usr-789","email":"new@example.com"},"nested":[{"entity":"child","data":{"is":"subordinated"}}],"consent":{"functional":true},"id":"ev-1700001002","trigger":"test","entity":"user","action":"signup","timestamp":1700001002000,"timing":3.14,"source":{"count":1,"trace":"0a1b2c3d4e5f60718293a4b5c6d7e8f9","type":"express","platform":"server"}}\n')}]}]]},y={title:"Mapped record",description:"A mapping that produces an object sends that object as the record instead of the full event. Keep the event id in it for deduplication.",in:g,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:[["client.send",{DeliveryStreamName:p,Records:[{Data:Buffer.from('{"id":"ev-1700001001","name":"order complete","order_id":"ORD-400","total":99.99}\n')}]}]]},A={public:!1,description:"A rule with silent: true sends no record to Firehose.",in:u,mapping:{silent:!0},out:[]},b={settings:{streamName:"walkeros-events"}},w={};s(w,{env:()=>E,minimal:()=>G,step:()=>D});var E={};s(E,{push:()=>x,simulation:()=>I});var C=class{constructor(e){this.input=e}input},N=class extends C{get[Symbol.toStringTag](){return"CreateTopicCommand"}},_=class extends C{get[Symbol.toStringTag](){return"PublishCommand"}},k=class extends C{get[Symbol.toStringTag](){return"GetTopicAttributesCommand"}},R=class extends C{get[Symbol.toStringTag](){return"SubscribeCommand"}},T=class extends C{get[Symbol.toStringTag](){return"GetCallerIdentityCommand"}},x={AWS:{SNSClient:class{constructor(e){this.config=e}config;async send(e){return e instanceof N?{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events"}:e instanceof _?{MessageId:"mock-message-id"}:{}}destroy(){}},CreateTopicCommand:N,PublishCommand:_,GetTopicAttributesCommand:k,SubscribeCommand:R,STSClient:class{constructor(e){this.config=e}config;async send(){return{Account:"123456789012",Arn:"arn:aws:iam::123456789012:user/walkeros"}}destroy(){}},GetCallerIdentityCommand:T}},I=["call:AWS.SNSClient.send"],D={};s(D,{attributedPublish:()=>$,init:()=>W,mappedMessage:()=>z,orderEvent:()=>q,pageView:()=>P,silentRule:()=>Y});import{getEvent as K}from"@walkeros/core";var O="arn:aws:sns:eu-central-1:123456789012:walkeros-events",W={title:"Initialization",description:"Init builds one SNSClient in the region of the topic ARN with the credentials from config.credentials and a 2500 ms per-attempt timeout. No topic is created and nothing is sent until the first event.",in:{settings:{topicArn:O},credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"}},out:[["new SNSClient",{region:"eu-central-1",credentials:{accessKeyId:"$secret.AWS_ACCESS_KEY_ID",secretAccessKey:"$secret.AWS_SECRET_ACCESS_KEY"},requestHandler:{requestTimeout:2500,throwOnRequestTimeout:!0}}]]},F=K("page view",{id:"ev-1700001000",timestamp:1700001e6,data:{title:"Home",url:"https://example.com/"},source:{type:"express",platform:"server"}}),M=K("order complete",{id:"ev-1700001001",timestamp:1700001001e3,data:{id:"ORD-400",value:99.99,currency:"EUR"},user:{id:"usr-789"},source:{type:"express",platform:"server"}}),j=K("product view",{id:"ev-1700001002",timestamp:1700001002e3,data:{id:"SKU-1",tenant_id:"acme"},source:{type:"express",platform:"server"}}),P={title:"Page view publish",description:"A page view event is JSON-stringified and published as the Message of an SNS Publish call.",in:F,mapping:void 0,out:[["client.send",{TopicArn:O,Message:JSON.stringify(F)}]]},q={title:"Order publish with FIFO group (path-resolved)",description:'An order complete event is published to a FIFO topic with a messageGroupId resolved from the event via the mapping path "user.id". The deduplication id defaults to the event id.',in:M,mapping:{settings:{messageGroupId:"user.id"}},out:[["client.send",{TopicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events.fifo",Message:JSON.stringify(M),MessageGroupId:"usr-789",MessageDeduplicationId:"ev-1700001001"}]]},$={title:"Publish with per-event message attributes",description:"Demonstrates `messageAttributes` as `Mapping.Map`: each attribute value resolves per event. Operators express the SDK shape (`{ DataType, StringValue }`) per entry.",in:j,mapping:{settings:{messageAttributes:{schema_version:{value:{DataType:"String",StringValue:"v4"}},tenant:{value:{DataType:"String",StringValue:"acme"}}}}},out:[["client.send",{TopicArn:O,Message:JSON.stringify(j),MessageAttributes:{schema_version:{DataType:"String",StringValue:"v4"},tenant:{DataType:"String",StringValue:"acme"}}}]]},z={title:"Mapped message",description:"A mapping that produces an object publishes that object as the Message instead of the full event. Keep the event id in it for deduplication.",in:M,mapping:{data:{map:{id:"id",name:"name",order_id:"data.id",total:"data.value"}}},out:[["client.send",{TopicArn:O,Message:JSON.stringify({id:"ev-1700001001",name:"order complete",order_id:"ORD-400",total:99.99})}]]},Y={public:!1,description:"A rule with silent: true publishes no message to SNS.",in:F,mapping:{silent:!0},out:[]},G={settings:{topicArn:"arn:aws:sns:eu-central-1:123456789012:walkeros-events"}};import{zodToSchema as B}from"@walkeros/core/dev";import{z as U}from"@walkeros/core/dev";var J=U.string().min(1).describe("Name of the Firehose stream (like walkeros-events). Required.").optional(),L=U.string().describe("AWS region of the stream (like eu-central-1). Default: AWS_REGION or the active profile, else eu-central-1."),V=U.any().describe("A FirehoseClient of your own. Used as is and never closed by the destination."),H=U.any().describe("Raw FirehoseClient options passed to the SDK (like { endpoint, maxAttempts }). Put keys in config.credentials instead."),Q=U.object({streamName:J,client:V.optional(),region:L.optional(),config:H.optional()}),X=U.object({streamName:J,region:L.optional(),newline:U.boolean().describe("Append a newline to every record (default true). Set false when the stream adds its own new line delimiter.").optional(),config:H.optional(),client:V.optional(),firehose:Q.describe("Deprecated: use the flat fields streamName, region, config and client.").optional()}).refine(e=>void 0!==e.streamName||void 0!==e.firehose?.streamName,{message:"Set settings.streamName"}).meta({anyOf:[{required:["streamName"]},{required:["firehose"],properties:{firehose:{required:["streamName"]}}}]});import{z as Z}from"@walkeros/core/dev";var ee=Z.object({}),te=B(X),se=B(ee),ie=B(Q);import{zodToSchema as ne}from"@walkeros/core/dev";import{z as re}from"@walkeros/core/dev";var oe=re.object({topicArn:re.string().describe("Topic ARN (like arn:aws:sns:eu-central-1:123456789012:walkeros-events). Region and topic name derive from it. Required unless topicName is set.").optional(),topicName:re.string().min(1).describe("Topic name (like walkeros-events). Used by walkeros setup; without topicArn the ARN is completed with the account id at the first publish.").optional(),region:re.string().describe("AWS region (like eu-central-1). Default: the region in topicArn, AWS_REGION or the active profile, else eu-central-1.").optional(),client:re.any().describe("An SNSClient of your own. Used as is and never closed by the destination.").optional(),config:re.any().describe("Raw SNSClient options passed to the SDK. Put keys in config.credentials instead.").optional()}).refine(e=>void 0!==e.topicArn||void 0!==e.topicName,{message:"Set settings.topicArn or settings.topicName"}).meta({anyOf:[{required:["topicArn"]},{required:["topicName"]}]});import{z as ae}from"@walkeros/core/dev";var ce=ae.object({messageAttributes:ae.record(ae.string(),ae.unknown()).optional(),messageGroupId:ae.unknown().optional(),messageDeduplicationId:ae.unknown().optional()});import{z as de}from"@walkeros/core/dev";var le=de.object({protocol:de.enum(["sqs","lambda","https","http","email","sms"]),endpoint:de.string().min(1),rawMessageDelivery:de.boolean().optional(),filterPolicy:de.record(de.string(),de.unknown()).optional(),deadLetterTargetArn:de.string().optional()}),pe=de.object({region:de.string().optional(),displayName:de.string().optional(),fifoTopic:de.boolean().optional(),kmsMasterKeyId:de.string().optional(),tags:de.record(de.string(),de.string()).optional(),subscriptions:de.array(le).optional()}),me=ne(oe),ue=ne(ce),ge=ne(pe),he={};s(he,{firehose:()=>ie,firehoseMapping:()=>se,firehoseSettings:()=>te,mapping:()=>se,settings:()=>te,snsMapping:()=>ue,snsSettings:()=>me,snsSetup:()=>ge});var ve={};s(ve,{env:()=>n,firehose:()=>i,sns:()=>w,step:()=>c});var fe={"minimal-config":{text:"Firehose needs settings.streamName (plus settings.region when the stream is not in AWS_REGION or eu-central-1). SNS needs settings.topicArn; region and topic name derive from it. Off AWS, add config.credentials. Nothing is sent and no credentials are loaded until the first event.",code:[{lang:"json",code:'{ "settings": { "streamName": "walkeros-events", "region": "eu-central-1" }, "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'},{lang:"json",code:'{ "settings": { "topicArn": "arn:aws:sns:eu-central-1:123456789012:walkeros-events" } }'}]},"auth-credentials":{text:"On AWS compute an attached IAM role needs no config at all. Elsewhere, config.credentials ({ accessKeyId, secretAccessKey, sessionToken? }, or the same as a JSON string) wins over settings.config.credentials, which wins over the AWS default chain (AWS_* variables, AWS_PROFILE, ECS, EC2 and web identity roles; Kubernetes can go keyless with AWS_ROLE_ARN plus AWS_WEB_IDENTITY_TOKEN_FILE). Back every value with $secret; never write a literal key. Credentials are shape-checked at init and loaded only at the first send.",code:[{lang:"json",code:'{ "credentials": { "accessKeyId": "$secret.AWS_ACCESS_KEY_ID", "secretAccessKey": "$secret.AWS_SECRET_ACCESS_KEY" } }'}]},"firehose-records":{text:"Each record is the mapped data object, or the full event when the mapping produced none, followed by a newline. Set settings.newline: false when the stream adds its own new line delimiter. Batching is on by default (500 records or 1 s); calls carry at most 500 records and 2,900,000 bytes, and a record over 1,000,000 bytes fails as RecordTooLarge without being sent."},"delivery-guarantee":{text:"Delivery is at least once: deduplicate downstream on event.id, and keep id in mapped data. A record AWS rejects is reported as failed with code, status and retryable. There is no retry beyond the built-in AWS SDK retry: a rejected record goes to the in-memory dead letter queue of the collector, which nothing replays. On SNS FIFO topics MessageDeduplicationId defaults to event.id."},"troubleshoot-errors":{text:"Every failure carries code, status and retryable, and its message names the stream or topic and the region; the AWS error itself stays on the error as its cause. ResourceNotFoundException: wrong settings.streamName or region. AccessDeniedException / AuthorizationErrorException: the credentials lack firehose:PutRecordBatch or sns:Publish. UnrecognizedClientException, InvalidSignatureException, ExpiredTokenException or no credentials found: check config.credentials or the environment. SNS NotFoundException: the topic does not exist; run walkeros setup or set settings.topicArn. NULL rows in Athena: the stream adds its own new line delimiter too, so set newline: false. Code config at start: a missing or conflicting setting, named in the message."}},Se={destinationFirehose:i,destinationSNS:w},ye={destinationFirehose:{settings:te,mapping:se},destinationSNS:{settings:me,mapping:ue,setup:ge}};export{ve as examples,Se as exportExamples,ye as exportSchemas,fe as hints,he as schemas};//# sourceMappingURL=dev.mjs.map
|