@omen.foundation/node-microservice-runtime 0.1.65 → 0.1.67
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/package.json +4 -1
- package/.env +0 -13
- package/env.sample +0 -13
- package/scripts/generate-openapi.mjs +0 -114
- package/scripts/lib/cli-utils.mjs +0 -58
- package/scripts/prepare-cjs.mjs +0 -44
- package/scripts/publish-service.mjs +0 -1119
- package/scripts/validate-service.mjs +0 -103
- package/scripts/ws-test.mjs +0 -25
- package/src/auth.ts +0 -117
- package/src/cli/index.ts +0 -725
- package/src/collector-manager.ts +0 -1267
- package/src/decorators.ts +0 -207
- package/src/dependency.ts +0 -211
- package/src/dev.ts +0 -17
- package/src/discovery.ts +0 -88
- package/src/docs.ts +0 -262
- package/src/env.ts +0 -148
- package/src/errors.ts +0 -55
- package/src/federation.ts +0 -559
- package/src/index.ts +0 -84
- package/src/inventory.ts +0 -491
- package/src/logger.ts +0 -727
- package/src/message.ts +0 -19
- package/src/requester.ts +0 -126
- package/src/routing.ts +0 -42
- package/src/runtime.ts +0 -1071
- package/src/services.ts +0 -459
- package/src/storage.ts +0 -206
- package/src/types/beamable-sdk-api.d.ts +0 -5
- package/src/types.ts +0 -117
- package/src/utils/urls.ts +0 -53
- package/src/websocket.ts +0 -170
- package/test-downloads/collector-test +0 -0
- package/test-downloads/collector-test.gz +0 -0
- package/tsconfig.base.json +0 -31
- package/tsconfig.build.json +0 -10
- package/tsconfig.cjs.json +0 -16
- package/tsconfig.dev.json +0 -14
package/src/message.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { GatewayRequest, GatewayResponse, WebsocketEventEnvelope } from './types.js';
|
|
2
|
-
|
|
3
|
-
let nextRequestId = -1;
|
|
4
|
-
|
|
5
|
-
export function allocateRequestId(): number {
|
|
6
|
-
nextRequestId -= 1;
|
|
7
|
-
if (nextRequestId < -9_000_000_000) {
|
|
8
|
-
nextRequestId = -1;
|
|
9
|
-
}
|
|
10
|
-
return nextRequestId;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function serializeGatewayRequest(request: GatewayRequest): string {
|
|
14
|
-
return JSON.stringify(request);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function deserializeGatewayResponse(raw: string): GatewayResponse | WebsocketEventEnvelope {
|
|
18
|
-
return JSON.parse(raw) as GatewayResponse | WebsocketEventEnvelope;
|
|
19
|
-
}
|
package/src/requester.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'node:events';
|
|
2
|
-
import type { Logger } from 'pino';
|
|
3
|
-
import { AuthenticationError, TimeoutError } from './errors.js';
|
|
4
|
-
import { allocateRequestId, deserializeGatewayResponse, serializeGatewayRequest } from './message.js';
|
|
5
|
-
import { BeamableWebSocket } from './websocket.js';
|
|
6
|
-
import type { GatewayRequest, GatewayResponse, WebsocketEventEnvelope } from './types.js';
|
|
7
|
-
|
|
8
|
-
interface PendingRequest<T = unknown> {
|
|
9
|
-
resolve: (value: T) => void;
|
|
10
|
-
reject: (error: Error) => void;
|
|
11
|
-
timeoutHandle: NodeJS.Timeout;
|
|
12
|
-
path: string;
|
|
13
|
-
method: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export class GatewayRequester {
|
|
17
|
-
private readonly socket: BeamableWebSocket;
|
|
18
|
-
private readonly logger: Logger;
|
|
19
|
-
private readonly pending = new Map<number, PendingRequest>();
|
|
20
|
-
private readonly emitter = new EventEmitter();
|
|
21
|
-
private requestTimeoutMs = 15_000;
|
|
22
|
-
|
|
23
|
-
constructor(socket: BeamableWebSocket, logger: Logger) {
|
|
24
|
-
this.socket = socket;
|
|
25
|
-
this.logger = logger.child({ component: 'GatewayRequester' });
|
|
26
|
-
this.socket.on('message', (...args) => this.onRawMessage(String(args[0] ?? '')));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
on(event: 'event', listener: (envelope: WebsocketEventEnvelope) => void): void {
|
|
30
|
-
this.emitter.on(event, listener);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
off(event: 'event', listener: (envelope: WebsocketEventEnvelope) => void): void {
|
|
34
|
-
this.emitter.off(event, listener);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
setRequestTimeout(timeoutMs: number): void {
|
|
38
|
-
this.requestTimeoutMs = timeoutMs;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async request<T>(method: string, path: string, body?: unknown): Promise<T> {
|
|
42
|
-
const id = allocateRequestId();
|
|
43
|
-
const effectiveBody = body ?? {};
|
|
44
|
-
const request: GatewayRequest = {
|
|
45
|
-
id,
|
|
46
|
-
method: method.toLowerCase(),
|
|
47
|
-
path,
|
|
48
|
-
body: effectiveBody,
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
this.logger.debug({ id, method, path, body: effectiveBody }, 'Sending gateway request.');
|
|
52
|
-
|
|
53
|
-
const payload = serializeGatewayRequest(request);
|
|
54
|
-
|
|
55
|
-
return new Promise<T>((resolve, reject) => {
|
|
56
|
-
const timeoutHandle = setTimeout(() => {
|
|
57
|
-
this.pending.delete(id);
|
|
58
|
-
reject(new TimeoutError(`Request ${method} ${path} timed out after ${this.requestTimeoutMs}ms`));
|
|
59
|
-
}, this.requestTimeoutMs).unref();
|
|
60
|
-
|
|
61
|
-
this.pending.set(id, {
|
|
62
|
-
resolve: resolve as (value: unknown) => void,
|
|
63
|
-
reject,
|
|
64
|
-
timeoutHandle,
|
|
65
|
-
path,
|
|
66
|
-
method,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
this.socket
|
|
70
|
-
.send(payload)
|
|
71
|
-
.catch((error) => {
|
|
72
|
-
clearTimeout(timeoutHandle);
|
|
73
|
-
this.pending.delete(id);
|
|
74
|
-
reject(error instanceof Error ? error : new Error(String(error)));
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async sendResponse(response: GatewayResponse): Promise<void> {
|
|
80
|
-
const payload = JSON.stringify(response);
|
|
81
|
-
await this.socket.send(payload);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async acknowledge(id: number, status = 200): Promise<void> {
|
|
85
|
-
await this.sendResponse({ id, status, body: null });
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private onRawMessage(raw: string): void {
|
|
89
|
-
this.logger.debug({ raw }, 'Received websocket frame.');
|
|
90
|
-
let envelope: GatewayResponse | WebsocketEventEnvelope;
|
|
91
|
-
try {
|
|
92
|
-
envelope = deserializeGatewayResponse(raw);
|
|
93
|
-
} catch (error) {
|
|
94
|
-
this.logger.error({ err: error, raw }, 'Failed to parse gateway message.');
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (typeof envelope.id !== 'number') {
|
|
99
|
-
this.logger.warn({ envelope }, 'Invalid gateway message without id.');
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const pending = this.pending.get(envelope.id);
|
|
104
|
-
if (pending) {
|
|
105
|
-
clearTimeout(pending.timeoutHandle);
|
|
106
|
-
this.pending.delete(envelope.id);
|
|
107
|
-
if ('status' in envelope && envelope.status === 403) {
|
|
108
|
-
pending.reject(new AuthenticationError('Gateway rejected the request with 403.'));
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
pending.resolve(envelope.body as unknown);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
this.emitter.emit('event', envelope as WebsocketEventEnvelope);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
dispose(): void {
|
|
119
|
-
for (const [id, pending] of this.pending.entries()) {
|
|
120
|
-
clearTimeout(pending.timeoutHandle);
|
|
121
|
-
pending.reject(new Error(`Request ${pending.method} ${pending.path} cancelled during shutdown.`));
|
|
122
|
-
this.pending.delete(id);
|
|
123
|
-
}
|
|
124
|
-
this.emitter.removeAllListeners();
|
|
125
|
-
}
|
|
126
|
-
}
|
package/src/routing.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { hostname, networkInterfaces } from 'node:os';
|
|
3
|
-
|
|
4
|
-
function getMacAddressBytes(): Buffer {
|
|
5
|
-
const interfaces = networkInterfaces();
|
|
6
|
-
const names = Object.keys(interfaces).sort((a, b) => a.localeCompare(b));
|
|
7
|
-
|
|
8
|
-
for (const name of names) {
|
|
9
|
-
const entries = interfaces[name];
|
|
10
|
-
if (!entries) {
|
|
11
|
-
continue;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
for (const entry of entries) {
|
|
15
|
-
const mac = entry.mac?.toLowerCase() ?? '';
|
|
16
|
-
if (!mac || mac === '00:00:00:00:00:00') {
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const sanitized = mac.replace(/:/g, '');
|
|
21
|
-
if (sanitized.length % 2 !== 0) {
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const macBytes = Buffer.from(sanitized, 'hex');
|
|
26
|
-
if (macBytes.length > 0) {
|
|
27
|
-
return macBytes;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
throw new Error('No network interface with a valid MAC address was found.');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function getDefaultRoutingKeyForMachine(): string {
|
|
36
|
-
const macBytes = getMacAddressBytes();
|
|
37
|
-
const hash = createHash('md5').update(macBytes).digest('hex');
|
|
38
|
-
const key = `${hostname()}_${hash}`
|
|
39
|
-
.replace(/[: ,]/g, '_')
|
|
40
|
-
.toLowerCase();
|
|
41
|
-
return key;
|
|
42
|
-
}
|