@hahnpro/flow-sdk 5.0.0-0 → 5.0.1
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/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/FlowApplication.d.ts +53 -14
- package/dist/FlowApplication.js +266 -85
- package/dist/FlowElement.d.ts +12 -4
- package/dist/FlowElement.js +47 -48
- package/dist/FlowEvent.d.ts +7 -1
- package/dist/FlowEvent.js +5 -5
- package/dist/FlowLogger.d.ts +9 -6
- package/dist/FlowLogger.js +17 -18
- package/dist/FlowModule.d.ts +1 -1
- package/dist/FlowModule.js +3 -3
- package/dist/RpcClient.d.ts +5 -3
- package/dist/RpcClient.js +23 -9
- package/dist/TestModule.js +6 -6
- package/dist/amqp.d.ts +14 -0
- package/dist/amqp.js +13 -0
- package/dist/extra-validators.js +15 -8
- package/dist/flow.interface.d.ts +7 -1
- package/dist/flow.interface.js +7 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/rpc_server.py +89 -77
- package/dist/unit-decorators.d.ts +39 -0
- package/dist/unit-decorators.js +157 -0
- package/dist/unit-utils.d.ts +8 -0
- package/dist/unit-utils.js +144 -0
- package/dist/units.d.ts +31 -0
- package/dist/units.js +570 -0
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +40 -7
- package/package.json +35 -33
- package/dist/api/Queue.d.ts +0 -15
- package/dist/api/Queue.js +0 -25
- package/dist/api/api.d.ts +0 -22
- package/dist/api/api.interface.d.ts +0 -14
- package/dist/api/api.interface.js +0 -2
- package/dist/api/api.js +0 -38
- package/dist/api/asset.interface.d.ts +0 -45
- package/dist/api/asset.interface.js +0 -2
- package/dist/api/asset.service.d.ts +0 -8
- package/dist/api/asset.service.js +0 -18
- package/dist/api/content.interface.d.ts +0 -33
- package/dist/api/content.interface.js +0 -2
- package/dist/api/content.service.d.ts +0 -9
- package/dist/api/content.service.js +0 -22
- package/dist/api/data.interface.d.ts +0 -29
- package/dist/api/data.interface.js +0 -2
- package/dist/api/data.service.d.ts +0 -15
- package/dist/api/data.service.js +0 -50
- package/dist/api/endpoint.interface.d.ts +0 -18
- package/dist/api/endpoint.interface.js +0 -2
- package/dist/api/endpoint.service.d.ts +0 -7
- package/dist/api/endpoint.service.js +0 -14
- package/dist/api/http.service.d.ts +0 -29
- package/dist/api/http.service.js +0 -96
- package/dist/api/index.d.ts +0 -11
- package/dist/api/index.js +0 -15
- package/dist/api/mock/api.mock.d.ts +0 -102
- package/dist/api/mock/api.mock.js +0 -81
- package/dist/api/mock/asset.mock.service.d.ts +0 -9
- package/dist/api/mock/asset.mock.service.js +0 -18
- package/dist/api/mock/content.mock.service.d.ts +0 -9
- package/dist/api/mock/content.mock.service.js +0 -21
- package/dist/api/mock/data.mock.service.d.ts +0 -11
- package/dist/api/mock/data.mock.service.js +0 -53
- package/dist/api/mock/endpoint.mock.service.d.ts +0 -10
- package/dist/api/mock/endpoint.mock.service.js +0 -15
- package/dist/api/mock/index.d.ts +0 -7
- package/dist/api/mock/index.js +0 -10
- package/dist/api/mock/secret.mock.service.d.ts +0 -5
- package/dist/api/mock/secret.mock.service.js +0 -11
- package/dist/api/mock/task.mock.service.d.ts +0 -8
- package/dist/api/mock/task.mock.service.js +0 -16
- package/dist/api/mock/timeseries.mock.service.d.ts +0 -18
- package/dist/api/mock/timeseries.mock.service.js +0 -70
- package/dist/api/mock/user.mock.service.d.ts +0 -7
- package/dist/api/mock/user.mock.service.js +0 -12
- package/dist/api/secret.interface.d.ts +0 -9
- package/dist/api/secret.interface.js +0 -2
- package/dist/api/secret.service.d.ts +0 -6
- package/dist/api/secret.service.js +0 -10
- package/dist/api/sidriveiq.interface.d.ts +0 -104
- package/dist/api/sidriveiq.interface.js +0 -2
- package/dist/api/sidriveiq.service.d.ts +0 -31
- package/dist/api/sidriveiq.service.js +0 -97
- package/dist/api/task.interface.d.ts +0 -26
- package/dist/api/task.interface.js +0 -2
- package/dist/api/task.service.d.ts +0 -7
- package/dist/api/task.service.js +0 -13
- package/dist/api/timeseries.interface.d.ts +0 -51
- package/dist/api/timeseries.interface.js +0 -2
- package/dist/api/timeseries.service.d.ts +0 -17
- package/dist/api/timeseries.service.js +0 -38
- package/dist/api/user.interface.d.ts +0 -3
- package/dist/api/user.interface.js +0 -2
- package/dist/api/user.service.d.ts +0 -7
- package/dist/api/user.service.js +0 -21
package/dist/FlowElement.js
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FlowDashboard = exports.FlowTrigger = exports.FlowTask = exports.FlowResource = exports.FlowFunction = exports.InputStream = exports.FlowElement = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
4
|
const class_transformer_1 = require("class-transformer");
|
|
6
5
|
const class_validator_1 = require("class-validator");
|
|
7
6
|
const python_shell_1 = require("python-shell");
|
|
8
|
-
const string_interp_1 = tslib_1.__importDefault(require("string-interp"));
|
|
9
7
|
const FlowEvent_1 = require("./FlowEvent");
|
|
10
8
|
const FlowLogger_1 = require("./FlowLogger");
|
|
11
9
|
const utils_1 = require("./utils");
|
|
12
10
|
class FlowElement {
|
|
13
|
-
constructor(
|
|
14
|
-
var _b, _c;
|
|
15
|
-
var { app, logger } = _a, metadata = tslib_1.__rest(_a, ["app", "logger"]);
|
|
11
|
+
constructor({ app, logger, ...metadata }, properties, propertiesClassType, whitelist = false) {
|
|
16
12
|
this.propertiesClassType = propertiesClassType;
|
|
17
13
|
this.whitelist = whitelist;
|
|
14
|
+
this.stopPropagateStream = new Map();
|
|
18
15
|
this.onContextChanged = (context) => {
|
|
19
|
-
this.metadata =
|
|
16
|
+
this.metadata = { ...this.metadata, ...context };
|
|
20
17
|
};
|
|
21
18
|
this.onPropertiesChanged = (properties) => {
|
|
22
19
|
this.setProperties(properties);
|
|
23
20
|
};
|
|
21
|
+
this.getMetadata = () => this.metadata;
|
|
24
22
|
this.setProperties = (properties) => {
|
|
25
23
|
if (this.propertiesClassType) {
|
|
26
24
|
this.properties = this.validateProperties(this.propertiesClassType, properties, this.whitelist);
|
|
@@ -29,33 +27,42 @@ class FlowElement {
|
|
|
29
27
|
this.properties = properties;
|
|
30
28
|
}
|
|
31
29
|
};
|
|
32
|
-
this.handleApiError = (error) => utils_1.handleApiError(error, this.logger);
|
|
30
|
+
this.handleApiError = (error) => (0, utils_1.handleApiError)(error, this.logger);
|
|
31
|
+
this.interpolate = (value, ...templateVariables) => (0, utils_1.fillTemplate)(value, ...templateVariables);
|
|
33
32
|
this.app = app;
|
|
34
|
-
this.api =
|
|
35
|
-
this.metadata =
|
|
36
|
-
this.logger = new FlowLogger_1.FlowLogger(this.metadata, logger || undefined,
|
|
33
|
+
this.api = this.app?.api;
|
|
34
|
+
this.metadata = { ...metadata, functionFqn: this.functionFqn };
|
|
35
|
+
this.logger = new FlowLogger_1.FlowLogger(this.metadata, logger || undefined, this.app?.publishEvent);
|
|
37
36
|
this.rpcRoutingKey = (this.metadata.flowId || '') + (this.metadata.deploymentId || '') + this.metadata.id;
|
|
38
37
|
if (properties) {
|
|
39
38
|
this.setProperties(properties);
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
get flowProperties() {
|
|
43
|
-
|
|
44
|
-
return ((_b = (_a = this.app) === null || _a === void 0 ? void 0 : _a.getProperties) === null || _b === void 0 ? void 0 : _b.call(_a)) || {};
|
|
42
|
+
return this.app?.getProperties?.() || {};
|
|
45
43
|
}
|
|
46
44
|
emitOutput(data = {}, outputId = 'default', time = new Date()) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
return this.emitEvent(data, null, outputId, time);
|
|
46
|
+
}
|
|
47
|
+
emitEvent(data, inputEvent, outputId = 'default', time = new Date()) {
|
|
48
|
+
const partialEvent = new FlowEvent_1.FlowEvent(this.metadata, data, outputId, time);
|
|
49
|
+
const completeEvent = new FlowEvent_1.FlowEvent(this.metadata, { ...(inputEvent?.getData() || {}), ...data }, outputId, time);
|
|
50
|
+
const streamID = inputEvent?.getMetadata()?.inputStreamId || '';
|
|
51
|
+
if ((this.stopPropagateStream.has(streamID) && this.stopPropagateStream.get(streamID)) || !this.stopPropagateStream.has(streamID)) {
|
|
52
|
+
this.app?.emit(partialEvent);
|
|
53
|
+
return partialEvent;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
this.app?.emitPartial(completeEvent, partialEvent);
|
|
57
|
+
return completeEvent;
|
|
50
58
|
}
|
|
51
|
-
return event;
|
|
52
59
|
}
|
|
53
60
|
validateProperties(classType, properties = {}, whitelist = false) {
|
|
54
|
-
const props = class_transformer_1.
|
|
55
|
-
const errors = class_validator_1.validateSync(props, { whitelist });
|
|
56
|
-
if (
|
|
61
|
+
const props = (0, class_transformer_1.plainToInstance)(classType, properties);
|
|
62
|
+
const errors = (0, class_validator_1.validateSync)(props, { forbidUnknownValues: false, whitelist });
|
|
63
|
+
if (Array.isArray(errors) && errors.length > 0) {
|
|
57
64
|
for (const e of errors) {
|
|
58
|
-
this.
|
|
65
|
+
this.logValidationErrors(e);
|
|
59
66
|
}
|
|
60
67
|
throw new Error('Properties Validation failed');
|
|
61
68
|
}
|
|
@@ -63,36 +70,29 @@ class FlowElement {
|
|
|
63
70
|
return props;
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (!((_a = text === null || text === void 0 ? void 0 : text.includes) === null || _a === void 0 ? void 0 : _a.call(text, '${'))) {
|
|
72
|
-
return text;
|
|
73
|
+
logValidationErrors(error, parent) {
|
|
74
|
+
const { children, constraints, property, value } = error;
|
|
75
|
+
const name = parent ? parent + '.' + property : property;
|
|
76
|
+
if (constraints) {
|
|
77
|
+
this.logger.error(`Validation for property "${name}" failed:\n${JSON.stringify(constraints || {})}\nvalue: ${value}`);
|
|
73
78
|
}
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
return result;
|
|
79
|
+
else if (Array.isArray(children)) {
|
|
80
|
+
for (const child of children) {
|
|
81
|
+
this.logValidationErrors(child, name);
|
|
78
82
|
}
|
|
79
83
|
}
|
|
80
|
-
|
|
84
|
+
}
|
|
85
|
+
validateEventData(classType, event, whitelist = false) {
|
|
86
|
+
return this.validateProperties(classType, event.getData(), whitelist);
|
|
81
87
|
}
|
|
82
88
|
async callRpcFunction(functionName, ...args) {
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
return (_b = (_a = this.app) === null || _a === void 0 ? void 0 : _a.rpcClient) === null || _b === void 0 ? void 0 : _b.callFunction(this.rpcRoutingKey, functionName, ...args);
|
|
86
|
-
}
|
|
87
|
-
catch (err) {
|
|
88
|
-
this.logger.error(err);
|
|
89
|
-
}
|
|
89
|
+
return this.app?.rpcClient.callFunction(this.rpcRoutingKey, functionName, ...args);
|
|
90
90
|
}
|
|
91
|
-
runPyRpcScript(scriptPath) {
|
|
91
|
+
runPyRpcScript(scriptPath, ...args) {
|
|
92
92
|
const options = {
|
|
93
93
|
mode: 'text',
|
|
94
94
|
pythonOptions: ['-u'],
|
|
95
|
-
args: [__dirname, this.rpcRoutingKey],
|
|
95
|
+
args: [__dirname, this.rpcRoutingKey, ...args.map((v) => v.toString())],
|
|
96
96
|
};
|
|
97
97
|
return python_shell_1.PythonShell.run(scriptPath, options, (err, outputs) => {
|
|
98
98
|
if (err) {
|
|
@@ -110,18 +110,17 @@ function InputStream(id = 'default', options) {
|
|
|
110
110
|
Reflect.defineMetadata(`stream:options:${id}`, options, target.constructor);
|
|
111
111
|
}
|
|
112
112
|
const method = propertyDescriptor.value;
|
|
113
|
-
propertyDescriptor.value =
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
};
|
|
118
|
-
return method.call(this, event);
|
|
113
|
+
propertyDescriptor.value = function (event) {
|
|
114
|
+
if (!this.stopPropagateStream.has(id)) {
|
|
115
|
+
this.stopPropagateStream.set(id, options?.stopPropagation ?? false);
|
|
116
|
+
}
|
|
117
|
+
return method.call(this, new FlowEvent_1.FlowEvent({ id: event.getMetadata().elementId, ...event.getMetadata(), inputStreamId: id }, event.getData(), event.getType(), new Date(event.getTime())));
|
|
119
118
|
};
|
|
120
119
|
};
|
|
121
120
|
}
|
|
122
121
|
exports.InputStream = InputStream;
|
|
123
122
|
function FlowFunction(fqn) {
|
|
124
|
-
const fqnRegExp =
|
|
123
|
+
const fqnRegExp = /^([a-zA-Z][a-zA-Z\d]*[.-])*[a-zA-Z][a-zA-Z\d]*$/;
|
|
125
124
|
if (!fqnRegExp.test(fqn)) {
|
|
126
125
|
throw new Error(`Flow Function FQN (${fqn}) is not valid`);
|
|
127
126
|
}
|
package/dist/FlowEvent.d.ts
CHANGED
|
@@ -8,7 +8,13 @@ export declare class FlowEvent {
|
|
|
8
8
|
getDataContentType: () => string;
|
|
9
9
|
getDataschema: () => string;
|
|
10
10
|
getId: () => string;
|
|
11
|
-
getMetadata: () =>
|
|
11
|
+
getMetadata: () => {
|
|
12
|
+
deploymentId: string;
|
|
13
|
+
elementId: string;
|
|
14
|
+
flowId: string;
|
|
15
|
+
functionFqn: string;
|
|
16
|
+
inputStreamId: string;
|
|
17
|
+
};
|
|
12
18
|
getSource: () => string;
|
|
13
19
|
getStreamId: () => string;
|
|
14
20
|
getSubject: () => string;
|
package/dist/FlowEvent.js
CHANGED
|
@@ -16,7 +16,7 @@ class FlowEvent {
|
|
|
16
16
|
}
|
|
17
17
|
return event;
|
|
18
18
|
};
|
|
19
|
-
this.getData = () => lodash_1.cloneDeep(this.event.data || {});
|
|
19
|
+
this.getData = () => (0, lodash_1.cloneDeep)(this.event.data || {});
|
|
20
20
|
this.getDataContentType = () => this.event.datacontenttype;
|
|
21
21
|
this.getDataschema = () => this.event.dataschema;
|
|
22
22
|
this.getId = () => this.event.id;
|
|
@@ -28,13 +28,13 @@ class FlowEvent {
|
|
|
28
28
|
this.getType = () => this.event.type;
|
|
29
29
|
this.toJSON = () => this.event.toJSON();
|
|
30
30
|
this.toString = () => this.event.toString();
|
|
31
|
-
const { id: elementId, deploymentId, flowId, functionFqn } = metadata;
|
|
31
|
+
const { id: elementId, deploymentId, flowId, functionFqn, inputStreamId } = metadata;
|
|
32
32
|
if (data instanceof Error) {
|
|
33
33
|
const error = { message: data.message, stack: data.stack };
|
|
34
34
|
data = error;
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
data = lodash_1.cloneDeep(data);
|
|
37
|
+
data = (0, lodash_1.cloneDeep)(data);
|
|
38
38
|
}
|
|
39
39
|
if (data == null) {
|
|
40
40
|
data = {};
|
|
@@ -49,7 +49,7 @@ class FlowEvent {
|
|
|
49
49
|
dataType = 'text/plain';
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
else if (typeof data === 'object'
|
|
52
|
+
else if (typeof data === 'object') {
|
|
53
53
|
dataType = 'application/json';
|
|
54
54
|
}
|
|
55
55
|
else {
|
|
@@ -57,7 +57,7 @@ class FlowEvent {
|
|
|
57
57
|
dataType = 'text/plain';
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
this.metadata = { deploymentId, elementId, flowId, functionFqn };
|
|
60
|
+
this.metadata = { deploymentId, elementId, flowId, functionFqn, inputStreamId };
|
|
61
61
|
this.event = new cloudevents_1.CloudEvent({
|
|
62
62
|
source: `flows/${flowId}/deployments/${deploymentId}/elements/${elementId}`,
|
|
63
63
|
type: outputId,
|
package/dist/FlowLogger.d.ts
CHANGED
|
@@ -8,16 +8,19 @@ export interface Logger {
|
|
|
8
8
|
verbose(message: any, metadata?: any): void;
|
|
9
9
|
}
|
|
10
10
|
export declare const defaultLogger: Logger;
|
|
11
|
+
export interface LoggerOptions {
|
|
12
|
+
truncate: boolean;
|
|
13
|
+
}
|
|
11
14
|
export declare class FlowLogger implements Logger {
|
|
12
15
|
private readonly metadata;
|
|
13
16
|
private readonly logger;
|
|
14
17
|
private readonly publishEvent?;
|
|
15
18
|
private static getStackTrace;
|
|
16
|
-
constructor(metadata: FlowElementContext, logger?: Logger, publishEvent?: (event: FlowEvent) =>
|
|
17
|
-
debug: (message: any) => void;
|
|
18
|
-
error: (message: any) => void;
|
|
19
|
-
log: (message: any) => void;
|
|
20
|
-
warn: (message: any) => void;
|
|
21
|
-
verbose: (message: any) => void;
|
|
19
|
+
constructor(metadata: FlowElementContext, logger?: Logger, publishEvent?: (event: FlowEvent) => void);
|
|
20
|
+
debug: (message: any, options?: LoggerOptions) => void;
|
|
21
|
+
error: (message: any, options?: LoggerOptions) => void;
|
|
22
|
+
log: (message: any, options?: LoggerOptions) => void;
|
|
23
|
+
warn: (message: any, options?: LoggerOptions) => void;
|
|
24
|
+
verbose: (message: any, options?: LoggerOptions) => void;
|
|
22
25
|
private publish;
|
|
23
26
|
}
|
package/dist/FlowLogger.js
CHANGED
|
@@ -10,16 +10,6 @@ exports.defaultLogger = {
|
|
|
10
10
|
verbose: (msg, metadata) => console.log(msg, metadata),
|
|
11
11
|
};
|
|
12
12
|
class FlowLogger {
|
|
13
|
-
constructor(metadata, logger = exports.defaultLogger, publishEvent) {
|
|
14
|
-
this.metadata = metadata;
|
|
15
|
-
this.logger = logger;
|
|
16
|
-
this.publishEvent = publishEvent;
|
|
17
|
-
this.debug = (message) => this.publish(message, 'debug');
|
|
18
|
-
this.error = (message) => this.publish(message, 'error');
|
|
19
|
-
this.log = (message) => this.publish(message, 'info');
|
|
20
|
-
this.warn = (message) => this.publish(message, 'warn');
|
|
21
|
-
this.verbose = (message) => this.publish(message, 'verbose');
|
|
22
|
-
}
|
|
23
13
|
static getStackTrace() {
|
|
24
14
|
let stack;
|
|
25
15
|
try {
|
|
@@ -34,23 +24,32 @@ class FlowLogger {
|
|
|
34
24
|
.filter((value) => !value.includes('Logger'));
|
|
35
25
|
return stack.splice(1).join('\n');
|
|
36
26
|
}
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
constructor(metadata, logger = exports.defaultLogger, publishEvent) {
|
|
28
|
+
this.metadata = metadata;
|
|
29
|
+
this.logger = logger;
|
|
30
|
+
this.publishEvent = publishEvent;
|
|
31
|
+
this.debug = (message, options) => this.publish(message, 'debug', options);
|
|
32
|
+
this.error = (message, options) => this.publish(message, 'error', options);
|
|
33
|
+
this.log = (message, options) => this.publish(message, 'info', options);
|
|
34
|
+
this.warn = (message, options) => this.publish(message, 'warn', options);
|
|
35
|
+
this.verbose = (message, options) => this.publish(message, 'verbose', options);
|
|
36
|
+
}
|
|
37
|
+
publish(message, level, options) {
|
|
39
38
|
if (this.publishEvent) {
|
|
40
39
|
const event = new FlowEvent_1.FlowEvent(this.metadata, message, `flow.log.${level}`);
|
|
41
|
-
|
|
40
|
+
this.publishEvent(event);
|
|
42
41
|
}
|
|
43
42
|
switch (level) {
|
|
44
43
|
case 'debug':
|
|
45
|
-
return this.logger.debug(message, this.metadata);
|
|
44
|
+
return this.logger.debug(message, { ...this.metadata, ...options });
|
|
46
45
|
case 'error':
|
|
47
|
-
return this.logger.error(message, this.metadata);
|
|
46
|
+
return this.logger.error(message, { ...this.metadata, ...options });
|
|
48
47
|
case 'warn':
|
|
49
|
-
return this.logger.warn(message, this.metadata);
|
|
48
|
+
return this.logger.warn(message, { ...this.metadata, ...options });
|
|
50
49
|
case 'verbose':
|
|
51
|
-
return this.logger.verbose(message, this.metadata);
|
|
50
|
+
return this.logger.verbose(message, { ...this.metadata, ...options });
|
|
52
51
|
default:
|
|
53
|
-
this.logger.log(message, this.metadata);
|
|
52
|
+
this.logger.log(message, { ...this.metadata, ...options });
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
}
|
package/dist/FlowModule.d.ts
CHANGED
package/dist/FlowModule.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FlowModule = void 0;
|
|
4
4
|
function FlowModule(metadata) {
|
|
5
|
-
const
|
|
6
|
-
if (!
|
|
7
|
-
throw new Error(`Flow Module name (${metadata.name}) is not valid`);
|
|
5
|
+
const validateNameRegExp = new RegExp(/^(@[a-z][a-z0-9-]*\/)?[a-z][a-z0-9-]*$/);
|
|
6
|
+
if (!validateNameRegExp.test(metadata.name)) {
|
|
7
|
+
throw new Error(`Flow Module name (${metadata.name}) is not valid. Name must be all lowercase and not contain any special characters except for hyphens. Can optionally start with a scope "@scopename/"`);
|
|
8
8
|
}
|
|
9
9
|
return (target) => {
|
|
10
10
|
Reflect.defineMetadata('module:name', metadata.name, target);
|
package/dist/RpcClient.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { AmqpConnectionManager } from 'amqp-connection-manager';
|
|
1
|
+
import type { AmqpConnectionManager } from 'amqp-connection-manager';
|
|
2
|
+
import { FlowLogger } from './FlowLogger';
|
|
2
3
|
export declare class RpcClient {
|
|
3
|
-
private
|
|
4
|
+
private readonly logger?;
|
|
5
|
+
private readonly channel;
|
|
4
6
|
private openRequests;
|
|
5
|
-
constructor(
|
|
7
|
+
constructor(amqpConnection: AmqpConnectionManager, logger?: FlowLogger);
|
|
6
8
|
private onMessage;
|
|
7
9
|
callFunction: (routingKey: string, functionName: string, ...args: any[]) => Promise<unknown>;
|
|
8
10
|
declareFunction: (routingKey: string, name: string) => (...args: any[]) => Promise<unknown>;
|
package/dist/RpcClient.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RpcClient = void 0;
|
|
4
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const object_sizeof_1 = tslib_1.__importDefault(require("object-sizeof"));
|
|
7
|
+
const MAX_MSG_SIZE = +process.env.MAX_RPC_MSG_SIZE_BYTES;
|
|
8
|
+
const WARN_MSG_SIZE = +process.env.WARN_RPC_MSG_SIZE_BYTES;
|
|
5
9
|
class RpcClient {
|
|
6
|
-
constructor(
|
|
10
|
+
constructor(amqpConnection, logger) {
|
|
11
|
+
this.logger = logger;
|
|
7
12
|
this.openRequests = new Map();
|
|
8
13
|
this.onMessage = (msg) => {
|
|
9
14
|
if (this.openRequests.has(msg.properties.correlationId)) {
|
|
@@ -38,8 +43,17 @@ class RpcClient {
|
|
|
38
43
|
this.callFunction = (routingKey, functionName, ...args) => {
|
|
39
44
|
const stack = new Error('test').stack;
|
|
40
45
|
return new Promise((resolve, reject) => {
|
|
46
|
+
if (MAX_MSG_SIZE || WARN_MSG_SIZE) {
|
|
47
|
+
const messageSize = (0, object_sizeof_1.default)(args);
|
|
48
|
+
if (messageSize > MAX_MSG_SIZE) {
|
|
49
|
+
throw new Error(`Max RPC message size exceeded: ${messageSize} bytes / ${MAX_MSG_SIZE} bytes`);
|
|
50
|
+
}
|
|
51
|
+
if (messageSize > WARN_MSG_SIZE) {
|
|
52
|
+
this.logger?.warn(`Large RPC message size detected: ${messageSize} bytes`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
41
55
|
const call = { functionName, arguments: args };
|
|
42
|
-
const correlationId =
|
|
56
|
+
const correlationId = (0, crypto_1.randomUUID)();
|
|
43
57
|
this.openRequests.set(correlationId, { resolve, reject, trace: RpcClient.formatTrace(stack) });
|
|
44
58
|
this.channel
|
|
45
59
|
.publish('rpc_direct_exchange', routingKey, call, { correlationId, replyTo: 'amq.rabbitmq.reply-to' })
|
|
@@ -49,15 +63,15 @@ class RpcClient {
|
|
|
49
63
|
this.declareFunction = (routingKey, name) => {
|
|
50
64
|
return (...args) => this.callFunction(routingKey, name, ...args);
|
|
51
65
|
};
|
|
52
|
-
if (!
|
|
66
|
+
if (!amqpConnection) {
|
|
53
67
|
throw new Error('currently no amqp connection available');
|
|
54
68
|
}
|
|
55
|
-
this.channel =
|
|
69
|
+
this.channel = amqpConnection.createChannel({
|
|
56
70
|
json: true,
|
|
57
|
-
setup: (channel) =>
|
|
58
|
-
channel.assertExchange('rpc_direct_exchange', 'direct', { durable: false })
|
|
59
|
-
channel.consume('amq.rabbitmq.reply-to', this.onMessage, { noAck: true })
|
|
60
|
-
|
|
71
|
+
setup: async (channel) => {
|
|
72
|
+
await channel.assertExchange('rpc_direct_exchange', 'direct', { durable: false });
|
|
73
|
+
await channel.consume('amq.rabbitmq.reply-to', this.onMessage, { noAck: true });
|
|
74
|
+
},
|
|
61
75
|
});
|
|
62
76
|
}
|
|
63
77
|
close() {
|
package/dist/TestModule.js
CHANGED
|
@@ -7,21 +7,21 @@ const FlowEvent_1 = require("./FlowEvent");
|
|
|
7
7
|
const FlowModule_1 = require("./FlowModule");
|
|
8
8
|
let TestTrigger = class TestTrigger extends FlowElement_1.FlowTask {
|
|
9
9
|
async onDefault(event) {
|
|
10
|
-
return this.
|
|
10
|
+
return this.emitEvent({}, event);
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
13
|
tslib_1.__decorate([
|
|
14
|
-
FlowElement_1.InputStream('default'),
|
|
14
|
+
(0, FlowElement_1.InputStream)('default'),
|
|
15
15
|
tslib_1.__metadata("design:type", Function),
|
|
16
16
|
tslib_1.__metadata("design:paramtypes", [FlowEvent_1.FlowEvent]),
|
|
17
17
|
tslib_1.__metadata("design:returntype", Promise)
|
|
18
18
|
], TestTrigger.prototype, "onDefault", null);
|
|
19
19
|
TestTrigger = tslib_1.__decorate([
|
|
20
|
-
FlowElement_1.FlowFunction('test.task.Trigger')
|
|
20
|
+
(0, FlowElement_1.FlowFunction)('test.task.Trigger')
|
|
21
21
|
], TestTrigger);
|
|
22
22
|
let TestModule = class TestModule {
|
|
23
23
|
};
|
|
24
|
-
TestModule = tslib_1.__decorate([
|
|
25
|
-
FlowModule_1.FlowModule({ name: 'test', declarations: [TestTrigger] })
|
|
26
|
-
], TestModule);
|
|
27
24
|
exports.TestModule = TestModule;
|
|
25
|
+
exports.TestModule = TestModule = tslib_1.__decorate([
|
|
26
|
+
(0, FlowModule_1.FlowModule)({ name: 'test', declarations: [TestTrigger] })
|
|
27
|
+
], TestModule);
|
package/dist/amqp.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AmqpConnectionManager, ChannelWrapper } from 'amqp-connection-manager';
|
|
2
|
+
export interface AmqpConnection {
|
|
3
|
+
managedChannel: ChannelWrapper;
|
|
4
|
+
managedConnection: AmqpConnectionManager;
|
|
5
|
+
}
|
|
6
|
+
export interface AmqpConnectionConfig {
|
|
7
|
+
protocol?: string;
|
|
8
|
+
hostname?: string;
|
|
9
|
+
vhost?: string;
|
|
10
|
+
user?: string;
|
|
11
|
+
password?: string;
|
|
12
|
+
port?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function createAmqpConnection(config: AmqpConnectionConfig): AmqpConnectionManager;
|
package/dist/amqp.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAmqpConnection = void 0;
|
|
4
|
+
const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
5
|
+
function createAmqpConnection(config) {
|
|
6
|
+
if (!config) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const { protocol = process.env.RABBIT_PROTOCOL || 'amqp', hostname = process.env.RABBIT_HOST || 'localhost', port = +process.env.RABBIT_PORT || 5672, user = process.env.RABBIT_USER || 'guest', password = process.env.RABBIT_PASSWORD || 'guest', vhost = process.env.RABBIT_VHOST || '', } = config;
|
|
10
|
+
const uri = `${protocol}://${user}:${password}@${hostname}:${port}${vhost ? '/' + vhost : ''}`;
|
|
11
|
+
return (0, amqp_connection_manager_1.connect)(uri);
|
|
12
|
+
}
|
|
13
|
+
exports.createAmqpConnection = createAmqpConnection;
|
package/dist/extra-validators.js
CHANGED
|
@@ -5,24 +5,31 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const class_validator_1 = require("class-validator");
|
|
6
6
|
let IsNotSiblingOfConstraint = class IsNotSiblingOfConstraint {
|
|
7
7
|
validate(value, args) {
|
|
8
|
-
if (class_validator_1.isDefined(value)) {
|
|
8
|
+
if ((0, class_validator_1.isDefined)(value)) {
|
|
9
9
|
return this.getFailedConstraints(args).length === 0;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
else {
|
|
12
|
+
return !args.constraints.every((prop) => !(0, class_validator_1.isDefined)(args.object[prop]));
|
|
13
|
+
}
|
|
12
14
|
}
|
|
13
15
|
defaultMessage(args) {
|
|
14
|
-
|
|
16
|
+
if (args.value) {
|
|
17
|
+
return `${args.property} cannot exist alongside the following defined properties: ${this.getFailedConstraints(args).join(', ')}`;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return `at least one of the properties must be defined`;
|
|
21
|
+
}
|
|
15
22
|
}
|
|
16
23
|
getFailedConstraints(args) {
|
|
17
|
-
return args.constraints.filter((prop) => class_validator_1.isDefined(args.object[prop]));
|
|
24
|
+
return args.constraints.filter((prop) => (0, class_validator_1.isDefined)(args.object[prop]));
|
|
18
25
|
}
|
|
19
26
|
};
|
|
20
27
|
IsNotSiblingOfConstraint = tslib_1.__decorate([
|
|
21
|
-
class_validator_1.ValidatorConstraint({ async: false })
|
|
28
|
+
(0, class_validator_1.ValidatorConstraint)({ async: false })
|
|
22
29
|
], IsNotSiblingOfConstraint);
|
|
23
30
|
function IsNotSiblingOf(props, validationOptions) {
|
|
24
31
|
return (object, propertyName) => {
|
|
25
|
-
class_validator_1.registerDecorator({
|
|
32
|
+
(0, class_validator_1.registerDecorator)({
|
|
26
33
|
target: object.constructor,
|
|
27
34
|
propertyName,
|
|
28
35
|
options: validationOptions,
|
|
@@ -32,11 +39,11 @@ function IsNotSiblingOf(props, validationOptions) {
|
|
|
32
39
|
};
|
|
33
40
|
}
|
|
34
41
|
function incompatibleSiblingsNotPresent(incompatibleSiblings) {
|
|
35
|
-
return (o, v) => Boolean(class_validator_1.isDefined(v) || incompatibleSiblings.every((prop) => !class_validator_1.isDefined(o[prop])));
|
|
42
|
+
return (o, v) => Boolean((0, class_validator_1.isDefined)(v) || incompatibleSiblings.every((prop) => !(0, class_validator_1.isDefined)(o[prop])));
|
|
36
43
|
}
|
|
37
44
|
function IncompatableWith(incompatibleSiblings) {
|
|
38
45
|
const notSibling = IsNotSiblingOf(incompatibleSiblings);
|
|
39
|
-
const validateIf = class_validator_1.ValidateIf(incompatibleSiblingsNotPresent(incompatibleSiblings));
|
|
46
|
+
const validateIf = (0, class_validator_1.ValidateIf)(incompatibleSiblingsNotPresent(incompatibleSiblings));
|
|
40
47
|
return (target, key) => {
|
|
41
48
|
notSibling(target, key);
|
|
42
49
|
validateIf(target, key);
|
package/dist/flow.interface.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface FlowElementContext extends FlowContext {
|
|
|
7
7
|
id: string;
|
|
8
8
|
name?: string;
|
|
9
9
|
functionFqn?: string;
|
|
10
|
+
inputStreamId?: string;
|
|
10
11
|
}
|
|
11
12
|
export interface DeploymentMessage extends Record<string, any> {
|
|
12
13
|
elementId?: string;
|
|
@@ -36,5 +37,10 @@ export interface Flow {
|
|
|
36
37
|
export interface StreamOptions {
|
|
37
38
|
concurrent?: number;
|
|
38
39
|
}
|
|
39
|
-
export
|
|
40
|
+
export type ClassType<T> = new (...args: any[]) => T;
|
|
41
|
+
export declare enum LifecycleEvent {
|
|
42
|
+
ACTIVATED = "com.hahnpro.flow_function.activated",
|
|
43
|
+
COMPLETED = "com.hahnpro.flow_function.completed",
|
|
44
|
+
TERMINATED = "com.hahnpro.flow_function.terminated"
|
|
45
|
+
}
|
|
40
46
|
export {};
|
package/dist/flow.interface.js
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LifecycleEvent = void 0;
|
|
4
|
+
var LifecycleEvent;
|
|
5
|
+
(function (LifecycleEvent) {
|
|
6
|
+
LifecycleEvent["ACTIVATED"] = "com.hahnpro.flow_function.activated";
|
|
7
|
+
LifecycleEvent["COMPLETED"] = "com.hahnpro.flow_function.completed";
|
|
8
|
+
LifecycleEvent["TERMINATED"] = "com.hahnpro.flow_function.terminated";
|
|
9
|
+
})(LifecycleEvent || (exports.LifecycleEvent = LifecycleEvent = {}));
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from '
|
|
1
|
+
export * from '@hahnpro/hpc-api';
|
|
2
2
|
export * from './flow.interface';
|
|
3
3
|
export * from './utils';
|
|
4
4
|
export * from './FlowApplication';
|
|
@@ -7,4 +7,5 @@ export * from './FlowEvent';
|
|
|
7
7
|
export * from './FlowLogger';
|
|
8
8
|
export * from './FlowModule';
|
|
9
9
|
export * from './TestModule';
|
|
10
|
+
export * from './unit-decorators';
|
|
10
11
|
export { IncompatableWith } from './extra-validators';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IncompatableWith = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
tslib_1.__exportStar(require("
|
|
5
|
+
tslib_1.__exportStar(require("@hahnpro/hpc-api"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./flow.interface"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./utils"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./FlowApplication"), exports);
|
|
@@ -11,5 +11,6 @@ tslib_1.__exportStar(require("./FlowEvent"), exports);
|
|
|
11
11
|
tslib_1.__exportStar(require("./FlowLogger"), exports);
|
|
12
12
|
tslib_1.__exportStar(require("./FlowModule"), exports);
|
|
13
13
|
tslib_1.__exportStar(require("./TestModule"), exports);
|
|
14
|
+
tslib_1.__exportStar(require("./unit-decorators"), exports);
|
|
14
15
|
var extra_validators_1 = require("./extra-validators");
|
|
15
16
|
Object.defineProperty(exports, "IncompatableWith", { enumerable: true, get: function () { return extra_validators_1.IncompatableWith; } });
|