@walkeros/server-source-aws 4.1.0-next-1778668930820 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,14 +1,34 @@
1
1
  # @walkeros/server-source-aws
2
2
 
3
- ## 4.1.0-next-1778668930820
3
+ ## 4.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 13aaeaa: `Source.Context` no longer exposes `setIngest` or `setRespond`.
8
+ Server sources handling concurrent inbound requests must call
9
+ `context.withScope(rawScope, respond, body)` to bind per-request ingest and
10
+ respond. Browser and other single-scope sources keep working without changes.
4
11
 
5
12
  ### Patch Changes
6
13
 
14
+ - Updated dependencies [e155ff8]
15
+ - Updated dependencies [e800974]
16
+ - Updated dependencies [e155ff8]
7
17
  - Updated dependencies [1a8f2d7]
8
18
  - Updated dependencies [1a8f2d7]
19
+ - Updated dependencies [b276173]
9
20
  - Updated dependencies [dd9f5ad]
21
+ - Updated dependencies [c60ef35]
22
+ - Updated dependencies [adeebea]
23
+ - Updated dependencies [13aaeaa]
24
+ - Updated dependencies [e800974]
25
+ - Updated dependencies [adeebea]
26
+ - Updated dependencies [e800974]
27
+ - Updated dependencies [e800974]
28
+ - Updated dependencies [058f7ed]
10
29
  - Updated dependencies [28a8ac2]
11
- - @walkeros/core@4.1.0-next-1778668930820
30
+ - Updated dependencies [fd6076e]
31
+ - @walkeros/core@4.1.0
12
32
 
13
33
  ## 4.0.2
14
34
 
package/README.md CHANGED
@@ -1,481 +1,53 @@
1
+ <p align="left">
2
+ <a href="https://www.walkeros.io">
3
+ <img alt="walkerOS" title="walkerOS" src="https://www.walkeros.io/img/walkerOS_logo.svg" width="256px"/>
4
+ </a>
5
+ </p>
6
+
1
7
  # @walkeros/server-source-aws
2
8
 
