@tdxvolt/volt-client-grpc 0.18.2 → 0.18.4

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 (29) hide show
  1. package/lib/index.cjs +3214 -186
  2. package/package.json +6 -3
  3. package/scripts/generate-proto-assets.js +71 -0
  4. package/src/constants.js +2 -1
  5. package/src/grpc-call.js +7 -3
  6. package/src/proto-package-definition.js +183 -0
  7. package/src/proto-utils.js +41 -111
  8. package/src/volt-client-internal.js +5 -30
  9. package/src/volt-client.js +0 -57
  10. package/src/volt-proto-literals.js +2985 -0
  11. package/protobuf/README.md +0 -4
  12. package/protobuf/tdx/volt_api/data/v1/sqlite.proto +0 -43
  13. package/protobuf/tdx/volt_api/data/v1/sqlite_database_api.proto +0 -153
  14. package/protobuf/tdx/volt_api/data/v1/sqlite_server_api.proto +0 -50
  15. package/protobuf/tdx/volt_api/relay/v1/proxy_api.proto +0 -9
  16. package/protobuf/tdx/volt_api/relay/v1/relay_api.proto +0 -78
  17. package/protobuf/tdx/volt_api/sync/v1/sync.proto +0 -57
  18. package/protobuf/tdx/volt_api/volt/v1/discovery_api.proto +0 -35
  19. package/protobuf/tdx/volt_api/volt/v1/file.proto +0 -17
  20. package/protobuf/tdx/volt_api/volt/v1/file_api.proto +0 -165
  21. package/protobuf/tdx/volt_api/volt/v1/remote.proto +0 -93
  22. package/protobuf/tdx/volt_api/volt/v1/spark_api.proto +0 -121
  23. package/protobuf/tdx/volt_api/volt/v1/ssi.proto +0 -66
  24. package/protobuf/tdx/volt_api/volt/v1/ssi_api.proto +0 -214
  25. package/protobuf/tdx/volt_api/volt/v1/status.proto +0 -15
  26. package/protobuf/tdx/volt_api/volt/v1/terminal_api.proto +0 -42
  27. package/protobuf/tdx/volt_api/volt/v1/volt.proto +0 -666
  28. package/protobuf/tdx/volt_api/volt/v1/volt_api.proto +0 -1082
  29. package/protobuf/tdx/volt_api/volt/v1/wire_api.proto +0 -56
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.18.2",
6
+ "version": "0.18.4",
7
7
  "description": "tdx Volt library for nodejs clients",
8
8
  "type": "module",
