@twin.org/node-core 0.0.2-next.26 → 0.0.2-next.27

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 (89) hide show
  1. package/README.md +6 -20
  2. package/dist/es/bootstrap.js +374 -0
  3. package/dist/es/bootstrap.js.map +1 -0
  4. package/dist/es/builders/engineEnvBuilder.js +1051 -0
  5. package/dist/es/builders/engineEnvBuilder.js.map +1 -0
  6. package/dist/es/builders/engineServerEnvBuilder.js +197 -0
  7. package/dist/es/builders/engineServerEnvBuilder.js.map +1 -0
  8. package/dist/es/builders/extensionsBuilder.js +100 -0
  9. package/dist/es/builders/extensionsBuilder.js.map +1 -0
  10. package/dist/es/defaults.js +9 -0
  11. package/dist/es/defaults.js.map +1 -0
  12. package/dist/es/identity.js +169 -0
  13. package/dist/es/identity.js.map +1 -0
  14. package/dist/es/index.js +23 -0
  15. package/dist/es/index.js.map +1 -0
  16. package/dist/es/models/ICacheMetadata.js +4 -0
  17. package/dist/es/models/ICacheMetadata.js.map +1 -0
  18. package/dist/es/models/IEngineEnvironmentVariables.js +4 -0
  19. package/dist/es/models/IEngineEnvironmentVariables.js.map +1 -0
  20. package/dist/es/models/IEngineServerEnvironmentVariables.js +2 -0
  21. package/dist/es/models/IEngineServerEnvironmentVariables.js.map +1 -0
  22. package/dist/es/models/IModuleProtocol.js +2 -0
  23. package/dist/es/models/IModuleProtocol.js.map +1 -0
  24. package/dist/es/models/INodeEngineConfig.js +2 -0
  25. package/dist/es/models/INodeEngineConfig.js.map +1 -0
  26. package/dist/es/models/INodeEngineState.js +2 -0
  27. package/dist/es/models/INodeEngineState.js.map +1 -0
  28. package/dist/es/models/INodeEnvironmentVariables.js +2 -0
  29. package/dist/es/models/INodeEnvironmentVariables.js.map +1 -0
  30. package/dist/es/models/INodeOptions.js +2 -0
  31. package/dist/es/models/INodeOptions.js.map +1 -0
  32. package/dist/es/models/IProtocolHandlerResult.js +4 -0
  33. package/dist/es/models/IProtocolHandlerResult.js.map +1 -0
  34. package/dist/es/models/moduleProtocol.js +29 -0
  35. package/dist/es/models/moduleProtocol.js.map +1 -0
  36. package/dist/es/models/nodeExtensionMethods.js +2 -0
  37. package/dist/es/models/nodeExtensionMethods.js.map +1 -0
  38. package/dist/es/models/nodeFeatures.js +21 -0
  39. package/dist/es/models/nodeFeatures.js.map +1 -0
  40. package/dist/es/node.js +265 -0
  41. package/dist/es/node.js.map +1 -0
  42. package/dist/es/server.js +74 -0
  43. package/dist/es/server.js.map +1 -0
  44. package/dist/es/utils.js +418 -0
  45. package/dist/es/utils.js.map +1 -0
  46. package/dist/types/bootstrap.d.ts +27 -10
  47. package/dist/types/builders/engineEnvBuilder.d.ts +3 -2
  48. package/dist/types/builders/engineServerEnvBuilder.d.ts +3 -2
  49. package/dist/types/builders/extensionsBuilder.d.ts +2 -2
  50. package/dist/types/identity.d.ts +14 -0
  51. package/dist/types/index.d.ts +20 -19
  52. package/dist/types/models/IEngineEnvironmentVariables.d.ts +12 -5
  53. package/dist/types/models/IEngineServerEnvironmentVariables.d.ts +1 -1
  54. package/dist/types/models/IModuleProtocol.d.ts +1 -1
  55. package/dist/types/models/INodeEngineState.d.ts +22 -0
  56. package/dist/types/models/INodeEnvironmentVariables.d.ts +24 -8
  57. package/dist/types/models/INodeOptions.d.ts +13 -3
  58. package/dist/types/models/nodeExtensionMethods.d.ts +2 -2
  59. package/dist/types/models/nodeFeatures.d.ts +5 -5
  60. package/dist/types/node.d.ts +14 -5
  61. package/dist/types/server.d.ts +7 -6
  62. package/dist/types/utils.d.ts +5 -5
  63. package/docs/detailed-guide.md +14 -14
  64. package/docs/reference/functions/bootstrap.md +1 -1
  65. package/docs/reference/functions/bootstrapAuth.md +1 -1
  66. package/docs/reference/functions/bootstrapBlobEncryption.md +1 -1
  67. package/docs/reference/functions/bootstrapContextIdHandlers.md +35 -0
  68. package/docs/reference/functions/bootstrapImmutableProofMethod.md +1 -1
  69. package/docs/reference/functions/{bootstrapNodeUser.md → bootstrapNodeAdminUser.md} +3 -3
  70. package/docs/reference/functions/{bootstrapNodeIdentity.md → bootstrapNodeId.md} +3 -3
  71. package/docs/reference/functions/bootstrapSynchronisedStorage.md +1 -1
  72. package/docs/reference/functions/bootstrapTenantId.md +35 -0
  73. package/docs/reference/functions/buildConfiguration.md +2 -2
  74. package/docs/reference/functions/buildEngineConfiguration.md +7 -1
  75. package/docs/reference/functions/buildEngineServerConfiguration.md +7 -1
  76. package/docs/reference/functions/run.md +3 -3
  77. package/docs/reference/functions/start.md +8 -2
  78. package/docs/reference/index.md +5 -2
  79. package/docs/reference/interfaces/IEngineEnvironmentVariables.md +24 -9
  80. package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +36 -13
  81. package/docs/reference/interfaces/INodeEngineConfig.md +430 -0
  82. package/docs/reference/interfaces/INodeEngineState.md +39 -0
  83. package/docs/reference/interfaces/INodeEnvironmentVariables.md +79 -24
  84. package/docs/reference/interfaces/INodeOptions.md +21 -1
  85. package/docs/reference/variables/NodeFeatures.md +7 -7
  86. package/locales/en.json +10 -7
  87. package/package.json +40 -8
  88. package/dist/cjs/index.cjs +0 -2570
  89. package/dist/esm/index.mjs +0 -2508
