@twin.org/node-core 0.0.2-next.15 → 0.0.2-next.17

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 (42) hide show
  1. package/dist/cjs/index.cjs +360 -160
  2. package/dist/esm/index.mjs +351 -164
  3. package/dist/types/builders/engineEnvBuilder.d.ts +1 -1
  4. package/dist/types/builders/engineServerEnvBuilder.d.ts +2 -2
  5. package/dist/types/builders/extensionsBuilder.d.ts +31 -0
  6. package/dist/types/defaults.d.ts +6 -0
  7. package/dist/types/index.d.ts +4 -0
  8. package/dist/types/models/IEngineEnvironmentVariables.d.ts +60 -18
  9. package/dist/types/models/INodeEngineConfig.d.ts +6 -0
  10. package/dist/types/models/INodeOptions.d.ts +2 -1
  11. package/dist/types/models/nodeExtensionMethods.d.ts +22 -0
  12. package/dist/types/node.d.ts +2 -2
  13. package/dist/types/server.d.ts +4 -2
  14. package/dist/types/utils.d.ts +18 -0
  15. package/docs/changelog.md +15 -0
  16. package/docs/reference/functions/buildConfiguration.md +2 -2
  17. package/docs/reference/functions/buildEngineConfiguration.md +2 -2
  18. package/docs/reference/functions/buildEngineServerConfiguration.md +3 -3
  19. package/docs/reference/functions/directoryExists.md +19 -0
  20. package/docs/reference/functions/extensionsConfiguration.md +25 -0
  21. package/docs/reference/functions/extensionsInitialiseEngine.md +25 -0
  22. package/docs/reference/functions/extensionsInitialiseEngineServer.md +31 -0
  23. package/docs/reference/functions/getFiles.md +19 -0
  24. package/docs/reference/functions/getSubFolders.md +19 -0
  25. package/docs/reference/functions/shutdownExtensions.md +19 -0
  26. package/docs/reference/functions/start.md +4 -4
  27. package/docs/reference/index.md +17 -0
  28. package/docs/reference/interfaces/IEngineEnvironmentVariables.md +118 -26
  29. package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +166 -34
  30. package/docs/reference/interfaces/INodeEngineConfig.md +7 -0
  31. package/docs/reference/interfaces/INodeEnvironmentVariables.md +166 -34
  32. package/docs/reference/interfaces/INodeOptions.md +6 -2
  33. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineMethod.md +18 -0
  34. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineServerMethod.md +24 -0
  35. package/docs/reference/type-aliases/NodeExtensionInitialiseMethod.md +23 -0
  36. package/docs/reference/variables/ATTESTATION_VERIFICATION_METHOD_ID.md +3 -0
  37. package/docs/reference/variables/AUTH_SIGNING_KEY_ID.md +3 -0
  38. package/docs/reference/variables/BLOB_STORAGE_ENCRYPTION_KEY_ID.md +3 -0
  39. package/docs/reference/variables/IMMUTABLE_PROOF_VERIFICATION_METHOD_ID.md +3 -0
  40. package/docs/reference/variables/SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID.md +3 -0
  41. package/docs/reference/variables/VC_AUTHENTICATION_VERIFICATION_METHOD_ID.md +3 -0
  42. package/package.json +13 -2
