@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.
Files changed (98) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/dist/FlowApplication.d.ts +53 -14
  4. package/dist/FlowApplication.js +266 -85
  5. package/dist/FlowElement.d.ts +12 -4
  6. package/dist/FlowElement.js +47 -48
  7. package/dist/FlowEvent.d.ts +7 -1
  8. package/dist/FlowEvent.js +5 -5
  9. package/dist/FlowLogger.d.ts +9 -6
  10. package/dist/FlowLogger.js +17 -18
  11. package/dist/FlowModule.d.ts +1 -1
  12. package/dist/FlowModule.js +3 -3
  13. package/dist/RpcClient.d.ts +5 -3
  14. package/dist/RpcClient.js +23 -9
  15. package/dist/TestModule.js +6 -6
  16. package/dist/amqp.d.ts +14 -0
  17. package/dist/amqp.js +13 -0
  18. package/dist/extra-validators.js +15 -8
  19. package/dist/flow.interface.d.ts +7 -1
  20. package/dist/flow.interface.js +7 -0
  21. package/dist/index.d.ts +2 -1
  22. package/dist/index.js +2 -1
  23. package/dist/rpc_server.py +89 -77
  24. package/dist/unit-decorators.d.ts +39 -0
  25. package/dist/unit-decorators.js +157 -0
  26. package/dist/unit-utils.d.ts +8 -0
  27. package/dist/unit-utils.js +144 -0
  28. package/dist/units.d.ts +31 -0
  29. package/dist/units.js +570 -0
  30. package/dist/utils.d.ts +5 -1
  31. package/dist/utils.js +40 -7
  32. package/package.json +35 -33
  33. package/dist/api/Queue.d.ts +0 -15
  34. package/dist/api/Queue.js +0 -25
  35. package/dist/api/api.d.ts +0 -22
  36. package/dist/api/api.interface.d.ts +0 -14
  37. package/dist/api/api.interface.js +0 -2
  38. package/dist/api/api.js +0 -38
  39. package/dist/api/asset.interface.d.ts +0 -45
  40. package/dist/api/asset.interface.js +0 -2
  41. package/dist/api/asset.service.d.ts +0 -8
  42. package/dist/api/asset.service.js +0 -18
  43. package/dist/api/content.interface.d.ts +0 -33
  44. package/dist/api/content.interface.js +0 -2
  45. package/dist/api/content.service.d.ts +0 -9
  46. package/dist/api/content.service.js +0 -22
  47. package/dist/api/data.interface.d.ts +0 -29
  48. package/dist/api/data.interface.js +0 -2
  49. package/dist/api/data.service.d.ts +0 -15
  50. package/dist/api/data.service.js +0 -50
  51. package/dist/api/endpoint.interface.d.ts +0 -18
  52. package/dist/api/endpoint.interface.js +0 -2
  53. package/dist/api/endpoint.service.d.ts +0 -7
  54. package/dist/api/endpoint.service.js +0 -14
  55. package/dist/api/http.service.d.ts +0 -29
  56. package/dist/api/http.service.js +0 -96
  57. package/dist/api/index.d.ts +0 -11
  58. package/dist/api/index.js +0 -15
  59. package/dist/api/mock/api.mock.d.ts +0 -102
  60. package/dist/api/mock/api.mock.js +0 -81
  61. package/dist/api/mock/asset.mock.service.d.ts +0 -9
  62. package/dist/api/mock/asset.mock.service.js +0 -18
  63. package/dist/api/mock/content.mock.service.d.ts +0 -9
  64. package/dist/api/mock/content.mock.service.js +0 -21
  65. package/dist/api/mock/data.mock.service.d.ts +0 -11
  66. package/dist/api/mock/data.mock.service.js +0 -53
  67. package/dist/api/mock/endpoint.mock.service.d.ts +0 -10
  68. package/dist/api/mock/endpoint.mock.service.js +0 -15
  69. package/dist/api/mock/index.d.ts +0 -7
  70. package/dist/api/mock/index.js +0 -10
  71. package/dist/api/mock/secret.mock.service.d.ts +0 -5
  72. package/dist/api/mock/secret.mock.service.js +0 -11
  73. package/dist/api/mock/task.mock.service.d.ts +0 -8
  74. package/dist/api/mock/task.mock.service.js +0 -16
  75. package/dist/api/mock/timeseries.mock.service.d.ts +0 -18
  76. package/dist/api/mock/timeseries.mock.service.js +0 -70
  77. package/dist/api/mock/user.mock.service.d.ts +0 -7
  78. package/dist/api/mock/user.mock.service.js +0 -12
  79. package/dist/api/secret.interface.d.ts +0 -9
  80. package/dist/api/secret.interface.js +0 -2
  81. package/dist/api/secret.service.d.ts +0 -6
  82. package/dist/api/secret.service.js +0 -10
  83. package/dist/api/sidriveiq.interface.d.ts +0 -104
  84. package/dist/api/sidriveiq.interface.js +0 -2
  85. package/dist/api/sidriveiq.service.d.ts +0 -31
  86. package/dist/api/sidriveiq.service.js +0 -97
  87. package/dist/api/task.interface.d.ts +0 -26
  88. package/dist/api/task.interface.js +0 -2
  89. package/dist/api/task.service.d.ts +0 -7
  90. package/dist/api/task.service.js +0 -13
  91. package/dist/api/timeseries.interface.d.ts +0 -51
  92. package/dist/api/timeseries.interface.js +0 -2
  93. package/dist/api/timeseries.service.d.ts +0 -17
  94. package/dist/api/timeseries.service.js +0 -38
  95. package/dist/api/user.interface.d.ts +0 -3
  96. package/dist/api/user.interface.js +0 -2
  97. package/dist/api/user.service.d.ts +0 -7
  98. package/dist/api/user.service.js +0 -21