3
- AWS server sources for walkerOS, Lambda and SQS. Lightweight, single-purpose
4
- runtime adapters for AWS services.
9
+ AWS Lambda source for walkerOS. Works across API Gateway REST (v1), API Gateway
10
+ HTTP (v2), Lambda Function URLs, and direct invocation. The package also ships
11
+ an SQS source for ingesting from SQS queues.
12
+
13
+ [Documentation](https://www.walkeros.io/docs/sources/server/aws) &bull;
14
+ [NPM Package](https://www.npmjs.com/package/@walkeros/server-source-aws) &bull;
15
+ [Source Code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/sources/aws)
5
16
 
6
17
  ## Installation
7
18
 
8
19
  ```bash
9
- npm install @walkeros/server-source-aws @types/aws-lambda
10
- ```
11
-
12
- ## Usage
13
-
14
- ```typescript
15
- import { sourceLambda, type SourceLambda } from '@walkeros/server-source-aws';
16
- import { startFlow } from '@walkeros/collector';
17
-
18
- const { elb } = await startFlow<SourceLambda.Push>({
19
- sources: { lambda: { code: sourceLambda } },
20
- });
21
-
22
- export const handler = elb;
23
- ```
24
-
25
- ---
26
-
27
- ## Lambda Source
28
-
29
- The Lambda source provides an HTTP handler that receives walker events and
30
- forwards them to the walkerOS collector. Works with API Gateway v1 (REST API),
31
- v2 (HTTP API), and Lambda Function URLs.
32
-
33
- ### Basic Usage
34
-
35
- ```typescript
36
- import { sourceLambda, type SourceLambda } from '@walkeros/server-source-aws';
37
- import { startFlow } from '@walkeros/collector';
38
-
39
- // Handler singleton - reused across warm invocations
40
- let handler: SourceLambda.Push;
41
-
42
- async function setup() {
43
- if (handler) return handler;
44
-
45
- const { elb } = await startFlow<SourceLambda.Push>({
46
- sources: {
47
- lambda: {
48
- code: sourceLambda,
49
- config: {
50
- settings: {
51
- cors: true,
52
- healthPath: '/health',
53
- },
54
- },
55
- },
56
- },
57
- destinations: {
58
- // Your destinations
59
- },
60
- });
61
-
62
- handler = elb;
63
- return handler;
64
- }
65
-
66
- export const main: SourceLambda.Push = async (event, context) => {
67
- const h = await setup();
68
- return h(event, context);
69
- };
70
-
71
- // Export for Lambda runtime
72
- export { main as handler };
73
- ```
74
-
75
- ### Deployment
76
-
77
- #### Lambda Function URL (Simplest)
78
-
79
- ```typescript
80
- // No API Gateway needed
81
- import * as lambda from 'aws-cdk-lib/aws-lambda';
82
-
83
- const fn = new lambda.Function(this, 'Walker', {
84
- runtime: lambda.Runtime.NODEJS_20_X,
85
- handler: 'index.handler',
86
- code: lambda.Code.fromAsset('./dist'),
87
- });
88
-
89
- fn.addFunctionUrl({
90
- authType: lambda.FunctionUrlAuthType.NONE,
91
- cors: {
92
- allowedOrigins: ['*'],
93
- allowedMethods: [lambda.HttpMethod.GET, lambda.HttpMethod.POST],
94
- },
95
- });
96
- ```
97
-
98
- #### API Gateway HTTP API (v2) - Recommended
99
-
100
- ```yaml
101
- # serverless.yml
102
- service: walkeros-flow
103
-
104
- provider:
105
- name: aws
106
- runtime: nodejs20.x
107
- memorySize: 256
108
- timeout: 30
109
-
110
- functions:
111
- collector:
112
- handler: dist/index.handler
113
- events:
114
- - httpApi:
115
- path: /collect
116
- method: post
117
- - httpApi:
118
- path: /collect
119
- method: get
120
- - httpApi:
121
- path: /health
122
- method: get
20
+ npm install @walkeros/server-source-aws
123
21
  ```
124
22
 
125
- #### API Gateway REST API (v1)
126
-
127
- ```yaml
128
- # template.yaml (AWS SAM)
129
- AWSTemplateFormatVersion: '2010-09-09'
130
- Transform: AWS::Serverless-2016-10-31
131
-
132
- Resources:
133
- WalkerFunction:
134
- Type: AWS::Serverless::Function
135
- Properties:
136
- CodeUri: ./dist
137
- Handler: index.handler
138
- Runtime: nodejs20.x
139
- Architectures: [arm64]
140
- Events:
141
- CollectPost:
142
- Type: Api
143
- Properties:
144
- Path: /collect
145
- Method: POST
146
- CollectGet:
147
- Type: Api
148
- Properties:
149
- Path: /collect
150
- Method: GET
151
- Health:
152
- Type: Api
153
- Properties:
154
- Path: /health
155
- Method: GET
156
- ```
157
-
158
- ### Configuration Options
159
-
160
- ```typescript
161
- interface Settings {
162
- cors?: boolean | CorsOptions; // Enable CORS (default: true)
163
- timeout?: number; // Request timeout (default: 30000ms, max: 900000ms)
164
- enablePixelTracking?: boolean; // Enable GET tracking (default: true)
165
- healthPath?: string; // Health check path (default: '/health')
166
- }
167
-
168
- interface CorsOptions {
169
- origin?: string | string[]; // Allowed origins
170
- methods?: string[]; // Allowed methods
171
- headers?: string[]; // Allowed headers
172
- credentials?: boolean; // Allow credentials
173
- maxAge?: number; // Preflight cache time
174
- }
175
- ```
176
-
177
- ### Ingest Metadata
178
-
179
- Extract request metadata from Lambda events and forward it to processors and
180
- destinations:
181
-
182
- ```typescript
183
- await startFlow({
184
- sources: {
185
- lambda: {
186
- code: sourceLambda,
187
- config: {
188
- settings: { cors: true },
189
- ingest: {
190
- // API Gateway v1 (REST API)
191
- ip: 'requestContext.identity.sourceIp',
192
- ua: 'requestContext.identity.userAgent',
193
- // Or API Gateway v2 (HTTP API) / Function URLs:
194
- // ip: 'requestContext.http.sourceIp',
195
- // ua: 'requestContext.http.userAgent',
196
- },
197
- },
198
- },
199
- },
200
- });
201
- ```
202
-
203
- **Available ingest paths (API Gateway v1):**
204
-
205
- | Path | Description |
206
- | ----------------------------------- | ----------------- |
207
- | `requestContext.identity.sourceIp` | Client IP address |
208
- | `requestContext.identity.userAgent` | User agent string |
209
- | `headers.*` | HTTP headers |
210
- | `httpMethod` | HTTP method |
211
-
212
- **Available ingest paths (API Gateway v2 / Function URLs):**
213
-
214
- | Path | Description |
215
- | ------------------------------- | ----------------- |
216
- | `requestContext.http.sourceIp` | Client IP address |
217
- | `requestContext.http.userAgent` | User agent string |
218
- | `requestContext.http.method` | HTTP method |
219
- | `headers.*` | HTTP headers |
220
-
221
- ### Request Format
222
-
223
- **POST - Single Event:**
23
+ ## Quick start
224
24
 
225
25
  ```json
226
26
  {
227
- "event": "page view",
228
- "data": {
229
- "title": "Home Page",
230
- "path": "/"
231
- },
232
- "context": {
233
- "stage": ["prod", 1]
234
- },
235
- "user": {
236
- "id": "user-123"
27
+ "version": 4,
28
+ "flows": {
29
+ "default": {
30
+ "config": { "platform": "server" },
31
+ "sources": {
32
+ "lambda": { "package": "@walkeros/server-source-aws", "config": {} }
33
+ }
34
+ }
237
35
  }
238
36
  }
239
37
  ```
240
38
 
241
- **GET - Pixel Tracking:**
242
-
243
- ```
244
- GET /collect?event=page%20view&data[title]=Home&data[path]=/
245
- ```
246
-
247
- ### Response Format
248
-
249
- **Success:**
250
-
251
- ```json
252
- {
253
- "success": true,
254
- "id": "event-id-123",
255
- "requestId": "aws-request-id"
256
- }
257
- ```
258
-
259
- **Error:**
260
-
261
- ```json
262
- {
263
- "success": false,
264
- "error": "Invalid request format",
265
- "requestId": "aws-request-id"
266
- }
267
- ```
268
-
269
- **Health Check:**
270
-
271
- ```json
272
- {
273
- "status": "ok",
274
- "timestamp": 1733328000000,
275
- "source": "lambda",
276
- "requestId": "aws-request-id"
277
- }
278
- ```
279
-
280
- ### Supported Platforms
281
-
282
- - ✅ AWS API Gateway REST API (v1)
283
- - ✅ AWS API Gateway HTTP API (v2)
284
- - ✅ Lambda Function URLs
285
- - ✅ Direct Lambda invocation
286
-
287
- ### Features
288
-
289
- - **Auto-detection**: Automatically detects API Gateway version
290
- - **CORS**: Configurable CORS with defaults
291
- - **Pixel Tracking**: Optional GET requests with 1x1 GIF response
292
- - **Base64 Decoding**: Handles base64-encoded request bodies
293
- - **Health Checks**: Built-in health check endpoint
294
- - **Request IDs**: AWS request ID in all responses and logs
295
- - **Logging**: Integrated with walkerOS logger
296
- - **Type-Safe**: Full TypeScript support
297
-
298
- ### Production Considerations
299
-
300
- #### Cold Starts
301
-
302
- Use handler singleton pattern (shown in Basic Usage) to reuse source instance
303
- across warm invocations.
304
-
305
- #### Logging
306
-
307
- The source integrates with the walkerOS logger from `env.logger`. Configure
308
- CloudWatch Logs:
309
-
310
- ```typescript
311
- import { createLogger } from '@walkeros/core';
312
-
313
- const logger = createLogger({
314
- level: 'info',
315
- // CloudWatch-friendly JSON output
316
- format: (level, message, meta) =>
317
- JSON.stringify({ level, message, ...meta, timestamp: Date.now() }),
318
- });
319
- ```
320
-
321
- #### Error Handling
322
-
323
- All errors include request IDs for tracing. Configure CloudWatch Insights
324
- queries:
325
-
326
- ```
327
- fields @timestamp, level, message, requestId, error
328
- | filter level = "error"
329
- | sort @timestamp desc
330
- ```
331
-
332
- #### Monitoring
333
-
334
- Key metrics to track:
335
-
336
- - Lambda Duration (p50, p99)
337
- - Lambda Errors
338
- - Lambda Throttles
339
- - API Gateway 4xx/5xx responses
340
-
341
- #### Security
342
-
343
- - Use API Gateway with API keys or AWS IAM for authentication
344
- - Enable AWS WAF for DDoS protection
345
- - Set Lambda reserved concurrency to prevent runaway costs
346
- - Validate CORS origins in production (don't use `cors: true`)
347
-
348
- ### Examples
349
-
350
- See [examples directory](./examples/) for:
351
-
352
- - SAM deployment
353
- - Serverless Framework deployment
354
- - CDK deployment
355
- - Local testing with SAM CLI
356
-
357
- ---
358
-
359
- ## SQS source
360
-
361
- Long-running listener that polls an AWS SQS queue and forwards each message to
362
- the walkerOS collector. Idempotent queue provisioning via
363
- `walkeros setup source.<id>`, optional sibling DLQ, optional SNS topic
364
- subscription with auto-applied queue policy.
365
-
366
- ### Quickstart
367
-
368
- ```typescript
369
- import { sourceSqs } from '@walkeros/server-source-aws';
370
- import { startFlow } from '@walkeros/collector';
371
-
372
- await startFlow({
373
- sources: {
374
- sqs: {
375
- code: sourceSqs,
376
- config: {
377
- settings: {
378
- queueName: 'walkeros-events',
379
- region: 'eu-central-1',
380
- },
381
- setup: {
382
- visibilityTimeoutSeconds: 30,
383
- messageRetentionSeconds: 345600,
384
- tags: { env: 'prod', team: 'data' },
385
- },
386
- },
387
- },
388
- },
389
- destinations: {
390
- // your destinations
391
- },
392
- });
393
- ```
394
-
395
- The SQS source is event-driven. `init()` validates the queue exists and starts
396
- the long-poll loop as a background task. The source's `push()` is a deliberate
397
- no-op stub in production. `destroy()` stops the loop, drains in-flight messages,
398
- and force-closes after `shutdownTimeoutMs` (default 30000).
399
-
400
- ### Setup
401
-
402
- Run `walkeros setup source.<id>` to provision the queue idempotently with
403
- declared attributes. Optionally creates a sibling dead-letter queue, and
404
- optionally subscribes the queue to an SNS topic, including the matching queue
405
- policy. AWS treats identical CreateQueue inputs as success; setup never calls
406
- SetQueueAttributes.
407
-
408
- ### Authoritative-apply
409
-
410
- Setup writes declared state to declared resources unconditionally. Non-declared
411
- tags or non-declared SNS subscriptions are left untouched, not detected, not
412
- logged. On attribute conflict (`QueueNameExists`), setup hard-fails and asks the
413
- operator to delete or rename, since AWS does not allow `CreateQueue` to
414
- overwrite attributes.
39
+ ## Documentation
415
40
 
416
- ### IAM
41
+ Full configuration, mapping, and examples live in the docs:
42
+ **https://www.walkeros.io/docs/sources/server/aws**
417
43
 
418
- Separate setup vs runtime roles.
44
+ ## Contribute
419
45
 
420
- | Phase | Permissions |
421
- | ------- | --------------------------------------------------------------------------------------- |
422
- | Setup | `sqs:CreateQueue`, `sqs:GetQueueAttributes`, `sqs:TagQueue`, optionally `sns:Subscribe` |
423
- | Runtime | `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:GetQueueUrl`, `sqs:GetQueueAttributes` |
424
-
425
- ### DLQ defaults
426
-
427
- When `setup.deadLetterQueue.create: true`, walkerOS provisions a sibling DLQ
428
- named `<queueName>-dlq` (or `<queueName>-dlq.fifo` for FIFO). The DLQ inherits
429
- the parent's `region` and `tags`, plus `walkerOS: 'dlq'`. Retention is extended
430
- to 14 days (AWS max). Visibility timeout, max message size, and KMS default to
431
- AWS defaults rather than inheriting. No nested DLQ-of-DLQ.
432
-
433
- ### SNS subscription
434
-
435
- When `setup.subscribeToSnsTopic` is set, walkerOS calls `sns.SubscribeCommand`
436
- with the queue ARN as endpoint and writes a queue policy with deterministic Sid
437
- `walkerOSAllowSNSPublish-<sourceId>` so re-runs upsert in place. Operators who
438
- manage policies externally should leave `subscribeToSnsTopic` unset and add the
439
- subscription via Terraform or console.
440
-
441
- ### Decoders
442
-
443
- | Decoder | Behavior |
444
- | ------- | ------------------------------------------------------------------------- |
445
- | `json` | Default. `JSON.parse(body)`. Throws on parse failure. |
446
- | `text` | Forwards body string under `data.payload`. |
447
- | `raw` | Forwards `Buffer.from(body, 'utf8')` base64-encoded under `data.payload`. |
448
-
449
- ### Flow control
450
-
451
- | Setting | Default | Description |
452
- | ------------------- | ----------- | --------------------------------------- |
453
- | `maxMessages` | 10 (cap 10) | Receive batch size. |
454
- | `waitTimeSeconds` | 20 (cap 20) | Long-poll duration. SQS hard cap is 20. |
455
- | `visibilityTimeout` | queue value | Per-receive override. |
456
-
457
- ### Error handling
458
-
459
- | `onPushError` | Behavior |
460
- | ------------- | -------------------------------------------------------------------------------- |
461
- | `nack` | Default. Skip `DeleteMessage` so SQS redelivers when visibility timeout expires. |
462
- | `ack` | Call `DeleteMessage` even on push failure. Drops the message. |
463
-
464
- SQS has no explicit nack RPC; redelivery is automatic when visibility timeout
465
- expires without a `DeleteMessage`.
466
-
467
- ### See also
468
-
469
- - [AWS Lambda source](#lambda-source) (this package's other source).
470
- - [AWS SNS destination](https://www.walkeros.io/docs/destinations/server/sns)
471
- for the standard SNS-to-SQS fan-out pattern.
46
+ Feel free to contribute by submitting an
47
+ [issue](https://github.com/elbwalker/walkerOS/issues), starting a
48
+ [discussion](https://github.com/elbwalker/walkerOS/discussions), or getting in
49
+ [contact](https://calendly.com/elb-alexander/30min).
472
50
 
473
51
  ## License
474
52
 
475
53
  MIT
476
-
477
- ## Support
478
-
479
- - [Documentation](https://www.walkeros.io/docs)
480
- - [GitHub Issues](https://github.com/elbwalker/walkerOS/issues)
481
- - [Discord Community](https://discord.gg/elbwalker)