@versori/run 0.2.0-alpha.1 → 0.2.0-alpha.11
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 +7 -1
- package/esm/src/context/Context.d.ts.map +1 -1
- package/esm/src/context/Context.js +30 -4
- package/esm/src/context/ContextProvider.d.ts +3 -1
- package/esm/src/context/ContextProvider.d.ts.map +1 -1
- package/esm/src/context/ContextProvider.js +9 -2
- package/esm/src/dsl/http/default.d.ts +2 -0
- package/esm/src/dsl/http/default.d.ts.map +1 -1
- package/esm/src/dsl/http/default.js +10 -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/contextcredentials.d.ts +10 -0
- package/esm/src/dsl/http/versori/contextcredentials.d.ts.map +1 -0
- package/esm/src/dsl/http/versori/contextcredentials.js +1 -0
- package/esm/src/dsl/http/versori/credentials/client.d.ts +4 -4
- package/esm/src/dsl/http/versori/credentials/client.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/credentials/client.js +8 -13
- package/esm/src/dsl/http/versori/credentials/credentials.d.ts +38 -0
- package/esm/src/dsl/http/versori/credentials/credentials.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/credentials/credentials.js +7 -8
- package/esm/src/dsl/http/versori/credentials/v1alpha1/common_pb.d.ts +31 -0
- package/esm/src/dsl/http/versori/credentials/v1alpha1/common_pb.d.ts.map +1 -0
- package/esm/src/dsl/http/versori/credentials/v1alpha1/common_pb.js +31 -0
- package/esm/src/dsl/http/versori/credentials/v1alpha1/credential_service_pb.d.ts +84 -0
- package/esm/src/dsl/http/versori/credentials/v1alpha1/credential_service_pb.d.ts.map +1 -0
- package/esm/src/dsl/http/versori/credentials/v1alpha1/credential_service_pb.js +128 -0
- 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 +11 -5
- package/esm/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/roundtripper.js +168 -75
- 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 +49 -10
- 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 +7 -1
- package/script/src/context/Context.d.ts.map +1 -1
- package/script/src/context/Context.js +30 -4
- package/script/src/context/ContextProvider.d.ts +3 -1
- package/script/src/context/ContextProvider.d.ts.map +1 -1
- package/script/src/context/ContextProvider.js +9 -2
- package/script/src/dsl/http/default.d.ts +2 -0
- package/script/src/dsl/http/default.d.ts.map +1 -1
- package/script/src/dsl/http/default.js +10 -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/contextcredentials.d.ts +10 -0
- package/script/src/dsl/http/versori/contextcredentials.d.ts.map +1 -0
- package/script/src/dsl/http/versori/contextcredentials.js +2 -0
- package/script/src/dsl/http/versori/credentials/client.d.ts +4 -4
- package/script/src/dsl/http/versori/credentials/client.d.ts.map +1 -1
- package/script/src/dsl/http/versori/credentials/client.js +7 -10
- package/script/src/dsl/http/versori/credentials/credentials.d.ts +38 -0
- package/script/src/dsl/http/versori/credentials/credentials.d.ts.map +1 -1
- package/script/src/dsl/http/versori/credentials/credentials.js +8 -8
- package/script/src/dsl/http/versori/credentials/v1alpha1/common_pb.d.ts +31 -0
- package/script/src/dsl/http/versori/credentials/v1alpha1/common_pb.d.ts.map +1 -0
- package/script/src/dsl/http/versori/credentials/v1alpha1/common_pb.js +34 -0
- package/script/src/dsl/http/versori/credentials/v1alpha1/credential_service_pb.d.ts +84 -0
- package/script/src/dsl/http/versori/credentials/v1alpha1/credential_service_pb.d.ts.map +1 -0
- package/script/src/dsl/http/versori/credentials/v1alpha1/credential_service_pb.js +131 -0
- 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 +11 -5
- package/script/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
- package/script/src/dsl/http/versori/roundtripper.js +170 -77
- 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 +48 -9
- 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.
|
|
@@ -10,19 +11,25 @@ import { envVarCredsBaseURL, envVarEnvId, envVarOrgId, envVarPlatformApiBaseURL,
|
|
|
10
11
|
*
|
|
11
12
|
* @example
|
|
12
13
|
* ```typescript
|
|
13
|
-
* const factory = new
|
|
14
|
+
* const factory = new VersoriCredentialsFactory(connectAPIClient, tokenClient);
|
|
14
15
|
* const customFetch = await factory.create('connectionName');
|
|
15
16
|
* const response = await customFetch('https://api.example.com/data');
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
|
-
export class
|
|
19
|
-
constructor(credsClient, platformAPIClient, logger) {
|
|
19
|
+
export class VersoriCredentialsFactory {
|
|
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,9 +60,11 @@ 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;
|
|
67
|
+
this.credentials = this.credentials.bind(this);
|
|
59
68
|
}
|
|
60
69
|
static fromEnv(logger) {
|
|
61
70
|
const credsBaseURL = Deno.env.get(envVarCredsBaseURL);
|
|
@@ -74,20 +83,23 @@ export class VersoriRoundTripperFactory {
|
|
|
74
83
|
missingVars.push(envVarCredsBaseURL);
|
|
75
84
|
throw new Error(`Missing environment variables: ${missingVars.join(', ')}`);
|
|
76
85
|
}
|
|
77
|
-
const pAPIClient = new PlatformAPIClient(platformApiBaseURL, orgId, envId);
|
|
78
|
-
const tokenClient = new VersoriCredentialClient(credsBaseURL);
|
|
79
86
|
const log = logger || new ConsoleLogger('debug');
|
|
80
|
-
|
|
87
|
+
const pAPIClient = new PlatformAPIClient(platformApiBaseURL, orgId, envId, log);
|
|
88
|
+
const tokenClient = new VersoriCredentialClient(credsBaseURL);
|
|
89
|
+
return new VersoriCredentialsFactory(tokenClient, credsBaseURL, pAPIClient, log);
|
|
81
90
|
}
|
|
82
91
|
// takes the info and modifies the url using changeBaseUrl if necessary
|
|
92
|
+
// if a full valid URL is passed as a string, it will be returned as is
|
|
93
|
+
// if a valid URL object is passed, it will be returned as is
|
|
83
94
|
changeRequestInit(info, conn) {
|
|
84
95
|
if (typeof info === 'string') {
|
|
85
|
-
|
|
96
|
+
if (isValidURL(info)) {
|
|
97
|
+
return info;
|
|
98
|
+
}
|
|
86
99
|
return this.changeBaseUrl(info, conn);
|
|
87
100
|
}
|
|
88
101
|
else if (info instanceof URL) {
|
|
89
|
-
|
|
90
|
-
return newUrl;
|
|
102
|
+
return info;
|
|
91
103
|
}
|
|
92
104
|
else if (info instanceof Request) {
|
|
93
105
|
const url = this.changeBaseUrl(info.url, conn);
|
|
@@ -99,6 +111,7 @@ export class VersoriRoundTripperFactory {
|
|
|
99
111
|
const connBaseURL = conn.baseUrl;
|
|
100
112
|
// if the connection has no baseUrl set, but the pathname is a valid URL, return it as is
|
|
101
113
|
if (!connBaseURL && isValidURL(pathname)) {
|
|
114
|
+
this.log.debug('Using given URL as is', { url: pathname });
|
|
102
115
|
return pathname;
|
|
103
116
|
}
|
|
104
117
|
const connBaseURLObj = new URL(connBaseURL);
|
|
@@ -108,36 +121,45 @@ export class VersoriRoundTripperFactory {
|
|
|
108
121
|
_pathname = pathnameObj.pathname;
|
|
109
122
|
}
|
|
110
123
|
const newURL = new URL(_pathname, connBaseURLObj.origin);
|
|
124
|
+
this.log.debug('Using baseURL from connection', { url: newURL.toString() });
|
|
111
125
|
return newURL.toString();
|
|
112
126
|
}
|
|
113
|
-
|
|
114
|
-
async create(connName, fn = globalThis.fetch) {
|
|
127
|
+
create(connName, fn = globalThis.fetch) {
|
|
115
128
|
const cnxId = this.getConnectionID(connName);
|
|
116
|
-
|
|
117
|
-
|
|
129
|
+
if (!cnxId) {
|
|
130
|
+
this.log.debug('Connection not found in config, could be a dynamic connection', {
|
|
131
|
+
connectionName: connName,
|
|
132
|
+
});
|
|
118
133
|
return undefined;
|
|
119
134
|
}
|
|
120
|
-
const _fn = (input, init) => {
|
|
135
|
+
const _fn = async (input, init) => {
|
|
136
|
+
const conn = await this.platformAPIClient.getStaticConnection(cnxId);
|
|
137
|
+
if (!conn) {
|
|
138
|
+
this.log.error('Connection not found for user, using default fetch', {
|
|
139
|
+
connectionName: connName,
|
|
140
|
+
});
|
|
141
|
+
return globalThis.fetch(input, init);
|
|
142
|
+
}
|
|
121
143
|
const _input = this.changeRequestInit(input, conn);
|
|
122
|
-
|
|
144
|
+
switch (conn.credentials[0].authSchemeConfig.type) {
|
|
145
|
+
case 'api-key':
|
|
146
|
+
return (await this.apiKeyFetcher(conn, fn))(_input, init);
|
|
147
|
+
case 'basic-auth':
|
|
148
|
+
return (await this.basicAuthFetcher(conn, fn))(_input, init);
|
|
149
|
+
case 'jwt-bearer':
|
|
150
|
+
return (await this.bearerTokenFetcher(conn, fn))(_input, init);
|
|
151
|
+
case 'oauth2':
|
|
152
|
+
return (await this.oauth2Fetcher(conn, fn))(_input, init);
|
|
153
|
+
default:
|
|
154
|
+
return fn(_input, init);
|
|
155
|
+
}
|
|
123
156
|
};
|
|
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
|
-
}
|
|
157
|
+
return _fn;
|
|
136
158
|
}
|
|
137
|
-
|
|
159
|
+
createDynamic(templateName, fn = globalThis.fetch) {
|
|
138
160
|
const template = this.getTemplateID(templateName);
|
|
139
161
|
if (!template) {
|
|
140
|
-
this.log.
|
|
162
|
+
this.log.debug('Template not found in config, could be a static connection', {
|
|
141
163
|
templateName: templateName,
|
|
142
164
|
});
|
|
143
165
|
return undefined;
|
|
@@ -167,8 +189,50 @@ export class VersoriRoundTripperFactory {
|
|
|
167
189
|
};
|
|
168
190
|
return _fn;
|
|
169
191
|
}
|
|
192
|
+
credentials() {
|
|
193
|
+
return {
|
|
194
|
+
getRaw: this.getRawByName.bind(this),
|
|
195
|
+
getAccessToken: this.getTokenByName.bind(this),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
async getTokenByName(name) {
|
|
199
|
+
const credId = await this.getCredentialIDFromName(name);
|
|
200
|
+
const token = await this.tokenClient.getToken(credId);
|
|
201
|
+
if (!token?.token) {
|
|
202
|
+
throw new Error(`Token not found for connection ${name} with credential ID ${credId}`);
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
accessToken: token.token.accessToken,
|
|
206
|
+
tokenType: token.token.tokenType,
|
|
207
|
+
expiry: token.token.expiry ? new Date(Number(token.token.expiry.seconds) * 1000) : undefined,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
async getRawByName(name) {
|
|
211
|
+
const credId = await this.getCredentialIDFromName(name);
|
|
212
|
+
const raw = await this.tokenClient.getRaw(credId);
|
|
213
|
+
if (!raw) {
|
|
214
|
+
throw new Error(`Raw data not found for connection ${name} with credential ID ${credId}`);
|
|
215
|
+
}
|
|
216
|
+
let buffer = raw?.credential?.data['raw'];
|
|
217
|
+
return buffer;
|
|
218
|
+
}
|
|
219
|
+
async getCredentialIDFromName(name) {
|
|
220
|
+
const conId = this.getConnectionID(name);
|
|
221
|
+
if (!conId) {
|
|
222
|
+
throw new Error(`Connection ${name} not found`);
|
|
223
|
+
}
|
|
224
|
+
const conn = await this.platformAPIClient.getStaticConnection(conId);
|
|
225
|
+
if (!conn) {
|
|
226
|
+
throw new Error(`Connection ${name} not found`);
|
|
227
|
+
}
|
|
228
|
+
if (!conn?.credentials[0]?.credential?.id) {
|
|
229
|
+
throw new Error(`Connection ${name}/${conId} has no credentials defined on it`);
|
|
230
|
+
}
|
|
231
|
+
return conn.credentials[0].credential.id;
|
|
232
|
+
}
|
|
170
233
|
getConnectionID(connName) {
|
|
171
|
-
const conn = this.versoriCfg.mappings.find((c) => (c.dynamic === undefined || c.dynamic === false) &&
|
|
234
|
+
const conn = this.versoriCfg.mappings.find((c) => (c.dynamic === undefined || c.dynamic === false) &&
|
|
235
|
+
c.name.toLowerCase() === connName.toLowerCase());
|
|
172
236
|
if (!conn || !conn.connId) {
|
|
173
237
|
return '';
|
|
174
238
|
}
|
|
@@ -181,17 +245,17 @@ export class VersoriRoundTripperFactory {
|
|
|
181
245
|
}
|
|
182
246
|
return template.templateId;
|
|
183
247
|
}
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
248
|
+
apiKeyFetcher(conn, fn) {
|
|
249
|
+
const _fn = async (input, init) => {
|
|
250
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
|
|
251
|
+
const token = tokenResponse.token?.accessToken;
|
|
252
|
+
const asc = conn.credentials[0].authSchemeConfig.apiKey;
|
|
253
|
+
if (!token) {
|
|
254
|
+
throw new Error('Token not found');
|
|
255
|
+
}
|
|
256
|
+
if (!asc) {
|
|
257
|
+
throw new Error('API Key configuration not found');
|
|
258
|
+
}
|
|
195
259
|
if (!init) {
|
|
196
260
|
init = {};
|
|
197
261
|
}
|
|
@@ -229,13 +293,13 @@ export class VersoriRoundTripperFactory {
|
|
|
229
293
|
};
|
|
230
294
|
return _fn;
|
|
231
295
|
}
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
296
|
+
basicAuthFetcher(conn, fn) {
|
|
297
|
+
const _fn = async (input, init) => {
|
|
298
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
|
|
299
|
+
const token = tokenResponse.token?.accessToken;
|
|
300
|
+
if (!token) {
|
|
301
|
+
throw new Error('Token not found');
|
|
302
|
+
}
|
|
239
303
|
if (!init) {
|
|
240
304
|
init = {};
|
|
241
305
|
}
|
|
@@ -259,13 +323,13 @@ export class VersoriRoundTripperFactory {
|
|
|
259
323
|
return _fn;
|
|
260
324
|
}
|
|
261
325
|
// TODO: need to make the prefix and header name configurable from authschemeconfig
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
326
|
+
bearerTokenFetcher(conn, fn) {
|
|
327
|
+
const _fn = async (input, init) => {
|
|
328
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
|
|
329
|
+
const token = tokenResponse.token?.accessToken;
|
|
330
|
+
if (!token) {
|
|
331
|
+
throw new Error('Token not found');
|
|
332
|
+
}
|
|
269
333
|
if (!init) {
|
|
270
334
|
init = {};
|
|
271
335
|
}
|
|
@@ -288,27 +352,27 @@ export class VersoriRoundTripperFactory {
|
|
|
288
352
|
};
|
|
289
353
|
return _fn;
|
|
290
354
|
}
|
|
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';
|
|
355
|
+
oauth2Fetcher(conn, fn) {
|
|
356
|
+
const refreshFn = async (input, init, forceRefresh = false) => {
|
|
357
|
+
const tokenResponse = await this.getToken(conn.credentials[0].credential.id, forceRefresh);
|
|
358
|
+
const token = tokenResponse.token?.accessToken;
|
|
359
|
+
const tokenType = tokenResponse.token?.tokenType;
|
|
360
|
+
if (!token) {
|
|
361
|
+
throw new Error('Token not found');
|
|
309
362
|
}
|
|
310
|
-
|
|
311
|
-
|
|
363
|
+
const _tokenType = () => {
|
|
364
|
+
const _tt = tokenType?.toLowerCase();
|
|
365
|
+
switch (_tt) {
|
|
366
|
+
case 'bearer':
|
|
367
|
+
return 'Bearer';
|
|
368
|
+
case 'mac':
|
|
369
|
+
return 'MAC';
|
|
370
|
+
case 'basic':
|
|
371
|
+
return 'Basic';
|
|
372
|
+
default:
|
|
373
|
+
return 'Bearer';
|
|
374
|
+
}
|
|
375
|
+
};
|
|
312
376
|
if (!init) {
|
|
313
377
|
init = {};
|
|
314
378
|
}
|
|
@@ -329,8 +393,37 @@ export class VersoriRoundTripperFactory {
|
|
|
329
393
|
}
|
|
330
394
|
return fn(input, init);
|
|
331
395
|
};
|
|
396
|
+
const _fn = async (input, init) => {
|
|
397
|
+
const resp = await refreshFn(input, init, false);
|
|
398
|
+
if (resp.status === 401) {
|
|
399
|
+
this.log.debug('Received 401 Unauthorized response, attempting refresh', {
|
|
400
|
+
url: input,
|
|
401
|
+
status: resp.status,
|
|
402
|
+
});
|
|
403
|
+
// TODO: attempt refresh until precondition failed??
|
|
404
|
+
return refreshFn(input, init, true);
|
|
405
|
+
}
|
|
406
|
+
return Promise.resolve(resp);
|
|
407
|
+
};
|
|
332
408
|
return _fn;
|
|
333
409
|
}
|
|
410
|
+
async getToken(id) {
|
|
411
|
+
try {
|
|
412
|
+
return await this.tokenClient.getToken(id);
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
this.log.error('unable to get credential', { error });
|
|
416
|
+
if (error instanceof ConnectError) {
|
|
417
|
+
if (error.rawMessage.includes("connection error received: not a result of an error") && error.code === Code.Internal) {
|
|
418
|
+
this.log.info('Connection error received, attempting to reconnect');
|
|
419
|
+
this.tokenClient = new VersoriCredentialClient(this.credsBaseURL);
|
|
420
|
+
return await this.tokenClient.getToken(id);
|
|
421
|
+
}
|
|
422
|
+
throw error;
|
|
423
|
+
}
|
|
424
|
+
throw error;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
334
427
|
}
|
|
335
428
|
function isValidURL(url) {
|
|
336
429
|
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;AAMpE,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"}
|
|
@@ -3,14 +3,15 @@ import { catchError, EMPTY, mergeMap, of, tap } from 'rxjs';
|
|
|
3
3
|
import { ContextProviderImpl } from '../../context/ContextProvider.js';
|
|
4
4
|
import { DefaultRoundTripperFactory } from '../../dsl/http/default.js';
|
|
5
5
|
import { PlatformAPIClient } from '../../dsl/http/versori/platformapi.js';
|
|
6
|
-
import {
|
|
6
|
+
import { VersoriCredentialsFactory } from '../../dsl/http/versori/roundtripper.js';
|
|
7
7
|
import { WorkflowImpl } from '../../dsl/Workflow.js';
|
|
8
8
|
import { MemoryKeyValueProvider } from '../../kv/memory/MemoryKeyValueProvider.js';
|
|
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,
|
|
@@ -82,16 +95,16 @@ export class MemoryInterpreter {
|
|
|
82
95
|
const compiler = options.compiler || new ObservableCompiler();
|
|
83
96
|
const roundTripperFactory = options.skipVersoriCredentials
|
|
84
97
|
? new DefaultRoundTripperFactory()
|
|
85
|
-
:
|
|
98
|
+
: VersoriCredentialsFactory.fromEnv(log);
|
|
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.credentials()), 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"}
|