9
9
  "exports": {
@@ -16,9 +16,10 @@
16
16
  "files": [
17
17
  "lib",
18
18
  "src",
19
- "protobuf"
19
+ "scripts"
20
20
  ],
21
21
  "scripts": {
22
+ "prebuild": "node ./scripts/generate-proto-assets.js",
22
23
  "build": "rollup -c",
23
24
  "dev": "rollup -c -w",
24
25
  "prepare": "npm run build"
@@ -36,7 +37,7 @@
36
37
  "author": "toby.ealden@gmail.com",
37
38
  "license": "ISC",
38
39
  "dependencies": {
39
- "@grpc/proto-loader": "^0.6.4",
40
+ "@grpc/proto-loader": "^0.7.13",
40
41
  "@tdxvolt/volt-client-web": "^0.18.1",
41
42
  "bent": "^7.3.12",
42
43
  "builtin-modules": "^3.3.0",
@@ -44,6 +45,8 @@
44
45
  "ip": "^1.1.5",
45
46
  "jsonwebtoken": "^8.5.1",
46
47
  "lodash": "^4.17.15",
48
+ "lodash.camelcase": "^4.3.0",
49
+ "protobufjs": "^7.4.0",
47
50
  "uuid": "^8.1.0"
48
51
  }
49
52
  }
@@ -0,0 +1,71 @@
1
+ // Recursively load all `.proto` files in the `protobuf` directory.
2
+ //
3
+
4
+ import { readdirSync, statSync, readFileSync, writeFileSync } from "fs";
5
+ import { dirname, join } from "path";
6
+ import { fileURLToPath } from "url";
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+
10
+ const protoFolder = "../../../../tdxvolt-core/src/volt_api";
11
+ const folder = join(__dirname, protoFolder);
12
+
13
+ // Verify that the proto folder exists.
14
+ try {
15
+ statSync(folder);
16
+ } catch (e) {
17
+ console.error(`\nThe proto folder '${folder}' does not exist.`);
18
+ console.error(
19
+ `\nTo build this package, you must clone the https://github.com/tdxvolt/tdxvolt-core repository such that the folder structure resembles the following:`
20
+ );
21
+ console.error(`\ntdxvolt`);
22
+ console.error(` └── tdxvolt-core`);
23
+ console.error(` └── tdxvolt-js`);
24
+ console.error(`\n`);
25
+ process.exit(1);
26
+ }
27
+
28
+ function getProtoFiles(dir) {
29
+ let protoFiles = [];
30
+
31
+ const files = readdirSync(dir);
32
+ files.forEach((file) => {
33
+ const filePath = join(dir, file);
34
+ const stats = statSync(filePath);
35
+ if (stats.isDirectory()) {
36
+ protoFiles = protoFiles.concat(getProtoFiles(filePath));
37
+ } else if (file.endsWith(".proto")) {
38
+ protoFiles.push(filePath);
39
+ }
40
+ });
41
+
42
+ return protoFiles;
43
+ }
44
+
45
+ const protoFiles = getProtoFiles(folder);
46
+
47
+ // Load the contents of each proto file, and write as string literals
48
+ // to the 'volt-proto-literals.js' file.
49
+ let protoLiterals =
50
+ "/**\n * This file is generated by the 'generate-proto-assets.js' script.\n * Do not modify this file directly.\n */\n\n";
51
+ protoFiles.forEach((filePath) => {
52
+ // Escape backticks in the proto file.
53
+ const contents = readFileSync(filePath, "utf8").replace(/`/g, "\\`");
54
+
55
+ // Get the base file name without the extension.
56
+ filePath = filePath.split("/").pop();
57
+
58
+ protoLiterals += `export const ${filePath.replace(
59
+ ".proto",
60
+ ""
61
+ )} = \`${contents}\`;\n`;
62
+ });
63
+
64
+ // Add an array that contains all the literals.
65
+ protoLiterals += `export const voltProtos = [${protoFiles
66
+ .map((filePath) => filePath.split("/").pop().replace(".proto", ""))
67
+ .join(", ")}];`;
68
+
69
+ writeFileSync(join(__dirname, "../src/volt-proto-literals.js"), protoLiterals);
70
+
71
+ console.log("Proto files loaded and written to 'volt-proto-literals.js'");
package/src/constants.js CHANGED
@@ -7,7 +7,7 @@ export const constants = {
7
7
  privateEncryptedKeyPrefix: "-----BEGIN ENCRYPTED PRIVATE KEY-----",
8
8
  /**
9
9
  * These top-level service types should map to a protobuf definition
10
- * in @tdxvolt/volt-proto.
10
+ * in the volt-proto-literals.js file.
11
11
  */
12
12
  serviceType: {
13
13
  fileAPI: "tdx.volt_api.volt.v1.FileAPI",
@@ -15,6 +15,7 @@ export const constants = {
15
15
  sqliteDatabaseAPI: "tdx.volt_api.data.v1.SqliteDatabaseAPI",
16
16
  ssiAPI: "tdx.volt_api.volt.v1.SsiAPI",
17
17
  relayAPI: "tdx.volt_api.relay.v1.RelayAPI",
18
+ terminalAPI: "tdx.volt_api.volt.v1.TerminalAPI",
18
19
  voltAPI: "tdx.volt_api.volt.v1.VoltAPI",
19
20
  wireAPI: "tdx.volt_api.volt.v1.WireAPI"
20
21
  }
package/src/grpc-call.js CHANGED
@@ -330,7 +330,7 @@ export default class GRPCCall extends EventEmitter {
330
330
  this._encryptionKey = null;
331
331
  }
332
332
 
333
- start(grpcClient, request) {
333
+ start(grpcClient, request, unary = false) {
334
334
  this._grpcClient = grpcClient;
335
335
 
336
336
  if (typeof this._grpcClient[this._methodName] !== "function") {
@@ -441,8 +441,12 @@ export default class GRPCCall extends EventEmitter {
441
441
  });
442
442
 
443
443
  if (this._initialRequest.request) {
444
- // Allow callee to attach event handlers before we actually send the initial payload.
445
- process.nextTick(() => this._call.write(this._initialRequest.request));
444
+ if (unary) {
445
+ this._call.end(this._initialRequest.request);
446
+ } else {
447
+ // Allow callee to attach event handlers before we actually send the initial payload.
448
+ process.nextTick(() => this._call.write(this._initialRequest.request));
449
+ }
446
450
  }
447
451
 
448
452
  return this;
@@ -0,0 +1,183 @@
1
+ /**
2
+ *
3
+ * This is copied from the proto-loader package file @grpc/proto-loader/build/src/index.js,
4
+ * simply in order to export the createPackageDefinition function, which we need to be
5
+ * able to dynamically load protobuf from strings stored in the Volt database rather than
6
+ * from files.
7
+ *
8
+ * There doesn't seem to be any plans to export this function from the package itself,
9
+ * see https://github.com/grpc/grpc-node/issues/550.
10
+ *
11
+ * This is deemed to be low-risk as the protobuf code is not expected to change often.
12
+ *
13
+ * Used by `getServiceDescriptors` in `proto-utils.js`.
14
+ *
15
+ */
16
+
17
+ import camelCase from "lodash.camelcase";
18
+ import Protobuf from "protobufjs";
19
+ import descriptor from "protobufjs/ext/descriptor/index.js";
20
+ import IdempotencyLevel from "@grpc/proto-loader";
21
+
22
+ const descriptorOptions = {
23
+ longs: String,
24
+ enums: String,
25
+ bytes: String,
26
+ defaults: true,
27
+ oneofs: true,
28
+ json: true
29
+ };
30
+ function joinName(baseName, name) {
31
+ if (baseName === "") {
32
+ return name;
33
+ } else {
34
+ return baseName + "." + name;
35
+ }
36
+ }
37
+ function isHandledReflectionObject(obj) {
38
+ return (
39
+ obj instanceof Protobuf.Service ||
40
+ obj instanceof Protobuf.Type ||
41
+ obj instanceof Protobuf.Enum
42
+ );
43
+ }
44
+ function isNamespaceBase(obj) {
45
+ return obj instanceof Protobuf.Namespace || obj instanceof Protobuf.Root;
46
+ }
47
+ function getAllHandledReflectionObjects(obj, parentName) {
48
+ const objName = joinName(parentName, obj.name);
49
+ if (isHandledReflectionObject(obj)) {
50
+ return [[objName, obj]];
51
+ } else {
52
+ if (isNamespaceBase(obj) && typeof obj.nested !== "undefined") {
53
+ return Object.keys(obj.nested)
54
+ .map((name) => {
55
+ return getAllHandledReflectionObjects(obj.nested[name], objName);
56
+ })
57
+ .reduce(
58
+ (accumulator, currentValue) => accumulator.concat(currentValue),
59
+ []
60
+ );
61
+ }
62
+ }
63
+ return [];
64
+ }
65
+ function createDeserializer(cls, options) {
66
+ return function deserialize(argBuf) {
67
+ return cls.toObject(cls.decode(argBuf), options);
68
+ };
69
+ }
70
+ function createSerializer(cls) {
71
+ return function serialize(arg) {
72
+ if (Array.isArray(arg)) {
73
+ throw new Error(
74
+ `Failed to serialize message: expected object with ${cls.name} structure, got array instead`
75
+ );
76
+ }
77
+ const message = cls.fromObject(arg);
78
+ return cls.encode(message).finish();
79
+ };
80
+ }
81
+ function mapMethodOptions(options) {
82
+ return (options || []).reduce(
83
+ (obj, item) => {
84
+ for (const [key, value] of Object.entries(item)) {
85
+ switch (key) {
86
+ case "uninterpreted_option":
87
+ obj.uninterpreted_option.push(item.uninterpreted_option);
88
+ break;
89
+ default:
90
+ obj[key] = value;
91
+ }
92
+ }
93
+ return obj;
94
+ },
95
+ {
96
+ deprecated: false,
97
+ idempotency_level: IdempotencyLevel.IDEMPOTENCY_UNKNOWN,
98
+ uninterpreted_option: []
99
+ }
100
+ );
101
+ }
102
+ function createMethodDefinition(method, serviceName, options, fileDescriptors) {
103
+ /* This is only ever called after the corresponding root.resolveAll(), so we
104
+ * can assume that the resolved request and response types are non-null */
105
+ const requestType = method.resolvedRequestType;
106
+ const responseType = method.resolvedResponseType;
107
+ return {
108
+ path: "/" + serviceName + "/" + method.name,
109
+ requestStream: !!method.requestStream,
110
+ responseStream: !!method.responseStream,
111
+ requestSerialize: createSerializer(requestType),
112
+ requestDeserialize: createDeserializer(requestType, options),
113
+ responseSerialize: createSerializer(responseType),
114
+ responseDeserialize: createDeserializer(responseType, options),
115
+ // TODO(murgatroid99): Find a better way to handle this
116
+ originalName: camelCase(method.name),
117
+ requestType: createMessageDefinition(requestType, fileDescriptors),
118
+ responseType: createMessageDefinition(responseType, fileDescriptors),
119
+ options: mapMethodOptions(method.parsedOptions)
120
+ };
121
+ }
122
+ function createServiceDefinition(service, name, options, fileDescriptors) {
123
+ const def = {};
124
+ for (const method of service.methodsArray) {
125
+ def[method.name] = createMethodDefinition(
126
+ method,
127
+ name,
128
+ options,
129
+ fileDescriptors
130
+ );
131
+ }
132
+ return def;
133
+ }
134
+ function createMessageDefinition(message, fileDescriptors) {
135
+ const messageDescriptor = message.toDescriptor("proto3");
136
+ return {
137
+ format: "Protocol Buffer 3 DescriptorProto",
138
+ type: messageDescriptor.$type.toObject(
139
+ messageDescriptor,
140
+ descriptorOptions
141
+ ),
142
+ fileDescriptorProtos: fileDescriptors
143
+ };
144
+ }
145
+ function createEnumDefinition(enumType, fileDescriptors) {
146
+ const enumDescriptor = enumType.toDescriptor("proto3");
147
+ return {
148
+ format: "Protocol Buffer 3 EnumDescriptorProto",
149
+ type: enumDescriptor.$type.toObject(enumDescriptor, descriptorOptions),
150
+ fileDescriptorProtos: fileDescriptors
151
+ };
152
+ }
153
+ /**
154
+ * function createDefinition(obj: Protobuf.Service, name: string, options:
155
+ * Options): ServiceDefinition; function createDefinition(obj: Protobuf.Type,
156
+ * name: string, options: Options): MessageTypeDefinition; function
157
+ * createDefinition(obj: Protobuf.Enum, name: string, options: Options):
158
+ * EnumTypeDefinition;
159
+ */
160
+ function createDefinition(obj, name, options, fileDescriptors) {
161
+ if (obj instanceof Protobuf.Service) {
162
+ return createServiceDefinition(obj, name, options, fileDescriptors);
163
+ } else if (obj instanceof Protobuf.Type) {
164
+ return createMessageDefinition(obj, fileDescriptors);
165
+ } else if (obj instanceof Protobuf.Enum) {
166
+ return createEnumDefinition(obj, fileDescriptors);
167
+ } else {
168
+ throw new Error("Type mismatch in reflection object handling");
169
+ }
170
+ }
171
+
172
+ export function createPackageDefinition(root, options) {
173
+ const def = {};
174
+ root.resolveAll();
175
+ const descriptorList = root.toDescriptor("proto3").file;
176
+ const bufferList = descriptorList.map((value) =>
177
+ Buffer.from(descriptor.FileDescriptorProto.encode(value).finish())
178
+ );
179
+ for (const [name, obj] of getAllHandledReflectionObjects(root, "")) {
180
+ def[name] = createDefinition(obj, name, options, bufferList);
181
+ }
182
+ return def;
183
+ }
@@ -1,130 +1,60 @@
1
- import protoLoader from "@grpc/proto-loader";
2
- import lodash from "lodash";
3
- import { dirname, join } from "path";
4
- import { fileURLToPath } from "url";
5
- import { writeFileSync, mkdirSync } from "fs";
6
-
7
- const { get: getProp, snakeCase } = lodash;
8
- const __dirname = dirname(fileURLToPath(import.meta.url));
9
-
10
- const defaultProtoPath = join(__dirname, "../protobuf");
1
+ import debug from "debug";
2
+ import protobuf from "protobufjs";
3
+ import { createPackageDefinition } from "./proto-package-definition.js";
4
+ import { voltProtos } from "./volt-proto-literals.js";
5
+ import { constants } from "./constants.js";
6
+
7
+ const log = debug("volt-client-grpc:proto-utils");
8
+
9
+ const voltServices = [
10
+ constants.serviceType.voltAPI,
11
+ constants.serviceType.fileAPI,
12
+ constants.serviceType.sqliteDatabaseAPI,
13
+ constants.serviceType.sqliteServerAPI,
14
+ constants.serviceType.ssiAPI,
15
+ constants.serviceType.relayAPI,
16
+ constants.serviceType.terminalAPI,
17
+ constants.serviceType.wireAPI
18
+ ];
11
19
 
12
20
  const defaultLoaderOptions = {
13
21
  keepCase: true,
14
22
  longs: String,
15
23
  enums: String,
16
24
  defaults: true,
17
- oneofs: true,
18
- includeDirs: [defaultProtoPath],
25
+ oneofs: true
19
26
  };
20
27
 
21
- function getProtoDescriptors(grpc, protoPath, opts) {
22
- const definition = protoLoader.loadSync(
23
- protoPath,
24
- opts || defaultLoaderOptions,
25
- );
26
- const descriptors = grpc.loadPackageDefinition(definition);
27
- return descriptors;
28
- }
29
-
30
- function getProtoService(descriptors, servicePath) {
31
- const serviceDef = getProp(descriptors, servicePath);
32
- if (serviceDef?.service) {
33
- return serviceDef.service;
34
- } else {
35
- return null;
36
- }
37
- }
38
-
39
- function getServiceDescriptorsFromPath(
40
- grpc,
41
- protoPath,
42
- servicePackageName,
43
- opts,
44
- ) {
45
- if (!opts) {
46
- opts = { ...defaultLoaderOptions };
47
- opts.includeDirs = [protoPath];
48
- }
49
-
50
- // Extract the package components of the service proto package. The package name should be of the
51
- // fully qualified proto path, e.g. tdx.volt_api.webcam.v1.WebcamControlAPI.
52
- const protoServiceComponents = servicePackageName.split(".");
53
-
54
- // The service name is the last component of the path.
55
- const protoServiceName = protoServiceComponents.pop();
56
-
57
- // The actual file name should match the snake case of the service name.
58
- const protoFileName = `${snakeCase(protoServiceName).toLowerCase()}.proto`;
59
-
60
- // The path to the proto file should match each component of the package name.
61
- const serviceProtoPath = join(
62
- protoPath,
63
- ...protoServiceComponents,
64
- protoFileName,
65
- );
66
-
67
- let serviceDescriptors;
68
- const descriptors = getProtoDescriptors(grpc, serviceProtoPath, opts);
69
- if (descriptors) {
70
- serviceDescriptors = getProtoService(descriptors, servicePackageName);
28
+ function getServiceDescriptors(service) {
29
+ let root = new protobuf.Root();
30
+ for (let protoFile of service.service_description.proto_file) {
31
+ protobuf.parse(protoFile.protobuf, root, defaultLoaderOptions);
32
+ log("parsed proto file %s", protoFile.file_path);
71
33
  }
72
34
 
73
- return serviceDescriptors;
74
- }
75
-
76
- function getServiceDescriptors(grpc, servicePackageName, opts) {
77
- // Extract the package components of the service proto package. The package name should be of the
78
- // fully qualified proto path, e.g. tdx.volt_api.webcam.v1.WebcamControlAPI.
79
- const protoServiceComponents = servicePackageName.split(".");
80
-
81
- // The service name is the last component of the path.
82
- const protoServiceName = protoServiceComponents.pop();
35
+ // Create a package definition from the root object.
36
+ const packageDefinition = createPackageDefinition(root, defaultLoaderOptions);
83
37
 
84
- // The actual file name should match the snake case of the service name.
85
- const protoFileName = `${snakeCase(protoServiceName).toLowerCase()}.proto`;
86
-
87
- // The path to the proto file should match each component of the package name.
88
- const protoPath = join(
89
- defaultProtoPath,
90
- ...protoServiceComponents,
91
- protoFileName,
92
- );
93
-
94
- let serviceDescriptors;
95
- const descriptors = getProtoDescriptors(grpc, protoPath, opts);
96
- if (descriptors) {
97
- serviceDescriptors = getProtoService(descriptors, servicePackageName);
38
+ // Merge the service API definitions into a single object.
39
+ let serviceDescriptors = {};
40
+ for (let api of service.service_description.service_api) {
41
+ const packageDescriptors = packageDefinition[api];
42
+ serviceDescriptors = { ...serviceDescriptors, ...packageDescriptors };
98
43
  }
99
44
 
100
45
  return serviceDescriptors;
101
46
  }
102
47
 
103
- function getProtoDescriptorMethods(protoDescriptor) {
104
- const methods = [];
105
- Object.keys(protoDescriptor).forEach((methodName) => {
106
- const method = protoDescriptor[methodName];
107
- methods.push({
108
- path: method.path,
109
- client_streaming: method.requestStream,
110
- server_streaming: method.responseStream,
111
- });
112
- });
113
- return methods;
114
- }
48
+ function getBuiltInServiceDescriptors() {
49
+ // Create a placeholder service object for the Volt API service.
50
+ const voltServicePlaceholder = {
51
+ service_description: {
52
+ proto_file: voltProtos.map((proto) => ({ protobuf: proto })),
53
+ service_api: voltServices
54
+ }
55
+ };
115
56
 
116
- function createServiceProtobufFiles(service, protoPath) {
117
- for (let protoFile of service.service_description.proto_file) {
118
- const filePath = join(protoPath, protoFile.file_path);
119
- mkdirSync(dirname(filePath), { recursive: true });
120
- writeFileSync(filePath, protoFile.protobuf);
121
- }
57
+ return getServiceDescriptors(voltServicePlaceholder);
122
58
  }
123
59
 
124
- export {
125
- createServiceProtobufFiles,
126
- getServiceDescriptors,
127
- getProtoDescriptors,
128
- getProtoDescriptorMethods,
129
- getServiceDescriptorsFromPath,
130
- };
60
+ export { getServiceDescriptors, getBuiltInServiceDescriptors };
@@ -4,11 +4,9 @@ import ip from "ip";
4
4
  import bent from "bent";
5
5
  import lodash from "lodash";
6
6
  import VoltConnection from "./volt-connection.js";
7
- import { join } from "path";
8
7
  import {
9
- createServiceProtobufFiles,
10
8
  getServiceDescriptors,
11
- getServiceDescriptorsFromPath
9
+ getBuiltInServiceDescriptors
12
10
  } from "./proto-utils.js";
13
11
  import { createClient as createGrpcClient } from "./grpc-utils.js";
14
12
  import * as voltUtils from "./utils.js";
@@ -23,15 +21,6 @@ const { publicKeyToPem, removeCarriageReturn, signBase64 } = voltClientUtils;
23
21
  const { filter, pick } = lodash;
24
22
 
25
23
  const log = debug("volt-client-grpc:volt-client-internal");
26
- const voltServices = [
27
- constants.serviceType.voltAPI,
28
- constants.serviceType.fileAPI,
29
- constants.serviceType.sqliteDatabaseAPI,
30
- constants.serviceType.sqliteServerAPI,
31
- constants.serviceType.ssiAPI,
32
- constants.serviceType.relayAPI,
33
- constants.serviceType.wireAPI
34
- ];
35
24
 
36
25
  function issueAuthenticate(authenticateRequest, ttl) {
37
26
  // eslint-disable-next-line no-use-before-define
@@ -371,11 +360,8 @@ export function getVoltAPIClientInternal() {
371
360
  ? this._voltConfig.relay.address
372
361
  : this._voltConfig.address;
373
362
  log("creating cached VoltAPI service client on %s", serviceAddress);
374
- let serviceDescriptors = {};
375
- voltServices.forEach((pkg) => {
376
- const packageDescriptors = getServiceDescriptors(this._grpc, pkg);
377
- serviceDescriptors = { ...serviceDescriptors, ...packageDescriptors };
378
- });
363
+
364
+ const serviceDescriptors = getBuiltInServiceDescriptors();
379
365
 
380
366
  this._cachedClient = createGrpcClient(
381
367
  this._grpc,
@@ -396,20 +382,9 @@ export function getAPIClientInternal(service) {
396
382
  const serviceAddress = this.isRelayed
397
383
  ? this._voltConfig.relay.address
398
384
  : service.service_description.host_address;
399
-
400
- createServiceProtobufFiles(service, "./service-proto");
401
-
402
385
  log("creating API service client on %s", serviceAddress);
403
- let serviceDescriptors = {};
404
- const fullProtoPath = join(process.cwd(), "./service-proto");
405
- for (let api of service.service_description.service_api) {
406
- const packageDescriptors = getServiceDescriptorsFromPath(
407
- this._grpc,
408
- fullProtoPath,
409
- api
410
- );
411
- serviceDescriptors = { ...serviceDescriptors, ...packageDescriptors };
412
- }
386
+
387
+ const serviceDescriptors = getServiceDescriptors(service);
413
388
 
414
389
  this._cachedService[service.id] = createGrpcClient(
415
390
  this._grpc,
@@ -248,63 +248,6 @@ export class VoltClient extends EventEmitter {
248
248
  });
249
249
  }
250
250
 
251
- /**
252
- * Creates a GRPC client for the given Volt service description.
253
- *
254
- * Automatically handles remote connections.
255
- *
256
- * n.b. for this javascript client Protobuf definitions should conform to the recommended
257
- * structure, which is that a package proto file resides in a folder path that matches the
258
- * package name, and services contained in the package are named in in Pascal Case and using
259
- * the suffix 'API'. For example the WebcamControlAPI in package tdx.volt_api.webcam.v1 should reside
260
- * in a protobuf file at tdx/api/webcam/v1/webcam_control_api.proto
261
- *
262
- * @param {object} service a service description.
263
- * @param {object} descriptors the service descriptors, must be specified unless the service
264
- * packages are well-known Volt APIs.
265
- */
266
- createServiceClient(service, descriptors) {
267
- const pkg = service.service_description.service_api;
268
-
269
- let serviceDescriptors;
270
- if (descriptors) {
271
- serviceDescriptors = descriptors;
272
- } else {
273
- serviceDescriptors = {};
274
- pkg.forEach((svc) => {
275
- log("adding service %s to service client", svc);
276
- const packageDescriptors = getServiceDescriptors(this._grpc, svc);
277
- serviceDescriptors = { ...serviceDescriptors, ...packageDescriptors };
278
- });
279
- }
280
-
281
- if (this.isRelayed) {
282
- if (!this._voltConfig?.relay?.address) {
283
- throw new Error(
284
- "Remote connection enabled but no Relay address - have you called start()?"
285
- );
286
- }
287
-
288
- // In remote mode => create a client using the discovered Relay address **and** passing the service reourceId
289
- return createGrpcClient(
290
- this._grpc,
291
- serviceDescriptors,
292
- this._voltConfig.relay.address,
293
- this._credential,
294
- false,
295
- service.volt_id,
296
- service.id
297
- );
298
- } else {
299
- return createGrpcClient(
300
- this._grpc,
301
- serviceDescriptors,
302
- service.service_description.address,
303
- this._credential
304
- );
305
- }
306
- }
307
-
308
251
  get isRelayed() {
309
252
  return !!(this._voltConfig?.relay && this._voltConfig.id);
310
253
  }