@@ -38,6 +38,15 @@ function _interopNamespaceDefault(e) {
38
38
 
39
39
  var dotenv__namespace = /*#__PURE__*/_interopNamespaceDefault(dotenv);
40
40
 
41
+ // Copyright 2024 IOTA Stiftung.
42
+ // SPDX-License-Identifier: Apache-2.0.
43
+ const ATTESTATION_VERIFICATION_METHOD_ID = "attestation-assertion";
44
+ const IMMUTABLE_PROOF_VERIFICATION_METHOD_ID = "immutable-proof-assertion";
45
+ const BLOB_STORAGE_ENCRYPTION_KEY_ID = "blob-encryption";
46
+ const SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID = "synchronised-storage-blob-encryption";
47
+ const VC_AUTHENTICATION_VERIFICATION_METHOD_ID = "node-authentication-assertion";
48
+ const AUTH_SIGNING_KEY_ID = "auth-signing";
49
+
41
50
  // Copyright 2024 IOTA Stiftung.
42
51
  // SPDX-License-Identifier: Apache-2.0.
43
52
  /**
@@ -98,6 +107,64 @@ async function fileExists(filename) {
98
107
  return false;
99
108
  }
100
109
  }
110
+ /**
111
+ * Does the specified directory exist.
112
+ * @param directory The directory to check for existence.
113
+ * @returns True if the directory exists.
114
+ */
115
+ async function directoryExists(directory) {
116
+ try {
117
+ const stats = await promises.stat(directory);
118
+ return stats.isDirectory();
119
+ }
120
+ catch {
121
+ return false;
122
+ }
123
+ }
124
+ /**
125
+ * Get the sub folders for the folder.
126
+ * @param directory The directory to get the sub folders.
127
+ * @returns The list of sub folders.
128
+ */
129
+ async function getSubFolders(directory) {
130
+ try {
131
+ const dir = await promises.readdir(directory);
132
+ const folders = [];
133
+ for (const dirEntry of dir) {
134
+ const fullPath = path.join(directory, dirEntry);
135
+ const stats = await promises.stat(fullPath);
136
+ if (stats.isDirectory()) {
137
+ folders.push(fullPath);
138
+ }
139
+ }
140
+ return folders;
141
+ }
142
+ catch {
143
+ return [];
144
+ }
145
+ }
146
+ /**
147
+ * Get the files in the directory.
148
+ * @param directory The directory to get the files from.
149
+ * @returns The list of files in the directory.
150
+ */
151
+ async function getFiles(directory) {
152
+ try {
153
+ const dir = await promises.readdir(directory);
154
+ const files = [];
155
+ for (const dirEntry of dir) {
156
+ const fullPath = path.join(directory, dirEntry);
157
+ const stats = await promises.stat(fullPath);
158
+ if (stats.isFile()) {
159
+ files.push(fullPath);
160
+ }
161
+ }
162
+ return files;
163
+ }
164
+ catch {
165
+ return [];
166
+ }
167
+ }
101
168
  /**
102
169
  * Load the text file.
103
170
  * @param filename The filename of the text file to load.
@@ -151,10 +218,16 @@ async function bootstrap(engineCore, context, envVars) {
151
218
  await bootstrapNodeUser(engineCore, context, envVars, features);
152
219
  await bootstrapAuth(engineCore, context, envVars);
153
220
  await bootstrapBlobEncryption(engineCore, context, envVars);
154
- await addVerificationMethod(engineCore, context, "attestation", envVars.attestationVerificationMethodId);
155
- await addVerificationMethod(engineCore, context, "immutable proof", envVars.immutableProofVerificationMethodId);
221
+ const defaultAttestationConnectorType = engineCore.getRegisteredInstanceTypeOptional("attestationConnector");
222
+ if (!core.Is.empty(defaultAttestationConnectorType)) {
223
+ await addVerificationMethod(engineCore, context, "attestation", envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID);
224
+ }
225
+ const defaultImmutableProofComponentType = engineCore.getRegisteredInstanceTypeOptional("immutableProofComponent");
226
+ if (!core.Is.empty(defaultImmutableProofComponentType)) {
227
+ await addVerificationMethod(engineCore, context, "immutable proof", envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID);
228
+ }
156
229
  if (core.Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
157
- await addVerificationMethod(engineCore, context, "verifiable credential authentication", envVars.vcAuthenticationVerificationMethodId);
230
+ await addVerificationMethod(engineCore, context, "verifiable credential authentication", envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID);
158
231
  }
159
232
  await bootstrapSynchronisedStorage(engineCore, context, envVars);
160
233
  }
@@ -267,7 +340,7 @@ async function finaliseWallet(engineCore, envVars, features, finalIdentity, addr
267
340
  // If we are using entity storage for wallet the identity associated with the
268
341
  // address will be wrong, so fix it
269
342
  if (defaultWalletConnectorType.startsWith(engineTypes.WalletConnectorType.EntityStorage)) {
270
- const walletAddress = entityStorageModels.EntityStorageConnectorFactory.get(core.StringHelper.kebabCase("WalletAddress"));
343
+ const walletAddress = entityStorageModels.EntityStorageConnectorFactory.get("wallet-address");
271
344
  const addr = await walletAddress.get(addresses[0]);
272
345
  if (!core.Is.empty(addr)) {
273
346
  addr.identity = finalIdentity;
@@ -337,7 +410,7 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
337
410
  const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceType("authenticationComponent");
338
411
  if (defaultAuthenticationComponentType.startsWith(engineServerTypes.AuthenticationComponentType.EntityStorage) &&
339
412
  core.Is.stringValue(context.state.nodeIdentity)) {
340
- const authUserEntityStorage = entityStorageModels.EntityStorageConnectorFactory.get(core.StringHelper.kebabCase("AuthenticationUser"));
413
+ const authUserEntityStorage = entityStorageModels.EntityStorageConnectorFactory.get("authentication-user");
341
414
  const email = envVars.username ?? DEFAULT_NODE_USERNAME;
342
415
  let nodeAdminUser = await authUserEntityStorage.get(email);
343
416
  if (core.Is.empty(nodeAdminUser)) {
@@ -430,7 +503,7 @@ async function bootstrapBlobEncryption(engineCore, context, envVars, features) {
430
503
  // Create a new key for encrypting blobs
431
504
  const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
432
505
  const vaultConnector = vaultModels.VaultConnectorFactory.get(defaultVaultConnectorType);
433
- const keyName = `${context.state.nodeIdentity}/${envVars.blobStorageEncryptionKeyId}`;
506
+ const keyName = `${context.state.nodeIdentity}/${envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID}`;
434
507
  let existingKey;
435
508
  try {
436
509
  existingKey = await vaultConnector.getKey(keyName);
@@ -470,7 +543,7 @@ async function bootstrapAuth(engineCore, context, envVars, features) {
470
543
  // Create a new JWT signing key and a user login for the node
471
544
  const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
472
545
  const vaultConnector = vaultModels.VaultConnectorFactory.get(defaultVaultConnectorType);
473
- const keyName = `${context.state.nodeIdentity}/${envVars.authSigningKeyId}`;
546
+ const keyName = `${context.state.nodeIdentity}/${envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID}`;
474
547
  let existingKey;
475
548
  try {
476
549
  existingKey = await vaultConnector.getKey(keyName);
@@ -495,11 +568,11 @@ async function bootstrapAuth(engineCore, context, envVars, features) {
495
568
  async function bootstrapSynchronisedStorage(engineCore, context, envVars, features) {
496
569
  if (core.Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false) {
497
570
  // If this is a trusted node we need to add the blob encryption key pair
498
- if (core.Is.stringValue(envVars.synchronisedStorageBlobStorageEncryptionKeyId) &&
499
- core.Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {
571
+ if (core.Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {
500
572
  const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
501
573
  const vaultConnector = vaultModels.VaultConnectorFactory.get(defaultVaultConnectorType);
502
- const keyName = envVars.synchronisedStorageBlobStorageEncryptionKeyId;
574
+ const keyName = envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
575
+ SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;
503
576
  let existingKey;
504
577
  try {
505
578
  existingKey = await vaultConnector.getKey(keyName);
@@ -561,49 +634,43 @@ async function addVerificationMethod(engineCore, context, verificationMethodTitl
561
634
  * @param envVars The environment variables.
562
635
  * @returns The config for the core.
563
636
  */
564
- function buildEngineConfiguration(envVars) {
637
+ async function buildEngineConfiguration(envVars) {
565
638
  if (core.Is.stringValue(envVars.storageFileRoot)) {
566
639
  envVars.stateFilename ??= "engine-state.json";
567
640
  envVars.storageFileRoot = path.resolve(envVars.storageFileRoot);
568
641
  envVars.stateFilename = path.join(envVars.storageFileRoot, envVars.stateFilename);
569
642
  }
570
- envVars.attestationVerificationMethodId ??= "attestation-assertion";
571
- envVars.immutableProofVerificationMethodId ??= "immutable-proof-assertion";
572
- envVars.blobStorageEnableEncryption ??= "false";
573
- envVars.blobStorageEncryptionKeyId ??= "blob-encryption";
574
- envVars.synchronisedStorageBlobStorageEncryptionKeyId ??= "synchronised-storage-blob-encryption";
575
- envVars.vcAuthenticationVerificationMethodId ??= "node-authentication-assertion";
576
643
  const coreConfig = {
577
644
  debug: core.Coerce.boolean(envVars.debug) ?? false,
578
645
  types: {}
579
646
  };
580
- configureEntityStorage(coreConfig, envVars);
581
- configureBlobStorage(coreConfig, envVars);
582
- configureVault(coreConfig, envVars);
583
- configureDlt(coreConfig, envVars);
584
- configureLogging(coreConfig, envVars);
585
- configureBackgroundTask(coreConfig, envVars);
586
- configureTaskScheduler(coreConfig, envVars);
587
- configureEventBus(coreConfig, envVars);
588
- configureTelemetry(coreConfig, envVars);
589
- configureMessaging(coreConfig, envVars);
590
- configureFaucet(coreConfig, envVars);
591
- configureWallet(coreConfig, envVars);
592
- configureNft(coreConfig, envVars);
593
- configureVerifiableStorage(coreConfig, envVars);
594
- configureIdentity(coreConfig, envVars);
595
- configureIdentityResolver(coreConfig, envVars);
596
- configureIdentityProfile(coreConfig, envVars);
597
- configureAttestation(coreConfig, envVars);
598
- configureDataProcessing(coreConfig, envVars);
599
- configureAuditableItemGraph(coreConfig, envVars);
600
- configureAuditableItemStream(coreConfig, envVars);
601
- configureDocumentManagement(coreConfig, envVars);
602
- configureVerifiableCredentialAuthentication(coreConfig, envVars);
603
- configureRightsManagement(coreConfig, envVars);
604
- configureSynchronisedStorage(coreConfig, envVars);
605
- configureFederatedCatalogue(coreConfig, envVars);
606
- configureDataSpaceConnector(coreConfig, envVars);
647
+ await configureEntityStorage(coreConfig, envVars);
648
+ await configureBlobStorage(coreConfig, envVars);
649
+ await configureVault(coreConfig, envVars);
650
+ await configureDlt(coreConfig, envVars);
651
+ await configureLogging(coreConfig, envVars);
652
+ await configureBackgroundTask(coreConfig, envVars);
653
+ await configureTaskScheduler(coreConfig, envVars);
654
+ await configureEventBus(coreConfig, envVars);
655
+ await configureTelemetry(coreConfig, envVars);
656
+ await configureMessaging(coreConfig, envVars);
657
+ await configureFaucet(coreConfig, envVars);
658
+ await configureWallet(coreConfig, envVars);
659
+ await configureNft(coreConfig, envVars);
660
+ await configureVerifiableStorage(coreConfig, envVars);
661
+ await configureIdentity(coreConfig, envVars);
662
+ await configureIdentityResolver(coreConfig, envVars);
663
+ await configureIdentityProfile(coreConfig, envVars);
664
+ await configureAttestation(coreConfig, envVars);
665
+ await configureDataProcessing(coreConfig, envVars);
666
+ await configureAuditableItemGraph(coreConfig, envVars);
667
+ await configureAuditableItemStream(coreConfig, envVars);
668
+ await configureDocumentManagement(coreConfig, envVars);
669
+ await configureVerifiableCredentialAuthentication(coreConfig, envVars);
670
+ await configureRightsManagement(coreConfig, envVars);
671
+ await configureSynchronisedStorage(coreConfig, envVars);
672
+ await configureFederatedCatalogue(coreConfig, envVars);
673
+ await configureDataSpaceConnector(coreConfig, envVars);
607
674
  return coreConfig;
608
675
  }
609
676
  /**
@@ -611,7 +678,7 @@ function buildEngineConfiguration(envVars) {
611
678
  * @param coreConfig The core config.
612
679
  * @param envVars The environment variables.
613
680
  */
614
- function configureEntityStorage(coreConfig, envVars) {
681
+ async function configureEntityStorage(coreConfig, envVars) {
615
682
  coreConfig.types ??= {};
616
683
  coreConfig.types.entityStorageConnector ??= [];
617
684
  const entityStorageConnectorTypes = envVars.entityStorageConnectorType?.split(",") ?? [];
@@ -635,9 +702,10 @@ function configureEntityStorage(coreConfig, envVars) {
635
702
  options: {
636
703
  config: {
637
704
  region: envVars.awsDynamodbRegion ?? "",
638
- accessKeyId: envVars.awsDynamodbAccessKeyId ?? "",
639
- secretAccessKey: envVars.awsDynamodbSecretAccessKey ?? "",
640
- endpoint: envVars.awsDynamodbEndpoint ?? ""
705
+ authMode: envVars.awsDynamodbAuthMode,
706
+ accessKeyId: envVars.awsDynamodbAccessKeyId,
707
+ secretAccessKey: envVars.awsDynamodbSecretAccessKey,
708
+ endpoint: envVars.awsDynamodbEndpoint
641
709
  },
642
710
  tablePrefix: envVars.entityStorageTablePrefix
643
711
  }
@@ -755,7 +823,7 @@ function configureEntityStorage(coreConfig, envVars) {
755
823
  * @param coreConfig The core config.
756
824
  * @param envVars The environment variables.
757
825
  */
758
- function configureBlobStorage(coreConfig, envVars) {
826
+ async function configureBlobStorage(coreConfig, envVars) {
759
827
  coreConfig.types.blobStorageConnector ??= [];
760
828
  const blobStorageConnectorTypes = envVars.blobStorageConnectorType?.split(",") ?? [];
761
829
  if (blobStorageConnectorTypes.includes(engineTypes.BlobStorageConnectorType.Memory)) {
@@ -794,9 +862,10 @@ function configureBlobStorage(coreConfig, envVars) {
794
862
  config: {
795
863
  region: envVars.awsS3Region ?? "",
796
864
  bucketName: envVars.awsS3BucketName ?? "",
797
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
798
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
799
- endpoint: envVars.awsS3Endpoint ?? ""
865
+ authMode: envVars.awsS3AuthMode,
866
+ accessKeyId: envVars.awsS3AccessKeyId,
867
+ secretAccessKey: envVars.awsS3SecretAccessKey,
868
+ endpoint: envVars.awsS3Endpoint
800
869
  },
801
870
  storagePrefix: envVars.blobStoragePrefix
802
871
  }
@@ -853,7 +922,7 @@ function configureBlobStorage(coreConfig, envVars) {
853
922
  options: {
854
923
  config: {
855
924
  vaultKeyId: (envVars.blobStorageEnableEncryption ?? false)
856
- ? envVars.blobStorageEncryptionKeyId
925
+ ? (envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID)
857
926
  : undefined
858
927
  }
859
928
  }
@@ -865,7 +934,7 @@ function configureBlobStorage(coreConfig, envVars) {
865
934
  * @param coreConfig The core config.
866
935
  * @param envVars The environment variables.
867
936
  */
868
- function configureLogging(coreConfig, envVars) {
937
+ async function configureLogging(coreConfig, envVars) {
869
938
  coreConfig.types.loggingConnector ??= [];
870
939
  const loggingConnectors = (envVars.loggingConnector ?? "").split(",");
871
940
  for (const loggingConnector of loggingConnectors) {
@@ -907,7 +976,7 @@ function configureLogging(coreConfig, envVars) {
907
976
  * @param coreConfig The core config.
908
977
  * @param envVars The environment variables.
909
978
  */
910
- function configureVault(coreConfig, envVars) {
979
+ async function configureVault(coreConfig, envVars) {
911
980
  coreConfig.types.vaultConnector ??= [];
912
981
  if (envVars.vaultConnector === engineTypes.VaultConnectorType.EntityStorage) {
913
982
  coreConfig.types.vaultConnector.push({
@@ -931,7 +1000,7 @@ function configureVault(coreConfig, envVars) {
931
1000
  * @param coreConfig The core config.
932
1001
  * @param envVars The environment variables.
933
1002
  */
934
- function configureBackgroundTask(coreConfig, envVars) {
1003
+ async function configureBackgroundTask(coreConfig, envVars) {
935
1004
  coreConfig.types.backgroundTaskConnector ??= [];
936
1005
  if (envVars.backgroundTaskConnector === engineTypes.BackgroundTaskConnectorType.EntityStorage) {
937
1006
  coreConfig.types.backgroundTaskConnector.push({
@@ -944,7 +1013,7 @@ function configureBackgroundTask(coreConfig, envVars) {
944
1013
  * @param coreConfig The core config.
945
1014
  * @param envVars The environment variables.
946
1015
  */
947
- function configureEventBus(coreConfig, envVars) {
1016
+ async function configureEventBus(coreConfig, envVars) {
948
1017
  coreConfig.types.eventBusConnector ??= [];
949
1018
  if (envVars.eventBusConnector === engineTypes.EventBusConnectorType.Local) {
950
1019
  coreConfig.types.eventBusConnector.push({
@@ -961,7 +1030,7 @@ function configureEventBus(coreConfig, envVars) {
961
1030
  * @param coreConfig The core config.
962
1031
  * @param envVars The environment variables.
963
1032
  */
964
- function configureTelemetry(coreConfig, envVars) {
1033
+ async function configureTelemetry(coreConfig, envVars) {
965
1034
  coreConfig.types.telemetryConnector ??= [];
966
1035
  if (envVars.telemetryConnector === engineTypes.TelemetryConnectorType.EntityStorage) {
967
1036
  coreConfig.types.telemetryConnector.push({
@@ -978,71 +1047,84 @@ function configureTelemetry(coreConfig, envVars) {
978
1047
  * @param coreConfig The core config.
979
1048
  * @param envVars The environment variables.
980
1049
  */
981
- function configureMessaging(coreConfig, envVars) {
982
- coreConfig.types.messagingEmailConnector ??= [];
983
- coreConfig.types.messagingSmsConnector ??= [];
984
- coreConfig.types.messagingPushNotificationConnector ??= [];
985
- if (envVars.messagingEmailConnector === engineTypes.MessagingEmailConnectorType.EntityStorage) {
986
- coreConfig.types.messagingEmailConnector.push({
987
- type: engineTypes.MessagingEmailConnectorType.EntityStorage
988
- });
989
- }
990
- else if (envVars.messagingEmailConnector === engineTypes.MessagingEmailConnectorType.Aws) {
991
- coreConfig.types.messagingEmailConnector.push({
992
- type: engineTypes.MessagingEmailConnectorType.Aws,
993
- options: {
994
- config: {
995
- region: envVars.awsS3Region ?? "",
996
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
997
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
998
- endpoint: envVars.awsS3Endpoint ?? ""
1050
+ async function configureMessaging(coreConfig, envVars) {
1051
+ if (core.Coerce.boolean(envVars.messagingEnabled) ?? false) {
1052
+ coreConfig.types.messagingEmailConnector ??= [];
1053
+ coreConfig.types.messagingSmsConnector ??= [];
1054
+ coreConfig.types.messagingPushNotificationConnector ??= [];
1055
+ if (envVars.messagingEmailConnector === engineTypes.MessagingEmailConnectorType.EntityStorage) {
1056
+ coreConfig.types.messagingEmailConnector.push({
1057
+ type: engineTypes.MessagingEmailConnectorType.EntityStorage
1058
+ });
1059
+ }
1060
+ else if (envVars.messagingEmailConnector === engineTypes.MessagingEmailConnectorType.Aws) {
1061
+ coreConfig.types.messagingEmailConnector.push({
1062
+ type: engineTypes.MessagingEmailConnectorType.Aws,
1063
+ options: {
1064
+ config: {
1065
+ region: envVars.awsSesRegion ?? "",
1066
+ authMode: envVars.awsSesAuthMode,
1067
+ accessKeyId: envVars.awsSesAccessKeyId,
1068
+ secretAccessKey: envVars.awsSesSecretAccessKey,
1069
+ endpoint: envVars.awsSesEndpoint
1070
+ }
999
1071
  }
1000
- }
1001
- });
1002
- }
1003
- if (envVars.messagingSmsConnector === engineTypes.MessagingSmsConnectorType.EntityStorage) {
1004
- coreConfig.types.messagingSmsConnector.push({
1005
- type: engineTypes.MessagingSmsConnectorType.EntityStorage
1006
- });
1007
- }
1008
- else if (envVars.messagingSmsConnector === engineTypes.MessagingSmsConnectorType.Aws) {
1009
- coreConfig.types.messagingSmsConnector.push({
1010
- type: engineTypes.MessagingSmsConnectorType.Aws,
1011
- options: {
1012
- config: {
1013
- region: envVars.awsS3Region ?? "",
1014
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
1015
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
1016
- endpoint: envVars.awsS3Endpoint ?? ""
1072
+ });
1073
+ }
1074
+ if (envVars.messagingSmsConnector === engineTypes.MessagingSmsConnectorType.EntityStorage) {
1075
+ coreConfig.types.messagingSmsConnector.push({
1076
+ type: engineTypes.MessagingSmsConnectorType.EntityStorage
1077
+ });
1078
+ }
1079
+ else if (envVars.messagingSmsConnector === engineTypes.MessagingSmsConnectorType.Aws) {
1080
+ coreConfig.types.messagingSmsConnector.push({
1081
+ type: engineTypes.MessagingSmsConnectorType.Aws,
1082
+ options: {
1083
+ config: {
1084
+ region: envVars.awsSesRegion ?? "",
1085
+ authMode: envVars.awsSesAuthMode,
1086
+ accessKeyId: envVars.awsSesAccessKeyId,
1087
+ secretAccessKey: envVars.awsSesSecretAccessKey,
1088
+ endpoint: envVars.awsSesEndpoint
1089
+ }
1017
1090
  }
1018
- }
1019
- });
1020
- }
1021
- if (envVars.messagingPushNotificationConnector ===
1022
- engineTypes.MessagingPushNotificationConnectorType.EntityStorage) {
1023
- coreConfig.types.messagingPushNotificationConnector.push({
1024
- type: engineTypes.MessagingPushNotificationConnectorType.EntityStorage
1025
- });
1026
- }
1027
- else if (envVars.messagingPushNotificationConnector === engineTypes.MessagingPushNotificationConnectorType.Aws) {
1028
- coreConfig.types.messagingPushNotificationConnector.push({
1029
- type: engineTypes.MessagingPushNotificationConnectorType.Aws,
1091
+ });
1092
+ }
1093
+ if (envVars.messagingPushNotificationConnector ===
1094
+ engineTypes.MessagingPushNotificationConnectorType.EntityStorage) {
1095
+ coreConfig.types.messagingPushNotificationConnector.push({
1096
+ type: engineTypes.MessagingPushNotificationConnectorType.EntityStorage
1097
+ });
1098
+ }
1099
+ else if (envVars.messagingPushNotificationConnector === engineTypes.MessagingPushNotificationConnectorType.Aws) {
1100
+ coreConfig.types.messagingPushNotificationConnector.push({
1101
+ type: engineTypes.MessagingPushNotificationConnectorType.Aws,
1102
+ options: {
1103
+ config: {
1104
+ region: envVars.awsSesRegion ?? "",
1105
+ authMode: envVars.awsSesAuthMode,
1106
+ accessKeyId: envVars.awsSesAccessKeyId,
1107
+ secretAccessKey: envVars.awsSesSecretAccessKey,
1108
+ endpoint: envVars.awsSesEndpoint,
1109
+ applicationsSettings: core.Is.json(envVars.awsMessagingPushNotificationApplications)
1110
+ ? JSON.parse(envVars.awsMessagingPushNotificationApplications)
1111
+ : []
1112
+ }
1113
+ }
1114
+ });
1115
+ }
1116
+ const templates = core.Is.arrayValue(envVars.messagingTemplates)
1117
+ ? envVars.messagingTemplates
1118
+ : undefined;
1119
+ coreConfig.types.messagingAdminComponent ??= [];
1120
+ coreConfig.types.messagingAdminComponent.push({
1121
+ type: engineTypes.MessagingAdminComponentType.Service,
1030
1122
  options: {
1031
1123
  config: {
1032
- region: envVars.awsS3Region ?? "",
1033
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
1034
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
1035
- endpoint: envVars.awsS3Endpoint ?? "",
1036
- applicationsSettings: core.Is.json(envVars.awsMessagingPushNotificationApplications)
1037
- ? JSON.parse(envVars.awsMessagingPushNotificationApplications)
1038
- : []
1124
+ templates
1039
1125
  }
1040
1126
  }
1041
1127
  });
1042
- }
1043
- if (coreConfig.types.messagingEmailConnector.length > 0 ||
1044
- coreConfig.types.messagingSmsConnector.length > 0 ||
1045
- coreConfig.types.messagingPushNotificationConnector.length > 0) {
1046
1128
  coreConfig.types.messagingComponent ??= [];
1047
1129
  coreConfig.types.messagingComponent.push({ type: engineTypes.MessagingComponentType.Service });
1048
1130
  }
@@ -1052,7 +1134,7 @@ function configureMessaging(coreConfig, envVars) {
1052
1134
  * @param coreConfig The core config.
1053
1135
  * @param envVars The environment variables.
1054
1136
  */
1055
- function configureFaucet(coreConfig, envVars) {
1137
+ async function configureFaucet(coreConfig, envVars) {
1056
1138
  coreConfig.types.faucetConnector ??= [];
1057
1139
  if (envVars.faucetConnector === engineTypes.FaucetConnectorType.EntityStorage) {
1058
1140
  coreConfig.types.faucetConnector.push({
@@ -1078,7 +1160,7 @@ function configureFaucet(coreConfig, envVars) {
1078
1160
  * @param coreConfig The core config.
1079
1161
  * @param envVars The environment variables.
1080
1162
  */
1081
- function configureWallet(coreConfig, envVars) {
1163
+ async function configureWallet(coreConfig, envVars) {
1082
1164
  coreConfig.types.walletConnector ??= [];
1083
1165
  if (envVars.walletConnector === engineTypes.WalletConnectorType.EntityStorage) {
1084
1166
  coreConfig.types.walletConnector.push({
@@ -1100,7 +1182,7 @@ function configureWallet(coreConfig, envVars) {
1100
1182
  * @param coreConfig The core config.
1101
1183
  * @param envVars The environment variables.
1102
1184
  */
1103
- function configureNft(coreConfig, envVars) {
1185
+ async function configureNft(coreConfig, envVars) {
1104
1186
  coreConfig.types.nftConnector ??= [];
1105
1187
  if (envVars.nftConnector === engineTypes.NftConnectorType.EntityStorage) {
1106
1188
  coreConfig.types.nftConnector.push({
@@ -1126,7 +1208,7 @@ function configureNft(coreConfig, envVars) {
1126
1208
  * @param coreConfig The core config.
1127
1209
  * @param envVars The environment variables.
1128
1210
  */
1129
- function configureVerifiableStorage(coreConfig, envVars) {
1211
+ async function configureVerifiableStorage(coreConfig, envVars) {
1130
1212
  coreConfig.types.verifiableStorageConnector ??= [];
1131
1213
  if (envVars.verifiableStorageConnector === engineTypes.VerifiableStorageConnectorType.EntityStorage) {
1132
1214
  coreConfig.types.verifiableStorageConnector.push({
@@ -1152,7 +1234,7 @@ function configureVerifiableStorage(coreConfig, envVars) {
1152
1234
  type: engineTypes.ImmutableProofComponentType.Service,
1153
1235
  options: {
1154
1236
  config: {
1155
- verificationMethodId: envVars.immutableProofVerificationMethodId
1237
+ verificationMethodId: envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID
1156
1238
  }
1157
1239
  }
1158
1240
  });
@@ -1163,7 +1245,7 @@ function configureVerifiableStorage(coreConfig, envVars) {
1163
1245
  * @param coreConfig The core config.
1164
1246
  * @param envVars The environment variables.
1165
1247
  */
1166
- function configureIdentity(coreConfig, envVars) {
1248
+ async function configureIdentity(coreConfig, envVars) {
1167
1249
  coreConfig.types.identityConnector ??= [];
1168
1250
  if (envVars.identityConnector === engineTypes.IdentityConnectorType.EntityStorage) {
1169
1251
  coreConfig.types.identityConnector.push({
@@ -1189,7 +1271,7 @@ function configureIdentity(coreConfig, envVars) {
1189
1271
  * @param coreConfig The core config.
1190
1272
  * @param envVars The environment variables.
1191
1273
  */
1192
- function configureIdentityResolver(coreConfig, envVars) {
1274
+ async function configureIdentityResolver(coreConfig, envVars) {
1193
1275
  coreConfig.types.identityResolverConnector ??= [];
1194
1276
  if (envVars.identityResolverConnector === engineTypes.IdentityResolverConnectorType.EntityStorage) {
1195
1277
  coreConfig.types.identityResolverConnector.push({
@@ -1227,7 +1309,7 @@ function configureIdentityResolver(coreConfig, envVars) {
1227
1309
  * @param coreConfig The core config.
1228
1310
  * @param envVars The environment variables.
1229
1311
  */
1230
- function configureIdentityProfile(coreConfig, envVars) {
1312
+ async function configureIdentityProfile(coreConfig, envVars) {
1231
1313
  coreConfig.types.identityProfileConnector ??= [];
1232
1314
  if (envVars.identityProfileConnector === engineTypes.IdentityConnectorType.EntityStorage) {
1233
1315
  coreConfig.types.identityProfileConnector.push({
@@ -1244,7 +1326,7 @@ function configureIdentityProfile(coreConfig, envVars) {
1244
1326
  * @param coreConfig The core config.
1245
1327
  * @param envVars The environment variables.
1246
1328
  */
1247
- function configureAttestation(coreConfig, envVars) {
1329
+ async function configureAttestation(coreConfig, envVars) {
1248
1330
  coreConfig.types.attestationConnector ??= [];
1249
1331
  if (envVars.attestationConnector === engineTypes.AttestationConnectorType.Nft) {
1250
1332
  coreConfig.types.attestationConnector.push({
@@ -1257,7 +1339,7 @@ function configureAttestation(coreConfig, envVars) {
1257
1339
  type: engineTypes.AttestationComponentType.Service,
1258
1340
  options: {
1259
1341
  config: {
1260
- verificationMethodId: envVars.attestationVerificationMethodId
1342
+ verificationMethodId: envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID
1261
1343
  }
1262
1344
  }
1263
1345
  });
@@ -1268,7 +1350,7 @@ function configureAttestation(coreConfig, envVars) {
1268
1350
  * @param coreConfig The core config.
1269
1351
  * @param envVars The environment variables.
1270
1352
  */
1271
- function configureAuditableItemGraph(coreConfig, envVars) {
1353
+ async function configureAuditableItemGraph(coreConfig, envVars) {
1272
1354
  if (core.Coerce.boolean(envVars.auditableItemGraphEnabled) ?? false) {
1273
1355
  coreConfig.types.auditableItemGraphComponent ??= [];
1274
1356
  coreConfig.types.auditableItemGraphComponent.push({
@@ -1281,7 +1363,7 @@ function configureAuditableItemGraph(coreConfig, envVars) {
1281
1363
  * @param coreConfig The core config.
1282
1364
  * @param envVars The environment variables.
1283
1365
  */
1284
- function configureAuditableItemStream(coreConfig, envVars) {
1366
+ async function configureAuditableItemStream(coreConfig, envVars) {
1285
1367
  if (core.Coerce.boolean(envVars.auditableItemStreamEnabled) ?? false) {
1286
1368
  coreConfig.types.auditableItemStreamComponent ??= [];
1287
1369
  coreConfig.types.auditableItemStreamComponent.push({
@@ -1294,7 +1376,7 @@ function configureAuditableItemStream(coreConfig, envVars) {
1294
1376
  * @param coreConfig The core config.
1295
1377
  * @param envVars The environment variables.
1296
1378
  */
1297
- function configureDataProcessing(coreConfig, envVars) {
1379
+ async function configureDataProcessing(coreConfig, envVars) {
1298
1380
  if (core.Coerce.boolean(envVars.dataProcessingEnabled) ?? false) {
1299
1381
  coreConfig.types.dataProcessingComponent ??= [];
1300
1382
  coreConfig.types.dataProcessingComponent.push({ type: engineTypes.DataProcessingComponentType.Service });
@@ -1328,7 +1410,7 @@ function configureDataProcessing(coreConfig, envVars) {
1328
1410
  * @param coreConfig The core config.
1329
1411
  * @param envVars The environment variables.
1330
1412
  */
1331
- function configureDocumentManagement(coreConfig, envVars) {
1413
+ async function configureDocumentManagement(coreConfig, envVars) {
1332
1414
  if (core.Coerce.boolean(envVars.documentManagementEnabled) ?? false) {
1333
1415
  coreConfig.types.documentManagementComponent ??= [];
1334
1416
  coreConfig.types.documentManagementComponent.push({
@@ -1341,14 +1423,16 @@ function configureDocumentManagement(coreConfig, envVars) {
1341
1423
  * @param coreConfig The core config.
1342
1424
  * @param envVars The environment variables.
1343
1425
  */
1344
- function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
1426
+ async function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
1345
1427
  if (core.Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
1346
1428
  // Can only perform VC authentication if identity component is available
1347
1429
  coreConfig.types.authenticationGeneratorComponent ??= [];
1348
1430
  coreConfig.types.authenticationGeneratorComponent.push({
1349
1431
  type: engineTypes.AuthenticationGeneratorComponentType.VerifiableCredential,
1350
1432
  options: {
1351
- config: { verificationMethodId: envVars.vcAuthenticationVerificationMethodId ?? "" }
1433
+ config: {
1434
+ verificationMethodId: envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID
1435
+ }
1352
1436
  },
1353
1437
  features: ["verifiable-credential"]
1354
1438
  });
@@ -1359,7 +1443,7 @@ function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
1359
1443
  * @param coreConfig The core config.
1360
1444
  * @param envVars The environment variables.
1361
1445
  */
1362
- function configureRightsManagement(coreConfig, envVars) {
1446
+ async function configureRightsManagement(coreConfig, envVars) {
1363
1447
  if (core.Coerce.boolean(envVars.rightsManagementEnabled) ?? false) {
1364
1448
  coreConfig.types.rightsManagementPapComponent ??= [];
1365
1449
  coreConfig.types.rightsManagementPapComponent.push({
@@ -1448,7 +1532,7 @@ function configureRightsManagement(coreConfig, envVars) {
1448
1532
  * @param coreConfig The core config.
1449
1533
  * @param envVars The environment variables.
1450
1534
  */
1451
- function configureTaskScheduler(coreConfig, envVars) {
1535
+ async function configureTaskScheduler(coreConfig, envVars) {
1452
1536
  if (core.Coerce.boolean(envVars.taskSchedulerEnabled) ?? false) {
1453
1537
  coreConfig.types.taskSchedulerComponent ??= [];
1454
1538
  coreConfig.types.taskSchedulerComponent.push({
@@ -1461,7 +1545,7 @@ function configureTaskScheduler(coreConfig, envVars) {
1461
1545
  * @param coreConfig The core config.
1462
1546
  * @param envVars The environment variables.
1463
1547
  */
1464
- function configureSynchronisedStorage(coreConfig, envVars) {
1548
+ async function configureSynchronisedStorage(coreConfig, envVars) {
1465
1549
  if (core.Is.arrayValue(coreConfig.types.identityResolverComponent) &&
1466
1550
  (core.Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false)) {
1467
1551
  // Check if the config provides a custom verifiable storage key id
@@ -1476,7 +1560,8 @@ function configureSynchronisedStorage(coreConfig, envVars) {
1476
1560
  options: {
1477
1561
  config: {
1478
1562
  verifiableStorageKeyId: verifiableStorageKeyId ?? "",
1479
- blobStorageEncryptionKeyId: envVars.synchronisedStorageBlobStorageEncryptionKeyId,
1563
+ blobStorageEncryptionKeyId: envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
1564
+ SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID,
1480
1565
  entityUpdateIntervalMinutes: core.Coerce.number(envVars.synchronisedStorageEntityUpdateIntervalMinutes),
1481
1566
  consolidationIntervalMinutes: core.Coerce.number(envVars.synchronisedStorageConsolidationIntervalMinutes),
1482
1567
  consolidationBatchSize: core.Coerce.number(envVars.synchronisedStorageConsolidationBatchSize),
@@ -1503,7 +1588,7 @@ function configureSynchronisedStorage(coreConfig, envVars) {
1503
1588
  * @param coreConfig The core config.
1504
1589
  * @param envVars The environment variables.
1505
1590
  */
1506
- function configureFederatedCatalogue(coreConfig, envVars) {
1591
+ async function configureFederatedCatalogue(coreConfig, envVars) {
1507
1592
  if (core.Coerce.boolean(envVars.federatedCatalogueEnabled) ?? false) {
1508
1593
  coreConfig.types.federatedCatalogueComponent ??= [];
1509
1594
  coreConfig.types.federatedCatalogueComponent.push({
@@ -1522,16 +1607,15 @@ function configureFederatedCatalogue(coreConfig, envVars) {
1522
1607
  * @param coreConfig The core config.
1523
1608
  * @param envVars The environment variables.
1524
1609
  */
1525
- function configureDataSpaceConnector(coreConfig, envVars) {
1610
+ async function configureDataSpaceConnector(coreConfig, envVars) {
1526
1611
  if (core.Coerce.boolean(envVars.dataSpaceConnectorEnabled) ?? false) {
1527
1612
  coreConfig.types.dataSpaceConnectorComponent ??= [];
1528
1613
  coreConfig.types.dataSpaceConnectorComponent.push({
1529
1614
  type: engineTypes.DataSpaceConnectorComponentType.Service,
1530
1615
  options: {
1531
1616
  config: {
1532
- dataSpaceConnectorAppDescriptors: core.Is.arrayValue(envVars.dataSpaceConnectorApps)
1533
- ? envVars.dataSpaceConnectorApps
1534
- : undefined
1617
+ retainActivityLogsFor: core.Coerce.number(envVars.dataSpaceConnectorRetainActivityLogsFor),
1618
+ activityLogsCleanUpInterval: core.Coerce.number(envVars.dataSpaceConnectorActivityLogsCleanUpInterval)
1535
1619
  }
1536
1620
  }
1537
1621
  });
@@ -1542,7 +1626,7 @@ function configureDataSpaceConnector(coreConfig, envVars) {
1542
1626
  * @param coreConfig The core config.
1543
1627
  * @param envVars The environment variables.
1544
1628
  */
1545
- function configureDlt(coreConfig, envVars) {
1629
+ async function configureDlt(coreConfig, envVars) {
1546
1630
  // Create centralized DLT configuration for IOTA if essential IOTA variables are set
1547
1631
  if (core.Is.stringValue(envVars.iotaNodeEndpoint) && core.Is.stringValue(envVars.iotaNetwork)) {
1548
1632
  coreConfig.types.dltConfig ??= [];
@@ -1577,10 +1661,9 @@ function configureDlt(coreConfig, envVars) {
1577
1661
  * @param serverInfo The server information.
1578
1662
  * @param openApiSpecPath The path to the open api spec.
1579
1663
  * @param favIconPath The path to the favicon.
1580
- * @returns The the config for the core and the server.
1664
+ * @returns The config for the core and the server.
1581
1665
  */
1582
- function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath, favIconPath) {
1583
- envVars.authSigningKeyId ??= "auth-signing";
1666
+ async function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath, favIconPath) {
1584
1667
  const webServerOptions = {
1585
1668
  port: core.Coerce.number(envVars.port),
1586
1669
  host: core.Coerce.string(envVars.host),
@@ -1696,7 +1779,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1696
1779
  type: engineServerTypes.AuthenticationComponentType.EntityStorage,
1697
1780
  options: {
1698
1781
  config: {
1699
- signingKeyName: envVars.authSigningKeyId
1782
+ signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
1700
1783
  }
1701
1784
  }
1702
1785
  });
@@ -1704,7 +1787,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1704
1787
  type: engineServerTypes.RestRouteProcessorType.AuthHeader,
1705
1788
  options: {
1706
1789
  config: {
1707
- signingKeyName: envVars.authSigningKeyId
1790
+ signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
1708
1791
  }
1709
1792
  }
1710
1793
  });
@@ -1712,7 +1795,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1712
1795
  type: engineServerTypes.SocketRouteProcessorType.AuthHeader,
1713
1796
  options: {
1714
1797
  config: {
1715
- signingKeyName: envVars.authSigningKeyId
1798
+ signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
1716
1799
  }
1717
1800
  }
1718
1801
  });
@@ -1730,17 +1813,111 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1730
1813
  return serverConfig;
1731
1814
  }
1732
1815
 
1816
+ // Copyright 2024 IOTA Stiftung.
1817
+ // SPDX-License-Identifier: Apache-2.0.
1818
+ /* eslint-disable no-console */
1819
+ /**
1820
+ * Handles the configuration of the extensions.
1821
+ * @param envVars The environment variables for the node.
1822
+ * @param nodeEngineConfig The node engine config.
1823
+ * @returns The config for the core and the server.
1824
+ */
1825
+ async function extensionsConfiguration(envVars, nodeEngineConfig) {
1826
+ if (core.Is.stringValue(envVars.extensions)) {
1827
+ const extensions = envVars.extensions.split(",");
1828
+ for (const extension of extensions) {
1829
+ let initialiseConfigMethod;
1830
+ try {
1831
+ console.info(`Loading extension "${extension}"`);
1832
+ initialiseConfigMethod = await modules.ModuleHelper.getModuleMethod(extension, "extensionInitialise");
1833
+ }
1834
+ catch (err) {
1835
+ console.error(`Failed to load extension "${extension}":`, err);
1836
+ }
1837
+ if (core.Is.function(initialiseConfigMethod)) {
1838
+ await initialiseConfigMethod(envVars, nodeEngineConfig);
1839
+ }
1840
+ }
1841
+ }
1842
+ return nodeEngineConfig;
1843
+ }
1844
+ /**
1845
+ * Handles the initialisation of the extensions when the engine has been constructed.
1846
+ * @param envVars The environment variables for the node.
1847
+ * @param engineCore The engine core instance.
1848
+ * @returns Nothing.
1849
+ */
1850
+ async function extensionsInitialiseEngine(envVars, engineCore) {
1851
+ if (core.Is.stringValue(envVars.extensions)) {
1852
+ const extensions = envVars.extensions.split(",");
1853
+ for (const extension of extensions) {
1854
+ let initialiseEngineMethod;
1855
+ try {
1856
+ initialiseEngineMethod =
1857
+ await modules.ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngine");
1858
+ }
1859
+ catch { }
1860
+ if (core.Is.function(initialiseEngineMethod)) {
1861
+ await initialiseEngineMethod(engineCore);
1862
+ }
1863
+ }
1864
+ }
1865
+ }
1866
+ /**
1867
+ * Handles the initialisation of the extensions when the engine server has been constructed.
1868
+ * @param envVars The environment variables for the node.
1869
+ * @param engineCore The engine core instance.
1870
+ * @param engineServer The engine server instance.
1871
+ * @returns Nothing.
1872
+ */
1873
+ async function extensionsInitialiseEngineServer(envVars, engineCore, engineServer) {
1874
+ if (core.Is.stringValue(envVars.extensions)) {
1875
+ const extensions = envVars.extensions.split(",");
1876
+ for (const extension of extensions) {
1877
+ let initialiseEngineServerMethod;
1878
+ try {
1879
+ initialiseEngineServerMethod =
1880
+ await modules.ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngineServer");
1881
+ }
1882
+ catch { }
1883
+ if (core.Is.function(initialiseEngineServerMethod)) {
1884
+ await initialiseEngineServerMethod(engineCore, engineServer);
1885
+ }
1886
+ }
1887
+ }
1888
+ }
1889
+ /**
1890
+ * Handles the shutdown of the extensions.
1891
+ * @param envVars The environment variables for the node.
1892
+ * @returns Nothing.
1893
+ */
1894
+ async function shutdownExtensions(envVars) {
1895
+ if (core.Is.stringValue(envVars.extensions)) {
1896
+ const extensions = envVars.extensions.split(",");
1897
+ for (const extension of extensions) {
1898
+ let shutdownMethod;
1899
+ try {
1900
+ shutdownMethod = await modules.ModuleHelper.getModuleMethod(extension, "extensionShutdown");
1901
+ }
1902
+ catch { }
1903
+ if (core.Is.function(shutdownMethod)) {
1904
+ await shutdownMethod();
1905
+ }
1906
+ }
1907
+ }
1908
+ }
1909
+
1733
1910
  // Copyright 2024 IOTA Stiftung.
1734
1911
  // SPDX-License-Identifier: Apache-2.0.
1735
1912
  /* eslint-disable no-console */
1736
1913
  /**
1737
1914
  * Start the engine server.
1738
1915
  * @param nodeOptions Optional run options for the engine server.
1739
- * @param engineServerConfig The configuration for the engine server.
1916
+ * @param nodeEngineConfig The configuration for the engine server.
1740
1917
  * @param envVars The environment variables.
1741
1918
  * @returns The engine server.
1742
1919
  */
1743
- async function start(nodeOptions, engineServerConfig, envVars) {
1920
+ async function start(nodeOptions, nodeEngineConfig, envVars) {
1744
1921
  const entityStorageConnectorType = envVars.entityStorageConnectorType?.split(",") ?? [];
1745
1922
  const blobStorageConnectorType = envVars.blobStorageConnectorType?.split(",") ?? [];
1746
1923
  // If the blob storage or entity storage is configured with file connectors
@@ -1755,7 +1932,7 @@ async function start(nodeOptions, engineServerConfig, envVars) {
1755
1932
  }
1756
1933
  // Create the engine instance using file state storage unless one is configured in options
1757
1934
  const engine$1 = new engine.Engine({
1758
- config: engineServerConfig,
1935
+ config: nodeEngineConfig,
1759
1936
  stateStorage: nodeOptions?.stateStorage ?? new engineCore.FileStateStorage(envVars.stateFilename ?? ""),
1760
1937
  customBootstrap: async (core, engineContext) => bootstrap(core, engineContext, envVars)
1761
1938
  });
@@ -1766,11 +1943,13 @@ async function start(nodeOptions, engineServerConfig, envVars) {
1766
1943
  console.info("Extending Engine");
1767
1944
  await nodeOptions.extendEngine(engine$1);
1768
1945
  }
1946
+ await extensionsInitialiseEngine(envVars, engine$1);
1769
1947
  // Extend the engine server.
1770
1948
  if (core.Is.function(nodeOptions?.extendEngineServer)) {
1771
1949
  console.info("Extending Engine Server");
1772
1950
  await nodeOptions?.extendEngineServer(server);
1773
1951
  }
1952
+ await extensionsInitialiseEngineServer(envVars, engine$1, server);
1774
1953
  // Need to register the engine with the factory so that background tasks
1775
1954
  // can clone it to spawn new instances.
1776
1955
  engineModels.EngineCoreFactory.register("engine", () => engine$1);
@@ -1779,7 +1958,11 @@ async function start(nodeOptions, engineServerConfig, envVars) {
1779
1958
  if (canContinue) {
1780
1959
  return {
1781
1960
  engine: engine$1,
1782
- server
1961
+ server,
1962
+ shutdown: async () => {
1963
+ await server.stop();
1964
+ await shutdownExtensions(envVars);
1965
+ }
1783
1966
  };
1784
1967
  }
1785
1968
  }
@@ -1797,7 +1980,7 @@ async function run(nodeOptions) {
1797
1980
  nodeOptions ??= {};
1798
1981
  const serverInfo = {
1799
1982
  name: nodeOptions?.serverName ?? "TWIN Node Server",
1800
- version: nodeOptions?.serverVersion ?? "0.0.2-next.15" // x-release-please-version
1983
+ version: nodeOptions?.serverVersion ?? "0.0.2-next.17" // x-release-please-version
1801
1984
  };
1802
1985
  console.log(`\u001B[4m🌩️ ${serverInfo.name} v${serverInfo.version}\u001B[24m\n`);
1803
1986
  if (!core.Is.stringValue(nodeOptions?.executionDirectory)) {
@@ -1828,13 +2011,16 @@ async function run(nodeOptions) {
1828
2011
  nodeOptions.envPrefix ??= "TWIN_NODE_";
1829
2012
  console.info("Environment Prefix:", nodeOptions.envPrefix);
1830
2013
  overrideModuleImport(nodeOptions.executionDirectory ?? "");
1831
- const { engineServerConfig, nodeEnvVars: envVars } = await buildConfiguration(process.env, nodeOptions, serverInfo);
2014
+ const { nodeEngineConfig, nodeEnvVars: envVars } = await buildConfiguration(
2015
+ // This is the only location in the code base that should access process.env directly
2016
+ // eslint-disable-next-line no-restricted-syntax
2017
+ process.env, nodeOptions, serverInfo);
1832
2018
  console.info();
1833
- const startResult = await start(nodeOptions, engineServerConfig, envVars);
2019
+ const startResult = await start(nodeOptions, nodeEngineConfig, envVars);
1834
2020
  if (!core.Is.empty(startResult)) {
1835
2021
  for (const signal of ["SIGHUP", "SIGINT", "SIGTERM"]) {
1836
2022
  process.on(signal, async () => {
1837
- await startResult.server.stop();
2023
+ await startResult.shutdown();
1838
2024
  });
1839
2025
  }
1840
2026
  }
@@ -1900,8 +2086,8 @@ async function buildConfiguration(processEnv, options, serverInfo) {
1900
2086
  await options.extendEnvVars(envVars);
1901
2087
  }
1902
2088
  // Build the engine configuration from the environment variables.
1903
- const coreConfig = buildEngineConfiguration(envVars);
1904
- const engineServerConfig = buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile, options?.favIconFile);
2089
+ const coreConfig = await buildEngineConfiguration(envVars);
2090
+ const engineServerConfig = await buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile, options?.favIconFile);
1905
2091
  // Merge any custom configuration provided in the options.
1906
2092
  if (core.Is.arrayValue(options?.configFilenames)) {
1907
2093
  for (const configFile of options.configFilenames) {
@@ -1918,9 +2104,10 @@ async function buildConfiguration(processEnv, options, serverInfo) {
1918
2104
  // Merge any custom configuration provided in the options.
1919
2105
  if (core.Is.function(options?.extendConfig)) {
1920
2106
  console.info("Extending Configuration");
1921
- await options.extendConfig(engineServerConfig);
2107
+ await options.extendConfig(envVars, engineServerConfig);
1922
2108
  }
1923
- return { engineServerConfig, nodeEnvVars: envVars };
2109
+ const nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);
2110
+ return { nodeEngineConfig, nodeEnvVars: envVars };
1924
2111
  }
1925
2112
  /**
1926
2113
  * Override module imports to use local files where possible.
@@ -1957,7 +2144,13 @@ function overrideModuleImport(executionDirectory) {
1957
2144
  });
1958
2145
  }
1959
2146
 
2147
+ exports.ATTESTATION_VERIFICATION_METHOD_ID = ATTESTATION_VERIFICATION_METHOD_ID;
2148
+ exports.AUTH_SIGNING_KEY_ID = AUTH_SIGNING_KEY_ID;
2149
+ exports.BLOB_STORAGE_ENCRYPTION_KEY_ID = BLOB_STORAGE_ENCRYPTION_KEY_ID;
2150
+ exports.IMMUTABLE_PROOF_VERIFICATION_METHOD_ID = IMMUTABLE_PROOF_VERIFICATION_METHOD_ID;
1960
2151
  exports.NodeFeatures = NodeFeatures;
2152
+ exports.SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID = SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;
2153
+ exports.VC_AUTHENTICATION_VERIFICATION_METHOD_ID = VC_AUTHENTICATION_VERIFICATION_METHOD_ID;
1961
2154
  exports.bootstrap = bootstrap;
1962
2155
  exports.bootstrapAuth = bootstrapAuth;
1963
2156
  exports.bootstrapBlobEncryption = bootstrapBlobEncryption;
@@ -1968,12 +2161,19 @@ exports.bootstrapSynchronisedStorage = bootstrapSynchronisedStorage;
1968
2161
  exports.buildConfiguration = buildConfiguration;
1969
2162
  exports.buildEngineConfiguration = buildEngineConfiguration;
1970
2163
  exports.buildEngineServerConfiguration = buildEngineServerConfiguration;
2164
+ exports.directoryExists = directoryExists;
2165
+ exports.extensionsConfiguration = extensionsConfiguration;
2166
+ exports.extensionsInitialiseEngine = extensionsInitialiseEngine;
2167
+ exports.extensionsInitialiseEngineServer = extensionsInitialiseEngineServer;
1971
2168
  exports.fileExists = fileExists;
1972
2169
  exports.getExecutionDirectory = getExecutionDirectory;
1973
2170
  exports.getFeatures = getFeatures;
2171
+ exports.getFiles = getFiles;
2172
+ exports.getSubFolders = getSubFolders;
1974
2173
  exports.initialiseLocales = initialiseLocales;
1975
2174
  exports.loadJsonFile = loadJsonFile;
1976
2175
  exports.loadTextFile = loadTextFile;
1977
2176
  exports.overrideModuleImport = overrideModuleImport;
1978
2177
  exports.run = run;
2178
+ exports.shutdownExtensions = shutdownExtensions;
1979
2179
  exports.start = start;