@@ -1,2570 +0,0 @@
1
- 'use strict';
2
-
3
- var apiAuthEntityStorageService = require('@twin.org/api-auth-entity-storage-service');
4
- var core = require('@twin.org/core');
5
- var crypto = require('@twin.org/crypto');
6
- var engineServerTypes = require('@twin.org/engine-server-types');
7
- var engineTypes = require('@twin.org/engine-types');
8
- var entityStorageModels = require('@twin.org/entity-storage-models');
9
- var identityModels = require('@twin.org/identity-models');
10
- var vaultModels = require('@twin.org/vault-models');
11
- var walletModels = require('@twin.org/wallet-models');
12
- var node_child_process = require('node:child_process');
13
- var promises = require('node:fs/promises');
14
- var node_https = require('node:https');
15
- var path = require('node:path');
16
- var cliCore = require('@twin.org/cli-core');
17
- var modules = require('@twin.org/modules');
18
- var rightsManagementRestClient = require('@twin.org/rights-management-rest-client');
19
- var engineServer = require('@twin.org/engine-server');
20
- var dotenv = require('dotenv');
21
- var engine = require('@twin.org/engine');
22
- var engineCore = require('@twin.org/engine-core');
23
- var engineModels = require('@twin.org/engine-models');
24
-
25
- function _interopNamespaceDefault(e) {
26
- var n = Object.create(null);
27
- if (e) {
28
- Object.keys(e).forEach(function (k) {
29
- if (k !== 'default') {
30
- var d = Object.getOwnPropertyDescriptor(e, k);
31
- Object.defineProperty(n, k, d.get ? d : {
32
- enumerable: true,
33
- get: function () { return e[k]; }
34
- });
35
- }
36
- });
37
- }
38
- n.default = e;
39
- return Object.freeze(n);
40
- }
41
-
42
- var dotenv__namespace = /*#__PURE__*/_interopNamespaceDefault(dotenv);
43
-
44
- // Copyright 2024 IOTA Stiftung.
45
- // SPDX-License-Identifier: Apache-2.0.
46
- const ATTESTATION_VERIFICATION_METHOD_ID = "attestation-assertion";
47
- const IMMUTABLE_PROOF_VERIFICATION_METHOD_ID = "immutable-proof-assertion";
48
- const BLOB_STORAGE_ENCRYPTION_KEY_ID = "blob-encryption";
49
- const SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID = "synchronised-storage-blob-encryption";
50
- const VC_AUTHENTICATION_VERIFICATION_METHOD_ID = "node-authentication-assertion";
51
- const AUTH_SIGNING_KEY_ID = "auth-signing";
52
-
53
- // Copyright 2024 IOTA Stiftung.
54
- // SPDX-License-Identifier: Apache-2.0.
55
- /**
56
- * The features that can be enabled on the node.
57
- */
58
- // eslint-disable-next-line @typescript-eslint/naming-convention
59
- const NodeFeatures = {
60
- /**
61
- * NodeIdentity - generates an identity for the node if not provided in config.
62
- */
63
- NodeIdentity: "node-identity",
64
- /**
65
- * NodeUser - generates a user for the node if not provided in config.
66
- */
67
- NodeUser: "node-user",
68
- /**
69
- * NodeWallet - generates a wallet for the node and funds it when there is a faucet available.
70
- */
71
- NodeWallet: "node-wallet"
72
- };
73
-
74
- // Copyright 2024 IOTA Stiftung.
75
- // SPDX-License-Identifier: Apache-2.0.
76
- /**
77
- * The protocol types for modules.
78
- */
79
- // eslint-disable-next-line @typescript-eslint/naming-convention
80
- const ModuleProtocol = {
81
- /**
82
- * Local module (starts with . or / or file://).
83
- */
84
- Local: "local",
85
- /**
86
- * NPM package (starts with npm:).
87
- */
88
- Npm: "npm",
89
- /**
90
- * HTTPS URL (starts with https://).
91
- */
92
- Https: "https",
93
- /**
94
- * HTTP URL (starts with http://).
95
- */
96
- Http: "http",
97
- /**
98
- * Default/standard module resolution.
99
- */
100
- Default: "default"
101
- };
102
-
103
- // Copyright 2024 IOTA Stiftung.
104
- // SPDX-License-Identifier: Apache-2.0.
105
- /**
106
- * Initialise the locales for the application.
107
- * @param localesDirectory The directory containing the locales.
108
- */
109
- async function initialiseLocales(localesDirectory) {
110
- const localesFile = path.resolve(path.join(localesDirectory, "en.json"));
111
- cliCore.CLIDisplay.value("Locales File", localesFile);
112
- if (await fileExists(localesFile)) {
113
- const enLangContent = await promises.readFile(localesFile, "utf8");
114
- core.I18n.addDictionary("en", JSON.parse(enLangContent));
115
- }
116
- else {
117
- cliCore.CLIDisplay.error(`Locales file not found: ${localesFile}`);
118
- }
119
- }
120
- /**
121
- * Get the directory where the application is being executed.
122
- * @returns The execution directory.
123
- */
124
- function getExecutionDirectory() {
125
- return process.cwd();
126
- }
127
- /**
128
- * Does the specified file exist.
129
- * @param filename The filename to check for existence.
130
- * @returns True if the file exists.
131
- */
132
- async function fileExists(filename) {
133
- try {
134
- const stats = await promises.stat(filename);
135
- return stats.isFile();
136
- }
137
- catch {
138
- return false;
139
- }
140
- }
141
- /**
142
- * Does the specified directory exist.
143
- * @param directory The directory to check for existence.
144
- * @returns True if the directory exists.
145
- */
146
- async function directoryExists(directory) {
147
- try {
148
- const stats = await promises.stat(directory);
149
- return stats.isDirectory();
150
- }
151
- catch {
152
- return false;
153
- }
154
- }
155
- /**
156
- * Get the sub folders for the folder.
157
- * @param directory The directory to get the sub folders.
158
- * @returns The list of sub folders.
159
- */
160
- async function getSubFolders(directory) {
161
- try {
162
- const dir = await promises.readdir(directory);
163
- const folders = [];
164
- for (const dirEntry of dir) {
165
- const fullPath = path.join(directory, dirEntry);
166
- const stats = await promises.stat(fullPath);
167
- if (stats.isDirectory()) {
168
- folders.push(fullPath);
169
- }
170
- }
171
- return folders;
172
- }
173
- catch {
174
- return [];
175
- }
176
- }
177
- /**
178
- * Get the files in the directory.
179
- * @param directory The directory to get the files from.
180
- * @returns The list of files in the directory.
181
- */
182
- async function getFiles(directory) {
183
- try {
184
- const dir = await promises.readdir(directory);
185
- const files = [];
186
- for (const dirEntry of dir) {
187
- const fullPath = path.join(directory, dirEntry);
188
- const stats = await promises.stat(fullPath);
189
- if (stats.isFile()) {
190
- files.push(fullPath);
191
- }
192
- }
193
- return files;
194
- }
195
- catch {
196
- return [];
197
- }
198
- }
199
- /**
200
- * Load the text file.
201
- * @param filename The filename of the text file to load.
202
- * @returns The contents of the text file if it could not be loaded.
203
- */
204
- async function loadTextFile(filename) {
205
- return promises.readFile(filename, "utf8");
206
- }
207
- /**
208
- * Load the JSON file.
209
- * @param filename The filename of the JSON file to load.
210
- * @returns The contents of the JSON file or null if it could not be loaded.
211
- */
212
- async function loadJsonFile(filename) {
213
- const content = await loadTextFile(filename);
214
- return JSON.parse(content);
215
- }
216
- /**
217
- * Get the features that are enabled on the node.
218
- * @param env The environment variables for the node.
219
- * @returns The features that are enabled on the node.
220
- */
221
- function getFeatures(env) {
222
- if (core.Is.empty(env.features)) {
223
- return [];
224
- }
225
- const features = [];
226
- const allFeatures = Object.values(NodeFeatures);
227
- const splitFeatures = env.features.split(",");
228
- for (const feature of splitFeatures) {
229
- const featureTrimmed = feature.trim();
230
- if (allFeatures.includes(featureTrimmed)) {
231
- features.push(featureTrimmed);
232
- }
233
- }
234
- return features;
235
- }
236
- /**
237
- * Parse the protocol from a module name.
238
- * @param moduleName The module name to parse.
239
- * @returns The parsed protocol information.
240
- */
241
- function parseModuleProtocol(moduleName) {
242
- const trimmed = moduleName.trim();
243
- if (trimmed.startsWith("npm:")) {
244
- return {
245
- protocol: ModuleProtocol.Npm,
246
- identifier: trimmed.slice(4),
247
- original: trimmed
248
- };
249
- }
250
- if (trimmed.startsWith("https://")) {
251
- return {
252
- protocol: ModuleProtocol.Https,
253
- identifier: trimmed,
254
- original: trimmed
255
- };
256
- }
257
- if (trimmed.startsWith("http://")) {
258
- return {
259
- protocol: ModuleProtocol.Http,
260
- identifier: trimmed,
261
- original: trimmed
262
- };
263
- }
264
- if (trimmed.startsWith("file://")) {
265
- return {
266
- protocol: ModuleProtocol.Local,
267
- identifier: trimmed,
268
- original: trimmed
269
- };
270
- }
271
- if (modules.ModuleHelper.isLocalModule(trimmed)) {
272
- return {
273
- protocol: ModuleProtocol.Local,
274
- identifier: trimmed,
275
- original: trimmed
276
- };
277
- }
278
- return {
279
- protocol: ModuleProtocol.Default,
280
- identifier: trimmed,
281
- original: trimmed
282
- };
283
- }
284
- /**
285
- * Hash a URL to create a safe filename.
286
- * @param url The URL to hash.
287
- * @returns A hashed filename safe for the filesystem.
288
- */
289
- function hashUrl(url) {
290
- const urlBytes = core.Converter.utf8ToBytes(url);
291
- const hashBytes = crypto.Sha256.sum256(urlBytes);
292
- const hash = core.Converter.bytesToHex(hashBytes);
293
- const ext = path.extname(new URL(url).pathname);
294
- return `${hash}${ext}`;
295
- }
296
- /**
297
- * Get the extensions cache directory.
298
- * @param executionDirectory The execution directory.
299
- * @param protocol The protocol type for subdirectory organization.
300
- * @param cacheDirectory The cache directory base path.
301
- * @returns The cache directory path.
302
- */
303
- function getExtensionsCacheDir(executionDirectory, protocol, cacheDirectory) {
304
- // Resolve to absolute path to ensure consistent behavior
305
- const absoluteDir = path.resolve(executionDirectory);
306
- const baseDir = cacheDirectory ?? ".tmp";
307
- return path.join(absoluteDir, baseDir, "extensions", protocol);
308
- }
309
- /**
310
- * Handle the npm: protocol by installing the package if needed.
311
- * @param packageName The npm package name (without npm: prefix).
312
- * @param executionDirectory The execution directory.
313
- * @param cacheDirectory The cache directory base path.
314
- * @returns The resolved path to the installed module.
315
- */
316
- async function handleNpmProtocol(packageName, executionDirectory, cacheDirectory) {
317
- const cacheDir = getExtensionsCacheDir(executionDirectory, ModuleProtocol.Npm, cacheDirectory);
318
- // Extract just the package name (without version) for the directory
319
- // e.g. "picocolors@1.0.0" becomes "picocolors"
320
- // e.g. "@scope/package@1.0.0" becomes "@scope/package"
321
- const lastAtIndex = packageName.lastIndexOf("@");
322
- const packageNameOnly = lastAtIndex > 0 ? packageName.slice(0, lastAtIndex) : packageName;
323
- const packageDir = path.join(cacheDir, "node_modules", packageNameOnly);
324
- const packageJsonPath = path.join(packageDir, "package.json");
325
- const exists = await fileExists(packageJsonPath);
326
- if (exists) {
327
- const mainFile = await resolvePackageEntryPoint(packageDir, packageNameOnly);
328
- const modulePath = path.join(packageDir, mainFile);
329
- return {
330
- resolvedPath: modulePath,
331
- cached: true
332
- };
333
- }
334
- await promises.mkdir(cacheDir, { recursive: true });
335
- cliCore.CLIDisplay.task(core.I18n.formatMessage("node.extensionNpmInstalling"), packageName);
336
- try {
337
- // Always pipe stdio to comply with env access restrictions in tests/lint
338
- const stdio = "pipe";
339
- node_child_process.execSync(`npm install ${packageName} --prefix "${cacheDir}" --no-save --no-package-lock`, {
340
- cwd: cacheDir,
341
- stdio
342
- });
343
- }
344
- catch (err) {
345
- throw new core.GeneralError("node", "extensionNpmInstallFailed", {
346
- package: packageName
347
- }, core.BaseError.fromError(err));
348
- }
349
- const mainFile = await resolvePackageEntryPoint(packageDir, packageNameOnly);
350
- const modulePath = path.join(packageDir, mainFile);
351
- return {
352
- resolvedPath: modulePath,
353
- cached: false
354
- };
355
- }
356
- /**
357
- * Check if a cached file has expired based on TTL and force refresh settings.
358
- * @param metadataPath Path to the cache metadata file.
359
- * @param ttlHours Time to live in hours.
360
- * @param forceRefresh Whether to force refresh regardless of TTL.
361
- * @returns True if the cache is expired or should be refreshed.
362
- */
363
- async function isCacheExpired(metadataPath, ttlHours, forceRefresh) {
364
- if (forceRefresh) {
365
- return true;
366
- }
367
- try {
368
- const metadata = await loadJsonFile(metadataPath);
369
- const ttlMillis = ttlHours * 60 * 60 * 1000;
370
- const expireTime = metadata.downloadedAt + ttlMillis;
371
- return Date.now() > expireTime;
372
- }
373
- catch {
374
- // If metadata doesn't exist or is corrupted, consider expired
375
- return true;
376
- }
377
- }
378
- /**
379
- * Handle the https: protocol by downloading the module if needed.
380
- * @param url The HTTPS URL to download from.
381
- * @param executionDirectory The execution directory.
382
- * @param maxSizeMb The maximum size in MB for the download.
383
- * @param cacheDirectory The cache directory base path.
384
- * @param ttlHours TTL in hours for cache expiration.
385
- * @param forceRefresh Whether to force refresh the cache.
386
- * @returns The resolved path to the downloaded module.
387
- */
388
- async function handleHttpsProtocol(url, executionDirectory, maxSizeMb, cacheDirectory, ttlHours, forceRefresh) {
389
- const effectiveTtlHours = ttlHours ?? 24;
390
- const effectiveForceRefresh = forceRefresh ?? false;
391
- const cacheDir = getExtensionsCacheDir(executionDirectory, ModuleProtocol.Https, cacheDirectory);
392
- const filename = hashUrl(url);
393
- const cachedPath = path.join(cacheDir, filename);
394
- const metadataPath = `${cachedPath}.meta`;
395
- const exists = await fileExists(cachedPath);
396
- if (exists) {
397
- const expired = await isCacheExpired(metadataPath, effectiveTtlHours, effectiveForceRefresh);
398
- if (!expired) {
399
- return {
400
- resolvedPath: cachedPath,
401
- cached: true
402
- };
403
- }
404
- if (effectiveForceRefresh) {
405
- cliCore.CLIDisplay.warning(core.I18n.formatMessage("node.extensionForceRefresh", { url }));
406
- }
407
- else {
408
- cliCore.CLIDisplay.task(core.I18n.formatMessage("node.extensionCacheExpired", { url }));
409
- }
410
- }
411
- cliCore.CLIDisplay.warning(core.I18n.formatMessage("node.extensionSecurityWarning", { url }));
412
- cliCore.CLIDisplay.task(core.I18n.formatMessage("node.extensionHttpsDownloading"), url);
413
- await promises.mkdir(cacheDir, { recursive: true });
414
- const maxSizeBytes = maxSizeMb * 1024 * 1024;
415
- let downloadedSize = 0;
416
- const chunks = [];
417
- try {
418
- await new Promise((resolve, reject) => {
419
- node_https.get(url, response => {
420
- if (response.statusCode !== 200) {
421
- reject(new core.GeneralError("node", "extensionDownloadFailed", {
422
- url,
423
- status: response.statusCode ?? 0
424
- }));
425
- return;
426
- }
427
- response.on("data", (chunk) => {
428
- downloadedSize += chunk.length;
429
- if (downloadedSize > maxSizeBytes) {
430
- response.destroy();
431
- reject(new core.GeneralError("node", "extensionSizeLimitExceeded", {
432
- size: downloadedSize,
433
- limit: maxSizeBytes
434
- }));
435
- return;
436
- }
437
- chunks.push(chunk);
438
- });
439
- response.on("end", () => {
440
- resolve();
441
- });
442
- response.on("error", err => {
443
- reject(core.BaseError.fromError(err));
444
- });
445
- }).on("error", err => {
446
- reject(core.BaseError.fromError(err));
447
- });
448
- });
449
- }
450
- catch (err) {
451
- throw new core.GeneralError("node", "extensionDownloadFailed", {
452
- url
453
- }, core.BaseError.fromError(err));
454
- }
455
- const tempPath = `${cachedPath}.tmp`;
456
- await promises.writeFile(tempPath, Buffer.concat(chunks));
457
- // Atomic move from temp to final location
458
- await promises.rename(tempPath, cachedPath);
459
- // Save metadata for TTL tracking
460
- const metadata = {
461
- downloadedAt: Date.now(),
462
- url,
463
- size: Buffer.concat(chunks).length
464
- };
465
- await promises.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
466
- return {
467
- resolvedPath: cachedPath,
468
- cached: false
469
- };
470
- }
471
- /**
472
- * Resolve the main entry point from a package directory using Node.js resolution with fallback.
473
- * Uses require.resolve() when possible for standard Node.js behavior, with manual fallback.
474
- * @param packagePath The absolute path to the package directory.
475
- * @param packageName The package name for require.resolve().
476
- * @param fallback The fallback file name if no entry point is found.
477
- * @returns The resolved entry point file name (relative to package directory).
478
- */
479
- async function resolvePackageEntryPoint(packagePath, packageName, fallback = "index.js") {
480
- try {
481
- // Try require.resolve() first - handles exports, main, module automatically
482
- const resolvedPath = require.resolve(packageName, { paths: [path.dirname(packagePath)] });
483
- // Convert absolute path back to relative filename within package
484
- const relativePath = path.relative(packagePath, resolvedPath);
485
- return relativePath ?? fallback;
486
- }
487
- catch {
488
- // Fallback to manual package.json parsing if require.resolve fails
489
- try {
490
- const packageJsonPath = path.join(packagePath, "package.json");
491
- const packageJsonContent = await loadJsonFile(packageJsonPath);
492
- // Future: Could expand exports field support here
493
- return packageJsonContent.module ?? packageJsonContent.main ?? fallback;
494
- }
495
- catch {
496
- return fallback;
497
- }
498
- }
499
- }
500
- /**
501
- * Convert a file path to an import-compatible URL for cross-platform module loading.
502
- * On Windows, adds the 'file://' protocol prefix required for dynamic imports.
503
- * On other platforms, returns the path unchanged.
504
- * @param filePath The absolute file path to convert.
505
- * @returns A URL string compatible with dynamic import().
506
- */
507
- function createModuleImportUrl(filePath) {
508
- return process.platform === "win32" ? `file://${filePath}` : filePath;
509
- }
510
-
511
- // Copyright 2024 IOTA Stiftung.
512
- // SPDX-License-Identifier: Apache-2.0.
513
- const DEFAULT_NODE_USERNAME = "admin@node";
514
- /**
515
- * Bootstrap the application.
516
- * @param engineCore The engine core for the node.
517
- * @param context The context for the node.
518
- * @param envVars The environment variables for the node.
519
- */
520
- async function bootstrap(engineCore, context, envVars) {
521
- const features = getFeatures(envVars);
522
- await bootstrapNodeIdentity(engineCore, context, envVars, features);
523
- await bootstrapNodeUser(engineCore, context, envVars, features);
524
- await bootstrapAuth(engineCore, context, envVars);
525
- await bootstrapBlobEncryption(engineCore, context, envVars);
526
- const defaultAttestationConnectorType = engineCore.getRegisteredInstanceTypeOptional("attestationConnector");
527
- if (!core.Is.empty(defaultAttestationConnectorType)) {
528
- await addVerificationMethod(engineCore, context, "attestation", envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID);
529
- }
530
- const defaultImmutableProofComponentType = engineCore.getRegisteredInstanceTypeOptional("immutableProofComponent");
531
- if (!core.Is.empty(defaultImmutableProofComponentType)) {
532
- await addVerificationMethod(engineCore, context, "immutable proof", envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID);
533
- }
534
- if (core.Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
535
- await addVerificationMethod(engineCore, context, "verifiable credential authentication", envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID);
536
- }
537
- await bootstrapSynchronisedStorage(engineCore, context, envVars);
538
- }
539
- /**
540
- * Bootstrap the node creating any necessary resources.
541
- * @param engineCore The engine core for the node.
542
- * @param context The context for the node.
543
- * @param envVars The environment variables for the node.
544
- * @param features The features that are enabled on the node. The features that are enabled on the node.
545
- */
546
- async function bootstrapNodeIdentity(engineCore, context, envVars, features) {
547
- if (features.includes(NodeFeatures.NodeIdentity)) {
548
- // When we bootstrap the node we need to generate an identity for it,
549
- // But we have a chicken and egg problem in that we can't create the identity
550
- // to store the mnemonic in the vault without an identity. We use a temporary identity
551
- // and then replace it with the new identity later in the process.
552
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
553
- const vaultConnector = vaultModels.VaultConnectorFactory.get(defaultVaultConnectorType);
554
- const workingIdentity = envVars.identity ??
555
- context.state.nodeIdentity ??
556
- `bootstrap-temp-${core.Converter.bytesToHex(core.RandomHelper.generate(16))}`;
557
- await bootstrapMnemonic(engineCore, envVars, features, vaultConnector, workingIdentity);
558
- const addresses = await bootstrapWallet(engineCore, envVars, features, workingIdentity);
559
- const finalIdentity = await bootstrapIdentity(engineCore, envVars, features, workingIdentity);
560
- await finaliseWallet(engineCore, envVars, features, finalIdentity, addresses);
561
- await finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity);
562
- context.state.nodeIdentity = finalIdentity;
563
- context.stateDirty = true;
564
- engineCore.logInfo(core.I18n.formatMessage("node.nodeIdentity", {
565
- identity: context.state.nodeIdentity
566
- }));
567
- }
568
- }
569
- /**
570
- * Bootstrap the identity for the node.
571
- * @param engineCore The engine core for the node.
572
- * @param envVars The environment variables for the node.
573
- * @param features The features that are enabled on the node. The features that are enabled on the node.
574
- * @param nodeIdentity The identity of the node.
575
- * @returns The addresses for the wallet.
576
- */
577
- async function bootstrapIdentity(engineCore, envVars, features, nodeIdentity) {
578
- const defaultIdentityConnectorType = engineCore.getRegisteredInstanceType("identityConnector");
579
- // Now create an identity for the node controlled by the address we just funded
580
- const identityConnector = identityModels.IdentityConnectorFactory.get(defaultIdentityConnectorType);
581
- let identityDocument;
582
- try {
583
- const defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType("identityResolverConnector");
584
- const identityResolverConnector = identityModels.IdentityResolverConnectorFactory.get(defaultIdentityResolverConnectorType);
585
- identityDocument = await identityResolverConnector.resolveDocument(nodeIdentity);
586
- engineCore.logInfo(core.I18n.formatMessage("node.existingNodeIdentity", { identity: nodeIdentity }));
587
- }
588
- catch { }
589
- if (core.Is.empty(identityDocument)) {
590
- engineCore.logInfo(core.I18n.formatMessage("node.generatingNodeIdentity"));
591
- identityDocument = await identityConnector.createDocument(nodeIdentity);
592
- engineCore.logInfo(core.I18n.formatMessage("node.createdNodeIdentity", { identity: identityDocument.id }));
593
- }
594
- if (defaultIdentityConnectorType.startsWith(engineTypes.IdentityConnectorType.Iota)) {
595
- const didUrn = core.Urn.fromValidString(identityDocument.id);
596
- const didParts = didUrn.parts();
597
- const objectId = didParts[3];
598
- engineCore.logInfo(core.I18n.formatMessage("node.identityExplorer", {
599
- url: `${envVars.iotaExplorerEndpoint}object/${objectId}?network=${envVars.iotaNetwork}`
600
- }));
601
- }
602
- return identityDocument.id;
603
- }
604
- /**
605
- * Bootstrap the wallet for the node.
606
- * @param engineCore The engine core for the node.
607
- * @param envVars The environment variables for the node.
608
- * @param features The features that are enabled on the node.
609
- * @param nodeIdentity The identity of the node.
610
- * @returns The addresses for the wallet.
611
- */
612
- async function bootstrapWallet(engineCore, envVars, features, nodeIdentity) {
613
- if (features.includes(NodeFeatures.NodeWallet)) {
614
- const defaultWalletConnectorType = engineCore.getRegisteredInstanceType("walletConnector");
615
- const walletConnector = walletModels.WalletConnectorFactory.get(defaultWalletConnectorType);
616
- const addresses = await walletConnector.getAddresses(nodeIdentity, 0, 0, 5);
617
- const balance = await walletConnector.getBalance(nodeIdentity, addresses[0]);
618
- if (balance === 0n) {
619
- let address0 = addresses[0];
620
- if (defaultWalletConnectorType.startsWith(engineTypes.WalletConnectorType.Iota)) {
621
- address0 = `${envVars.iotaExplorerEndpoint}address/${address0}?network=${envVars.iotaNetwork}`;
622
- }
623
- engineCore.logInfo(core.I18n.formatMessage("node.fundingWallet", { address: address0 }));
624
- // Add some funds to the wallet from the faucet
625
- await walletConnector.ensureBalance(nodeIdentity, addresses[0], 1000000000n);
626
- }
627
- else {
628
- engineCore.logInfo(core.I18n.formatMessage("node.fundedWallet"));
629
- }
630
- return addresses;
631
- }
632
- return [];
633
- }
634
- /**
635
- * Bootstrap the identity for the node.
636
- * @param engineCore The engine core for the node.
637
- * @param envVars The environment variables for the node.
638
- * @param features The features that are enabled on the node.
639
- * @param finalIdentity The identity of the node.
640
- * @param addresses The addresses for the wallet.
641
- */
642
- async function finaliseWallet(engineCore, envVars, features, finalIdentity, addresses) {
643
- if (features.includes(NodeFeatures.NodeWallet)) {
644
- const defaultWalletConnectorType = engineCore.getRegisteredInstanceType("walletConnector");
645
- // If we are using entity storage for wallet the identity associated with the
646
- // address will be wrong, so fix it
647
- if (defaultWalletConnectorType.startsWith(engineTypes.WalletConnectorType.EntityStorage)) {
648
- const walletAddress = entityStorageModels.EntityStorageConnectorFactory.get("wallet-address");
649
- const addr = await walletAddress.get(addresses[0]);
650
- if (!core.Is.empty(addr)) {
651
- addr.identity = finalIdentity;
652
- await walletAddress.set(addr);
653
- }
654
- }
655
- }
656
- }
657
- /**
658
- * Generate a mnemonic for the node identity.
659
- * @param engineCore The engine core for the node.
660
- * @param envVars The environment variables for the node.
661
- * @param features The features that are enabled on the node.
662
- * @param vaultConnector The vault connector to use.
663
- * @param nodeIdentity The identity of the node.
664
- */
665
- async function bootstrapMnemonic(engineCore, envVars, features, vaultConnector, nodeIdentity) {
666
- let mnemonic = envVars.mnemonic;
667
- let storeMnemonic = false;
668
- try {
669
- const storedMnemonic = await vaultConnector.getSecret(`${nodeIdentity}/mnemonic`);
670
- storeMnemonic = storedMnemonic !== mnemonic;
671
- mnemonic = storedMnemonic;
672
- }
673
- catch {
674
- storeMnemonic = true;
675
- }
676
- // If there is no mnemonic then we need to generate one
677
- if (core.Is.empty(mnemonic)) {
678
- mnemonic = crypto.Bip39.randomMnemonic();
679
- storeMnemonic = true;
680
- engineCore.logInfo(core.I18n.formatMessage("node.generatingMnemonic", { mnemonic }));
681
- }
682
- // If there is no mnemonic stored in the vault then we need to store it
683
- if (storeMnemonic) {
684
- engineCore.logInfo(core.I18n.formatMessage("node.storingMnemonic"));
685
- await vaultConnector.setSecret(`${nodeIdentity}/mnemonic`, mnemonic);
686
- }
687
- else {
688
- engineCore.logInfo(core.I18n.formatMessage("node.existingMnemonic"));
689
- }
690
- }
691
- /**
692
- * Finalise the mnemonic for the node identity.
693
- * @param vaultConnector The vault connector to use.
694
- * @param workingIdentity The identity of the node.
695
- * @param finalIdentity The final identity for the node.
696
- */
697
- async function finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity) {
698
- // Now that we have an identity we can remove the temporary one
699
- // and store the mnemonic with the new identity
700
- if (workingIdentity.startsWith("bootstrap-temp-") && workingIdentity !== finalIdentity) {
701
- const mnemonic = await vaultConnector.getSecret(`${workingIdentity}/mnemonic`);
702
- await vaultConnector.setSecret(`${finalIdentity}/mnemonic`, mnemonic);
703
- await vaultConnector.removeSecret(`${workingIdentity}/mnemonic`);
704
- }
705
- }
706
- /**
707
- * Bootstrap the user.
708
- * @param engineCore The engine core for the node.
709
- * @param context The context for the node.
710
- * @param envVars The environment variables for the node.
711
- * @param features The features that are enabled on the node.
712
- */
713
- async function bootstrapNodeUser(engineCore, context, envVars, features) {
714
- if (features.includes(NodeFeatures.NodeUser)) {
715
- const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceType("authenticationComponent");
716
- if (defaultAuthenticationComponentType.startsWith(engineServerTypes.AuthenticationComponentType.EntityStorage) &&
717
- core.Is.stringValue(context.state.nodeIdentity)) {
718
- const authUserEntityStorage = entityStorageModels.EntityStorageConnectorFactory.get("authentication-user");
719
- const email = envVars.username ?? DEFAULT_NODE_USERNAME;
720
- let nodeAdminUser = await authUserEntityStorage.get(email);
721
- if (core.Is.empty(nodeAdminUser)) {
722
- engineCore.logInfo(core.I18n.formatMessage("node.creatingNodeUser", { email }));
723
- const generatedPassword = envVars.password ?? crypto.PasswordGenerator.generate(16);
724
- const passwordBytes = core.Converter.utf8ToBytes(generatedPassword);
725
- const saltBytes = core.RandomHelper.generate(16);
726
- const hashedPassword = await apiAuthEntityStorageService.PasswordHelper.hashPassword(passwordBytes, saltBytes);
727
- nodeAdminUser = {
728
- email,
729
- password: hashedPassword,
730
- salt: core.Converter.bytesToBase64(saltBytes),
731
- identity: context.state.nodeIdentity
732
- };
733
- engineCore.logInfo(core.I18n.formatMessage("node.nodeAdminUserEmail", { email: nodeAdminUser.email }));
734
- engineCore.logInfo(core.I18n.formatMessage("node.nodeAdminUserPassword", { password: generatedPassword }));
735
- await authUserEntityStorage.set(nodeAdminUser);
736
- }
737
- else {
738
- engineCore.logInfo(core.I18n.formatMessage("node.existingNodeUser", { email }));
739
- // The user already exists, so double check the other details match
740
- let needsUpdate = false;
741
- if (nodeAdminUser.identity !== context.state.nodeIdentity) {
742
- nodeAdminUser.identity = context.state.nodeIdentity;
743
- needsUpdate = true;
744
- }
745
- if (core.Is.stringValue(envVars.password)) {
746
- const passwordBytes = core.Converter.utf8ToBytes(envVars.password);
747
- const saltBytes = core.Converter.base64ToBytes(nodeAdminUser.salt);
748
- const hashedPassword = await apiAuthEntityStorageService.PasswordHelper.hashPassword(passwordBytes, saltBytes);
749
- if (nodeAdminUser.password !== hashedPassword) {
750
- nodeAdminUser.password = hashedPassword;
751
- needsUpdate = true;
752
- }
753
- }
754
- if (needsUpdate) {
755
- await authUserEntityStorage.set(nodeAdminUser);
756
- }
757
- }
758
- // We have create a node user, now we need to create a profile for the user
759
- const defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType("identityProfileConnector");
760
- const identityProfileConnector = identityModels.IdentityProfileConnectorFactory.get(defaultIdentityProfileConnectorType);
761
- if (identityProfileConnector) {
762
- let userProfile;
763
- try {
764
- userProfile = await identityProfileConnector.get(context.state.nodeIdentity);
765
- }
766
- catch { }
767
- if (core.Is.empty(userProfile)) {
768
- engineCore.logInfo(core.I18n.formatMessage("node.creatingUserProfile", { identity: context.state.nodeIdentity }));
769
- const publicProfile = {
770
- "@context": "https://schema.org",
771
- "@type": "Person",
772
- name: "Node Administrator"
773
- };
774
- const privateProfile = {
775
- "@context": "https://schema.org",
776
- "@type": "Person",
777
- givenName: "Node",
778
- familyName: "Administrator",
779
- email
780
- };
781
- await identityProfileConnector.create(context.state.nodeIdentity, publicProfile, privateProfile);
782
- }
783
- else {
784
- engineCore.logInfo(core.I18n.formatMessage("node.existingUserProfile", { identity: context.state.nodeIdentity }));
785
- }
786
- }
787
- }
788
- }
789
- }
790
- /**
791
- * Bootstrap the immutable proof verification methods.
792
- * @param engineCore The engine core for the node.
793
- * @param context The context for the node.
794
- * @param envVars The environment variables for the node.
795
- * @param features The features that are enabled on the node.
796
- */
797
- async function bootstrapImmutableProofMethod(engineCore, context, envVars, features) { }
798
- /**
799
- * Bootstrap the keys for blob encryption.
800
- * @param engineCore The engine core for the node.
801
- * @param context The context for the node.
802
- * @param envVars The environment variables for the node.
803
- * @param features The features that are enabled on the node.
804
- */
805
- async function bootstrapBlobEncryption(engineCore, context, envVars, features) {
806
- if ((core.Coerce.boolean(envVars.blobStorageEnableEncryption) ?? false) &&
807
- core.Is.stringValue(context.state.nodeIdentity)) {
808
- // Create a new key for encrypting blobs
809
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
810
- const vaultConnector = vaultModels.VaultConnectorFactory.get(defaultVaultConnectorType);
811
- const keyName = `${context.state.nodeIdentity}/${envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID}`;
812
- let existingKey;
813
- try {
814
- existingKey = await vaultConnector.getKey(keyName);
815
- }
816
- catch { }
817
- if (core.Is.empty(existingKey)) {
818
- if (core.Is.stringBase64(envVars.blobStorageSymmetricEncryptionKey)) {
819
- engineCore.logInfo(core.I18n.formatMessage("node.addingBlobEncryptionKey", { keyName }));
820
- await vaultConnector.addKey(keyName, vaultModels.VaultKeyType.ChaCha20Poly1305, core.Converter.base64ToBytes(envVars.blobStorageSymmetricEncryptionKey));
821
- }
822
- else {
823
- engineCore.logInfo(core.I18n.formatMessage("node.creatingBlobEncryptionKey", { keyName }));
824
- const key = await vaultConnector.createKey(keyName, vaultModels.VaultKeyType.ChaCha20Poly1305);
825
- engineCore.logInfo(core.I18n.formatMessage("node.createdBlobEncryptionKey", {
826
- keyName,
827
- keyValue: core.Converter.bytesToBase64(key)
828
- }));
829
- }
830
- }
831
- else {
832
- engineCore.logInfo(core.I18n.formatMessage("node.existingBlobEncryptionKey", { keyName }));
833
- }
834
- }
835
- }
836
- /**
837
- * Bootstrap the JWT signing key.
838
- * @param engineCore The engine core for the node.
839
- * @param context The context for the node.
840
- * @param envVars The environment variables for the node.
841
- * @param features The features that are enabled on the node.
842
- */
843
- async function bootstrapAuth(engineCore, context, envVars, features) {
844
- const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceTypeOptional("authenticationComponent");
845
- if (core.Is.stringValue(defaultAuthenticationComponentType) &&
846
- defaultAuthenticationComponentType.startsWith(engineServerTypes.AuthenticationComponentType.EntityStorage) &&
847
- core.Is.stringValue(context.state.nodeIdentity)) {
848
- // Create a new JWT signing key and a user login for the node
849
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
850
- const vaultConnector = vaultModels.VaultConnectorFactory.get(defaultVaultConnectorType);
851
- const keyName = `${context.state.nodeIdentity}/${envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID}`;
852
- let existingKey;
853
- try {
854
- existingKey = await vaultConnector.getKey(keyName);
855
- }
856
- catch { }
857
- if (core.Is.empty(existingKey)) {
858
- engineCore.logInfo(core.I18n.formatMessage("node.creatingAuthKey", { keyName }));
859
- await vaultConnector.createKey(keyName, vaultModels.VaultKeyType.Ed25519);
860
- }
861
- else {
862
- engineCore.logInfo(core.I18n.formatMessage("node.existingAuthKey", { keyName }));
863
- }
864
- }
865
- }
866
- /**
867
- * Bootstrap the synchronised storage blob encryption and verification methods.
868
- * @param engineCore The engine core for the node.
869
- * @param context The context for the node.
870
- * @param envVars The environment variables for the node.
871
- * @param features The features that are enabled on the node.
872
- */
873
- async function bootstrapSynchronisedStorage(engineCore, context, envVars, features) {
874
- if (core.Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false) {
875
- // If this is a trusted node we need to add the blob encryption key pair
876
- if (core.Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {
877
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
878
- const vaultConnector = vaultModels.VaultConnectorFactory.get(defaultVaultConnectorType);
879
- const keyName = envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
880
- SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;
881
- let existingKey;
882
- try {
883
- existingKey = await vaultConnector.getKey(keyName);
884
- }
885
- catch { }
886
- if (core.Is.empty(existingKey)) {
887
- engineCore.logInfo(core.I18n.formatMessage("node.addingSynchronisedStorageBlobEncryptionKey", { keyName }));
888
- await vaultConnector.addKey(keyName, vaultModels.VaultKeyType.ChaCha20Poly1305, core.Converter.base64ToBytes(envVars.synchronisedStorageBlobStorageKey));
889
- }
890
- else {
891
- engineCore.logInfo(core.I18n.formatMessage("node.existingSynchronisedStorageBlobEncryptionKey", { keyName }));
892
- }
893
- }
894
- }
895
- }
896
- /**
897
- * Add a verification method if it doesn't exist.
898
- * @param engineCore The engine core for the node.
899
- * @param context The context for the node.
900
- * @param verificationMethodTitle The verification method title.
901
- * @param verificationMethodId The verification method ID.
902
- */
903
- async function addVerificationMethod(engineCore, context, verificationMethodTitle, verificationMethodId) {
904
- if (core.Is.stringValue(context.state.nodeIdentity) &&
905
- core.Is.arrayValue(context.config.types.identityConnector) &&
906
- core.Is.stringValue(verificationMethodId)) {
907
- const defaultIdentityConnectorType = engineCore.getRegisteredInstanceType("identityConnector");
908
- const identityConnector = identityModels.IdentityConnectorFactory.get(defaultIdentityConnectorType);
909
- const defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType("identityResolverConnector");
910
- const identityResolverConnector = identityModels.IdentityResolverConnectorFactory.get(defaultIdentityResolverConnectorType);
911
- const identityDocument = await identityResolverConnector.resolveDocument(context.state.nodeIdentity);
912
- const fullMethodId = `${identityDocument.id}#${verificationMethodId}`;
913
- let exists = false;
914
- try {
915
- identityModels.DocumentHelper.getVerificationMethod(identityDocument, fullMethodId, "assertionMethod");
916
- exists = true;
917
- }
918
- catch { }
919
- if (!exists) {
920
- engineCore.logInfo(core.I18n.formatMessage("node.addingVerificationMethod", {
921
- title: verificationMethodTitle,
922
- methodId: fullMethodId
923
- }));
924
- await identityConnector.addVerificationMethod(context.state.nodeIdentity, context.state.nodeIdentity, "assertionMethod", verificationMethodId);
925
- }
926
- else {
927
- engineCore.logInfo(core.I18n.formatMessage("node.existingVerificationMethod", {
928
- title: verificationMethodTitle,
929
- methodId: fullMethodId
930
- }));
931
- }
932
- }
933
- }
934
-
935
- // Copyright 2024 IOTA Stiftung.
936
- // SPDX-License-Identifier: Apache-2.0.
937
- /**
938
- * Build the engine core configuration from environment variables.
939
- * @param envVars The environment variables.
940
- * @returns The config for the core.
941
- */
942
- async function buildEngineConfiguration(envVars) {
943
- if (core.Is.stringValue(envVars.storageFileRoot)) {
944
- envVars.stateFilename ??= "engine-state.json";
945
- envVars.storageFileRoot = path.resolve(envVars.storageFileRoot);
946
- envVars.stateFilename = path.join(envVars.storageFileRoot, envVars.stateFilename);
947
- }
948
- const coreConfig = {
949
- debug: core.Coerce.boolean(envVars.debug) ?? false,
950
- types: {}
951
- };
952
- await configureEntityStorage(coreConfig, envVars);
953
- await configureBlobStorage(coreConfig, envVars);
954
- await configureVault(coreConfig, envVars);
955
- await configureDlt(coreConfig, envVars);
956
- await configureLogging(coreConfig, envVars);
957
- await configureBackgroundTask(coreConfig, envVars);
958
- await configureTaskScheduler(coreConfig, envVars);
959
- await configureEventBus(coreConfig, envVars);
960
- await configureTelemetry(coreConfig, envVars);
961
- await configureMessaging(coreConfig, envVars);
962
- await configureFaucet(coreConfig, envVars);
963
- await configureWallet(coreConfig, envVars);
964
- await configureNft(coreConfig, envVars);
965
- await configureVerifiableStorage(coreConfig, envVars);
966
- await configureIdentity(coreConfig, envVars);
967
- await configureIdentityResolver(coreConfig, envVars);
968
- await configureIdentityProfile(coreConfig, envVars);
969
- await configureAttestation(coreConfig, envVars);
970
- await configureDataProcessing(coreConfig, envVars);
971
- await configureAuditableItemGraph(coreConfig, envVars);
972
- await configureAuditableItemStream(coreConfig, envVars);
973
- await configureDocumentManagement(coreConfig, envVars);
974
- await configureVerifiableCredentialAuthentication(coreConfig, envVars);
975
- await configureRightsManagement(coreConfig, envVars);
976
- await configureSynchronisedStorage(coreConfig, envVars);
977
- await configureFederatedCatalogue(coreConfig, envVars);
978
- await configureDataSpaceConnector(coreConfig, envVars);
979
- return coreConfig;
980
- }
981
- /**
982
- * Configures the entity storage.
983
- * @param coreConfig The core config.
984
- * @param envVars The environment variables.
985
- */
986
- async function configureEntityStorage(coreConfig, envVars) {
987
- coreConfig.types ??= {};
988
- coreConfig.types.entityStorageConnector ??= [];
989
- const entityStorageConnectorTypes = envVars.entityStorageConnectorType?.split(",") ?? [];
990
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.Memory)) {
991
- coreConfig.types.entityStorageConnector.push({
992
- type: engineTypes.EntityStorageConnectorType.Memory
993
- });
994
- }
995
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.File)) {
996
- coreConfig.types.entityStorageConnector.push({
997
- type: engineTypes.EntityStorageConnectorType.File,
998
- options: {
999
- config: { directory: envVars.storageFileRoot ?? "" },
1000
- folderPrefix: envVars.entityStorageTablePrefix
1001
- }
1002
- });
1003
- }
1004
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.AwsDynamoDb)) {
1005
- coreConfig.types.entityStorageConnector.push({
1006
- type: engineTypes.EntityStorageConnectorType.AwsDynamoDb,
1007
- options: {
1008
- config: {
1009
- region: envVars.awsDynamodbRegion ?? "",
1010
- authMode: envVars.awsDynamodbAuthMode,
1011
- accessKeyId: envVars.awsDynamodbAccessKeyId,
1012
- secretAccessKey: envVars.awsDynamodbSecretAccessKey,
1013
- endpoint: envVars.awsDynamodbEndpoint
1014
- },
1015
- tablePrefix: envVars.entityStorageTablePrefix
1016
- }
1017
- });
1018
- }
1019
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.AzureCosmosDb)) {
1020
- coreConfig.types.entityStorageConnector.push({
1021
- type: engineTypes.EntityStorageConnectorType.AzureCosmosDb,
1022
- options: {
1023
- config: {
1024
- endpoint: envVars.azureCosmosdbEndpoint ?? "",
1025
- key: envVars.azureCosmosdbKey ?? "",
1026
- databaseId: envVars.azureCosmosdbDatabaseId ?? "",
1027
- containerId: envVars.azureCosmosdbContainerId ?? ""
1028
- },
1029
- tablePrefix: envVars.entityStorageTablePrefix
1030
- }
1031
- });
1032
- }
1033
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.GcpFirestoreDb)) {
1034
- coreConfig.types.entityStorageConnector.push({
1035
- type: engineTypes.EntityStorageConnectorType.GcpFirestoreDb,
1036
- options: {
1037
- config: {
1038
- projectId: envVars.gcpFirestoreProjectId ?? "",
1039
- credentials: envVars.gcpFirestoreCredentials ?? "",
1040
- databaseId: envVars.gcpFirestoreDatabaseId ?? "",
1041
- collectionName: envVars.gcpFirestoreCollectionName ?? "",
1042
- endpoint: envVars.gcpFirestoreApiEndpoint ?? ""
1043
- },
1044
- tablePrefix: envVars.entityStorageTablePrefix
1045
- }
1046
- });
1047
- }
1048
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.ScyllaDb)) {
1049
- coreConfig.types.entityStorageConnector.push({
1050
- type: engineTypes.EntityStorageConnectorType.ScyllaDb,
1051
- options: {
1052
- config: {
1053
- hosts: envVars.scylladbHosts?.split(",") ?? [],
1054
- localDataCenter: envVars.scylladbLocalDataCenter ?? "",
1055
- keyspace: envVars.scylladbKeyspace ?? "",
1056
- port: core.Coerce.integer(envVars.scylladbPort)
1057
- },
1058
- tablePrefix: envVars.entityStorageTablePrefix
1059
- }
1060
- });
1061
- }
1062
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.MySqlDb)) {
1063
- coreConfig.types.entityStorageConnector.push({
1064
- type: engineTypes.EntityStorageConnectorType.MySqlDb,
1065
- options: {
1066
- config: {
1067
- host: envVars.mySqlHost ?? "",
1068
- port: core.Coerce.integer(envVars.mySqlPort),
1069
- user: envVars.mySqlUser ?? "",
1070
- password: envVars.mySqlPassword ?? "",
1071
- database: envVars.mySqlDatabase ?? ""
1072
- },
1073
- tablePrefix: envVars.entityStorageTablePrefix
1074
- }
1075
- });
1076
- }
1077
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.MongoDb)) {
1078
- coreConfig.types.entityStorageConnector.push({
1079
- type: engineTypes.EntityStorageConnectorType.MongoDb,
1080
- options: {
1081
- config: {
1082
- host: envVars.mongoDbHost ?? "",
1083
- port: core.Coerce.integer(envVars.mongoDbPort),
1084
- user: envVars.mongoDbUser ?? "",
1085
- password: envVars.mongoDbPassword ?? "",
1086
- database: envVars.mongoDbDatabase ?? ""
1087
- },
1088
- tablePrefix: envVars.entityStorageTablePrefix
1089
- }
1090
- });
1091
- }
1092
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.PostgreSql)) {
1093
- coreConfig.types.entityStorageConnector.push({
1094
- type: engineTypes.EntityStorageConnectorType.PostgreSql,
1095
- options: {
1096
- config: {
1097
- host: envVars.postgreSqlHost ?? "",
1098
- port: core.Coerce.integer(envVars.postgreSqlPort),
1099
- user: envVars.postgreSqlUser ?? "",
1100
- password: envVars.postgreSqlPassword ?? "",
1101
- database: envVars.postgreSqlDatabase ?? ""
1102
- },
1103
- tablePrefix: envVars.entityStorageTablePrefix
1104
- }
1105
- });
1106
- }
1107
- const defaultEntityStorageConnectorType = envVars.entityStorageConnectorDefault ?? entityStorageConnectorTypes[0];
1108
- if (entityStorageConnectorTypes.includes(engineTypes.EntityStorageConnectorType.Synchronised)) {
1109
- // For synchronised storage we use the default connector as the one we wrap for real DB operations
1110
- coreConfig.types.entityStorageConnector.push({
1111
- type: engineTypes.EntityStorageConnectorType.Synchronised,
1112
- options: {
1113
- entityStorageConnectorType: defaultEntityStorageConnectorType
1114
- }
1115
- });
1116
- }
1117
- if (core.Is.arrayValue(entityStorageConnectorTypes)) {
1118
- for (const config of coreConfig.types.entityStorageConnector) {
1119
- if (config.type === defaultEntityStorageConnectorType) {
1120
- config.isDefault = true;
1121
- break;
1122
- }
1123
- }
1124
- }
1125
- }
1126
- /**
1127
- * Configures the blob storage.
1128
- * @param coreConfig The core config.
1129
- * @param envVars The environment variables.
1130
- */
1131
- async function configureBlobStorage(coreConfig, envVars) {
1132
- coreConfig.types.blobStorageConnector ??= [];
1133
- const blobStorageConnectorTypes = envVars.blobStorageConnectorType?.split(",") ?? [];
1134
- if (blobStorageConnectorTypes.includes(engineTypes.BlobStorageConnectorType.Memory)) {
1135
- coreConfig.types.blobStorageConnector.push({
1136
- type: engineTypes.BlobStorageConnectorType.Memory
1137
- });
1138
- }
1139
- if (blobStorageConnectorTypes.includes(engineTypes.BlobStorageConnectorType.File)) {
1140
- coreConfig.types.blobStorageConnector.push({
1141
- type: engineTypes.BlobStorageConnectorType.File,
1142
- options: {
1143
- config: {
1144
- directory: core.Is.stringValue(envVars.storageFileRoot)
1145
- ? path.join(envVars.storageFileRoot, "blob-storage")
1146
- : ""
1147
- },
1148
- storagePrefix: envVars.blobStoragePrefix
1149
- }
1150
- });
1151
- }
1152
- if (blobStorageConnectorTypes.includes(engineTypes.BlobStorageConnectorType.Ipfs)) {
1153
- coreConfig.types.blobStorageConnector.push({
1154
- type: engineTypes.BlobStorageConnectorType.Ipfs,
1155
- options: {
1156
- config: {
1157
- apiUrl: envVars.ipfsApiUrl ?? "",
1158
- bearerToken: envVars.ipfsBearerToken
1159
- }
1160
- }
1161
- });
1162
- }
1163
- if (blobStorageConnectorTypes.includes(engineTypes.BlobStorageConnectorType.AwsS3)) {
1164
- coreConfig.types.blobStorageConnector.push({
1165
- type: engineTypes.BlobStorageConnectorType.AwsS3,
1166
- options: {
1167
- config: {
1168
- region: envVars.awsS3Region ?? "",
1169
- bucketName: envVars.awsS3BucketName ?? "",
1170
- authMode: envVars.awsS3AuthMode,
1171
- accessKeyId: envVars.awsS3AccessKeyId,
1172
- secretAccessKey: envVars.awsS3SecretAccessKey,
1173
- endpoint: envVars.awsS3Endpoint
1174
- },
1175
- storagePrefix: envVars.blobStoragePrefix
1176
- }
1177
- });
1178
- }
1179
- if (blobStorageConnectorTypes.includes(engineTypes.BlobStorageConnectorType.AzureStorage)) {
1180
- coreConfig.types.blobStorageConnector.push({
1181
- type: engineTypes.BlobStorageConnectorType.AzureStorage,
1182
- options: {
1183
- config: {
1184
- accountName: envVars.azureStorageAccountName ?? "",
1185
- accountKey: envVars.azureStorageAccountKey ?? "",
1186
- containerName: envVars.azureStorageContainerName ?? "",
1187
- endpoint: envVars.azureStorageEndpoint ?? ""
1188
- },
1189
- storagePrefix: envVars.blobStoragePrefix
1190
- }
1191
- });
1192
- }
1193
- if (blobStorageConnectorTypes.includes(engineTypes.BlobStorageConnectorType.GcpStorage)) {
1194
- coreConfig.types.blobStorageConnector.push({
1195
- type: engineTypes.BlobStorageConnectorType.GcpStorage,
1196
- options: {
1197
- config: {
1198
- projectId: envVars.gcpStorageProjectId ?? "",
1199
- credentials: envVars.gcpStorageCredentials ?? "",
1200
- bucketName: envVars.gcpStorageBucketName ?? "",
1201
- apiEndpoint: envVars.gcpFirestoreApiEndpoint
1202
- },
1203
- storagePrefix: envVars.blobStoragePrefix
1204
- }
1205
- });
1206
- }
1207
- if (core.Is.arrayValue(blobStorageConnectorTypes)) {
1208
- const defaultStorageConnectorType = envVars.blobStorageConnectorDefault ?? blobStorageConnectorTypes[0];
1209
- for (const config of coreConfig.types.blobStorageConnector) {
1210
- if (config.type === defaultStorageConnectorType) {
1211
- config.isDefault = true;
1212
- }
1213
- // If this blob storage connector is the one to use for public access
1214
- // then add it as a feature
1215
- if (core.Is.stringValue(envVars.blobStorageConnectorPublic) &&
1216
- config.type === envVars.blobStorageConnectorPublic) {
1217
- config.features ??= [];
1218
- config.features.push("public");
1219
- break;
1220
- }
1221
- }
1222
- }
1223
- if (coreConfig.types.blobStorageConnector.length > 0) {
1224
- coreConfig.types.blobStorageComponent ??= [];
1225
- coreConfig.types.blobStorageComponent.push({
1226
- type: engineTypes.BlobStorageComponentType.Service,
1227
- options: {
1228
- config: {
1229
- vaultKeyId: (envVars.blobStorageEnableEncryption ?? false)
1230
- ? (envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID)
1231
- : undefined
1232
- }
1233
- }
1234
- });
1235
- }
1236
- }
1237
- /**
1238
- * Configures the logging.
1239
- * @param coreConfig The core config.
1240
- * @param envVars The environment variables.
1241
- */
1242
- async function configureLogging(coreConfig, envVars) {
1243
- coreConfig.types.loggingConnector ??= [];
1244
- const loggingConnectorTypes = (envVars.loggingConnector ?? "").split(",");
1245
- let additionalConnectorCount = 0;
1246
- for (const loggingConnector of loggingConnectorTypes) {
1247
- if (loggingConnector === engineTypes.LoggingConnectorType.Console) {
1248
- coreConfig.types.loggingConnector.push({
1249
- type: engineTypes.LoggingConnectorType.Console,
1250
- options: {
1251
- config: {
1252
- translateMessages: true,
1253
- hideGroups: true
1254
- }
1255
- }
1256
- });
1257
- additionalConnectorCount++;
1258
- }
1259
- else if (loggingConnector === engineTypes.LoggingConnectorType.EntityStorage) {
1260
- coreConfig.types.loggingConnector.push({
1261
- type: engineTypes.LoggingConnectorType.EntityStorage
1262
- });
1263
- additionalConnectorCount++;
1264
- }
1265
- }
1266
- // If more than one logging connector, then we need to add a multi connector
1267
- // and set it as the default one
1268
- if (additionalConnectorCount > 1) {
1269
- coreConfig.types.loggingConnector.push({
1270
- type: engineTypes.LoggingConnectorType.Multi,
1271
- options: {
1272
- loggingConnectorTypes
1273
- },
1274
- isDefault: true
1275
- });
1276
- }
1277
- else if (additionalConnectorCount > 0) {
1278
- // If only one connector, then we set it as the default one
1279
- coreConfig.types.loggingConnector[coreConfig.types.loggingConnector.length - 1].isDefault =
1280
- true;
1281
- }
1282
- if (additionalConnectorCount > 0) {
1283
- coreConfig.types.loggingComponent ??= [];
1284
- // We set the isDefault flag so that other components will get this service by default
1285
- // and not the generic one from the engine core
1286
- coreConfig.types.loggingComponent.push({ type: engineTypes.LoggingComponentType.Service, isDefault: true });
1287
- }
1288
- }
1289
- /**
1290
- * Configures the vault.
1291
- * @param coreConfig The core config.
1292
- * @param envVars The environment variables.
1293
- */
1294
- async function configureVault(coreConfig, envVars) {
1295
- coreConfig.types.vaultConnector ??= [];
1296
- if (envVars.vaultConnector === engineTypes.VaultConnectorType.EntityStorage) {
1297
- coreConfig.types.vaultConnector.push({
1298
- type: engineTypes.VaultConnectorType.EntityStorage
1299
- });
1300
- }
1301
- else if (envVars.vaultConnector === engineTypes.VaultConnectorType.Hashicorp) {
1302
- coreConfig.types.vaultConnector.push({
1303
- type: engineTypes.VaultConnectorType.Hashicorp,
1304
- options: {
1305
- config: {
1306
- endpoint: envVars.hashicorpVaultEndpoint ?? "",
1307
- token: envVars.hashicorpVaultToken ?? ""
1308
- }
1309
- }
1310
- });
1311
- }
1312
- }
1313
- /**
1314
- * Configures the background task.
1315
- * @param coreConfig The core config.
1316
- * @param envVars The environment variables.
1317
- */
1318
- async function configureBackgroundTask(coreConfig, envVars) {
1319
- coreConfig.types.backgroundTaskConnector ??= [];
1320
- if (envVars.backgroundTaskConnector === engineTypes.BackgroundTaskConnectorType.EntityStorage) {
1321
- coreConfig.types.backgroundTaskConnector.push({
1322
- type: engineTypes.BackgroundTaskConnectorType.EntityStorage
1323
- });
1324
- }
1325
- }
1326
- /**
1327
- * Configures the event bud.
1328
- * @param coreConfig The core config.
1329
- * @param envVars The environment variables.
1330
- */
1331
- async function configureEventBus(coreConfig, envVars) {
1332
- coreConfig.types.eventBusConnector ??= [];
1333
- if (envVars.eventBusConnector === engineTypes.EventBusConnectorType.Local) {
1334
- coreConfig.types.eventBusConnector.push({
1335
- type: engineTypes.EventBusConnectorType.Local
1336
- });
1337
- }
1338
- if (coreConfig.types.eventBusConnector.length > 0) {
1339
- coreConfig.types.eventBusComponent ??= [];
1340
- coreConfig.types.eventBusComponent.push({ type: engineTypes.EventBusComponentType.Service });
1341
- }
1342
- }
1343
- /**
1344
- * Configures the telemetry.
1345
- * @param coreConfig The core config.
1346
- * @param envVars The environment variables.
1347
- */
1348
- async function configureTelemetry(coreConfig, envVars) {
1349
- coreConfig.types.telemetryConnector ??= [];
1350
- if (envVars.telemetryConnector === engineTypes.TelemetryConnectorType.EntityStorage) {
1351
- coreConfig.types.telemetryConnector.push({
1352
- type: engineTypes.TelemetryConnectorType.EntityStorage
1353
- });
1354
- }
1355
- if (coreConfig.types.telemetryConnector.length > 0) {
1356
- coreConfig.types.telemetryComponent ??= [];
1357
- coreConfig.types.telemetryComponent.push({ type: engineTypes.TelemetryComponentType.Service });
1358
- }
1359
- }
1360
- /**
1361
- * Configures the messaging.
1362
- * @param coreConfig The core config.
1363
- * @param envVars The environment variables.
1364
- */
1365
- async function configureMessaging(coreConfig, envVars) {
1366
- if (core.Coerce.boolean(envVars.messagingEnabled) ?? false) {
1367
- coreConfig.types.messagingEmailConnector ??= [];
1368
- coreConfig.types.messagingSmsConnector ??= [];
1369
- coreConfig.types.messagingPushNotificationConnector ??= [];
1370
- if (envVars.messagingEmailConnector === engineTypes.MessagingEmailConnectorType.EntityStorage) {
1371
- coreConfig.types.messagingEmailConnector.push({
1372
- type: engineTypes.MessagingEmailConnectorType.EntityStorage
1373
- });
1374
- }
1375
- else if (envVars.messagingEmailConnector === engineTypes.MessagingEmailConnectorType.Aws) {
1376
- coreConfig.types.messagingEmailConnector.push({
1377
- type: engineTypes.MessagingEmailConnectorType.Aws,
1378
- options: {
1379
- config: {
1380
- region: envVars.awsSesRegion ?? "",
1381
- authMode: envVars.awsSesAuthMode,
1382
- accessKeyId: envVars.awsSesAccessKeyId,
1383
- secretAccessKey: envVars.awsSesSecretAccessKey,
1384
- endpoint: envVars.awsSesEndpoint
1385
- }
1386
- }
1387
- });
1388
- }
1389
- if (envVars.messagingSmsConnector === engineTypes.MessagingSmsConnectorType.EntityStorage) {
1390
- coreConfig.types.messagingSmsConnector.push({
1391
- type: engineTypes.MessagingSmsConnectorType.EntityStorage
1392
- });
1393
- }
1394
- else if (envVars.messagingSmsConnector === engineTypes.MessagingSmsConnectorType.Aws) {
1395
- coreConfig.types.messagingSmsConnector.push({
1396
- type: engineTypes.MessagingSmsConnectorType.Aws,
1397
- options: {
1398
- config: {
1399
- region: envVars.awsSesRegion ?? "",
1400
- authMode: envVars.awsSesAuthMode,
1401
- accessKeyId: envVars.awsSesAccessKeyId,
1402
- secretAccessKey: envVars.awsSesSecretAccessKey,
1403
- endpoint: envVars.awsSesEndpoint
1404
- }
1405
- }
1406
- });
1407
- }
1408
- if (envVars.messagingPushNotificationConnector ===
1409
- engineTypes.MessagingPushNotificationConnectorType.EntityStorage) {
1410
- coreConfig.types.messagingPushNotificationConnector.push({
1411
- type: engineTypes.MessagingPushNotificationConnectorType.EntityStorage
1412
- });
1413
- }
1414
- else if (envVars.messagingPushNotificationConnector === engineTypes.MessagingPushNotificationConnectorType.Aws) {
1415
- coreConfig.types.messagingPushNotificationConnector.push({
1416
- type: engineTypes.MessagingPushNotificationConnectorType.Aws,
1417
- options: {
1418
- config: {
1419
- region: envVars.awsSesRegion ?? "",
1420
- authMode: envVars.awsSesAuthMode,
1421
- accessKeyId: envVars.awsSesAccessKeyId,
1422
- secretAccessKey: envVars.awsSesSecretAccessKey,
1423
- endpoint: envVars.awsSesEndpoint,
1424
- applicationsSettings: core.Is.json(envVars.awsMessagingPushNotificationApplications)
1425
- ? JSON.parse(envVars.awsMessagingPushNotificationApplications)
1426
- : []
1427
- }
1428
- }
1429
- });
1430
- }
1431
- const templates = core.Is.arrayValue(envVars.messagingTemplates)
1432
- ? envVars.messagingTemplates
1433
- : undefined;
1434
- coreConfig.types.messagingAdminComponent ??= [];
1435
- coreConfig.types.messagingAdminComponent.push({
1436
- type: engineTypes.MessagingAdminComponentType.Service,
1437
- options: {
1438
- config: {
1439
- templates
1440
- }
1441
- }
1442
- });
1443
- coreConfig.types.messagingComponent ??= [];
1444
- coreConfig.types.messagingComponent.push({ type: engineTypes.MessagingComponentType.Service });
1445
- }
1446
- }
1447
- /**
1448
- * Configures the faucet.
1449
- * @param coreConfig The core config.
1450
- * @param envVars The environment variables.
1451
- */
1452
- async function configureFaucet(coreConfig, envVars) {
1453
- coreConfig.types.faucetConnector ??= [];
1454
- if (envVars.faucetConnector === engineTypes.FaucetConnectorType.EntityStorage) {
1455
- coreConfig.types.faucetConnector.push({
1456
- type: engineTypes.FaucetConnectorType.EntityStorage
1457
- });
1458
- }
1459
- else if (envVars.faucetConnector === engineTypes.FaucetConnectorType.Iota) {
1460
- const dltConfig = engineTypes.EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", engineTypes.DltConfigType.Iota);
1461
- coreConfig.types.faucetConnector.push({
1462
- type: engineTypes.FaucetConnectorType.Iota,
1463
- options: {
1464
- config: {
1465
- endpoint: envVars.iotaFaucetEndpoint ?? "",
1466
- clientOptions: dltConfig?.options?.config?.clientOptions ?? { url: "" },
1467
- network: dltConfig?.options?.config?.network ?? ""
1468
- }
1469
- }
1470
- });
1471
- }
1472
- }
1473
- /**
1474
- * Configures the wallet.
1475
- * @param coreConfig The core config.
1476
- * @param envVars The environment variables.
1477
- */
1478
- async function configureWallet(coreConfig, envVars) {
1479
- coreConfig.types.walletConnector ??= [];
1480
- if (envVars.walletConnector === engineTypes.WalletConnectorType.EntityStorage) {
1481
- coreConfig.types.walletConnector.push({
1482
- type: engineTypes.WalletConnectorType.EntityStorage
1483
- });
1484
- }
1485
- else if (envVars.walletConnector === engineTypes.WalletConnectorType.Iota) {
1486
- const dltConfig = engineTypes.EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", engineTypes.DltConfigType.Iota);
1487
- coreConfig.types.walletConnector.push({
1488
- type: engineTypes.WalletConnectorType.Iota,
1489
- options: {
1490
- config: dltConfig?.options?.config ?? {}
1491
- }
1492
- });
1493
- }
1494
- }
1495
- /**
1496
- * Configures the NFT.
1497
- * @param coreConfig The core config.
1498
- * @param envVars The environment variables.
1499
- */
1500
- async function configureNft(coreConfig, envVars) {
1501
- coreConfig.types.nftConnector ??= [];
1502
- if (envVars.nftConnector === engineTypes.NftConnectorType.EntityStorage) {
1503
- coreConfig.types.nftConnector.push({
1504
- type: engineTypes.NftConnectorType.EntityStorage
1505
- });
1506
- }
1507
- else if (envVars.nftConnector === engineTypes.NftConnectorType.Iota) {
1508
- const dltConfig = engineTypes.EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", engineTypes.DltConfigType.Iota);
1509
- coreConfig.types.nftConnector.push({
1510
- type: engineTypes.NftConnectorType.Iota,
1511
- options: {
1512
- config: dltConfig?.options?.config ?? {}
1513
- }
1514
- });
1515
- }
1516
- if (coreConfig.types.nftConnector.length > 0) {
1517
- coreConfig.types.nftComponent ??= [];
1518
- coreConfig.types.nftComponent.push({ type: engineTypes.NftComponentType.Service });
1519
- }
1520
- }
1521
- /**
1522
- * Configures the verifiable storage.
1523
- * @param coreConfig The core config.
1524
- * @param envVars The environment variables.
1525
- */
1526
- async function configureVerifiableStorage(coreConfig, envVars) {
1527
- coreConfig.types.verifiableStorageConnector ??= [];
1528
- if (envVars.verifiableStorageConnector === engineTypes.VerifiableStorageConnectorType.EntityStorage) {
1529
- coreConfig.types.verifiableStorageConnector.push({
1530
- type: engineTypes.VerifiableStorageConnectorType.EntityStorage
1531
- });
1532
- }
1533
- else if (envVars.verifiableStorageConnector === engineTypes.VerifiableStorageConnectorType.Iota) {
1534
- const dltConfig = engineTypes.EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", engineTypes.DltConfigType.Iota);
1535
- coreConfig.types.verifiableStorageConnector.push({
1536
- type: engineTypes.VerifiableStorageConnectorType.Iota,
1537
- options: {
1538
- config: dltConfig?.options?.config ?? {}
1539
- }
1540
- });
1541
- }
1542
- if (coreConfig.types.verifiableStorageConnector.length > 0) {
1543
- coreConfig.types.verifiableStorageComponent ??= [];
1544
- coreConfig.types.verifiableStorageComponent.push({
1545
- type: engineTypes.VerifiableStorageComponentType.Service
1546
- });
1547
- coreConfig.types.immutableProofComponent ??= [];
1548
- coreConfig.types.immutableProofComponent.push({
1549
- type: engineTypes.ImmutableProofComponentType.Service,
1550
- options: {
1551
- config: {
1552
- verificationMethodId: envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID
1553
- }
1554
- }
1555
- });
1556
- }
1557
- }
1558
- /**
1559
- * Configures the identity.
1560
- * @param coreConfig The core config.
1561
- * @param envVars The environment variables.
1562
- */
1563
- async function configureIdentity(coreConfig, envVars) {
1564
- coreConfig.types.identityConnector ??= [];
1565
- if (envVars.identityConnector === engineTypes.IdentityConnectorType.EntityStorage) {
1566
- coreConfig.types.identityConnector.push({
1567
- type: engineTypes.IdentityConnectorType.EntityStorage
1568
- });
1569
- }
1570
- else if (envVars.identityConnector === engineTypes.IdentityConnectorType.Iota) {
1571
- const dltConfig = engineTypes.EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", engineTypes.DltConfigType.Iota);
1572
- coreConfig.types.identityConnector.push({
1573
- type: engineTypes.IdentityConnectorType.Iota,
1574
- options: {
1575
- config: dltConfig?.options?.config ?? {}
1576
- }
1577
- });
1578
- }
1579
- if (coreConfig.types.identityConnector.length > 0) {
1580
- coreConfig.types.identityComponent ??= [];
1581
- coreConfig.types.identityComponent.push({ type: engineTypes.IdentityComponentType.Service });
1582
- }
1583
- }
1584
- /**
1585
- * Configures the identity resolver.
1586
- * @param coreConfig The core config.
1587
- * @param envVars The environment variables.
1588
- */
1589
- async function configureIdentityResolver(coreConfig, envVars) {
1590
- coreConfig.types.identityResolverConnector ??= [];
1591
- if (envVars.identityResolverConnector === engineTypes.IdentityResolverConnectorType.EntityStorage) {
1592
- coreConfig.types.identityResolverConnector.push({
1593
- type: engineTypes.IdentityResolverConnectorType.EntityStorage
1594
- });
1595
- }
1596
- else if (envVars.identityResolverConnector === engineTypes.IdentityResolverConnectorType.Iota) {
1597
- const dltConfig = engineTypes.EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", engineTypes.DltConfigType.Iota);
1598
- coreConfig.types.identityResolverConnector.push({
1599
- type: engineTypes.IdentityResolverConnectorType.Iota,
1600
- options: {
1601
- config: dltConfig?.options?.config ?? {}
1602
- }
1603
- });
1604
- }
1605
- else if (envVars.identityResolverConnector === engineTypes.IdentityResolverConnectorType.Universal) {
1606
- coreConfig.types.identityResolverConnector.push({
1607
- type: engineTypes.IdentityResolverConnectorType.Universal,
1608
- options: {
1609
- config: {
1610
- endpoint: envVars.universalResolverEndpoint ?? ""
1611
- }
1612
- }
1613
- });
1614
- }
1615
- if (coreConfig.types.identityResolverConnector.length > 0) {
1616
- coreConfig.types.identityResolverComponent ??= [];
1617
- coreConfig.types.identityResolverComponent.push({
1618
- type: engineTypes.IdentityResolverComponentType.Service
1619
- });
1620
- }
1621
- }
1622
- /**
1623
- * Configures the identity profile.
1624
- * @param coreConfig The core config.
1625
- * @param envVars The environment variables.
1626
- */
1627
- async function configureIdentityProfile(coreConfig, envVars) {
1628
- coreConfig.types.identityProfileConnector ??= [];
1629
- if (envVars.identityProfileConnector === engineTypes.IdentityConnectorType.EntityStorage) {
1630
- coreConfig.types.identityProfileConnector.push({
1631
- type: engineTypes.IdentityProfileConnectorType.EntityStorage
1632
- });
1633
- }
1634
- if (coreConfig.types.identityProfileConnector.length > 0) {
1635
- coreConfig.types.identityProfileComponent ??= [];
1636
- coreConfig.types.identityProfileComponent.push({ type: engineTypes.IdentityProfileComponentType.Service });
1637
- }
1638
- }
1639
- /**
1640
- * Configures the attestation.
1641
- * @param coreConfig The core config.
1642
- * @param envVars The environment variables.
1643
- */
1644
- async function configureAttestation(coreConfig, envVars) {
1645
- coreConfig.types.attestationConnector ??= [];
1646
- if (envVars.attestationConnector === engineTypes.AttestationConnectorType.Nft) {
1647
- coreConfig.types.attestationConnector.push({
1648
- type: engineTypes.AttestationConnectorType.Nft
1649
- });
1650
- }
1651
- if (coreConfig.types.attestationConnector.length > 0) {
1652
- coreConfig.types.attestationComponent ??= [];
1653
- coreConfig.types.attestationComponent.push({
1654
- type: engineTypes.AttestationComponentType.Service,
1655
- options: {
1656
- config: {
1657
- verificationMethodId: envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID
1658
- }
1659
- }
1660
- });
1661
- }
1662
- }
1663
- /**
1664
- * Configures the auditable item graph.
1665
- * @param coreConfig The core config.
1666
- * @param envVars The environment variables.
1667
- */
1668
- async function configureAuditableItemGraph(coreConfig, envVars) {
1669
- if (core.Coerce.boolean(envVars.auditableItemGraphEnabled) ?? false) {
1670
- coreConfig.types.auditableItemGraphComponent ??= [];
1671
- coreConfig.types.auditableItemGraphComponent.push({
1672
- type: engineTypes.AuditableItemGraphComponentType.Service
1673
- });
1674
- }
1675
- }
1676
- /**
1677
- * Configures the auditable item stream.
1678
- * @param coreConfig The core config.
1679
- * @param envVars The environment variables.
1680
- */
1681
- async function configureAuditableItemStream(coreConfig, envVars) {
1682
- if (core.Coerce.boolean(envVars.auditableItemStreamEnabled) ?? false) {
1683
- coreConfig.types.auditableItemStreamComponent ??= [];
1684
- coreConfig.types.auditableItemStreamComponent.push({
1685
- type: engineTypes.AuditableItemStreamComponentType.Service
1686
- });
1687
- }
1688
- }
1689
- /**
1690
- * Configures the data processing.
1691
- * @param coreConfig The core config.
1692
- * @param envVars The environment variables.
1693
- */
1694
- async function configureDataProcessing(coreConfig, envVars) {
1695
- if (core.Coerce.boolean(envVars.dataProcessingEnabled) ?? false) {
1696
- coreConfig.types.dataProcessingComponent ??= [];
1697
- coreConfig.types.dataProcessingComponent.push({ type: engineTypes.DataProcessingComponentType.Service });
1698
- coreConfig.types.dataConverterConnector ??= [];
1699
- const converterConnectors = envVars.dataConverterConnectors?.split(",") ?? [];
1700
- for (const converterConnector of converterConnectors) {
1701
- if (converterConnector === engineTypes.DataConverterConnectorType.Json) {
1702
- coreConfig.types.dataConverterConnector.push({
1703
- type: engineTypes.DataConverterConnectorType.Json
1704
- });
1705
- }
1706
- else if (converterConnector === engineTypes.DataConverterConnectorType.Xml) {
1707
- coreConfig.types.dataConverterConnector.push({
1708
- type: engineTypes.DataConverterConnectorType.Xml
1709
- });
1710
- }
1711
- }
1712
- coreConfig.types.dataExtractorConnector ??= [];
1713
- const extractorConnectors = envVars.dataExtractorConnectors?.split(",") ?? [];
1714
- for (const extractorConnector of extractorConnectors) {
1715
- if (extractorConnector === engineTypes.DataExtractorConnectorType.JsonPath) {
1716
- coreConfig.types.dataExtractorConnector.push({
1717
- type: engineTypes.DataExtractorConnectorType.JsonPath
1718
- });
1719
- }
1720
- }
1721
- }
1722
- }
1723
- /**
1724
- * Configures the document management.
1725
- * @param coreConfig The core config.
1726
- * @param envVars The environment variables.
1727
- */
1728
- async function configureDocumentManagement(coreConfig, envVars) {
1729
- if (core.Coerce.boolean(envVars.documentManagementEnabled) ?? false) {
1730
- coreConfig.types.documentManagementComponent ??= [];
1731
- coreConfig.types.documentManagementComponent.push({
1732
- type: engineTypes.DocumentManagementComponentType.Service
1733
- });
1734
- }
1735
- }
1736
- /**
1737
- * Configures the verifiable credential authentication.
1738
- * @param coreConfig The core config.
1739
- * @param envVars The environment variables.
1740
- */
1741
- async function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
1742
- if (core.Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
1743
- // Can only perform VC authentication if identity component is available
1744
- coreConfig.types.authenticationGeneratorComponent ??= [];
1745
- coreConfig.types.authenticationGeneratorComponent.push({
1746
- type: engineTypes.AuthenticationGeneratorComponentType.VerifiableCredential,
1747
- options: {
1748
- config: {
1749
- verificationMethodId: envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID
1750
- }
1751
- },
1752
- features: ["verifiable-credential"]
1753
- });
1754
- }
1755
- }
1756
- /**
1757
- * Configures the rights management.
1758
- * @param coreConfig The core config.
1759
- * @param envVars The environment variables.
1760
- */
1761
- async function configureRightsManagement(coreConfig, envVars) {
1762
- if (core.Coerce.boolean(envVars.rightsManagementEnabled) ?? false) {
1763
- coreConfig.types.rightsManagementPapComponent ??= [];
1764
- coreConfig.types.rightsManagementPapComponent.push({
1765
- type: engineTypes.RightsManagementPapComponentType.Service
1766
- });
1767
- coreConfig.types.rightsManagementPmpComponent ??= [];
1768
- coreConfig.types.rightsManagementPmpComponent.push({
1769
- type: engineTypes.RightsManagementPmpComponentType.Service
1770
- });
1771
- coreConfig.types.rightsManagementPipComponent ??= [];
1772
- coreConfig.types.rightsManagementPipComponent.push({
1773
- type: engineTypes.RightsManagementPipComponentType.Service,
1774
- options: {
1775
- informationModulesConfig: core.Is.arrayValue(envVars.rightsManagementInformationSources)
1776
- ? envVars.rightsManagementInformationSources
1777
- : undefined
1778
- }
1779
- });
1780
- coreConfig.types.rightsManagementPxpComponent ??= [];
1781
- coreConfig.types.rightsManagementPxpComponent.push({
1782
- type: engineTypes.RightsManagementPxpComponentType.Service,
1783
- options: {
1784
- actionModulesConfig: core.Is.arrayValue(envVars.rightsManagementExecutionActions)
1785
- ? envVars.rightsManagementExecutionActions
1786
- : undefined
1787
- }
1788
- });
1789
- coreConfig.types.rightsManagementPdpComponent ??= [];
1790
- coreConfig.types.rightsManagementPdpComponent.push({
1791
- type: engineTypes.RightsManagementPdpComponentType.Service,
1792
- options: {
1793
- arbiterModulesConfig: core.Is.arrayValue(envVars.rightsManagementArbiters)
1794
- ? envVars.rightsManagementArbiters
1795
- : undefined
1796
- }
1797
- });
1798
- coreConfig.types.rightsManagementPepComponent ??= [];
1799
- coreConfig.types.rightsManagementPepComponent.push({
1800
- type: engineTypes.RightsManagementPepComponentType.Service,
1801
- options: {
1802
- processorModulesConfig: core.Is.arrayValue(envVars.rightsManagementEnforcementProcessors)
1803
- ? envVars.rightsManagementEnforcementProcessors
1804
- : undefined
1805
- }
1806
- });
1807
- coreConfig.types.rightsManagementPnpComponent ??= [];
1808
- coreConfig.types.rightsManagementPnpComponent.push({
1809
- type: engineTypes.RightsManagementPnpComponentType.Service,
1810
- options: {
1811
- negotiatorModulesConfig: core.Is.arrayValue(envVars.rightsManagementNegotiators)
1812
- ? envVars.rightsManagementNegotiators
1813
- : undefined,
1814
- requesterModulesConfig: core.Is.arrayValue(envVars.rightsManagementRequesters)
1815
- ? envVars.rightsManagementRequesters
1816
- : undefined,
1817
- config: {
1818
- baseCallbackUrl: envVars.rightsManagementBaseCallbackUrl ?? "",
1819
- offers: core.Is.arrayValue(envVars.rightsManagementOffers)
1820
- ? envVars.rightsManagementOffers
1821
- : [],
1822
- negotiationComponentCreator: async (url) => new rightsManagementRestClient.PolicyNegotiationPointRestClient({ endpoint: url })
1823
- }
1824
- }
1825
- });
1826
- coreConfig.types.rightsManagementPnapComponent ??= [];
1827
- coreConfig.types.rightsManagementPnapComponent.push({
1828
- type: engineTypes.RightsManagementPnapComponentType.Service
1829
- });
1830
- coreConfig.types.rightsManagementDapComponent ??= [];
1831
- coreConfig.types.rightsManagementDapComponent.push({
1832
- type: engineTypes.RightsManagementDapComponentType.Service
1833
- });
1834
- coreConfig.types.rightsManagementDarpComponent ??= [];
1835
- coreConfig.types.rightsManagementDarpComponent.push({
1836
- type: engineTypes.RightsManagementDarpComponentType.Service,
1837
- options: {
1838
- config: {
1839
- dataAccessComponentCreator: async (url) => new rightsManagementRestClient.DataAccessPointRestClient({ endpoint: url })
1840
- }
1841
- }
1842
- });
1843
- }
1844
- }
1845
- /**
1846
- * Configures the task scheduler.
1847
- * @param coreConfig The core config.
1848
- * @param envVars The environment variables.
1849
- */
1850
- async function configureTaskScheduler(coreConfig, envVars) {
1851
- if (core.Coerce.boolean(envVars.taskSchedulerEnabled) ?? false) {
1852
- coreConfig.types.taskSchedulerComponent ??= [];
1853
- coreConfig.types.taskSchedulerComponent.push({
1854
- type: engineTypes.TaskSchedulerComponentType.Service
1855
- });
1856
- }
1857
- }
1858
- /**
1859
- * Configures the synchronised storage.
1860
- * @param coreConfig The core config.
1861
- * @param envVars The environment variables.
1862
- */
1863
- async function configureSynchronisedStorage(coreConfig, envVars) {
1864
- if (core.Is.arrayValue(coreConfig.types.identityResolverComponent) &&
1865
- (core.Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false)) {
1866
- // Check if the config provides a custom verifiable storage key id
1867
- let verifiableStorageKeyId = core.Coerce.string(envVars.synchronisedStorageVerifiableStorageKeyId);
1868
- if (!core.Is.stringValue(verifiableStorageKeyId)) {
1869
- // No custom key so default to the network setting
1870
- verifiableStorageKeyId = envVars.iotaNetwork;
1871
- }
1872
- coreConfig.types.synchronisedStorageComponent ??= [];
1873
- coreConfig.types.synchronisedStorageComponent.push({
1874
- type: engineTypes.SynchronisedStorageComponentType.Service,
1875
- options: {
1876
- config: {
1877
- verifiableStorageKeyId: verifiableStorageKeyId ?? "",
1878
- blobStorageEncryptionKeyId: envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
1879
- SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID,
1880
- entityUpdateIntervalMinutes: core.Coerce.number(envVars.synchronisedStorageEntityUpdateIntervalMinutes),
1881
- consolidationIntervalMinutes: core.Coerce.number(envVars.synchronisedStorageConsolidationIntervalMinutes),
1882
- consolidationBatchSize: core.Coerce.number(envVars.synchronisedStorageConsolidationBatchSize),
1883
- maxConsolidations: core.Coerce.number(envVars.synchronisedStorageMaxConsolidations)
1884
- }
1885
- }
1886
- });
1887
- // If there is a trusted url set, we need to add a client
1888
- // and give it a feature of trusted so that when the synchronised
1889
- // storage is created it can pickup the correct component
1890
- if (core.Is.stringValue(envVars.synchronisedStorageTrustedUrl)) {
1891
- coreConfig.types.synchronisedStorageComponent.push({
1892
- type: engineTypes.SynchronisedStorageComponentType.RestClient,
1893
- options: {
1894
- endpoint: envVars.synchronisedStorageTrustedUrl
1895
- },
1896
- features: ["trusted"]
1897
- });
1898
- }
1899
- }
1900
- }
1901
- /**
1902
- * Configures the federated catalogue.
1903
- * @param coreConfig The core config.
1904
- * @param envVars The environment variables.
1905
- */
1906
- async function configureFederatedCatalogue(coreConfig, envVars) {
1907
- if (core.Coerce.boolean(envVars.federatedCatalogueEnabled) ?? false) {
1908
- coreConfig.types.federatedCatalogueComponent ??= [];
1909
- coreConfig.types.federatedCatalogueComponent.push({
1910
- type: engineTypes.FederatedCatalogueComponentType.Service,
1911
- options: {
1912
- config: {
1913
- subResourceCacheTtlMs: core.Coerce.number(envVars.federatedCatalogueCacheTtlMs),
1914
- clearingHouseApproverList: core.Coerce.object(envVars.federatedCatalogueClearingHouseApproverList) ?? []
1915
- }
1916
- }
1917
- });
1918
- }
1919
- }
1920
- /**
1921
- * Configures the data space connector.
1922
- * @param coreConfig The core config.
1923
- * @param envVars The environment variables.
1924
- */
1925
- async function configureDataSpaceConnector(coreConfig, envVars) {
1926
- if (core.Coerce.boolean(envVars.dataSpaceConnectorEnabled) ?? false) {
1927
- coreConfig.types.dataSpaceConnectorComponent ??= [];
1928
- coreConfig.types.dataSpaceConnectorComponent.push({
1929
- type: engineTypes.DataSpaceConnectorComponentType.Service,
1930
- options: {
1931
- config: {
1932
- retainActivityLogsFor: core.Coerce.number(envVars.dataSpaceConnectorRetainActivityLogsFor),
1933
- activityLogsCleanUpInterval: core.Coerce.number(envVars.dataSpaceConnectorActivityLogsCleanUpInterval)
1934
- }
1935
- }
1936
- });
1937
- }
1938
- }
1939
- /**
1940
- * Configures the DLT.
1941
- * @param coreConfig The core config.
1942
- * @param envVars The environment variables.
1943
- */
1944
- async function configureDlt(coreConfig, envVars) {
1945
- // Create centralized DLT configuration for IOTA if essential IOTA variables are set
1946
- if (core.Is.stringValue(envVars.iotaNodeEndpoint) && core.Is.stringValue(envVars.iotaNetwork)) {
1947
- coreConfig.types.dltConfig ??= [];
1948
- const gasStationConfig = core.Is.stringValue(envVars.iotaGasStationEndpoint) &&
1949
- core.Is.stringValue(envVars.iotaGasStationAuthToken)
1950
- ? {
1951
- gasStationUrl: envVars.iotaGasStationEndpoint,
1952
- gasStationAuthToken: envVars.iotaGasStationAuthToken
1953
- }
1954
- : undefined;
1955
- coreConfig.types.dltConfig.push({
1956
- type: engineTypes.DltConfigType.Iota,
1957
- isDefault: true,
1958
- options: {
1959
- config: {
1960
- clientOptions: {
1961
- url: envVars.iotaNodeEndpoint ?? ""
1962
- },
1963
- network: envVars.iotaNetwork ?? "",
1964
- coinType: core.Coerce.number(envVars.iotaCoinType),
1965
- gasStation: gasStationConfig
1966
- }
1967
- }
1968
- });
1969
- }
1970
- }
1971
-
1972
- /**
1973
- * Handles the configuration of the server.
1974
- * @param envVars The environment variables for the engine server.
1975
- * @param coreEngineConfig The core engine config.
1976
- * @param serverInfo The server information.
1977
- * @param openApiSpecPath The path to the open api spec.
1978
- * @param favIconPath The path to the favicon.
1979
- * @returns The config for the core and the server.
1980
- */
1981
- async function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath, favIconPath) {
1982
- const webServerOptions = {
1983
- port: core.Coerce.number(envVars.port),
1984
- host: core.Coerce.string(envVars.host),
1985
- methods: core.Is.stringValue(envVars.httpMethods)
1986
- ? envVars.httpMethods.split(",")
1987
- : undefined,
1988
- allowedHeaders: core.Is.stringValue(envVars.httpAllowedHeaders)
1989
- ? envVars.httpAllowedHeaders.split(",")
1990
- : undefined,
1991
- exposedHeaders: core.Is.stringValue(envVars.httpExposedHeaders)
1992
- ? envVars.httpExposedHeaders.split(",")
1993
- : undefined,
1994
- corsOrigins: core.Is.stringValue(envVars.corsOrigins) ? envVars.corsOrigins.split(",") : undefined
1995
- };
1996
- const serverConfig = {
1997
- ...coreEngineConfig,
1998
- web: webServerOptions,
1999
- types: {
2000
- ...coreEngineConfig.types,
2001
- informationComponent: [
2002
- {
2003
- type: engineServerTypes.InformationComponentType.Service,
2004
- options: {
2005
- config: {
2006
- serverInfo,
2007
- openApiSpecPath,
2008
- favIconPath
2009
- }
2010
- }
2011
- }
2012
- ]
2013
- }
2014
- };
2015
- if (core.Is.stringValue(envVars.mimeTypeProcessors)) {
2016
- const mimeTypeProcessors = envVars.mimeTypeProcessors.split(",");
2017
- if (core.Is.arrayValue(mimeTypeProcessors)) {
2018
- serverConfig.types.mimeTypeProcessor ??= [];
2019
- for (const mimeTypeProcessor of mimeTypeProcessors) {
2020
- serverConfig.types.mimeTypeProcessor.push({
2021
- type: mimeTypeProcessor
2022
- });
2023
- }
2024
- }
2025
- }
2026
- serverConfig.types.restRouteProcessor ??= [];
2027
- serverConfig.types.socketRouteProcessor ??= [];
2028
- const features = getFeatures(envVars);
2029
- const hasNodeIdentity = features.includes(NodeFeatures.NodeIdentity);
2030
- if (hasNodeIdentity) {
2031
- serverConfig.types.restRouteProcessor.push({
2032
- type: engineServerTypes.RestRouteProcessorType.NodeIdentity
2033
- });
2034
- serverConfig.types.socketRouteProcessor.push({
2035
- type: engineServerTypes.SocketRouteProcessorType.NodeIdentity
2036
- });
2037
- }
2038
- if (!coreEngineConfig.silent) {
2039
- const includeBody = core.Coerce.boolean(envVars.routeLoggingIncludeBody) ?? coreEngineConfig.debug;
2040
- const fullBase64 = core.Coerce.boolean(envVars.routeLoggingFullBase64) ?? false;
2041
- const obfuscateProperties = core.Is.stringValue(envVars.routeLoggingObfuscateProperties)
2042
- ? envVars.routeLoggingObfuscateProperties.split(",")
2043
- : undefined;
2044
- serverConfig.types.restRouteProcessor.push({
2045
- type: engineServerTypes.RestRouteProcessorType.Logging,
2046
- options: {
2047
- config: {
2048
- includeBody,
2049
- fullBase64,
2050
- obfuscateProperties
2051
- }
2052
- }
2053
- });
2054
- serverConfig.types.socketRouteProcessor.push({
2055
- type: engineServerTypes.SocketRouteProcessorType.Logging,
2056
- options: {
2057
- config: {
2058
- includeBody,
2059
- fullBase64,
2060
- obfuscateProperties
2061
- }
2062
- }
2063
- });
2064
- }
2065
- serverConfig.types.restRouteProcessor.push({
2066
- type: engineServerTypes.RestRouteProcessorType.RestRoute,
2067
- options: {
2068
- config: {
2069
- includeErrorStack: coreEngineConfig.debug
2070
- }
2071
- }
2072
- });
2073
- serverConfig.types.socketRouteProcessor.push({
2074
- type: engineServerTypes.SocketRouteProcessorType.SocketRoute,
2075
- options: {
2076
- config: {
2077
- includeErrorStack: coreEngineConfig.debug
2078
- }
2079
- }
2080
- });
2081
- const authAdminProcessorType = envVars.authAdminProcessorType;
2082
- if (authAdminProcessorType === engineServerTypes.AuthenticationAdminComponentType.EntityStorage) {
2083
- serverConfig.types.authenticationAdminComponent ??= [];
2084
- serverConfig.types.authenticationAdminComponent.push({
2085
- type: engineServerTypes.AuthenticationAdminComponentType.EntityStorage,
2086
- options: {
2087
- config: {}
2088
- }
2089
- });
2090
- }
2091
- const authProcessorType = envVars.authProcessorType;
2092
- if (authProcessorType === engineServerTypes.AuthenticationComponentType.EntityStorage) {
2093
- serverConfig.types.authenticationComponent ??= [];
2094
- serverConfig.types.authenticationComponent.push({
2095
- type: engineServerTypes.AuthenticationComponentType.EntityStorage,
2096
- options: {
2097
- config: {
2098
- signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
2099
- }
2100
- }
2101
- });
2102
- serverConfig.types.restRouteProcessor.push({
2103
- type: engineServerTypes.RestRouteProcessorType.AuthHeader,
2104
- options: {
2105
- config: {
2106
- signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
2107
- }
2108
- }
2109
- });
2110
- serverConfig.types.socketRouteProcessor.push({
2111
- type: engineServerTypes.SocketRouteProcessorType.AuthHeader,
2112
- options: {
2113
- config: {
2114
- signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
2115
- }
2116
- }
2117
- });
2118
- }
2119
- if (core.Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
2120
- serverConfig.types.restRouteProcessor.push({
2121
- type: engineServerTypes.RestRouteProcessorType.AuthVerifiableCredential
2122
- });
2123
- serverConfig.types.socketRouteProcessor.push({
2124
- type: engineServerTypes.SocketRouteProcessorType.AuthVerifiableCredential
2125
- });
2126
- }
2127
- engineServer.addDefaultRestPaths(serverConfig);
2128
- engineServer.addDefaultSocketPaths(serverConfig);
2129
- return serverConfig;
2130
- }
2131
-
2132
- // Copyright 2024 IOTA Stiftung.
2133
- // SPDX-License-Identifier: Apache-2.0.
2134
- /**
2135
- * Handles the configuration of the extensions.
2136
- * @param envVars The environment variables for the node.
2137
- * @param nodeEngineConfig The node engine config.
2138
- * @returns The config for the core and the server.
2139
- */
2140
- async function extensionsConfiguration(envVars, nodeEngineConfig) {
2141
- if (core.Is.stringValue(envVars.extensions)) {
2142
- const extensions = envVars.extensions.split(",");
2143
- for (const extension of extensions) {
2144
- let initialiseConfigMethod;
2145
- try {
2146
- cliCore.CLIDisplay.value(core.I18n.formatMessage("node.extensionLoading"), extension);
2147
- initialiseConfigMethod = await modules.ModuleHelper.getModuleMethod(extension, "extensionInitialise");
2148
- }
2149
- catch (err) {
2150
- throw new core.GeneralError("node", "extensionLoadingError", { extension }, err);
2151
- }
2152
- if (core.Is.function(initialiseConfigMethod)) {
2153
- await initialiseConfigMethod(envVars, nodeEngineConfig);
2154
- }
2155
- }
2156
- }
2157
- return nodeEngineConfig;
2158
- }
2159
- /**
2160
- * Handles the initialisation of the extensions when the engine has been constructed.
2161
- * @param envVars The environment variables for the node.
2162
- * @param engineCore The engine core instance.
2163
- * @returns Nothing.
2164
- */
2165
- async function extensionsInitialiseEngine(envVars, engineCore) {
2166
- if (core.Is.stringValue(envVars.extensions)) {
2167
- const extensions = envVars.extensions.split(",");
2168
- for (const extension of extensions) {
2169
- let initialiseEngineMethod;
2170
- try {
2171
- engineCore.logInfo(core.I18n.formatMessage("node.extensionInitialisingEngine", { extension }));
2172
- initialiseEngineMethod =
2173
- await modules.ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngine");
2174
- }
2175
- catch { }
2176
- if (core.Is.function(initialiseEngineMethod)) {
2177
- await initialiseEngineMethod(engineCore);
2178
- }
2179
- }
2180
- }
2181
- }
2182
- /**
2183
- * Handles the initialisation of the extensions when the engine server has been constructed.
2184
- * @param envVars The environment variables for the node.
2185
- * @param engineCore The engine core instance.
2186
- * @param engineServer The engine server instance.
2187
- * @returns Nothing.
2188
- */
2189
- async function extensionsInitialiseEngineServer(envVars, engineCore, engineServer) {
2190
- if (core.Is.stringValue(envVars.extensions)) {
2191
- const extensions = envVars.extensions.split(",");
2192
- for (const extension of extensions) {
2193
- let initialiseEngineServerMethod;
2194
- try {
2195
- engineCore.logInfo(core.I18n.formatMessage("node.extensionInitialisingEngineServer", { extension }));
2196
- initialiseEngineServerMethod =
2197
- await modules.ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngineServer");
2198
- }
2199
- catch { }
2200
- if (core.Is.function(initialiseEngineServerMethod)) {
2201
- await initialiseEngineServerMethod(engineCore, engineServer);
2202
- }
2203
- }
2204
- }
2205
- }
2206
- /**
2207
- * Handles the shutdown of the extensions.
2208
- * @param envVars The environment variables for the node.
2209
- * @param engineCore The engine core instance.
2210
- * @returns Nothing.
2211
- */
2212
- async function shutdownExtensions(envVars, engineCore) {
2213
- if (core.Is.stringValue(envVars.extensions)) {
2214
- const extensions = envVars.extensions.split(",");
2215
- for (const extension of extensions) {
2216
- let shutdownMethod;
2217
- try {
2218
- engineCore.logInfo(core.I18n.formatMessage("node.extensionShutdown", { extension }));
2219
- shutdownMethod = await modules.ModuleHelper.getModuleMethod(extension, "extensionShutdown");
2220
- }
2221
- catch { }
2222
- if (core.Is.function(shutdownMethod)) {
2223
- await shutdownMethod();
2224
- }
2225
- }
2226
- }
2227
- }
2228
-
2229
- // Copyright 2024 IOTA Stiftung.
2230
- // SPDX-License-Identifier: Apache-2.0.
2231
- /**
2232
- * Start the engine server.
2233
- * @param nodeOptions Optional run options for the engine server.
2234
- * @param nodeEngineConfig The configuration for the engine server.
2235
- * @param envVars The environment variables.
2236
- * @returns The engine server.
2237
- */
2238
- async function start(nodeOptions, nodeEngineConfig, envVars) {
2239
- const entityStorageConnectorType = envVars.entityStorageConnectorType?.split(",") ?? [];
2240
- const blobStorageConnectorType = envVars.blobStorageConnectorType?.split(",") ?? [];
2241
- // If the blob storage or entity storage is configured with file connectors
2242
- // then we need to make sure the storageFileRoot is set
2243
- if ((entityStorageConnectorType.includes(engineTypes.EntityStorageConnectorType.File) ||
2244
- blobStorageConnectorType.includes(engineTypes.BlobStorageConnectorType.File) ||
2245
- core.Is.empty(nodeOptions?.stateStorage)) &&
2246
- !core.Is.stringValue(envVars.storageFileRoot)) {
2247
- throw new core.GeneralError("node", "storageFileRootNotSet", {
2248
- storageFileRoot: `${nodeOptions?.envPrefix ?? ""}_STORAGE_FILE_ROOT`
2249
- });
2250
- }
2251
- // Create the engine instance using file state storage unless one is configured in options
2252
- const engine$1 = new engine.Engine({
2253
- config: nodeEngineConfig,
2254
- stateStorage: nodeOptions?.stateStorage ?? new engineCore.FileStateStorage(envVars.stateFilename ?? ""),
2255
- customBootstrap: async (core, engineContext) => bootstrap(core, engineContext, envVars)
2256
- });
2257
- // Construct the server with the engine.
2258
- const server = new engineServer.EngineServer({ engineCore: engine$1 });
2259
- // Extend the engine.
2260
- if (core.Is.function(nodeOptions?.extendEngine)) {
2261
- engine$1.logInfo(core.I18n.formatMessage("node.extendingEngine"));
2262
- await nodeOptions.extendEngine(engine$1);
2263
- }
2264
- await extensionsInitialiseEngine(envVars, engine$1);
2265
- // Extend the engine server.
2266
- if (core.Is.function(nodeOptions?.extendEngineServer)) {
2267
- engine$1.logInfo(core.I18n.formatMessage("node.extendingEngineServer"));
2268
- await nodeOptions?.extendEngineServer(server);
2269
- }
2270
- await extensionsInitialiseEngineServer(envVars, engine$1, server);
2271
- // Need to register the engine with the factory so that background tasks
2272
- // can clone it to spawn new instances.
2273
- engineModels.EngineCoreFactory.register("engine", () => engine$1);
2274
- // Start the server, which also starts the engine.
2275
- const canContinue = await server.start();
2276
- if (canContinue) {
2277
- return {
2278
- engine: engine$1,
2279
- server,
2280
- shutdown: async () => {
2281
- await server.stop();
2282
- await shutdownExtensions(envVars, engine$1);
2283
- }
2284
- };
2285
- }
2286
- }
2287
-
2288
- // Copyright 2024 IOTA Stiftung.
2289
- // SPDX-License-Identifier: Apache-2.0.
2290
- const moduleCache = {};
2291
- /**
2292
- * Run the TWIN Node server.
2293
- * @param nodeOptions Optional configuration options for running the server.
2294
- * @returns A promise that resolves when the server is started.
2295
- */
2296
- async function run(nodeOptions) {
2297
- try {
2298
- nodeOptions ??= {};
2299
- const serverInfo = {
2300
- name: nodeOptions?.serverName ?? "TWIN Node Server",
2301
- version: nodeOptions?.serverVersion ?? "0.0.2-next.26" // x-release-please-version
2302
- };
2303
- cliCore.CLIDisplay.header(serverInfo.name, serverInfo.version, "🌩️ ");
2304
- if (!core.Is.stringValue(nodeOptions?.executionDirectory)) {
2305
- nodeOptions.executionDirectory = getExecutionDirectory();
2306
- }
2307
- cliCore.CLIDisplay.value("Execution Directory", nodeOptions.executionDirectory);
2308
- nodeOptions.localesDirectory =
2309
- nodeOptions?.localesDirectory ??
2310
- path.resolve(path.join(nodeOptions.executionDirectory, "dist", "locales"));
2311
- cliCore.CLIDisplay.value("Locales Directory", nodeOptions.localesDirectory);
2312
- await initialiseLocales(nodeOptions.localesDirectory);
2313
- if (core.Is.empty(nodeOptions?.openApiSpecFile)) {
2314
- const specFile = path.resolve(path.join(nodeOptions.executionDirectory ?? "", "docs", "open-api", "spec.json"));
2315
- cliCore.CLIDisplay.value("Default OpenAPI Spec File", specFile);
2316
- if (await fileExists(specFile)) {
2317
- nodeOptions ??= {};
2318
- nodeOptions.openApiSpecFile = specFile;
2319
- }
2320
- }
2321
- else {
2322
- cliCore.CLIDisplay.value("OpenAPI Spec File", nodeOptions.openApiSpecFile);
2323
- }
2324
- if (core.Is.empty(nodeOptions?.favIconFile)) {
2325
- const favIconFile = path.resolve(path.join(nodeOptions.executionDirectory ?? "", "static", "favicon.png"));
2326
- cliCore.CLIDisplay.value("Default Favicon File", favIconFile);
2327
- if (await fileExists(favIconFile)) {
2328
- nodeOptions ??= {};
2329
- nodeOptions.favIconFile = favIconFile;
2330
- }
2331
- }
2332
- else {
2333
- cliCore.CLIDisplay.value("Favicon File", nodeOptions.favIconFile);
2334
- }
2335
- nodeOptions.envPrefix ??= "TWIN_NODE_";
2336
- cliCore.CLIDisplay.value("Environment Variable Prefix", nodeOptions.envPrefix);
2337
- overrideModuleImport(nodeOptions.executionDirectory ?? "");
2338
- const { nodeEngineConfig, nodeEnvVars: envVars } = await buildConfiguration(
2339
- // This is the only location in the code base that should access process.env directly
2340
- // So we can safely disable the linting rule here.
2341
- // eslint-disable-next-line no-restricted-syntax
2342
- process.env, nodeOptions, serverInfo);
2343
- cliCore.CLIDisplay.break();
2344
- const startResult = await start(nodeOptions, nodeEngineConfig, envVars);
2345
- if (!core.Is.empty(startResult)) {
2346
- for (const signal of ["SIGHUP", "SIGINT", "SIGTERM"]) {
2347
- process.on(signal, async () => {
2348
- cliCore.CLIDisplay.value("Terminate Signal", signal);
2349
- await startResult.shutdown();
2350
- });
2351
- }
2352
- }
2353
- }
2354
- catch (err) {
2355
- cliCore.CLIDisplay.error(err);
2356
- // eslint-disable-next-line unicorn/no-process-exit
2357
- process.exit(1);
2358
- }
2359
- }
2360
- /**
2361
- * Build the configuration for the TWIN Node server.
2362
- * @param processEnv The environment variables from the process.
2363
- * @param options The options for running the server.
2364
- * @param serverInfo The server information.
2365
- * @returns A promise that resolves to the engine server configuration, environment prefix, environment variables,
2366
- * and options.
2367
- */
2368
- async function buildConfiguration(processEnv, options, serverInfo) {
2369
- let defaultEnvOnly = false;
2370
- if (core.Is.empty(options?.envFilenames)) {
2371
- const envFile = path.resolve(path.join(options.executionDirectory ?? "", ".env"));
2372
- cliCore.CLIDisplay.value("Default Environment File", envFile);
2373
- options ??= {};
2374
- options.envFilenames = [envFile];
2375
- defaultEnvOnly = true;
2376
- }
2377
- if (core.Is.arrayValue(options?.envFilenames)) {
2378
- const output = dotenv__namespace.config({
2379
- path: options?.envFilenames,
2380
- quiet: true
2381
- });
2382
- // We don't want to throw an error if the default environment file is not found.
2383
- // Only if we have custom environment files.
2384
- if (!defaultEnvOnly && output.error) {
2385
- throw output.error;
2386
- }
2387
- if (core.Is.objectValue(output.parsed)) {
2388
- Object.assign(processEnv, output.parsed);
2389
- }
2390
- }
2391
- const envVars = core.EnvHelper.envToJson(processEnv, options.envPrefix ?? "");
2392
- // Expand any environment variables that use the @file: syntax
2393
- const keys = Object.keys(envVars);
2394
- for (const key of keys) {
2395
- if (core.Is.stringValue(envVars[key]) &&
2396
- (envVars[key].startsWith("@text:") || envVars[key].startsWith("@json:"))) {
2397
- const filePath = envVars[key].slice(6).trim();
2398
- const embeddedFile = path.resolve(path.join(options.executionDirectory ?? "", filePath));
2399
- if (envVars[key].startsWith("@text:")) {
2400
- cliCore.CLIDisplay.value(`Expanding Environment Variable: ${key} from text file`, embeddedFile);
2401
- envVars[key] = await loadTextFile(embeddedFile);
2402
- }
2403
- else if (envVars[key].startsWith("@json:")) {
2404
- cliCore.CLIDisplay.value(`Expanding Environment Variable: ${key} from JSON file`, embeddedFile);
2405
- envVars[key] = await loadJsonFile(embeddedFile);
2406
- }
2407
- }
2408
- }
2409
- // Extend the environment variables with any additional custom configuration.
2410
- if (core.Is.function(options?.extendEnvVars)) {
2411
- cliCore.CLIDisplay.task("Extending Environment Variables");
2412
- await options.extendEnvVars(envVars);
2413
- }
2414
- // Build the engine configuration from the environment variables.
2415
- const coreConfig = await buildEngineConfiguration(envVars);
2416
- const engineServerConfig = await buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile, options?.favIconFile);
2417
- // Merge any custom configuration provided in the options.
2418
- if (core.Is.arrayValue(options?.configFilenames)) {
2419
- for (const configFile of options.configFilenames) {
2420
- cliCore.CLIDisplay.value("Loading Configuration File", configFile);
2421
- const configFilePath = path.resolve(path.join(options.executionDirectory ?? "", configFile));
2422
- const config = await loadJsonFile(configFilePath);
2423
- Object.assign(engineServerConfig, config);
2424
- }
2425
- }
2426
- if (core.Is.objectValue(options?.config)) {
2427
- cliCore.CLIDisplay.task("Merging Custom Configuration");
2428
- Object.assign(engineServerConfig, options.config);
2429
- }
2430
- // Merge any custom configuration provided in the options.
2431
- if (core.Is.function(options?.extendConfig)) {
2432
- cliCore.CLIDisplay.task("Extending Configuration");
2433
- await options.extendConfig(envVars, engineServerConfig);
2434
- }
2435
- const nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);
2436
- return { nodeEngineConfig, nodeEnvVars: envVars };
2437
- }
2438
- /**
2439
- * Override module imports to support protocol-based loading (npm:, https:) and local files.
2440
- * @param executionDirectory The execution directory for resolving local module paths.
2441
- * @param envVars The environment variables containing extension configuration (optional, uses defaults if not provided).
2442
- */
2443
- function overrideModuleImport(executionDirectory, envVars) {
2444
- const maxSizeMb = core.Coerce.number(envVars?.extensionsMaxSizeMb) ?? 10;
2445
- const cacheDirectory = envVars?.extensionsCacheDirectory;
2446
- modules.ModuleHelper.overrideImport(async (moduleName) => {
2447
- if (moduleCache[moduleName]) {
2448
- return {
2449
- module: moduleCache[moduleName],
2450
- useDefault: false
2451
- };
2452
- }
2453
- const parsed = parseModuleProtocol(moduleName);
2454
- let resolvedPath;
2455
- switch (parsed.protocol) {
2456
- case ModuleProtocol.Npm: {
2457
- const result = await handleNpmProtocol(parsed.identifier, executionDirectory, cacheDirectory);
2458
- resolvedPath = result.resolvedPath;
2459
- break;
2460
- }
2461
- case ModuleProtocol.Https: {
2462
- const result = await handleHttpsProtocol(parsed.identifier, executionDirectory, maxSizeMb, cacheDirectory, envVars?.extensionsCacheTtlHours, envVars?.extensionsForceRefresh);
2463
- resolvedPath = result.resolvedPath;
2464
- break;
2465
- }
2466
- case ModuleProtocol.Http: {
2467
- throw new core.GeneralError("node", "insecureProtocol", { protocol: ModuleProtocol.Http });
2468
- }
2469
- case ModuleProtocol.Local: {
2470
- let localFilename = path.resolve(moduleName);
2471
- let exists = await fileExists(localFilename);
2472
- if (!exists) {
2473
- localFilename = path.resolve(executionDirectory, moduleName);
2474
- exists = await fileExists(localFilename);
2475
- }
2476
- if (exists) {
2477
- resolvedPath = localFilename;
2478
- }
2479
- break;
2480
- }
2481
- case ModuleProtocol.Default: {
2482
- try {
2483
- const npmRoot = node_child_process.execSync("npm root").toString().trim().replace(/\\/g, "/");
2484
- const packagePath = path.resolve(npmRoot, moduleName);
2485
- const mainFile = await resolvePackageEntryPoint(packagePath, moduleName);
2486
- const modulePath = path.resolve(packagePath, mainFile);
2487
- const exists = await fileExists(modulePath);
2488
- if (exists) {
2489
- resolvedPath = modulePath;
2490
- break;
2491
- }
2492
- }
2493
- catch {
2494
- // Continue to fallback resolution
2495
- }
2496
- // Fallback: resolve from npm protocol cache directory (installed via handleNpmProtocol)
2497
- try {
2498
- const cacheNpmRoot = path.resolve(getExtensionsCacheDir(executionDirectory, ModuleProtocol.Npm, cacheDirectory), "node_modules");
2499
- const packagePath = path.resolve(cacheNpmRoot, moduleName);
2500
- const mainFile = await resolvePackageEntryPoint(packagePath, moduleName);
2501
- const modulePath = path.resolve(packagePath, mainFile);
2502
- const exists = await fileExists(modulePath);
2503
- if (exists) {
2504
- resolvedPath = modulePath;
2505
- }
2506
- }
2507
- catch {
2508
- // No cached resolution either; fall through
2509
- }
2510
- break;
2511
- }
2512
- }
2513
- // Common module loading and caching logic
2514
- if (resolvedPath) {
2515
- const module = await import(createModuleImportUrl(resolvedPath));
2516
- moduleCache[moduleName] = module;
2517
- return {
2518
- module,
2519
- useDefault: false
2520
- };
2521
- }
2522
- return {
2523
- module: undefined,
2524
- useDefault: true
2525
- };
2526
- });
2527
- }
2528
-
2529
- exports.ATTESTATION_VERIFICATION_METHOD_ID = ATTESTATION_VERIFICATION_METHOD_ID;
2530
- exports.AUTH_SIGNING_KEY_ID = AUTH_SIGNING_KEY_ID;
2531
- exports.BLOB_STORAGE_ENCRYPTION_KEY_ID = BLOB_STORAGE_ENCRYPTION_KEY_ID;
2532
- exports.IMMUTABLE_PROOF_VERIFICATION_METHOD_ID = IMMUTABLE_PROOF_VERIFICATION_METHOD_ID;
2533
- exports.ModuleProtocol = ModuleProtocol;
2534
- exports.NodeFeatures = NodeFeatures;
2535
- exports.SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID = SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;
2536
- exports.VC_AUTHENTICATION_VERIFICATION_METHOD_ID = VC_AUTHENTICATION_VERIFICATION_METHOD_ID;
2537
- exports.bootstrap = bootstrap;
2538
- exports.bootstrapAuth = bootstrapAuth;
2539
- exports.bootstrapBlobEncryption = bootstrapBlobEncryption;
2540
- exports.bootstrapImmutableProofMethod = bootstrapImmutableProofMethod;
2541
- exports.bootstrapNodeIdentity = bootstrapNodeIdentity;
2542
- exports.bootstrapNodeUser = bootstrapNodeUser;
2543
- exports.bootstrapSynchronisedStorage = bootstrapSynchronisedStorage;
2544
- exports.buildConfiguration = buildConfiguration;
2545
- exports.buildEngineConfiguration = buildEngineConfiguration;
2546
- exports.buildEngineServerConfiguration = buildEngineServerConfiguration;
2547
- exports.createModuleImportUrl = createModuleImportUrl;
2548
- exports.directoryExists = directoryExists;
2549
- exports.extensionsConfiguration = extensionsConfiguration;
2550
- exports.extensionsInitialiseEngine = extensionsInitialiseEngine;
2551
- exports.extensionsInitialiseEngineServer = extensionsInitialiseEngineServer;
2552
- exports.fileExists = fileExists;
2553
- exports.getExecutionDirectory = getExecutionDirectory;
2554
- exports.getExtensionsCacheDir = getExtensionsCacheDir;
2555
- exports.getFeatures = getFeatures;
2556
- exports.getFiles = getFiles;
2557
- exports.getSubFolders = getSubFolders;
2558
- exports.handleHttpsProtocol = handleHttpsProtocol;
2559
- exports.handleNpmProtocol = handleNpmProtocol;
2560
- exports.hashUrl = hashUrl;
2561
- exports.initialiseLocales = initialiseLocales;
2562
- exports.isCacheExpired = isCacheExpired;
2563
- exports.loadJsonFile = loadJsonFile;
2564
- exports.loadTextFile = loadTextFile;
2565
- exports.overrideModuleImport = overrideModuleImport;
2566
- exports.parseModuleProtocol = parseModuleProtocol;
2567
- exports.resolvePackageEntryPoint = resolvePackageEntryPoint;
2568
- exports.run = run;
2569
- exports.shutdownExtensions = shutdownExtensions;
2570
- exports.start = start;