@@ -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(_a, properties, propertiesClassType, whitelist = false) {
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 = Object.assign(Object.assign({}, this.metadata), context);
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 = (_b = this.app) === null || _b === void 0 ? void 0 : _b.api;
35
- this.metadata = Object.assign(Object.assign({}, metadata), { functionFqn: this.functionFqn });
36
- this.logger = new FlowLogger_1.FlowLogger(this.metadata, logger || undefined, (_c = this.app) === null || _c === void 0 ? void 0 : _c.publishEvent);
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
- var _a, _b;
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
- const event = new FlowEvent_1.FlowEvent(this.metadata, data, outputId, time);
48
- if (this.app) {
49
- this.app.emit(event);
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.plainToClass(classType, properties);
55
- const errors = class_validator_1.validateSync(props, { whitelist });
56
- if (errors && Array.isArray(errors) && errors.length > 0) {
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.logger.error(`Validation for property "${e.property}" failed:\n${JSON.stringify(e.constraints || {})}\nvalue: ${e.value}`);
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
- validateEventData(classType, event, whitelist = false) {
67
- return this.validateProperties(classType, event.getData(), whitelist);
68
- }
69
- interpolate(text, ...templateVariables) {
70
- var _a;
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
- for (const variables of templateVariables) {
75
- const result = string_interp_1.default(text, variables || {});
76
- if (result) {
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
- return text;
84
+ }
85
+ validateEventData(classType, event, whitelist = false) {
86
+ return this.validateProperties(classType, event.getData(), whitelist);
81
87
  }
82
88
  async callRpcFunction(functionName, ...args) {
83
- var _a, _b;
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 = async function (event) {
114
- const savedEmitOutput = this.emitOutput;
115
- this.emitOutput = (data = {}, outputId = 'default', time = new Date()) => {
116
- return savedEmitOutput.call(this, Object.assign(Object.assign({}, event.getData()), data), outputId, time);
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 = new RegExp('^([a-zA-Z][a-zA-Z0-9]*[.-])*[a-zA-Z][a-zA-Z0-9]*$');
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
  }
@@ -8,7 +8,13 @@ export declare class FlowEvent {
8
8
  getDataContentType: () => string;
9
9
  getDataschema: () => string;
10
10
  getId: () => string;
11
- getMetadata: () => any;
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' && data != null) {
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,
@@ -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) => Promise<void>);
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
  }
@@ -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
- publish(message, level) {
38
- var _a;
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
- (_a = this.publishEvent(event)) === null || _a === void 0 ? void 0 : _a.catch((err) => this.logger.error(err, this.metadata));
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
  }
@@ -3,5 +3,5 @@ export declare function FlowModule(metadata: {
3
3
  name: string;
4
4
  declarations: Array<ClassType<FlowElement>>;
5
5
  }): ClassDecorator;
6
- declare type ClassType<T> = new (...args: any[]) => T;
6
+ type ClassType<T> = new (...args: any[]) => T;
7
7
  export {};
@@ -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 fqnRegExp = new RegExp('^([a-zA-Z][a-zA-Z0-9]*[.-])*[a-zA-Z][a-zA-Z0-9]*$');
6
- if (!fqnRegExp.test(metadata.name)) {
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);
@@ -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 channel;
4
+ private readonly logger?;
5
+ private readonly channel;
4
6
  private openRequests;
5
- constructor(connection: AmqpConnectionManager);
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 uuid_1 = require("uuid");
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(connection) {
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 = uuid_1.v4();
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 (!connection) {
66
+ if (!amqpConnection) {
53
67
  throw new Error('currently no amqp connection available');
54
68
  }
55
- this.channel = connection.createChannel({
69
+ this.channel = amqpConnection.createChannel({
56
70
  json: true,
57
- setup: (channel) => Promise.all([
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() {
@@ -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.emitOutput(event.getData());
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;
@@ -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
- return true;
11
+ else {
12
+ return !args.constraints.every((prop) => !(0, class_validator_1.isDefined)(args.object[prop]));
13
+ }
12
14
  }
13
15
  defaultMessage(args) {
14
- return `${args.property} cannot exist alongside the following defined properties: ${this.getFailedConstraints(args).join(', ')}`;
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);
@@ -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 declare type ClassType<T> = new (...args: any[]) => T;
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 {};
@@ -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 './api';
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("./api"), exports);
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; } });