javonet-nodejs-sdk 2.6.13 → 2.6.14

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 (90) hide show
  1. package/dist/core/handler/ArraySetItemHandler.cjs +9 -8
  2. package/dist/core/handler/AsDtoHandler.cjs +36 -0
  3. package/dist/core/handler/AsKwargsHandler.cjs +1 -1
  4. package/dist/core/handler/DtoPropertyHandler.cjs +36 -0
  5. package/dist/core/handler/Handler.cjs +14 -9
  6. package/dist/core/handler/PassDelegateHandler.cjs +1 -1
  7. package/dist/core/handler/ProjectResultAsDtoHandler.cjs +66 -0
  8. package/dist/core/handler/SetInstanceFieldHandler.cjs +1 -1
  9. package/dist/core/handler/SetStaticFieldHandler.cjs +6 -6
  10. package/dist/core/interpreter/Interpreter.cjs +14 -2
  11. package/dist/core/protocol/CommandDeserializer.cjs +8 -0
  12. package/dist/core/protocol/TypeDeserializer.cjs +4 -0
  13. package/dist/core/protocol/TypeSerializer.cjs +10 -5
  14. package/dist/core/webSocketClient/WebSocketClient.cjs +23 -5
  15. package/dist/core/webSocketClient/WebSocketClientBrowser.cjs +23 -5
  16. package/dist/plugins/PluginImplementationRegistry.cjs +214 -0
  17. package/dist/plugins/PluginPayloadBuilder.cjs +76 -0
  18. package/dist/plugins/PluginRegistry.cjs +255 -0
  19. package/dist/plugins/index.cjs +51 -0
  20. package/dist/plugins/interfaces/ICommunityPlugin.cjs +44 -0
  21. package/dist/plugins/interfaces/ICommunityReceivingPlugin.cjs +62 -0
  22. package/dist/plugins/interfaces/ICommunitySendingPlugin.cjs +59 -0
  23. package/dist/plugins/settings/BasePluginSettings.cjs +67 -0
  24. package/dist/plugins/settings/JwtGraftocodePluginSettings.cjs +40 -0
  25. package/dist/sdk/InvocationContext.cjs +133 -12
  26. package/dist/sdk/RuntimeContext.cjs +27 -9
  27. package/dist/sdk/configuration/configResolvers/ConfigResolver.cjs +7 -6
  28. package/dist/sdk/tools/DtoHelper.cjs +100 -0
  29. package/dist/types/core/handler/ArraySetItemHandler.d.ts +1 -1
  30. package/dist/types/core/handler/AsDtoHandler.d.ts +7 -0
  31. package/dist/types/core/handler/AsKwargsHandler.d.ts +1 -1
  32. package/dist/types/core/handler/DtoPropertyHandler.d.ts +7 -0
  33. package/dist/types/core/handler/ProjectResultAsDtoHandler.d.ts +9 -0
  34. package/dist/types/core/handler/SetInstanceFieldHandler.d.ts +1 -1
  35. package/dist/types/core/handler/SetStaticFieldHandler.d.ts +1 -1
  36. package/dist/types/core/interpreter/Interpreter.d.ts +3 -3
  37. package/dist/types/core/protocol/CommandDeserializer.d.ts +1 -0
  38. package/dist/types/core/protocol/TypeDeserializer.d.ts +1 -0
  39. package/dist/types/core/protocol/TypeSerializer.d.ts +1 -0
  40. package/dist/types/plugins/PluginImplementationRegistry.d.ts +121 -0
  41. package/dist/types/plugins/PluginPayloadBuilder.d.ts +32 -0
  42. package/dist/types/plugins/PluginRegistry.d.ts +157 -0
  43. package/dist/types/plugins/index.d.ts +8 -0
  44. package/dist/types/plugins/interfaces/ICommunityPlugin.d.ts +14 -0
  45. package/dist/types/plugins/interfaces/ICommunityReceivingPlugin.d.ts +50 -0
  46. package/dist/types/plugins/interfaces/ICommunitySendingPlugin.d.ts +27 -0
  47. package/dist/types/plugins/settings/BasePluginSettings.d.ts +45 -0
  48. package/dist/types/plugins/settings/JwtGraftocodePluginSettings.d.ts +32 -0
  49. package/dist/types/sdk/InvocationContext.d.ts +20 -2
  50. package/dist/types/sdk/RuntimeContext.d.ts +6 -0
  51. package/dist/types/sdk/configuration/configResolvers/ConfigResolver.d.ts +3 -6
  52. package/dist/types/sdk/tools/DtoHelper.d.ts +35 -0
  53. package/dist/types/utils/Command.d.ts +5 -0
  54. package/dist/types/utils/CommandType.d.ts +3 -0
  55. package/dist/types/utils/Type.d.ts +2 -1
  56. package/dist/utils/Command.cjs +40 -0
  57. package/dist/utils/CommandType.cjs +4 -1
  58. package/dist/utils/Type.cjs +2 -1
  59. package/lib/core/handler/ArraySetItemHandler.js +11 -10
  60. package/lib/core/handler/AsDtoHandler.js +11 -0
  61. package/lib/core/handler/AsKwargsHandler.js +1 -1
  62. package/lib/core/handler/DtoPropertyHandler.js +11 -0
  63. package/lib/core/handler/Handler.js +16 -7
  64. package/lib/core/handler/PassDelegateHandler.js +2 -1
  65. package/lib/core/handler/ProjectResultAsDtoHandler.js +47 -0
  66. package/lib/core/handler/SetInstanceFieldHandler.js +1 -1
  67. package/lib/core/handler/SetStaticFieldHandler.js +6 -6
  68. package/lib/core/interpreter/Interpreter.js +18 -4
  69. package/lib/core/protocol/CommandDeserializer.js +9 -0
  70. package/lib/core/protocol/TypeDeserializer.js +5 -0
  71. package/lib/core/protocol/TypeSerializer.js +11 -8
  72. package/lib/core/webSocketClient/WebSocketClient.js +30 -5
  73. package/lib/core/webSocketClient/WebSocketClientBrowser.js +29 -5
  74. package/lib/plugins/PluginImplementationRegistry.js +231 -0
  75. package/lib/plugins/PluginPayloadBuilder.js +60 -0
  76. package/lib/plugins/PluginRegistry.js +295 -0
  77. package/lib/plugins/index.js +29 -0
  78. package/lib/plugins/interfaces/ICommunityPlugin.js +25 -0
  79. package/lib/plugins/interfaces/ICommunityReceivingPlugin.js +57 -0
  80. package/lib/plugins/interfaces/ICommunitySendingPlugin.js +42 -0
  81. package/lib/plugins/settings/BasePluginSettings.js +79 -0
  82. package/lib/plugins/settings/JwtGraftocodePluginSettings.js +43 -0
  83. package/lib/sdk/InvocationContext.js +149 -14
  84. package/lib/sdk/RuntimeContext.js +33 -9
  85. package/lib/sdk/configuration/configResolvers/ConfigResolver.js +14 -8
  86. package/lib/sdk/tools/DtoHelper.js +90 -0
  87. package/lib/utils/Command.js +47 -0
  88. package/lib/utils/CommandType.js +3 -0
  89. package/lib/utils/Type.js +2 -1
  90. package/package.json +5 -1
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Represents a sending plugin that executes before commands are sent to the target runtime.
3
+ * Sending plugins can add authentication tokens, modify payloads, or inject custom data.
4
+ *
5
+ * @interface ICommunitySendingPlugin
6
+ * @extends {ICommunityPlugin}
7
+ */
8
+ export class ICommunitySendingPlugin extends ICommunityPlugin {
9
+ /**
10
+ * Executes the plugin and returns the result.
11
+ * This method is called before sending commands to the target runtime.
12
+ * The returned object will be serialized and included in the command payload.
13
+ *
14
+ * @abstract
15
+ * @returns {object} The result of plugin execution as an object.
16
+ * @throws {Error} If not implemented by derived class
17
+ *
18
+ * @example
19
+ * class JwtPlugin extends ICommunitySendingPlugin {
20
+ * execute() {
21
+ * return { token: 'abc123', timestamp: Date.now() }
22
+ * }
23
+ * }
24
+ */
25
+ execute(): object;
26
+ }
27
+ import { ICommunityPlugin } from './ICommunityPlugin.js';
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Represents the base configuration model shared by all plugins.
3
+ * This class contains common metadata such as plugin ID, path, and language type.
4
+ *
5
+ * @abstract
6
+ * @class BasePluginSettings
7
+ */
8
+ export class BasePluginSettings {
9
+ /**
10
+ * A unique identifier assigned by the developer using a predefined plugin.
11
+ * Used to reference or distinguish plugin instances during registration or execution.
12
+ * @type {string}
13
+ */
14
+ pluginId: string;
15
+ /**
16
+ * The file system path to the plugin code.
17
+ * This may point to a DLL (for .NET) or other file (for external languages).
18
+ * Should remain empty if the plugin is executed directly from a referenced package.
19
+ * @type {string}
20
+ */
21
+ pluginPath: string;
22
+ /**
23
+ * Defines the language or technology in which the plugin is implemented.
24
+ * Used to determine how the plugin should be loaded or invoked.
25
+ * @type {PluginLangType}
26
+ */
27
+ pluginLangType: PluginLangType;
28
+ }
29
+ /**
30
+ * Specifies the programming language or runtime environment used to implement a plugin.
31
+ */
32
+ export type PluginLangType = number;
33
+ export namespace PluginLangType {
34
+ let Clr: number;
35
+ let Go: number;
36
+ let Jvm: number;
37
+ let Netcore: number;
38
+ let Perl: number;
39
+ let Python: number;
40
+ let Ruby: number;
41
+ let Nodejs: number;
42
+ let Cpp: number;
43
+ let Php: number;
44
+ let Python27: number;
45
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Represents configuration settings specific to JWT plugins,
3
+ * including user identity and authorization logic class information.
4
+ * Inherits shared properties from BasePluginSettings.
5
+ *
6
+ * @class JwtGraftocodePluginSettings
7
+ * @extends {BasePluginSettings}
8
+ */
9
+ export class JwtGraftocodePluginSettings extends BasePluginSettings {
10
+ /**
11
+ * Username for JWT token generation.
12
+ * @type {string}
13
+ */
14
+ username: string;
15
+ /**
16
+ * Secret key used for JWT token signing and validation.
17
+ * @type {string}
18
+ */
19
+ secretKey: string;
20
+ /**
21
+ * Whether to use attributes for authorization checks.
22
+ * @type {boolean}
23
+ */
24
+ useAttributes: boolean;
25
+ /**
26
+ * JWT authorization class implementation.
27
+ * In Node.js, this is typically a class constructor/function rather than a Type.
28
+ * @type {Function | null}
29
+ */
30
+ jwtAuthorizeClass: Function | null;
31
+ }
32
+ import { BasePluginSettings } from './BasePluginSettings.js';
@@ -11,12 +11,14 @@ export class InvocationContext {
11
11
  static _invocationContexts: Map<any, any>;
12
12
  /**
13
13
  *
14
+ * @param {string} runtimeContextId
14
15
  * @param {RuntimeNameType} runtimeName
15
16
  * @param {IConnectionData} connectionData
16
- * @param {Command} command
17
+ * @param {Command | null} command
17
18
  * @param {boolean} isExecuted
19
+ * @param {boolean} isDto
18
20
  */
19
- constructor(runtimeName: RuntimeNameType, connectionData: IConnectionData, command: Command, isExecuted?: boolean);
21
+ constructor(runtimeContextId: string, runtimeName: RuntimeNameType, connectionData: IConnectionData, command: Command | null, isExecuted?: boolean, isDto?: boolean);
20
22
  /**
21
23
  * @returns {string} guid of this InvocationContext
22
24
  */
@@ -191,6 +193,22 @@ export class InvocationContext {
191
193
  * @method
192
194
  */
193
195
  getInstanceMethodAsDelegate(methodName: string, ...args: any[]): InvocationContext;
196
+ /**
197
+ * Returns a new InvocationContext that acts as a DTO (Data Transfer Object).
198
+ * When actAsDto is true, field get/set operate on local state without remote calls.
199
+ * @param {boolean} actAsDto - Whether to treat this context as a DTO.
200
+ * @returns {InvocationContext} A new InvocationContext with the DTO flag set.
201
+ * @method
202
+ */
203
+ asDto(actAsDto?: boolean): InvocationContext;
204
+ /**
205
+ * Projects the result as a DTO with the specified property names.
206
+ * When propertiesNames is a single empty string, returns this context unchanged.
207
+ * @param {...string} propertiesNames - Names of properties to include in the DTO.
208
+ * @returns {InvocationContext} A new InvocationContext that will materialize as a DTO.
209
+ * @method
210
+ */
211
+ projectResultAsDto(...propertiesNames: string[]): InvocationContext;
194
212
  /**
195
213
  * Retrieves the type of the object from the target runtime.
196
214
  * @returns {Promise<string>} The type of the object.
@@ -38,6 +38,12 @@ export class RuntimeContext {
38
38
  _isExecuted: boolean;
39
39
  runtimeName: import("../types.d.ts").RuntimeName;
40
40
  connectionData: import("../utils/connectionData/IConnectionData.js").IConnectionData;
41
+ /**
42
+ * Gets the unique runtime context ID for this instance.
43
+ * This ID is used to associate plugins with specific runtime contexts.
44
+ * @returns {string} The runtime context ID (GUID/UUID string)
45
+ */
46
+ get runtimeContextId(): string;
41
47
  /**
42
48
  * Executes the current command. The initial state of RuntimeContext is non-materialized,
43
49
  * wrapping either a single command or a chain of recursively nested commands.
@@ -6,12 +6,9 @@ export class ConfigResolver {
6
6
  */
7
7
  static tryParseRuntime(runtime: string): any;
8
8
  /**
9
- * Build appropriate connection data object from a host string.
10
- * - empty / null => InMemoryConnectionData
11
- * - "inmemory" or "in-memory" => InMemoryConnectionData
12
- * - ws:// or wss:// => WsConnectionData(fullAddress)
13
- * - tcp://... => parsed by parseTcp
14
- * - host:port or host:port/... => TcpConnectionData(host, port) if valid, otherwise InMemoryConnectionData
9
+ * Builds connection data from the host string from config (JSON, YAML, or connection string).
10
+ * Recognized formats: empty (in-memory), "inmemory"/"in-memory", ws://..., wss://..., tcp://host:port, host:port.
11
+ * When the value is missing, invalid, or unparseable, falls back to InMemoryConnectionData and logs the reason.
15
12
  * @param {string} hostValue
16
13
  * @returns {InMemoryConnectionData|WsConnectionData|TcpConnectionData}
17
14
  */
@@ -0,0 +1,35 @@
1
+ export class DtoHelper {
2
+ /**
3
+ * Attempts to retrieve a DTO field value by field name from a command chain.
4
+ *
5
+ * @param {Command | null} command - The command to search through.
6
+ * @param {string} fieldName - The name of the field to retrieve.
7
+ * @returns {any}
8
+ */
9
+ static tryGetDtoFieldValue(command: Command | null, fieldName: string): any;
10
+ /**
11
+ * Attempts to extract the field name from a SetInstanceField command.
12
+ * @param {Command} command
13
+ * @returns {boolean}
14
+ */
15
+ static _tryGetDtoFieldName(command: Command): boolean;
16
+ /**
17
+ * Extracts the field name from a SetInstanceField command.
18
+ * @param {Command} command
19
+ * @returns {string}
20
+ */
21
+ static _getDtoFieldName(command: Command): string;
22
+ /**
23
+ * Attempts to extract the field value from a SetInstanceField command.
24
+ * @param {Command} command
25
+ * @returns {any}
26
+ */
27
+ static _tryGetDtoFieldValueFromCommand(command: Command): any;
28
+ /**
29
+ * Attempts to extract a value from a payload item, handling Value command types.
30
+ * @param {any} payloadItem
31
+ * @returns {any}
32
+ */
33
+ static _tryGetPayloadValue(payloadItem: any): any;
34
+ }
35
+ import { Command } from '../../utils/Command.js';
@@ -42,5 +42,10 @@ export class Command {
42
42
  * @returns {Command}
43
43
  */
44
44
  prependArgToPayload(current_command: Command | null): Command;
45
+ /**
46
+ * Returns string representation of the Command instance for debugging purposes.
47
+ * @returns {string}
48
+ */
49
+ toString(): string;
45
50
  }
46
51
  export type RuntimeName = import("../types.d.ts").RuntimeName;
@@ -49,4 +49,7 @@ export namespace CommandType {
49
49
  let GetGlobalField: 47;
50
50
  let RegisterForUpdate: 48;
51
51
  let ValueForUpdate: 49;
52
+ let AsDto: 50;
53
+ let DtoProperty: 51;
54
+ let ProjectResultAsDto: 52;
52
55
  }
@@ -11,5 +11,6 @@ export namespace Type {
11
11
  let JAVONET_UNSIGNED_LONG_LONG: 9;
12
12
  let JAVONET_UNSIGNED_INTEGER: 10;
13
13
  let JAVONET_NULL: 11;
14
- let JAVONET_VOID: 12;
14
+ let JAVONET_UNDEFINED: 12;
15
+ let JAVONET_VOID: 13;
15
16
  }
@@ -80,6 +80,46 @@ class Command {
80
80
  return new Command(this.runtimeName, this.commandType, [current_command].concat(this.payload));
81
81
  }
82
82
  }
83
+ /**
84
+ * Returns string representation of the Command instance for debugging purposes.
85
+ * @returns {string}
86
+ */
87
+ toString() {
88
+ try {
89
+ let result = " { ";
90
+ result += `RuntimeName: ${this.runtimeName}, `;
91
+ result += `CommandType: ${this.commandType}, `;
92
+ result += "Payload: \n";
93
+ result += " [";
94
+ const payload = this.payload || [];
95
+ const len = payload.length;
96
+ if (len > 0) {
97
+ result += "\n";
98
+ for (let i = 0; i < len; i++) {
99
+ const item = payload[i];
100
+ let itemStr;
101
+ if (item === null || item === void 0) {
102
+ itemStr = "null";
103
+ } else if (typeof item === "string") {
104
+ itemStr = ` "${item}"`;
105
+ } else if (item instanceof Command) {
106
+ itemStr = item.toString().replace(/\n/g, "\n ");
107
+ } else {
108
+ itemStr = " " + String(item);
109
+ }
110
+ result += " " + itemStr;
111
+ result += i < len - 1 ? ",\n" : "\n";
112
+ }
113
+ result += " ]\n";
114
+ } else {
115
+ result += " ]\n";
116
+ }
117
+ result += " }";
118
+ return result;
119
+ } catch (ex) {
120
+ return "Error while converting command to string:" + ex;
121
+ }
122
+ }
83
123
  }
84
124
  // Annotate the CommonJS export names for ESM import in node:
85
125
  0 && (module.exports = {
@@ -73,7 +73,10 @@ const CommandType = (
73
73
  GetResultType: 46,
74
74
  GetGlobalField: 47,
75
75
  RegisterForUpdate: 48,
76
- ValueForUpdate: 49
76
+ ValueForUpdate: 49,
77
+ AsDto: 50,
78
+ DtoProperty: 51,
79
+ ProjectResultAsDto: 52
77
80
  }
78
81
  );
79
82
  // Annotate the CommonJS export names for ESM import in node:
@@ -36,7 +36,8 @@ const Type = (
36
36
  JAVONET_UNSIGNED_LONG_LONG: 9,
37
37
  JAVONET_UNSIGNED_INTEGER: 10,
38
38
  JAVONET_NULL: 11,
39
- JAVONET_VOID: 12
39
+ JAVONET_UNDEFINED: 12,
40
+ JAVONET_VOID: 13
40
41
  }
41
42
  );
42
43
  // Annotate the CommonJS export names for ESM import in node:
@@ -21,29 +21,30 @@ class ArraySetItemHandler extends AbstractHandler {
21
21
  throw new Error('Array Set Item parameters mismatch')
22
22
  }
23
23
 
24
- let array = command.payload[0]
24
+ let data = command.payload[0]
25
+ let indexes_from_payload = command.payload[1]
25
26
  let value = command.payload[2]
26
27
 
27
28
  /** @type {number[]} */
28
29
  let indexes
29
- if (Array.isArray(command.payload[1])) {
30
- indexes = command.payload[1]
30
+ if (Array.isArray(indexes_from_payload)) {
31
+ indexes = indexes_from_payload
31
32
  } else {
32
- indexes = [command.payload[1]]
33
+ indexes = [indexes_from_payload]
33
34
  }
34
35
 
35
36
  if (indexes.length === 1) {
36
- // one-dimensional array
37
- array[indexes[0]] = value
37
+ // one-dimensional data
38
+ data[indexes[0]] = value
38
39
  } else {
39
- // multi-dimensional array
40
+ // multi-dimensional data
40
41
  for (let i = 0; i < indexes.length - 1; i++) {
41
- array = array[indexes[i]]
42
+ data = data[indexes[i]]
42
43
  }
43
- array[indexes[indexes.length - 1]] = value
44
+ data[indexes[indexes.length - 1]] = value
44
45
  }
45
46
 
46
- return 0
47
+ return data
47
48
  } catch (error) {
48
49
  throw this.process_stack_trace(error, this.constructor.name)
49
50
  }
@@ -0,0 +1,11 @@
1
+ // @ts-check
2
+ import { AbstractHandler } from './AbstractHandler.js'
3
+
4
+ export class AsDtoHandler extends AbstractHandler {
5
+ /**
6
+ * @param {any} command
7
+ */
8
+ process(command) {
9
+ throw new Error(`${this.constructor.name} is not implemented in Node.js`)
10
+ }
11
+ }
@@ -5,7 +5,7 @@ export class AsKwargsHandler extends AbstractHandler {
5
5
  /**
6
6
  * @param {any} command
7
7
  */
8
- handleCommand(command) {
8
+ process(command) {
9
9
  throw new Error(`${this.constructor.name} is not implemented in Node.js`)
10
10
  }
11
11
  }
@@ -0,0 +1,11 @@
1
+ // @ts-check
2
+ import { AbstractHandler } from './AbstractHandler.js'
3
+
4
+ export class DtoPropertyHandler extends AbstractHandler {
5
+ /**
6
+ * @param {any} command
7
+ */
8
+ process(command) {
9
+ throw new Error(`${this.constructor.name} is not implemented in Node.js`)
10
+ }
11
+ }
@@ -57,6 +57,9 @@ import { GetResultTypeHandler } from './GetResultTypeHandler.js'
57
57
  import { GetGlobalFieldHandler } from './GetGlobalFieldHandler.js'
58
58
  import { RegisterForUpdateHandler } from './RegisterForUpdateHandler.js'
59
59
  import { ValueForUpdateHandler } from './ValueForUpdateHandler.js'
60
+ import { AsDtoHandler } from './AsDtoHandler.js'
61
+ import { DtoPropertyHandler } from './DtoPropertyHandler.js'
62
+ import { ProjectResultAsDtoHandler } from './ProjectResultAsDtoHandler.js'
60
63
 
61
64
  /**
62
65
  * @typedef {import('../../types.d.ts').RuntimeName} RuntimeName
@@ -116,6 +119,9 @@ const handlers = {
116
119
  [CommandType.GetGlobalField]: new GetGlobalFieldHandler(),
117
120
  [CommandType.RegisterForUpdate]: new RegisterForUpdateHandler(),
118
121
  [CommandType.ValueForUpdate]: new ValueForUpdateHandler(),
122
+ [CommandType.AsDto]: new AsDtoHandler(),
123
+ [CommandType.DtoProperty]: new DtoPropertyHandler(),
124
+ [CommandType.ProjectResultAsDto]: new ProjectResultAsDtoHandler(),
119
125
  }
120
126
 
121
127
  class Handler {
@@ -146,7 +152,7 @@ class Handler {
146
152
  */
147
153
  static handleCommand(command) {
148
154
  Handler._initialize()
149
-
155
+
150
156
  try {
151
157
  if (command.commandType === CommandType.RetrieveArray) {
152
158
  /** @type {any} */
@@ -156,6 +162,11 @@ class Handler {
156
162
 
157
163
  /** @type {any} */
158
164
  const response = handlers[command.commandType].handleCommand(command)
165
+
166
+ if (command.commandType === CommandType.ProjectResultAsDto) {
167
+ return Command.createArrayResponse(response, command.runtimeName)
168
+ }
169
+
159
170
  return Handler.parseCommand(response, command.runtimeName)
160
171
  } catch (e) {
161
172
  return Handler.resolveException(e, command)
@@ -200,12 +211,10 @@ class Handler {
200
211
  for (const [contextKey, instance] of invocationContexts.entries()) {
201
212
  const instanceGuid = refCache.cacheReference(instance)
202
213
 
203
- const updateContextCommand = new Command(
204
- runtimeName,
205
- CommandType.ValueForUpdate,
206
- [contextKey.toString(),
207
- instanceGuid]
208
- )
214
+ const updateContextCommand = new Command(runtimeName, CommandType.ValueForUpdate, [
215
+ contextKey.toString(),
216
+ instanceGuid,
217
+ ])
209
218
 
210
219
  if (typeof responseCommand.addArgToPayload === 'function') {
211
220
  responseCommand = responseCommand.addArgToPayload(updateContextCommand)
@@ -112,7 +112,8 @@ class PassDelegateHandler extends AbstractHandler {
112
112
  */
113
113
  async createExecuteCall(command) {
114
114
  const { Interpreter } = await import('../interpreter/Interpreter.js')
115
- return Interpreter.execute(command, new InMemoryConnectionData())
115
+ // TODO: get runtimeContextId from command
116
+ return Interpreter.execute('runtimeContextId', command, new InMemoryConnectionData())
116
117
  }
117
118
 
118
119
  /**
@@ -0,0 +1,47 @@
1
+ // @ts-check
2
+ import { AbstractHandler } from './AbstractHandler.js'
3
+ import { GetInstanceFieldHandler } from './GetInstanceFieldHandler.js'
4
+ import { Command } from '../../utils/Command.js'
5
+ import { CommandType } from '../../utils/CommandType.js'
6
+
7
+ export class ProjectResultAsDtoHandler extends AbstractHandler {
8
+ constructor() {
9
+ super()
10
+ this.requiredParametersCount = 1
11
+ }
12
+
13
+ /**
14
+ * @param {Command} command
15
+ */
16
+ process(command) {
17
+ if (command.payload.length < this.requiredParametersCount) {
18
+ throw new Error(`${this.constructor.name} parameters mismatch`)
19
+ }
20
+
21
+ const instance = command.payload[0]
22
+ const responseArray = new Array(command.payload.length + 1)
23
+ responseArray[0] = instance
24
+
25
+ let typeName = 'Object'
26
+ if (instance !== null && instance !== undefined) {
27
+ typeName = instance.constructor ? instance.constructor.name : 'Object'
28
+ }
29
+
30
+ responseArray[1] = new Command(command.runtimeName, CommandType.GetType, [typeName])
31
+
32
+ const getInstanceFieldHandler = new GetInstanceFieldHandler()
33
+ for (let i = 1; i < command.payload.length; i++) {
34
+ const propertyName = command.payload[i]
35
+ const propertyValue = getInstanceFieldHandler.process(
36
+ new Command(command.runtimeName, CommandType.GetInstanceField, [instance, propertyName])
37
+ )
38
+ responseArray[i + 1] = new Command(
39
+ command.runtimeName,
40
+ CommandType.DtoProperty,
41
+ [propertyName, propertyValue]
42
+ )
43
+ }
44
+
45
+ return responseArray
46
+ }
47
+ }
@@ -32,7 +32,7 @@ class SetInstanceFieldHandler extends AbstractHandler {
32
32
  throw new Error(message)
33
33
  }
34
34
  instance[field] = value
35
- return 0
35
+ return instance
36
36
  } catch (error) {
37
37
  throw this.process_stack_trace(error, this.constructor.name)
38
38
  }
@@ -21,17 +21,17 @@ class SetStaticFieldHandler extends AbstractHandler {
21
21
  throw new Error('Set static field parameters mismatch')
22
22
  }
23
23
  const { payload } = command
24
- let [obj, field, value] = payload
25
- if (typeof obj[field] === 'undefined') {
26
- let fields = Object.keys(obj)
27
- let message = `Field ${field} not found in class ${obj.constructor.name}. Available fields:\n`
24
+ let [type, field, value] = payload
25
+ if (typeof type[field] === 'undefined') {
26
+ let fields = Object.keys(type)
27
+ let message = `Field ${field} not found in class ${type.constructor.name}. Available fields:\n`
28
28
  fields.forEach((fieldIter) => {
29
29
  message += `${fieldIter}\n`
30
30
  })
31
31
  throw new Error(message)
32
32
  }
33
- obj[field] = value
34
- return 0
33
+ type[field] = value
34
+ return type
35
35
  } catch (error) {
36
36
  throw this.process_stack_trace(error, this.constructor.name)
37
37
  }
@@ -7,11 +7,14 @@ import { CommandSerializer } from '../protocol/CommandSerializer.js'
7
7
  import { TransmitterWebsocketBrowser } from '../transmitter/TransmitterWebsocketBrowser.js'
8
8
  import { TransmitterWebsocket } from '../transmitter/TransmitterWebsocket.js'
9
9
  import { Handler } from '../handler/Handler.js'
10
-
10
+ import { PluginRegistry } from '../../plugins/PluginRegistry.js'
11
+ import { PluginPayloadBuilder } from '../../plugins/PluginPayloadBuilder.js'
12
+ import { Command } from '../../utils/Command.js'
13
+ import { CommandType } from '../../utils/CommandType.js'
14
+
11
15
  /**
12
16
  * @typedef {import('../../utils/connectionData/IConnectionData.js').IConnectionData} IConnectionData
13
17
  * @typedef {typeof import('../../types.d.ts').RuntimeName} RuntimeNameType
14
- * @typedef {import('../../utils/Command.js').Command} Command
15
18
  */
16
19
 
17
20
  /** @type {typeof import('../receiver/Receiver.js').Receiver} */
@@ -26,13 +29,24 @@ const requireDynamic = getRequire(import.meta.url)
26
29
  export class Interpreter {
27
30
 
28
31
  /**
29
- *
32
+ * @param {string} runtimeContextId
30
33
  * @param {Command} command
31
34
  * @param {IConnectionData} connectionData
32
35
  * @returns {Promise<Command>}
33
36
  */
34
- static async execute(command, connectionData) {
37
+ static async execute(runtimeContextId, command, connectionData) {
35
38
  try {
39
+ if (PluginRegistry.arePluginsRegisteredForRuntime(runtimeContextId)) {
40
+ const serializedPlugins = PluginPayloadBuilder.buildPluginsPayload(runtimeContextId)
41
+
42
+ // Wrap the command with PluginWrapper
43
+ command = new Command(
44
+ command.runtimeName,
45
+ CommandType.PluginWrapper,
46
+ [serializedPlugins, command]
47
+ )
48
+ }
49
+
36
50
  let messageByteArray = CommandSerializer.serialize(command, connectionData)
37
51
 
38
52
  if (!(messageByteArray instanceof Uint8Array)) {
@@ -60,6 +60,8 @@ export class CommandDeserializer {
60
60
  return this.readUInt()
61
61
  case 'JAVONET_NULL':
62
62
  return this.readNull()
63
+ case 'JAVONET_UNDEFINED':
64
+ return this.readUndefined()
63
65
  default:
64
66
  throw 'Unknown type - not supported in JavaScript'
65
67
  }
@@ -186,4 +188,11 @@ export class CommandDeserializer {
186
188
  this.position += size
187
189
  return TypeDeserializer.deserializeNull()
188
190
  }
191
+
192
+ readUndefined() {
193
+ const size = 1
194
+ this.position += 2
195
+ this.position += size
196
+ return TypeDeserializer.deserializeUndefined()
197
+ }
189
198
  }
@@ -114,4 +114,9 @@ export class TypeDeserializer {
114
114
  static deserializeNull(encodedNull = null) {
115
115
  return null
116
116
  }
117
+
118
+ // eslint-disable-next-line no-unused-vars
119
+ static deserializeUndefined(encodedUndefined = null) {
120
+ return undefined
121
+ }
117
122
  }
@@ -15,6 +15,9 @@ class TypeSerializer {
15
15
  if (payload_item === null) {
16
16
  return TypeSerializer.serializeNull()
17
17
  }
18
+ if (payload_item === undefined) {
19
+ return TypeSerializer.serializeUndefined()
20
+ }
18
21
  if (payload_item instanceof Command) {
19
22
  return TypeSerializer.serializeCommand(payload_item)
20
23
  } else if (typeof payload_item === 'number') {
@@ -36,14 +39,6 @@ class TypeSerializer {
36
39
  payload_item
37
40
  throw new CustomError(message, 'JAVONET_PROMISE')
38
41
  }
39
- if (payload_item === undefined) {
40
- throw Error(
41
- 'Unsupported payload item type: ' +
42
- typeof payload_item +
43
- ' for payload item: ' +
44
- payload_item
45
- )
46
- }
47
42
  throw Error(
48
43
  'Unsupported payload item type: ' +
49
44
  (payload_item?.constructor?.name || typeof payload_item) +
@@ -185,6 +180,14 @@ class TypeSerializer {
185
180
  return buffer
186
181
  }
187
182
 
183
+ static serializeUndefined() {
184
+ const buffer = Buffer.alloc(3)
185
+ buffer.writeUInt8(Type.JAVONET_UNDEFINED, 0)
186
+ buffer.writeUInt8(1, 1)
187
+ buffer.writeUInt8(0, 2)
188
+ return buffer
189
+ }
190
+
188
191
  /**
189
192
  * @param {number} int_value
190
193
  */