@versori/run 0.2.0-alpha.1 → 0.2.0-alpha.10
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/{script/deps/jsr.io/@std/fmt/1.0.6 → esm/deps/jsr.io/@std/fmt/1.0.7}/colors.d.ts.map +1 -1
- package/esm/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts.map +1 -1
- package/esm/deps/jsr.io/@std/log/0.224.14/console_handler.js +1 -1
- package/esm/deps/jsr.io/@std/log/0.224.14/rotating_file_handler.js +1 -1
- package/esm/src/context/Context.d.ts +2 -0
- package/esm/src/context/Context.d.ts.map +1 -1
- package/esm/src/context/Context.js +15 -0
- package/esm/src/dsl/http/types.d.ts +13 -2
- package/esm/src/dsl/http/types.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/activation.d.ts +13 -0
- package/esm/src/dsl/http/versori/activation.d.ts.map +1 -0
- package/esm/src/dsl/http/versori/activation.js +65 -0
- package/esm/src/dsl/http/versori/constants.d.ts +5 -0
- package/esm/src/dsl/http/versori/constants.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/constants.js +5 -0
- package/esm/src/dsl/http/versori/credentials/client.d.ts +1 -4
- package/esm/src/dsl/http/versori/credentials/client.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/credentials/client.js +3 -16
- package/esm/src/dsl/http/versori/cronapi.d.ts +10 -0
- package/esm/src/dsl/http/versori/cronapi.d.ts.map +1 -0
- package/esm/src/dsl/http/versori/cronapi.js +51 -0
- package/esm/src/dsl/http/versori/platformapi.d.ts +4 -1
- package/esm/src/dsl/http/versori/platformapi.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/platformapi.js +38 -6
- package/esm/src/dsl/http/versori/roundtripper.d.ts +3 -2
- package/esm/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/roundtripper.js +124 -73
- package/esm/src/interpreter/memory/MemoryInterpreter.d.ts +4 -2
- package/esm/src/interpreter/memory/MemoryInterpreter.d.ts.map +1 -1
- package/esm/src/interpreter/memory/MemoryInterpreter.js +47 -8
- package/esm/src/interpreter/memory/ObservableCompiler.d.ts +1 -0
- package/esm/src/interpreter/memory/ObservableCompiler.d.ts.map +1 -1
- package/esm/src/interpreter/memory/compilers/schedule.d.ts.map +1 -1
- package/esm/src/interpreter/memory/compilers/schedule.js +18 -23
- package/esm/src/observability/logging/ConsoleLogger.d.ts.map +1 -1
- package/esm/src/observability/logging/ConsoleLogger.js +55 -10
- package/package.json +1 -1
- package/{esm/deps/jsr.io/@std/fmt/1.0.6 → script/deps/jsr.io/@std/fmt/1.0.7}/colors.d.ts.map +1 -1
- package/script/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts.map +1 -1
- package/script/deps/jsr.io/@std/log/0.224.14/console_handler.js +1 -1
- package/script/deps/jsr.io/@std/log/0.224.14/rotating_file_handler.js +1 -1
- package/script/src/context/Context.d.ts +2 -0
- package/script/src/context/Context.d.ts.map +1 -1
- package/script/src/context/Context.js +15 -0
- package/script/src/dsl/http/types.d.ts +13 -2
- package/script/src/dsl/http/types.d.ts.map +1 -1
- package/script/src/dsl/http/versori/activation.d.ts +13 -0
- package/script/src/dsl/http/versori/activation.d.ts.map +1 -0
- package/script/src/dsl/http/versori/activation.js +69 -0
- package/script/src/dsl/http/versori/constants.d.ts +5 -0
- package/script/src/dsl/http/versori/constants.d.ts.map +1 -1
- package/script/src/dsl/http/versori/constants.js +6 -1
- package/script/src/dsl/http/versori/credentials/client.d.ts +1 -4
- package/script/src/dsl/http/versori/credentials/client.d.ts.map +1 -1
- package/script/src/dsl/http/versori/credentials/client.js +2 -15
- package/script/src/dsl/http/versori/cronapi.d.ts +10 -0
- package/script/src/dsl/http/versori/cronapi.d.ts.map +1 -0
- package/script/src/dsl/http/versori/cronapi.js +55 -0
- package/script/src/dsl/http/versori/platformapi.d.ts +4 -1
- package/script/src/dsl/http/versori/platformapi.d.ts.map +1 -1
- package/script/src/dsl/http/versori/platformapi.js +38 -6
- package/script/src/dsl/http/versori/roundtripper.d.ts +3 -2
- package/script/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
- package/script/src/dsl/http/versori/roundtripper.js +124 -73
- package/script/src/interpreter/memory/MemoryInterpreter.d.ts +4 -2
- package/script/src/interpreter/memory/MemoryInterpreter.d.ts.map +1 -1
- package/script/src/interpreter/memory/MemoryInterpreter.js +47 -8
- package/script/src/interpreter/memory/ObservableCompiler.d.ts +1 -0
- package/script/src/interpreter/memory/ObservableCompiler.d.ts.map +1 -1
- package/script/src/interpreter/memory/compilers/schedule.d.ts.map +1 -1
- package/script/src/interpreter/memory/compilers/schedule.js +18 -23
- package/script/src/observability/logging/ConsoleLogger.d.ts.map +1 -1
- package/script/src/observability/logging/ConsoleLogger.js +55 -10
- /package/esm/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.d.ts +0 -0
- /package/esm/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.js +0 -0
- /package/esm/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts +0 -0
- /package/esm/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.js +0 -0
- /package/script/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.d.ts +0 -0
- /package/script/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.js +0 -0
- /package/script/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts +0 -0
- /package/script/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.js +0 -0
|
@@ -3,6 +3,7 @@ import { VersoriCredentialClient } from './credentials/mod.js';
|
|
|
3
3
|
import { PlatformAPIClient } from './platformapi.js';
|
|
4
4
|
import { ConsoleLogger } from '../../../observability/mod.js';
|
|
5
5
|
import { envVarCredsBaseURL, envVarEnvId, envVarOrgId, envVarPlatformApiBaseURL, } from './constants.js';
|
|
6
|
+
import { ConnectError, Code } from '@connectrpc/connect';
|
|
6
7
|
/**
|
|
7
8
|
* VersoriRoundTripper is an implementation of the RoundTripperFactory interface for Versori connections.
|
|
8
9
|
* This is the intended implementation for when projects/services are hosted on Versori infrastructure.
|
|
@@ -16,13 +17,19 @@ import { envVarCredsBaseURL, envVarEnvId, envVarOrgId, envVarPlatformApiBaseURL,
|
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
19
|
export class VersoriRoundTripperFactory {
|
|
19
|
-
constructor(credsClient, platformAPIClient, logger) {
|
|
20
|
+
constructor(credsClient, credsBaseURL, platformAPIClient, logger) {
|
|
20
21
|
Object.defineProperty(this, "tokenClient", {
|
|
21
22
|
enumerable: true,
|
|
22
23
|
configurable: true,
|
|
23
24
|
writable: true,
|
|
24
25
|
value: void 0
|
|
25
26
|
});
|
|
27
|
+
Object.defineProperty(this, "credsBaseURL", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
writable: true,
|
|
31
|
+
value: void 0
|
|
32
|
+
});
|
|
26
33
|
Object.defineProperty(this, "platformAPIClient", {
|
|
27
34
|
enumerable: true,
|
|
28
35
|
configurable: true,
|
|
@@ -53,6 +60,7 @@ export class VersoriRoundTripperFactory {
|
|
|
53
60
|
}
|
|
54
61
|
});
|
|
55
62
|
this.tokenClient = credsClient;
|
|
63
|
+
this.credsBaseURL = credsBaseURL;
|
|
56
64
|
this.platformAPIClient = platformAPIClient;
|
|
57
65
|
this.versoriCfg = LoadConfigFromFile();
|
|
58
66
|
this.log = logger;
|
|
@@ -74,20 +82,23 @@ export class VersoriRoundTripperFactory {
|
|
|
74
82
|
missingVars.push(envVarCredsBaseURL);
|
|
75
83
|
throw new Error(`Missing environment variables: ${missingVars.join(', ')}`);
|
|
76
84
|
}
|
|
77
|
-
const pAPIClient = new PlatformAPIClient(platformApiBaseURL, orgId, envId);
|
|
78
|
-
const tokenClient = new VersoriCredentialClient(credsBaseURL);
|
|
79
85
|
const log = logger || new ConsoleLogger('debug');
|
|
80
|
-
|
|
86
|
+
const pAPIClient = new PlatformAPIClient(platformApiBaseURL, orgId, envId, log);
|
|
87
|
+
const tokenClient = new VersoriCredentialClient(credsBaseURL);
|
|
88
|
+
return new VersoriRoundTripperFactory(tokenClient, credsBaseURL, pAPIClient, log);
|
|
81
89
|
}
|
|
82
90
|
// takes the info and modifies the url using changeBaseUrl if necessary
|
|
91
|
+
// if a full valid URL is passed as a string, it will be returned as is
|
|
92
|
+
// if a valid URL object is passed, it will be returned as is
|
|
83
93
|
changeRequestInit(info, conn) {
|
|
84
94
|
if (typeof info === 'string') {
|
|
85
|
-
|
|
95
|
+
if (isValidURL(info)) {
|
|
96
|
+
return info;
|
|
97
|
+
}
|
|
86
98
|
return this.changeBaseUrl(info, conn);
|
|
87
99
|
}
|
|
88
100
|
else if (info instanceof URL) {
|
|
89
|
-
|
|
90
|
-
return newUrl;
|
|
101
|
+
return info;
|
|
91
102
|
}
|
|
92
103
|
else if (info instanceof Request) {
|
|
93
104
|
const url = this.changeBaseUrl(info.url, conn);
|
|
@@ -99,6 +110,7 @@ export class VersoriRoundTripperFactory {
|
|
|
99
110
|
const connBaseURL = conn.baseUrl;
|
|
100
111
|
// if the connection has no baseUrl set, but the pathname is a valid URL, return it as is
|
|
101
112
|
if (!connBaseURL && isValidURL(pathname)) {
|
|
113
|
+
this.log.debug('Using given URL as is', { url: pathname });
|
|
102
114
|
return pathname;
|
|
103
115
|
}
|
|
104
116
|
const connBaseURLObj = new URL(connBaseURL);
|
|
@@ -108,36 +120,45 @@ export class VersoriRoundTripperFactory {
|
|
|
108
120
|
_pathname = pathnameObj.pathname;
|
|
109
121
|
}
|
|
110
122
|
const newURL = new URL(_pathname, connBaseURLObj.origin);
|
|
123
|
+
this.log.debug('Using baseURL from connection', { url: newURL.toString() });
|
|
111
124
|
return newURL.toString();
|
|
112
125
|
}
|
|
113
|
-
|
|
114
|
-
async create(connName, fn = globalThis.fetch) {
|
|
126
|
+
create(connName, fn = globalThis.fetch) {
|
|
115
127
|
const cnxId = this.getConnectionID(connName);
|
|
116
|
-
|
|
117
|
-
|
|
128
|
+
if (!cnxId) {
|
|
129
|
+
this.log.debug('Connection not found in config, could be a dynamic connection', {
|
|
130
|
+
connectionName: connName,
|
|
131
|
+
});
|
|
118
132
|
return undefined;
|
|
119
133
|
}
|
|
120
|
-
const _fn = (input, init) => {
|
|
134
|
+
const _fn = async (input, init) => {
|
|
135
|
+
const conn = await this.platformAPIClient.getStaticConnection(cnxId);
|
|
136
|
+
if (!conn) {
|
|
137
|
+
this.log.error('Connection not found for user, using default fetch', {
|
|
138
|
+
connectionName: connName,
|
|
139
|
+
});
|
|
140
|
+
return globalThis.fetch(input, init);
|
|
141
|
+
}
|
|
121
142
|
const _input = this.changeRequestInit(input, conn);
|
|
122
|
-
|
|
143
|
+
switch (conn.credentials[0].authSchemeConfig.type) {
|
|
144
|
+
case 'api-key':
|
|
145
|
+
return (await this.apiKeyFetcher(conn, fn))(_input, init);
|
|
146
|
+
case 'basic-auth':
|
|
147
|
+
return (await this.basicAuthFetcher(conn, fn))(_input, init);
|
|
148
|
+
case 'jwt-bearer':
|
|
149
|
+
return (await this.bearerTokenFetcher(conn, fn))(_input, init);
|
|
150
|
+
case 'oauth2':
|
|
151
|
+
return (await this.oauth2Fetcher(conn, fn))(_input, init);
|
|
152
|
+
default:
|
|
153
|
+
return fn(_input, init);
|
|
154
|
+
}
|
|
123
155
|
};
|
|
124
|
-
|
|
125
|
-
case 'api-key':
|
|
126
|
-
return this.apiKeyFetcher(conn, _fn);
|
|
127
|
-
case 'basic-auth':
|
|
128
|
-
return this.basicAuthFetcher(conn, _fn);
|
|
129
|
-
case 'jwt-bearer':
|
|
130
|
-
return this.bearerTokenFetcher(conn, _fn);
|
|
131
|
-
case 'oauth2':
|
|
132
|
-
return this.oauth2Fetcher(conn, _fn);
|
|
133
|
-
default:
|
|
134
|
-
return fn;
|
|
135
|
-
}
|
|
156
|
+
return _fn;
|
|
136
157
|
}
|
|
137
|
-
|
|
158
|
+
createDynamic(templateName, fn = globalThis.fetch) {
|
|
138
159
|
const template = this.getTemplateID(templateName);
|
|
139
160
|
if (!template) {
|
|
140
|
-
this.log.
|
|
161
|
+
this.log.debug('Template not found in config, could be a static connection', {
|
|
141
162
|
templateName: templateName,
|
|
142
163
|
});
|
|
143
164
|
return undefined;
|
|
@@ -168,7 +189,8 @@ export class VersoriRoundTripperFactory {
|
|
|
168
189
|
return _fn;
|
|
169
190
|
}
|
|
170
191
|
getConnectionID(connName) {
|
|
171
|
-
const conn = this.versoriCfg.mappings.find((c) => (c.dynamic === undefined || c.dynamic === false) &&
|
|
192
|
+
const conn = this.versoriCfg.mappings.find((c) => (c.dynamic === undefined || c.dynamic === false) &&
|
|
193
|
+
c.name.toLowerCase() === connName.toLowerCase());
|
|
172
194
|
if (!conn || !conn.connId) {
|
|
173
195
|
return '';
|
|
174
196
|
}
|
|
@@ -181,17 +203,17 @@ export class VersoriRoundTripperFactory {
|
|
|
181
203
|
}
|
|
182
204
|
return template.templateId;
|
|
183
205
|
}
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
206
|
+
apiKeyFetcher(conn, fn) {
|
|
207
|
+
const _fn = async (input, init) => {
|
|
208
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
|
|
209
|
+
const token = tokenResponse.token?.accessToken;
|
|
210
|
+
const asc = conn.credentials[0].authSchemeConfig.apiKey;
|
|
211
|
+
if (!token) {
|
|
212
|
+
throw new Error('Token not found');
|
|
213
|
+
}
|
|
214
|
+
if (!asc) {
|
|
215
|
+
throw new Error('API Key configuration not found');
|
|
216
|
+
}
|
|
195
217
|
if (!init) {
|
|
196
218
|
init = {};
|
|
197
219
|
}
|
|
@@ -229,13 +251,13 @@ export class VersoriRoundTripperFactory {
|
|
|
229
251
|
};
|
|
230
252
|
return _fn;
|
|
231
253
|
}
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
254
|
+
basicAuthFetcher(conn, fn) {
|
|
255
|
+
const _fn = async (input, init) => {
|
|
256
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
|
|
257
|
+
const token = tokenResponse.token?.accessToken;
|
|
258
|
+
if (!token) {
|
|
259
|
+
throw new Error('Token not found');
|
|
260
|
+
}
|
|
239
261
|
if (!init) {
|
|
240
262
|
init = {};
|
|
241
263
|
}
|
|
@@ -259,13 +281,13 @@ export class VersoriRoundTripperFactory {
|
|
|
259
281
|
return _fn;
|
|
260
282
|
}
|
|
261
283
|
// TODO: need to make the prefix and header name configurable from authschemeconfig
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
284
|
+
bearerTokenFetcher(conn, fn) {
|
|
285
|
+
const _fn = async (input, init) => {
|
|
286
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
|
|
287
|
+
const token = tokenResponse.token?.accessToken;
|
|
288
|
+
if (!token) {
|
|
289
|
+
throw new Error('Token not found');
|
|
290
|
+
}
|
|
269
291
|
if (!init) {
|
|
270
292
|
init = {};
|
|
271
293
|
}
|
|
@@ -288,27 +310,27 @@ export class VersoriRoundTripperFactory {
|
|
|
288
310
|
};
|
|
289
311
|
return _fn;
|
|
290
312
|
}
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const _tokenType = () => {
|
|
299
|
-
const _tt = tokenType?.toLowerCase();
|
|
300
|
-
switch (_tt) {
|
|
301
|
-
case 'bearer':
|
|
302
|
-
return 'Bearer';
|
|
303
|
-
case 'mac':
|
|
304
|
-
return 'MAC';
|
|
305
|
-
case 'basic':
|
|
306
|
-
return 'Basic';
|
|
307
|
-
default:
|
|
308
|
-
return 'Bearer';
|
|
313
|
+
oauth2Fetcher(conn, fn) {
|
|
314
|
+
const refreshFn = async (input, init, forceRefresh = false) => {
|
|
315
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id, forceRefresh);
|
|
316
|
+
const token = tokenResponse.token?.accessToken;
|
|
317
|
+
const tokenType = tokenResponse.token?.tokenType;
|
|
318
|
+
if (!token) {
|
|
319
|
+
throw new Error('Token not found');
|
|
309
320
|
}
|
|
310
|
-
|
|
311
|
-
|
|
321
|
+
const _tokenType = () => {
|
|
322
|
+
const _tt = tokenType?.toLowerCase();
|
|
323
|
+
switch (_tt) {
|
|
324
|
+
case 'bearer':
|
|
325
|
+
return 'Bearer';
|
|
326
|
+
case 'mac':
|
|
327
|
+
return 'MAC';
|
|
328
|
+
case 'basic':
|
|
329
|
+
return 'Basic';
|
|
330
|
+
default:
|
|
331
|
+
return 'Bearer';
|
|
332
|
+
}
|
|
333
|
+
};
|
|
312
334
|
if (!init) {
|
|
313
335
|
init = {};
|
|
314
336
|
}
|
|
@@ -329,8 +351,37 @@ export class VersoriRoundTripperFactory {
|
|
|
329
351
|
}
|
|
330
352
|
return fn(input, init);
|
|
331
353
|
};
|
|
354
|
+
const _fn = async (input, init) => {
|
|
355
|
+
const resp = await refreshFn(input, init, false);
|
|
356
|
+
if (resp.status === 401) {
|
|
357
|
+
this.log.debug('Received 401 Unauthorized response, attempting refresh', {
|
|
358
|
+
url: input,
|
|
359
|
+
status: resp.status,
|
|
360
|
+
});
|
|
361
|
+
// TODO: attempt refresh until precondition failed??
|
|
362
|
+
return refreshFn(input, init, true);
|
|
363
|
+
}
|
|
364
|
+
return Promise.resolve(resp);
|
|
365
|
+
};
|
|
332
366
|
return _fn;
|
|
333
367
|
}
|
|
368
|
+
async getToken(id) {
|
|
369
|
+
try {
|
|
370
|
+
return await this.tokenClient.getToken(id);
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
this.log.error('unable to get credential', { error });
|
|
374
|
+
if (error instanceof ConnectError) {
|
|
375
|
+
if (error.rawMessage.includes("connection error received: not a result of an error") && error.code === Code.Internal) {
|
|
376
|
+
this.log.info('Connection error received, attempting to reconnect');
|
|
377
|
+
this.tokenClient = new VersoriCredentialClient(this.credsBaseURL);
|
|
378
|
+
return await this.tokenClient.getToken(id);
|
|
379
|
+
}
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
throw error;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
334
385
|
}
|
|
335
386
|
function isValidURL(url) {
|
|
336
387
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { Observable, Subscription } from 'rxjs';
|
|
3
3
|
import { ContextProvider } from '../../context/ContextProvider.js';
|
|
4
|
-
import { ConnectionProvider, RoundTripperFactory } from '../../dsl/http/types.js';
|
|
4
|
+
import { ConnectionProvider, CronProvider, RoundTripperFactory } from '../../dsl/http/types.js';
|
|
5
5
|
import { Workflow } from '../../dsl/Workflow.js';
|
|
6
6
|
import { Logger } from '../../observability/logging/Logger.js';
|
|
7
7
|
import { ObservableCompiler } from './ObservableCompiler.js';
|
|
@@ -26,12 +26,14 @@ export declare class MemoryInterpreter {
|
|
|
26
26
|
private readonly contextProvider;
|
|
27
27
|
private readonly roundTripperFactory;
|
|
28
28
|
private readonly router;
|
|
29
|
+
private cronRegistry;
|
|
29
30
|
private readonly connectionProvider;
|
|
31
|
+
private readonly cronProvider;
|
|
30
32
|
private registeredWorkflows;
|
|
31
33
|
private server?;
|
|
32
34
|
private shutdownServer?;
|
|
33
35
|
private isShuttingDown;
|
|
34
|
-
constructor(log: Logger, compiler: ObservableCompiler, contextProvider: ContextProvider, roundTripperFactory: RoundTripperFactory, router: Router, connectionProvider: ConnectionProvider);
|
|
36
|
+
constructor(log: Logger, compiler: ObservableCompiler, contextProvider: ContextProvider, roundTripperFactory: RoundTripperFactory, router: Router, cronRegistry: Map<string, string>, connectionProvider: ConnectionProvider, cronProvider: CronProvider);
|
|
35
37
|
static newInstance(options?: MemoryInterpreterOptions): Promise<MemoryInterpreter>;
|
|
36
38
|
register<O>(workflow: Workflow<O>, options?: MemoryInterpreterOptions): Registration;
|
|
37
39
|
start(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryInterpreter.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/MemoryInterpreter.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAA+B,UAAU,EAAW,YAAY,EAAE,MAAM,MAAM,CAAC;AACtF,OAAO,EAAE,eAAe,EAAuB,MAAM,kCAAkC,CAAC;AAExF,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"MemoryInterpreter.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/MemoryInterpreter.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAA+B,UAAU,EAAW,YAAY,EAAE,MAAM,MAAM,CAAC;AACtF,OAAO,EAAE,eAAe,EAAuB,MAAM,kCAAkC,CAAC;AAExF,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGhG,OAAO,EAAE,QAAQ,EAAgB,MAAM,uBAAuB,CAAC;AAI/D,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAC/D,OAAO,EAAmB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAIpE,MAAM,MAAM,wBAAwB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,KAAK,YAAY,GAAG;IAChB,QAAQ,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7C,KAAK,EAAE,uBAAuB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9C,oBAAoB,EAAE,eAAe,CAAC;IACtC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B,CAAA;AAED,qBAAa,iBAAiB;IAOtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAbjC,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,cAAc,CAAC,CAAa;IACpC,OAAO,CAAC,cAAc,CAAS;gBAGV,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,kBAAkB,EAC5B,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,mBAAmB,EACxC,MAAM,EAAE,MAAM,EACvB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY;WASlC,WAAW,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwC5F,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,wBAAwB;IA8C/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2ItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK9B"}
|
|
@@ -9,8 +9,9 @@ import { MemoryKeyValueProvider } from '../../kv/memory/MemoryKeyValueProvider.j
|
|
|
9
9
|
import { NatsKeyValueProvider } from '../../kv/nats/NatsKeyValueProvider.js';
|
|
10
10
|
import { ConsoleLogger } from '../../observability/logging/ConsoleLogger.js';
|
|
11
11
|
import { ObservableCompiler } from './ObservableCompiler.js';
|
|
12
|
+
import { CronAPIClient } from '../../dsl/http/versori/cronapi.js';
|
|
12
13
|
export class MemoryInterpreter {
|
|
13
|
-
constructor(log, compiler, contextProvider, roundTripperFactory, router, connectionProvider) {
|
|
14
|
+
constructor(log, compiler, contextProvider, roundTripperFactory, router, cronRegistry, connectionProvider, cronProvider) {
|
|
14
15
|
Object.defineProperty(this, "log", {
|
|
15
16
|
enumerable: true,
|
|
16
17
|
configurable: true,
|
|
@@ -41,12 +42,24 @@ export class MemoryInterpreter {
|
|
|
41
42
|
writable: true,
|
|
42
43
|
value: router
|
|
43
44
|
});
|
|
45
|
+
Object.defineProperty(this, "cronRegistry", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
writable: true,
|
|
49
|
+
value: cronRegistry
|
|
50
|
+
});
|
|
44
51
|
Object.defineProperty(this, "connectionProvider", {
|
|
45
52
|
enumerable: true,
|
|
46
53
|
configurable: true,
|
|
47
54
|
writable: true,
|
|
48
55
|
value: connectionProvider
|
|
49
56
|
});
|
|
57
|
+
Object.defineProperty(this, "cronProvider", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
configurable: true,
|
|
60
|
+
writable: true,
|
|
61
|
+
value: cronProvider
|
|
62
|
+
});
|
|
50
63
|
Object.defineProperty(this, "registeredWorkflows", {
|
|
51
64
|
enumerable: true,
|
|
52
65
|
configurable: true,
|
|
@@ -86,12 +99,12 @@ export class MemoryInterpreter {
|
|
|
86
99
|
if (options.contextProvider) {
|
|
87
100
|
// no need to set up a key-value provider if options.contextProvider is already
|
|
88
101
|
// initialised.
|
|
89
|
-
return new MemoryInterpreter(log, compiler, options.contextProvider, roundTripperFactory, express.Router(), PlatformAPIClient.fromEnv());
|
|
102
|
+
return new MemoryInterpreter(log, compiler, options.contextProvider, roundTripperFactory, express.Router(), new Map(), PlatformAPIClient.fromEnv(), CronAPIClient.fromEnv());
|
|
90
103
|
}
|
|
91
104
|
const kvp = await (options.skipVersoriCredentials
|
|
92
105
|
? new MemoryKeyValueProvider()
|
|
93
106
|
: NatsKeyValueProvider.fromEnv());
|
|
94
|
-
return new MemoryInterpreter(log, compiler, new ContextProviderImpl(log, kvp), roundTripperFactory, express.Router(), PlatformAPIClient.fromEnv());
|
|
107
|
+
return new MemoryInterpreter(log, compiler, new ContextProviderImpl(log, kvp), roundTripperFactory, express.Router(), new Map(), PlatformAPIClient.fromEnv(), CronAPIClient.fromEnv());
|
|
95
108
|
}
|
|
96
109
|
register(workflow, options) {
|
|
97
110
|
const localAbortController = new AbortController();
|
|
@@ -108,6 +121,7 @@ export class MemoryInterpreter {
|
|
|
108
121
|
contextProvider: this.contextProvider,
|
|
109
122
|
roundTripperFactory: this.roundTripperFactory,
|
|
110
123
|
router: this.router,
|
|
124
|
+
cronRegistry: this.cronRegistry,
|
|
111
125
|
connectionProvider: this.connectionProvider
|
|
112
126
|
};
|
|
113
127
|
const trigger$ = this.compiler.compileTrigger(compilerContext, workflow.trigger, combinedSignal);
|
|
@@ -140,9 +154,18 @@ export class MemoryInterpreter {
|
|
|
140
154
|
registration.subscription = registration.trigger$
|
|
141
155
|
.pipe(tap((ctx) => {
|
|
142
156
|
ctx.log.info('MemoryInterpreter.executionStarted', { data: ctx.data });
|
|
143
|
-
}), mergeMap((ctx) => of(ctx).pipe(registration.task$, catchError((
|
|
144
|
-
ctx.log.error('MemoryInterpreter.executionError', { error });
|
|
145
|
-
|
|
157
|
+
}), mergeMap((ctx) => of(ctx).pipe(registration.task$, catchError((err) => {
|
|
158
|
+
ctx.log.error('MemoryInterpreter.executionError', { error: err instanceof Error ? err.toString() : err });
|
|
159
|
+
try {
|
|
160
|
+
ctx.options.onError?.(ctx.withData(err));
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
ctx.log.error('MemoryInterpreter.onErrorError: failed to call onError handler', { error: err instanceof Error ? err.toString() : err });
|
|
164
|
+
ctx.options.onError?.(ctx.withData({
|
|
165
|
+
message: 'Internal server error',
|
|
166
|
+
error: err instanceof Error ? err.toString() : err,
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
146
169
|
return EMPTY;
|
|
147
170
|
}))))
|
|
148
171
|
.subscribe({
|
|
@@ -152,11 +175,20 @@ export class MemoryInterpreter {
|
|
|
152
175
|
durationMs,
|
|
153
176
|
data: ctx.data,
|
|
154
177
|
});
|
|
155
|
-
|
|
178
|
+
try {
|
|
179
|
+
ctx.options.onSuccess?.(ctx);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
ctx.log.error('MemoryInterpreter.onSuccessError: failed to call onSuccess handler', { error: err instanceof Error ? err.toString() : err });
|
|
183
|
+
ctx.options.onSuccess?.(ctx.withData({
|
|
184
|
+
message: 'Internal server error',
|
|
185
|
+
error: err instanceof Error ? err.toString() : err,
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
156
188
|
this.contextProvider.destroy(ctx);
|
|
157
189
|
},
|
|
158
190
|
error: (err) => {
|
|
159
|
-
this.log.error('MemoryInterpreter.error', { error: err });
|
|
191
|
+
this.log.error('MemoryInterpreter.error', { error: err instanceof Error ? err.toString() : err });
|
|
160
192
|
Deno.removeSignalListener('SIGINT', registration.sigintListener);
|
|
161
193
|
},
|
|
162
194
|
complete: () => {
|
|
@@ -168,6 +200,13 @@ export class MemoryInterpreter {
|
|
|
168
200
|
registration.subscription = undefined;
|
|
169
201
|
});
|
|
170
202
|
}
|
|
203
|
+
try {
|
|
204
|
+
this.cronProvider.updateCrons(this.cronRegistry);
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
this.log.error('MemoryInterpreter.updateCronsError', { error: err instanceof Error ? err.toString() : err });
|
|
208
|
+
throw new Error('Unable to register scheduler tasks with central cron provider');
|
|
209
|
+
}
|
|
171
210
|
this.server = app.listen(port, () => {
|
|
172
211
|
this.log.info(`Express server listening on http://localhost:${port}`);
|
|
173
212
|
});
|
|
@@ -14,6 +14,7 @@ export type CompilerContext = {
|
|
|
14
14
|
roundTripperFactory: RoundTripperFactory;
|
|
15
15
|
connectionProvider: ConnectionProvider;
|
|
16
16
|
router: Router;
|
|
17
|
+
cronRegistry: Map<string, string>;
|
|
17
18
|
};
|
|
18
19
|
export type CompilerFunc<In = any, Out = any, T extends Task<In, Out> = Task<In, Out>> = (ctx: CompilerContext, task: T) => OperatorFunction<In, Out>;
|
|
19
20
|
export declare class ObservableCompiler {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservableCompiler.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/ObservableCompiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,IAAI,EAAY,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAO/D,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAAE,OAAO,EAAe,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ObservableCompiler.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/ObservableCompiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,IAAI,EAAY,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAO/D,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAAE,OAAO,EAAe,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,SAAS,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CACrF,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,CAAC,KACN,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAE/B,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,aAAa,CAAkD;IACvE,OAAO,CAAC,gBAAgB,CAAgD;;IAgBxE,WAAW,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,KAAK,GAAG,IAAI,EACzC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,GACpB,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC;IAe1C,cAAc,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAC3D,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,WAAW,GACpB,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAerC,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAKjF,eAAe,CAAC,GAAG,EAAE,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC;CAIjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../../../src/src/interpreter/memory/compilers/schedule.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../../../src/src/interpreter/memory/compilers/schedule.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuF7C,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAAC,YAAY,EAAE,eAAe,CAG3E,CAAC"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { CronJob } from 'cron';
|
|
2
1
|
import { Observable } from 'rxjs';
|
|
3
2
|
import { ScheduleTrigger } from '../../../dsl/triggers/ScheduleTrigger.js';
|
|
4
3
|
function compileSchedule(ctx, trigger, signal) {
|
|
5
4
|
return new Observable((subscriber) => {
|
|
5
|
+
// Add HTTP endpoint for manual triggering
|
|
6
|
+
if (!ctx.router) {
|
|
7
|
+
throw new Error('Router not available in compiler context');
|
|
8
|
+
}
|
|
6
9
|
const client = ctx.connectionProvider;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
ctx.cronRegistry.set(trigger.id, trigger.schedule);
|
|
11
|
+
ctx.router.post(`/cron/${trigger.id}`, async (req, res) => {
|
|
12
|
+
try {
|
|
10
13
|
if (trigger.activationPredicate === undefined) {
|
|
11
14
|
const executionCtx = ctx.contextProvider.create({}, undefined);
|
|
12
15
|
try {
|
|
@@ -15,6 +18,7 @@ function compileSchedule(ctx, trigger, signal) {
|
|
|
15
18
|
catch (error) {
|
|
16
19
|
executionCtx.log.error('execution error inside schedule', { error });
|
|
17
20
|
}
|
|
21
|
+
res.status(200).json({ status: 'triggered', executionId: executionCtx.executionId });
|
|
18
22
|
return;
|
|
19
23
|
}
|
|
20
24
|
const activations = await client.listActivations();
|
|
@@ -27,6 +31,7 @@ function compileSchedule(ctx, trigger, signal) {
|
|
|
27
31
|
catch (error) {
|
|
28
32
|
executionCtx.log.error('execution error inside schedule', { error });
|
|
29
33
|
}
|
|
34
|
+
res.status(200).json({ status: 'triggered', executionId: executionCtx.executionId });
|
|
30
35
|
return;
|
|
31
36
|
}
|
|
32
37
|
activations.forEach((activation) => {
|
|
@@ -39,31 +44,21 @@ function compileSchedule(ctx, trigger, signal) {
|
|
|
39
44
|
executionCtx.log.error('execution error inside schedule', { error });
|
|
40
45
|
}
|
|
41
46
|
});
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
subscriber.complete();
|
|
49
|
-
},
|
|
50
|
-
errorHandler: (error) => {
|
|
51
|
-
ctx.log.error('schedule execution error', { error });
|
|
52
|
-
subscriber.error(error);
|
|
53
|
-
},
|
|
54
|
-
start: true,
|
|
47
|
+
res.status(200).json({ status: 'triggered' });
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
executionCtx.log.error('execution error inside schedule', { error });
|
|
51
|
+
res.status(500).json({ error: 'Failed to trigger schedule' });
|
|
52
|
+
}
|
|
55
53
|
});
|
|
56
54
|
function cleanup() {
|
|
57
|
-
ctx.log.debug('
|
|
58
|
-
|
|
55
|
+
ctx.log.debug('scheduler trigger stopped');
|
|
56
|
+
subscriber.complete();
|
|
59
57
|
}
|
|
60
58
|
signal.addEventListener('abort', cleanup, { once: true });
|
|
61
59
|
return () => {
|
|
62
60
|
signal.removeEventListener('abort', cleanup);
|
|
63
|
-
ctx.log.debug('
|
|
64
|
-
// call job.stop() directly rather than using cleanup since cleanup is called when the
|
|
65
|
-
// signal is aborted and we don't want duplicate logs when the unsubscription happens.
|
|
66
|
-
job.stop();
|
|
61
|
+
ctx.log.debug('scheduler execution unsubscribed');
|
|
67
62
|
};
|
|
68
63
|
});
|
|
69
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsoleLogger.d.ts","sourceRoot":"","sources":["../../../../src/src/observability/logging/ConsoleLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,+CAA+C,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ConsoleLogger.d.ts","sourceRoot":"","sources":["../../../../src/src/observability/logging/ConsoleLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,+CAA+C,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAmF/C;;GAEG;AACH,qBAAa,aAAc,YAAW,MAAM;IACxC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAEhB,KAAK,EAAE,QAAQ,CAAC;IAEhB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEpB,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAOjE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO7D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO9D,KAAK,CAAC,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,aAAa;IAOvD,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;CAGlC"}
|
|
@@ -1,4 +1,36 @@
|
|
|
1
1
|
import * as log from '../../../deps/jsr.io/@std/log/0.224.14/mod.js';
|
|
2
|
+
function valueOfUnknown(obj, idx) {
|
|
3
|
+
switch (typeof obj) {
|
|
4
|
+
case 'object':
|
|
5
|
+
if (obj instanceof Object) {
|
|
6
|
+
const valueOf = obj.valueOf();
|
|
7
|
+
if (typeof valueOf === 'object' && !Array.isArray(valueOf)) {
|
|
8
|
+
return valueOf;
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
[`arg${idx}`]: obj,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
if (obj === null) {
|
|
15
|
+
return {
|
|
16
|
+
[`arg${idx}`]: null,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return obj;
|
|
20
|
+
case 'undefined':
|
|
21
|
+
return {
|
|
22
|
+
[`arg${idx}`]: undefined,
|
|
23
|
+
};
|
|
24
|
+
case 'function':
|
|
25
|
+
return {
|
|
26
|
+
[`arg${idx}`]: obj.valueOf(),
|
|
27
|
+
};
|
|
28
|
+
default:
|
|
29
|
+
return {
|
|
30
|
+
[`arg${idx}`]: obj,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
2
34
|
log.setup({
|
|
3
35
|
handlers: {
|
|
4
36
|
default: new log.ConsoleHandler('DEBUG', {
|
|
@@ -8,16 +40,29 @@ log.setup({
|
|
|
8
40
|
// - args are rendered as a nested object named `args`.
|
|
9
41
|
//
|
|
10
42
|
// This implementation uses ISO 8601 time and flattens the args object.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
...
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
43
|
+
try {
|
|
44
|
+
return JSON.stringify({
|
|
45
|
+
level: record.levelName,
|
|
46
|
+
time: record.datetime.toISOString(),
|
|
47
|
+
...(record.loggerName ? { name: record.loggerName } : {}),
|
|
48
|
+
msg: record.msg,
|
|
49
|
+
...(Array.isArray(record.args)
|
|
50
|
+
? (record.args.reduce((acc, next, idx) => ({
|
|
51
|
+
...acc,
|
|
52
|
+
...(valueOfUnknown(next, idx)),
|
|
53
|
+
}), {}))
|
|
54
|
+
: {}),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
return JSON.stringify({
|
|
59
|
+
level: record.levelName,
|
|
60
|
+
time: record.datetime.toISOString(),
|
|
61
|
+
...(record.loggerName ? { name: record.loggerName } : {}),
|
|
62
|
+
msg: record.msg,
|
|
63
|
+
LOG_ERROR: `Failed to render args: ${err instanceof Error ? err.message : err}`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
21
66
|
},
|
|
22
67
|
}),
|
|
23
68
|
},
|