lemon-core 5.0.4 → 5.0.6
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/README.md +168 -136
- package/bin/lemon-fields-types.mjs +12 -0
- package/bin/lib/fields-types.mjs +629 -0
- package/dist/common/test-helper.js +6 -3
- package/dist/common/test-helper.js.map +1 -1
- package/dist/cores/aws/aws-sns-service.d.ts +6 -0
- package/dist/cores/aws/aws-sns-service.js +22 -3
- package/dist/cores/aws/aws-sns-service.js.map +1 -1
- package/dist/cores/aws/aws-sqs-service.js +5 -0
- package/dist/cores/aws/aws-sqs-service.js.map +1 -1
- package/dist/cores/config/config-service.js +3 -1
- package/dist/cores/config/config-service.js.map +1 -1
- package/dist/cores/lambda/lambda-alb-handler.js +5 -0
- package/dist/cores/lambda/lambda-alb-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-handler.js +4 -1
- package/dist/cores/lambda/lambda-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-notification-handler.js +4 -1
- package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sns-handler.d.ts +7 -1
- package/dist/cores/lambda/lambda-sns-handler.js +26 -3
- package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sqs-handler.d.ts +7 -1
- package/dist/cores/lambda/lambda-sqs-handler.js +26 -3
- package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-web-handler.js +63 -15
- package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
- package/dist/cores/protocol/aws-lambda-helper.d.ts +13 -0
- package/dist/cores/protocol/aws-lambda-helper.js +64 -41
- package/dist/cores/protocol/aws-lambda-helper.js.map +1 -1
- package/dist/cores/protocol/local-transport.d.ts +135 -0
- package/dist/cores/protocol/local-transport.js +392 -0
- package/dist/cores/protocol/local-transport.js.map +1 -0
- package/dist/cores/protocol/protocol-relay.d.ts +123 -0
- package/dist/cores/protocol/protocol-relay.js +339 -0
- package/dist/cores/protocol/protocol-relay.js.map +1 -0
- package/dist/cores/protocol/protocol-service.d.ts +11 -4
- package/dist/cores/protocol/protocol-service.js +140 -36
- package/dist/cores/protocol/protocol-service.js.map +1 -1
- package/dist/cores/protocol/protocol-sign.d.ts +22 -0
- package/dist/cores/protocol/protocol-sign.js +30 -3
- package/dist/cores/protocol/protocol-sign.js.map +1 -1
- package/dist/engine/engine.js +35 -15
- package/dist/engine/engine.js.map +1 -1
- package/dist/esm/index.mjs +2 -0
- package/dist/extended/cores/abstract-controllers.d.ts +18 -4
- package/dist/extended/cores/abstract-controllers.js +59 -19
- package/dist/extended/cores/abstract-controllers.js.map +1 -1
- package/dist/extended/cores/abstract-services.d.ts +54 -4
- package/dist/extended/cores/abstract-services.js +159 -14
- package/dist/extended/cores/abstract-services.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/log-mask.d.ts +19 -0
- package/dist/lib/log-mask.js +55 -0
- package/dist/lib/log-mask.js.map +1 -0
- package/dist/lib/safe-json.d.ts +23 -0
- package/dist/lib/safe-json.js +78 -0
- package/dist/lib/safe-json.js.map +1 -0
- package/package.json +14 -4
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { APIGatewayProxyEvent } from 'aws-lambda';
|
|
2
|
+
import type { ProtocolParam } from '../core-services';
|
|
3
|
+
import type { MyProtocolService } from './protocol-service';
|
|
4
|
+
/**
|
|
5
|
+
* env name of the local transport (`mock` = on, in local mode only).
|
|
6
|
+
*/
|
|
7
|
+
export declare const LOCAL_TRANSPORT = "LOCAL_TRANSPORT";
|
|
8
|
+
/**
|
|
9
|
+
* placeholder account of the local ARNs, URLs and the fake Lambda context.
|
|
10
|
+
*/
|
|
11
|
+
export declare const LOCAL_ACCOUNT_ID = "000000000000";
|
|
12
|
+
/**
|
|
13
|
+
* loop guard: max deliveries in one burst (until `drain()` or idle), and max chain depth (a send from a delivery is +1).
|
|
14
|
+
* - `kept`: max finished deliveries kept for `drain()`/`deliveries()` (the oldest are dropped).
|
|
15
|
+
*/
|
|
16
|
+
export declare const LOCAL_TRANSPORT_CAP: {
|
|
17
|
+
deliveries: number;
|
|
18
|
+
depth: number;
|
|
19
|
+
kept: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* kind of a local delivery (`notify` = sns, `enqueue` = sqs, `execute` = protocol).
|
|
23
|
+
*/
|
|
24
|
+
export type LocalDeliveryKind = 'sns' | 'sqs' | 'protocol';
|
|
25
|
+
/**
|
|
26
|
+
* one delivery of the local transport.
|
|
27
|
+
*/
|
|
28
|
+
export interface LocalDelivery {
|
|
29
|
+
/** transport of the delivery */
|
|
30
|
+
kind: LocalDeliveryKind;
|
|
31
|
+
/** topic, queue or function name (this service) */
|
|
32
|
+
target: string;
|
|
33
|
+
/** `mock-<uuid>` ('' if refused by the loop guard) */
|
|
34
|
+
messageId: string;
|
|
35
|
+
/** result of `LambdaHandler.handle()` (sqs: `{ batchItemFailures }`; protocol: the parsed body) */
|
|
36
|
+
result?: any;
|
|
37
|
+
/** error message (thrown, refused, SQS `batchItemFailures`, or the SNS failure result) */
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* a message attribute as the SDK input (`DataType`, `StringValue`).
|
|
42
|
+
*/
|
|
43
|
+
interface LocalAttributeValue {
|
|
44
|
+
DataType?: string;
|
|
45
|
+
StringValue?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* the log writer (one `_inf` line); an object, so a spec can spy on `inf`.
|
|
49
|
+
*/
|
|
50
|
+
export declare const transportLog: {
|
|
51
|
+
inf: (line: string) => void;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* true if the local transport is on: env `LOCAL_TRANSPORT=mock` and local mode (never in Lambda).
|
|
55
|
+
* - read from `process.env` on every call. an ignored value logs one warn line.
|
|
56
|
+
*/
|
|
57
|
+
export declare const isActive: () => boolean;
|
|
58
|
+
export declare const topicOf: (target: string) => string;
|
|
59
|
+
export declare const queueOf: (endpoint: string) => string;
|
|
60
|
+
/**
|
|
61
|
+
* host of this service by protocol (`sns://self`, `sqs://self`, `web://self`).
|
|
62
|
+
*
|
|
63
|
+
* @param type protocol type.
|
|
64
|
+
* @param service (optional) the protocol service (default: the engine's).
|
|
65
|
+
* @param config (optional) its config service.
|
|
66
|
+
*/
|
|
67
|
+
export declare const selfHostOf: (type: "sns" | "sqs" | "web", service?: MyProtocolService, config?: MyProtocolService["config"]) => Promise<string>;
|
|
68
|
+
/**
|
|
69
|
+
* SNS publish input (the fields a Lambda record needs).
|
|
70
|
+
*/
|
|
71
|
+
export interface LocalSnsMessage {
|
|
72
|
+
Subject?: string;
|
|
73
|
+
Message: string;
|
|
74
|
+
MessageAttributes?: Record<string, LocalAttributeValue>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* deliver an SNS message to this service: a `aws:sns` record → `LambdaHandler.handle()` (async).
|
|
78
|
+
*
|
|
79
|
+
* @param target topic name or ARN.
|
|
80
|
+
* @param msg subject, message (the `default` string), attributes.
|
|
81
|
+
* @param selfHost (optional) `sns://self` host (default: by the engine's protocol service).
|
|
82
|
+
* @returns the message id `mock-<uuid>`.
|
|
83
|
+
*/
|
|
84
|
+
export declare const localSns: (target: string, msg: LocalSnsMessage, selfHost?: string) => Promise<string>;
|
|
85
|
+
/**
|
|
86
|
+
* SQS send input (the fields a Lambda record needs).
|
|
87
|
+
*/
|
|
88
|
+
export interface LocalSqsMessage {
|
|
89
|
+
MessageBody?: string;
|
|
90
|
+
MessageAttributes?: Record<string, LocalAttributeValue>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* deliver an SQS message to this service: a `aws:sqs` record → `LambdaHandler.handle()` (async, no delay).
|
|
94
|
+
*
|
|
95
|
+
* @param endpoint queue url or name.
|
|
96
|
+
* @param msg body and attributes.
|
|
97
|
+
* @param selfHost (optional) `sqs://self` host (default: by the engine's protocol service).
|
|
98
|
+
* @returns the message id `mock-<uuid>`.
|
|
99
|
+
*/
|
|
100
|
+
export declare const localSqs: (endpoint: string, msg: LocalSqsMessage, selfHost?: string) => Promise<string>;
|
|
101
|
+
/**
|
|
102
|
+
* run a protocol `execute()` on this service: the web event → `LambdaHandler.handle()` (sync, like a sync invoke).
|
|
103
|
+
* - the result is parsed like `invokeLambda()` (a non-2xx throws). `useEvent` → async, returns the 202 output.
|
|
104
|
+
*
|
|
105
|
+
* @param fn function name (host of the `web://` uri).
|
|
106
|
+
* @param event the web event of `WEBProtocolTransformer`.
|
|
107
|
+
* @param selfHost `web://self` host of the calling protocol service.
|
|
108
|
+
* @param options `param` for logging, `useEvent` for an async invoke.
|
|
109
|
+
*/
|
|
110
|
+
export declare const localWeb: <T = any>(fn: string, event: APIGatewayProxyEvent, selfHost: string, options?: {
|
|
111
|
+
param?: ProtocolParam;
|
|
112
|
+
useEvent?: boolean;
|
|
113
|
+
}) => Promise<T>;
|
|
114
|
+
/**
|
|
115
|
+
* wait for every pending delivery (incl. the ones they send), then return the finished list and clear it.
|
|
116
|
+
* - resets the loop-guard count (idle also does). process-wide: it takes every delivery, not only the caller's.
|
|
117
|
+
* - must not be called inside an SNS/SQS delivery (it would wait for itself).
|
|
118
|
+
*/
|
|
119
|
+
export declare const drain: () => Promise<LocalDelivery[]>;
|
|
120
|
+
/**
|
|
121
|
+
* the finished deliveries since the last `drain()`, the last 100 only (a copy; it does not wait or clear).
|
|
122
|
+
*/
|
|
123
|
+
export declare const deliveries: () => LocalDelivery[];
|
|
124
|
+
/**
|
|
125
|
+
* the public API of the local transport (exported from the package root).
|
|
126
|
+
*/
|
|
127
|
+
export declare const $localTransport: {
|
|
128
|
+
/** true if `LOCAL_TRANSPORT=mock` and local mode */
|
|
129
|
+
isActive: () => boolean;
|
|
130
|
+
/** wait for all pending deliveries, return them, and clear */
|
|
131
|
+
drain: () => Promise<LocalDelivery[]>;
|
|
132
|
+
/** the finished deliveries since the last `drain()` */
|
|
133
|
+
deliveries: () => LocalDelivery[];
|
|
134
|
+
};
|
|
135
|
+
export {};
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.$localTransport = exports.deliveries = exports.drain = exports.localWeb = exports.localSqs = exports.localSns = exports.selfHostOf = exports.queueOf = exports.topicOf = exports.isActive = exports.transportLog = exports.LOCAL_TRANSPORT_CAP = exports.LOCAL_ACCOUNT_ID = exports.LOCAL_TRANSPORT = void 0;
|
|
40
|
+
/**
|
|
41
|
+
* `local-transport.ts`
|
|
42
|
+
* - opt-in local transport (mock delivery): in local mode, `sns.publish()`, `sqs.sendMessage()` and the protocol
|
|
43
|
+
* `execute/notify/enqueue/broadcast` deliver to this service in-process, with no AWS SDK client.
|
|
44
|
+
* - on only if env `LOCAL_TRANSPORT=mock` and `$U.isLocalMode()` (`LOCAL_MODE=1`, no `AWS_LAMBDA_FUNCTION_NAME`).
|
|
45
|
+
* in Lambda the env is ignored (one warn line). without the env nothing changes.
|
|
46
|
+
* - self only: a target that is not this service throws `501 NOT SUPPORTED` (no AWS call, no silent drop).
|
|
47
|
+
* no target and no env `MY_SNS_ENDPOINT`/`MY_SQS_ENDPOINT` (a local run) = this service's topic/queue.
|
|
48
|
+
* - fidelity: each delivery is a real Lambda event record, run by the engine's `LambdaHandler.handle()`.
|
|
49
|
+
* SNS/SQS kinds are async (`setImmediate`), `execute` is sync. `drain()` waits for all and returns them.
|
|
50
|
+
* - loop guard: over `LOCAL_TRANSPORT_CAP` (deliveries in one burst, or chain depth) → `508 LOOP DETECTED`.
|
|
51
|
+
* a burst ends at `drain()` or when nothing is pending (idle), so a long-running server never stays capped.
|
|
52
|
+
* - keeps only the last `LOCAL_TRANSPORT_CAP.kept` (100) finished deliveries (the oldest are dropped).
|
|
53
|
+
*
|
|
54
|
+
*
|
|
55
|
+
* @author Steve Jung <steve@lemoncloud.io>
|
|
56
|
+
* @date 2026-10-30 initial version.
|
|
57
|
+
* @date 2026-10-30 the burst count resets when idle (not only at `drain()`); keep the last 100 deliveries.
|
|
58
|
+
*
|
|
59
|
+
* @copyright (C) lemoncloud.io 2026 - All Rights Reserved.
|
|
60
|
+
*/
|
|
61
|
+
const async_hooks_1 = require("async_hooks");
|
|
62
|
+
const crypto_1 = require("crypto");
|
|
63
|
+
const url_1 = __importDefault(require("url"));
|
|
64
|
+
const engine_1 = require("../../engine/");
|
|
65
|
+
const test_helper_1 = require("../../common/test-helper");
|
|
66
|
+
//* lazy namespace: this file is in the engine closure (via `aws-sns-service`), so nothing runs `$U` at load.
|
|
67
|
+
const NS = (() => {
|
|
68
|
+
let ns;
|
|
69
|
+
return () => (ns ??= engine_1.$U.NS('MOCK', 'magenta'));
|
|
70
|
+
})();
|
|
71
|
+
/**
|
|
72
|
+
* env name of the local transport (`mock` = on, in local mode only).
|
|
73
|
+
*/
|
|
74
|
+
exports.LOCAL_TRANSPORT = 'LOCAL_TRANSPORT';
|
|
75
|
+
/**
|
|
76
|
+
* placeholder account of the local ARNs, URLs and the fake Lambda context.
|
|
77
|
+
*/
|
|
78
|
+
exports.LOCAL_ACCOUNT_ID = '000000000000';
|
|
79
|
+
/**
|
|
80
|
+
* loop guard: max deliveries in one burst (until `drain()` or idle), and max chain depth (a send from a delivery is +1).
|
|
81
|
+
* - `kept`: max finished deliveries kept for `drain()`/`deliveries()` (the oldest are dropped).
|
|
82
|
+
*/
|
|
83
|
+
exports.LOCAL_TRANSPORT_CAP = { deliveries: 50, depth: 8, kept: 100 };
|
|
84
|
+
/**
|
|
85
|
+
* the log writer (one `_inf` line); an object, so a spec can spy on `inf`.
|
|
86
|
+
*/
|
|
87
|
+
exports.transportLog = {
|
|
88
|
+
inf: (line) => (0, engine_1._inf)(NS(), line),
|
|
89
|
+
};
|
|
90
|
+
//* chain of the current delivery: `depth` (1 = sent by a client request), `async` (inside an SNS/SQS delivery).
|
|
91
|
+
const $chain = new async_hooks_1.AsyncLocalStorage();
|
|
92
|
+
//* process-wide state: pending deliveries, running sync `execute()`s, finished deliveries, count in this burst,
|
|
93
|
+
//* cap logged, warned keys.
|
|
94
|
+
const $state = {
|
|
95
|
+
pending: new Set(),
|
|
96
|
+
running: 0,
|
|
97
|
+
list: [],
|
|
98
|
+
count: 0,
|
|
99
|
+
capped: false,
|
|
100
|
+
warned: new Set(),
|
|
101
|
+
};
|
|
102
|
+
//* keep one finished delivery (the last `LOCAL_TRANSPORT_CAP.kept` only).
|
|
103
|
+
const record = (delivery) => {
|
|
104
|
+
$state.list.push(delivery);
|
|
105
|
+
if ($state.list.length > exports.LOCAL_TRANSPORT_CAP.kept)
|
|
106
|
+
$state.list.splice(0, $state.list.length - exports.LOCAL_TRANSPORT_CAP.kept);
|
|
107
|
+
};
|
|
108
|
+
//* end of a burst: nothing pending and no sync `execute()` running → reset the count and the cap line.
|
|
109
|
+
const resetIfIdle = () => {
|
|
110
|
+
if ($state.pending.size || $state.running)
|
|
111
|
+
return;
|
|
112
|
+
$state.count = 0;
|
|
113
|
+
$state.capped = false;
|
|
114
|
+
};
|
|
115
|
+
//* the configured region (env `REGION`, as the SNS service).
|
|
116
|
+
const region = () => `${engine_1.$engine.environ('REGION', 'ap-northeast-2') || 'ap-northeast-2'}`;
|
|
117
|
+
//* log one warn line per reason (never twice in a process).
|
|
118
|
+
const warnOnce = (key, line) => {
|
|
119
|
+
if ($state.warned.has(key))
|
|
120
|
+
return;
|
|
121
|
+
$state.warned.add(key);
|
|
122
|
+
exports.transportLog.inf(line);
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* true if the local transport is on: env `LOCAL_TRANSPORT=mock` and local mode (never in Lambda).
|
|
126
|
+
* - read from `process.env` on every call. an ignored value logs one warn line.
|
|
127
|
+
*/
|
|
128
|
+
const isActive = () => {
|
|
129
|
+
const val = `${process.env[exports.LOCAL_TRANSPORT] ?? ''}`;
|
|
130
|
+
if (!val)
|
|
131
|
+
return false;
|
|
132
|
+
//* the reason to ignore ('' = active).
|
|
133
|
+
const why = val !== 'mock'
|
|
134
|
+
? 'unknown value'
|
|
135
|
+
: process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
136
|
+
? 'in Lambda'
|
|
137
|
+
: !engine_1.$U.isLocalMode()
|
|
138
|
+
? 'not local mode'
|
|
139
|
+
: '';
|
|
140
|
+
if (!why)
|
|
141
|
+
return true;
|
|
142
|
+
warnOnce(`${val}/${why}`, `WARN! env.${exports.LOCAL_TRANSPORT}[${val.substring(0, 32)}] is ignored - ${why}`);
|
|
143
|
+
return false;
|
|
144
|
+
};
|
|
145
|
+
exports.isActive = isActive;
|
|
146
|
+
//* topic name of an SNS target: `arn:aws:sns:<region>:<account>:<topic>` → `<topic>`, a name as is.
|
|
147
|
+
const topicOf = (target) => `${target || ''}`.split(':').pop() || '';
|
|
148
|
+
exports.topicOf = topicOf;
|
|
149
|
+
//* queue name of an SQS endpoint: `https://sqs.<region>.amazonaws.com/<account>/<queue>` → `<queue>`, a name as is.
|
|
150
|
+
const queueOf = (endpoint) => `${endpoint || ''}`
|
|
151
|
+
.split('/')
|
|
152
|
+
.filter(_ => !!_)
|
|
153
|
+
.pop() || '';
|
|
154
|
+
exports.queueOf = queueOf;
|
|
155
|
+
//* host of a protocol uri like `sns://<acct>@<host>/<path>#<ver>`.
|
|
156
|
+
const hostOf = (uri) => `${url_1.default.parse(uri).hostname || ''}`;
|
|
157
|
+
/**
|
|
158
|
+
* host of this service by protocol (`sns://self`, `sqs://self`, `web://self`).
|
|
159
|
+
*
|
|
160
|
+
* @param type protocol type.
|
|
161
|
+
* @param service (optional) the protocol service (default: the engine's).
|
|
162
|
+
* @param config (optional) its config service.
|
|
163
|
+
*/
|
|
164
|
+
const selfHostOf = async (type, service, config) => {
|
|
165
|
+
//* lazy: the protocol module loads the AWS services (no import cycle at load).
|
|
166
|
+
const svc = service ?? (await Promise.resolve().then(() => __importStar(require('./index')))).default.service;
|
|
167
|
+
return hostOf(svc.asProtocolURI(type, { service: 'self' }, config));
|
|
168
|
+
};
|
|
169
|
+
exports.selfHostOf = selfHostOf;
|
|
170
|
+
//* throw `501` if the name is not one of this service's names.
|
|
171
|
+
const assertSelf = (name, selves) => {
|
|
172
|
+
if (!name || !selves.filter(_ => !!_).includes(name))
|
|
173
|
+
throw new Error(`501 NOT SUPPORTED - local transport: ${name} is not this service`);
|
|
174
|
+
};
|
|
175
|
+
//* loop guard: admit one delivery (returns its depth), or refuse with `508` (one `[MOCK] cap` line until `drain()`).
|
|
176
|
+
const admit = (kind, target) => {
|
|
177
|
+
const depth = ($chain.getStore()?.depth ?? 0) + 1;
|
|
178
|
+
if ($state.count >= exports.LOCAL_TRANSPORT_CAP.deliveries || depth > exports.LOCAL_TRANSPORT_CAP.depth) {
|
|
179
|
+
if (!$state.capped) {
|
|
180
|
+
$state.capped = true;
|
|
181
|
+
exports.transportLog.inf(`[MOCK] cap kind=${kind} target=${target} deliveries=${$state.count} depth=${depth}`);
|
|
182
|
+
}
|
|
183
|
+
const error = `508 LOOP DETECTED - local transport`;
|
|
184
|
+
record({ kind, target, messageId: '', error });
|
|
185
|
+
throw new Error(error);
|
|
186
|
+
}
|
|
187
|
+
$state.count++;
|
|
188
|
+
return depth;
|
|
189
|
+
};
|
|
190
|
+
//* a fake Lambda context of this service (placeholder account).
|
|
191
|
+
const asContext = (name) => ({
|
|
192
|
+
callbackWaitsForEmptyEventLoop: true,
|
|
193
|
+
functionName: name,
|
|
194
|
+
functionVersion: '$LATEST',
|
|
195
|
+
invokedFunctionArn: `arn:aws:lambda:${region()}:${exports.LOCAL_ACCOUNT_ID}:function:${name}`,
|
|
196
|
+
memoryLimitInMB: '1024',
|
|
197
|
+
awsRequestId: (0, crypto_1.randomUUID)(),
|
|
198
|
+
logGroupName: `/aws/lambda/${name}`,
|
|
199
|
+
logStreamName: 'local-transport',
|
|
200
|
+
getRemainingTimeInMillis: () => 30000,
|
|
201
|
+
done: () => { },
|
|
202
|
+
fail: () => { },
|
|
203
|
+
succeed: () => { },
|
|
204
|
+
});
|
|
205
|
+
//* run one event through the engine's `LambdaHandler.handle()` (never rejects, as in Lambda).
|
|
206
|
+
const handleEvent = async (event) => {
|
|
207
|
+
//* lazy: the lambda module imports the protocol and AWS modules (no import cycle at load).
|
|
208
|
+
const $lambda = (await Promise.resolve().then(() => __importStar(require('../lambda')))).default;
|
|
209
|
+
const context = asContext(await (0, exports.selfHostOf)('web'));
|
|
210
|
+
return $lambda.lambda.handle(event, context);
|
|
211
|
+
};
|
|
212
|
+
//* the error of a finished SNS/SQS delivery ('' if none): SQS `batchItemFailures`, or the failure result `{ error }`.
|
|
213
|
+
const errorOf = (result) => {
|
|
214
|
+
const failures = Array.isArray(result?.batchItemFailures) ? result.batchItemFailures : [];
|
|
215
|
+
if (failures.length)
|
|
216
|
+
return `500 BATCH ITEM FAILURES - ${failures.map(_ => _?.itemIdentifier).join(',')}`;
|
|
217
|
+
if (result && typeof result === 'object' && typeof result.error === 'string')
|
|
218
|
+
return result.error;
|
|
219
|
+
return '';
|
|
220
|
+
};
|
|
221
|
+
//* schedule one async delivery (`setImmediate`), tracked until `drain()`.
|
|
222
|
+
const deliverAsync = (kind, target, depth, messageId, event) => {
|
|
223
|
+
exports.transportLog.inf(`[MOCK] deliver kind=${kind} target=${target} message=${messageId}`);
|
|
224
|
+
const job = new Promise(resolve => setImmediate(() => {
|
|
225
|
+
$chain
|
|
226
|
+
.run({ depth, async: true }, () => handleEvent(event))
|
|
227
|
+
.then(result => {
|
|
228
|
+
const error = errorOf(result);
|
|
229
|
+
record({ kind, target, messageId, result, ...(error ? { error } : {}) });
|
|
230
|
+
})
|
|
231
|
+
.catch(e => record({ kind, target, messageId, error: (0, test_helper_1.GETERR)(e) }))
|
|
232
|
+
.finally(() => resolve());
|
|
233
|
+
}));
|
|
234
|
+
$state.pending.add(job);
|
|
235
|
+
//* done: forget it, and end the burst if this was the last one.
|
|
236
|
+
job.then(() => {
|
|
237
|
+
$state.pending.delete(job);
|
|
238
|
+
resetIfIdle();
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* deliver an SNS message to this service: a `aws:sns` record → `LambdaHandler.handle()` (async).
|
|
243
|
+
*
|
|
244
|
+
* @param target topic name or ARN.
|
|
245
|
+
* @param msg subject, message (the `default` string), attributes.
|
|
246
|
+
* @param selfHost (optional) `sns://self` host (default: by the engine's protocol service).
|
|
247
|
+
* @returns the message id `mock-<uuid>`.
|
|
248
|
+
*/
|
|
249
|
+
const localSns = async (target, msg, selfHost) => {
|
|
250
|
+
const self = selfHost ?? (await (0, exports.selfHostOf)('sns'));
|
|
251
|
+
//* '' (no target, no env `MY_SNS_ENDPOINT`) → this service's topic, as the Lambda deploy sets the env.
|
|
252
|
+
const topic = (0, exports.topicOf)(target) || self;
|
|
253
|
+
assertSelf(topic, [(0, exports.topicOf)(`${engine_1.$engine.environ('MY_SNS_ENDPOINT', '') || ''}`), self]);
|
|
254
|
+
const depth = admit('sns', topic);
|
|
255
|
+
const messageId = `mock-${(0, crypto_1.randomUUID)()}`;
|
|
256
|
+
const TopicArn = `arn:aws:sns:${region()}:${exports.LOCAL_ACCOUNT_ID}:${topic}`;
|
|
257
|
+
//* attributes as the Lambda record has them (`Type`, `Value`).
|
|
258
|
+
const MessageAttributes = Object.entries(msg.MessageAttributes || {}).reduce((M, [k, v]) => ({ ...M, [k]: { Type: v.DataType, Value: v.StringValue } }), {});
|
|
259
|
+
const record = {
|
|
260
|
+
EventSource: 'aws:sns',
|
|
261
|
+
EventVersion: '1.0',
|
|
262
|
+
EventSubscriptionArn: `${TopicArn}:${(0, crypto_1.randomUUID)()}`,
|
|
263
|
+
Sns: {
|
|
264
|
+
Type: 'Notification',
|
|
265
|
+
MessageId: messageId,
|
|
266
|
+
TopicArn,
|
|
267
|
+
Subject: msg.Subject ?? null,
|
|
268
|
+
Message: msg.Message,
|
|
269
|
+
Timestamp: new Date().toISOString(),
|
|
270
|
+
MessageAttributes,
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
deliverAsync('sns', topic, depth, messageId, { Records: [record] });
|
|
274
|
+
return messageId;
|
|
275
|
+
};
|
|
276
|
+
exports.localSns = localSns;
|
|
277
|
+
/**
|
|
278
|
+
* deliver an SQS message to this service: a `aws:sqs` record → `LambdaHandler.handle()` (async, no delay).
|
|
279
|
+
*
|
|
280
|
+
* @param endpoint queue url or name.
|
|
281
|
+
* @param msg body and attributes.
|
|
282
|
+
* @param selfHost (optional) `sqs://self` host (default: by the engine's protocol service).
|
|
283
|
+
* @returns the message id `mock-<uuid>`.
|
|
284
|
+
*/
|
|
285
|
+
const localSqs = async (endpoint, msg, selfHost) => {
|
|
286
|
+
const self = selfHost ?? (await (0, exports.selfHostOf)('sqs'));
|
|
287
|
+
//* '' (no endpoint, no env `MY_SQS_ENDPOINT`) → this service's queue, as the Lambda deploy sets the env.
|
|
288
|
+
const queue = (0, exports.queueOf)(endpoint) || self;
|
|
289
|
+
assertSelf(queue, [(0, exports.queueOf)(`${engine_1.$engine.environ('MY_SQS_ENDPOINT', '') || ''}`), self]);
|
|
290
|
+
const depth = admit('sqs', queue);
|
|
291
|
+
const messageId = `mock-${(0, crypto_1.randomUUID)()}`;
|
|
292
|
+
const now = `${Date.now()}`;
|
|
293
|
+
//* attributes as the Lambda record has them (`dataType`, `stringValue`).
|
|
294
|
+
const messageAttributes = Object.entries(msg.MessageAttributes || {}).reduce((M, [k, v]) => ({
|
|
295
|
+
...M,
|
|
296
|
+
[k]: { dataType: v.DataType, stringValue: v.StringValue, stringListValues: [], binaryListValues: [] },
|
|
297
|
+
}), {});
|
|
298
|
+
const record = {
|
|
299
|
+
messageId,
|
|
300
|
+
receiptHandle: `mock-${(0, crypto_1.randomUUID)()}`,
|
|
301
|
+
body: msg.MessageBody,
|
|
302
|
+
attributes: {
|
|
303
|
+
ApproximateReceiveCount: '1',
|
|
304
|
+
SentTimestamp: now,
|
|
305
|
+
SenderId: exports.LOCAL_ACCOUNT_ID,
|
|
306
|
+
ApproximateFirstReceiveTimestamp: now,
|
|
307
|
+
},
|
|
308
|
+
messageAttributes,
|
|
309
|
+
md5OfBody: (0, crypto_1.createHash)('md5')
|
|
310
|
+
.update(`${msg.MessageBody ?? ''}`)
|
|
311
|
+
.digest('hex'),
|
|
312
|
+
eventSource: 'aws:sqs',
|
|
313
|
+
eventSourceARN: `arn:aws:sqs:${region()}:${exports.LOCAL_ACCOUNT_ID}:${queue}`,
|
|
314
|
+
awsRegion: region(),
|
|
315
|
+
};
|
|
316
|
+
deliverAsync('sqs', queue, depth, messageId, { Records: [record] });
|
|
317
|
+
return messageId;
|
|
318
|
+
};
|
|
319
|
+
exports.localSqs = localSqs;
|
|
320
|
+
/**
|
|
321
|
+
* run a protocol `execute()` on this service: the web event → `LambdaHandler.handle()` (sync, like a sync invoke).
|
|
322
|
+
* - the result is parsed like `invokeLambda()` (a non-2xx throws). `useEvent` → async, returns the 202 output.
|
|
323
|
+
*
|
|
324
|
+
* @param fn function name (host of the `web://` uri).
|
|
325
|
+
* @param event the web event of `WEBProtocolTransformer`.
|
|
326
|
+
* @param selfHost `web://self` host of the calling protocol service.
|
|
327
|
+
* @param options `param` for logging, `useEvent` for an async invoke.
|
|
328
|
+
*/
|
|
329
|
+
const localWeb = async (fn, event, selfHost, options) => {
|
|
330
|
+
assertSelf(fn, [selfHost]);
|
|
331
|
+
const depth = admit('protocol', fn);
|
|
332
|
+
//* lazy: `aws-lambda-helper` runs `$U` at load (this file is in the engine closure).
|
|
333
|
+
const { asInvokeResult } = await Promise.resolve().then(() => __importStar(require('./aws-lambda-helper')));
|
|
334
|
+
const messageId = `mock-${(0, crypto_1.randomUUID)()}`;
|
|
335
|
+
//* async invoke (`InvocationType: Event`): deliver later, return the 202 output.
|
|
336
|
+
if (options?.useEvent) {
|
|
337
|
+
deliverAsync('protocol', fn, depth, messageId, event);
|
|
338
|
+
return asInvokeResult(fn, { StatusCode: 202 }, { ...options, useEvent: true });
|
|
339
|
+
}
|
|
340
|
+
exports.transportLog.inf(`[MOCK] deliver kind=protocol target=${fn} message=${messageId}`);
|
|
341
|
+
$state.running++;
|
|
342
|
+
try {
|
|
343
|
+
const result = await $chain.run({ depth, async: false }, () => handleEvent(event));
|
|
344
|
+
const Payload = new TextEncoder().encode(JSON.stringify(result ?? {}));
|
|
345
|
+
const body = await asInvokeResult(fn, { StatusCode: 200, Payload }, options);
|
|
346
|
+
record({ kind: 'protocol', target: fn, messageId, result: body });
|
|
347
|
+
return body;
|
|
348
|
+
}
|
|
349
|
+
catch (e) {
|
|
350
|
+
record({ kind: 'protocol', target: fn, messageId, error: (0, test_helper_1.GETERR)(e) });
|
|
351
|
+
throw e;
|
|
352
|
+
}
|
|
353
|
+
finally {
|
|
354
|
+
//* the sync call is over: end the burst if nothing else is pending.
|
|
355
|
+
$state.running--;
|
|
356
|
+
resetIfIdle();
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
exports.localWeb = localWeb;
|
|
360
|
+
/**
|
|
361
|
+
* wait for every pending delivery (incl. the ones they send), then return the finished list and clear it.
|
|
362
|
+
* - resets the loop-guard count (idle also does). process-wide: it takes every delivery, not only the caller's.
|
|
363
|
+
* - must not be called inside an SNS/SQS delivery (it would wait for itself).
|
|
364
|
+
*/
|
|
365
|
+
const drain = async () => {
|
|
366
|
+
if ($chain.getStore()?.async)
|
|
367
|
+
throw new Error(`500 INVALID STATE - drain() inside a delivery (local transport)`);
|
|
368
|
+
while ($state.pending.size)
|
|
369
|
+
await Promise.all([...$state.pending]);
|
|
370
|
+
const list = $state.list.splice(0);
|
|
371
|
+
$state.count = 0;
|
|
372
|
+
$state.capped = false;
|
|
373
|
+
return list;
|
|
374
|
+
};
|
|
375
|
+
exports.drain = drain;
|
|
376
|
+
/**
|
|
377
|
+
* the finished deliveries since the last `drain()`, the last 100 only (a copy; it does not wait or clear).
|
|
378
|
+
*/
|
|
379
|
+
const deliveries = () => [...$state.list];
|
|
380
|
+
exports.deliveries = deliveries;
|
|
381
|
+
/**
|
|
382
|
+
* the public API of the local transport (exported from the package root).
|
|
383
|
+
*/
|
|
384
|
+
exports.$localTransport = {
|
|
385
|
+
/** true if `LOCAL_TRANSPORT=mock` and local mode */
|
|
386
|
+
isActive: exports.isActive,
|
|
387
|
+
/** wait for all pending deliveries, return them, and clear */
|
|
388
|
+
drain: exports.drain,
|
|
389
|
+
/** the finished deliveries since the last `drain()` */
|
|
390
|
+
deliveries: exports.deliveries,
|
|
391
|
+
};
|
|
392
|
+
//# sourceMappingURL=local-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-transport.js","sourceRoot":"","sources":["../../../src/cores/protocol/local-transport.ts"],"names":[],"mappings":"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"}
|