@twin.org/node-core 0.9.2-next.6 → 0.9.2-next.7

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.
@@ -1,13 +1,14 @@
1
1
  // Copyright 2024 IOTA Stiftung.
2
2
  // SPDX-License-Identifier: Apache-2.0.
3
3
  import path from "node:path";
4
- import { Coerce, Is, Mutex } from "@twin.org/core";
4
+ import { Is, Mutex } from "@twin.org/core";
5
5
  import { AttestationComponentType, AttestationConnectorType, AuditableItemGraphComponentType, AuditableItemStreamComponentType, AutomationComponentType, BackgroundTaskComponentType, BlobStorageComponentType, BlobStorageConnectorType, ContextIdHandlerComponentType, DataProcessingComponentType, DataspaceControlPlaneComponentType, DataspaceDataPlaneComponentType, DltConfigType, DocumentManagementComponentType, EngineTypeHelper, EntityStorageConnectorType, EventBusComponentType, EventBusConnectorType, FaucetConnectorType, FederatedCatalogueComponentType, HealthComponentType, IdentityComponentType, IdentityConnectorType, IdentityProfileComponentType, IdentityProfileConnectorType, IdentityResolverComponentType, IdentityResolverConnectorType, ImmutableProofComponentType, LoggingComponentType, LoggingConnectorType, MessagingAdminComponentType, MessagingComponentType, MessagingEmailConnectorType, MessagingPushNotificationConnectorType, MessagingSmsConnectorType, MetricsCollectorComponentType, MetricsProducerComponentType, NftComponentType, NftConnectorType, NotarizationComponentType, NotarizationConnectorType, PlatformComponentType, RightsManagementPapComponentType, RightsManagementPdpComponentType, RightsManagementPepComponentType, RightsManagementPipComponentType, RightsManagementPmpComponentType, RightsManagementPnapComponentType, RightsManagementPnpComponentType, RightsManagementPxpComponentType, SchemaVersionMigrationComponentType, TaskSchedulerComponentType, TelemetryComponentType, TelemetryConnectorType, TenantAdminComponentType, TracingComponentType, TracingConnectorType, TrustComponentType, TrustVerifierComponentType, VaultConnectorType, WalletConnectorType } from "@twin.org/engine-types";
6
6
  import { OpenTelemetryExporterTypes } from "@twin.org/logging-connector-opentelemetry";
7
7
  import { OpenTelemetryReaderTypes } from "@twin.org/telemetry-connector-opentelemetry";
8
8
  import { OpenTelemetryProcessorTypes } from "@twin.org/tracing-connector-opentelemetry";
9
9
  import { CONTEXT_ID_HANDLER_FEATURE_DID, CONTEXT_ID_HANDLER_FEATURE_TENANT } from "../defaults.js";
10
10
  import { isAuthEntityStorageRequired } from "./engineServerEnvBuilder.js";
11
+ import { commaSeparatedListToArray, envBoolean, envCount, envDateTime, envInteger, envMinToMs, envMinutes, envMs, envSecToMs, envSeconds } from "./helper/envHelpers.js";
11
12
  /**
12
13
  * Build the engine core configuration from environment variables.
13
14
  * @param envVars The environment variables.
@@ -20,12 +21,12 @@ export async function buildEngineConfiguration(envVars) {
20
21
  envVars.stateFilename = path.join(envVars.storageFileRoot, envVars.stateFilename);
21
22
  }
22
23
  const coreConfig = {
23
- debug: Coerce.boolean(envVars.debug) ?? false,
24
- silent: Coerce.boolean(envVars.silent) ?? false,
24
+ debug: envBoolean(envVars, "debug", false),
25
+ silent: envBoolean(envVars, "silent", false),
25
26
  silentLoggers: commaSeparatedListToArray(envVars.loggingSilentComponents),
26
27
  types: {}
27
28
  };
28
- const mutexTimeoutMs = Coerce.integer(envVars.mutexTimeoutMsDefault);
29
+ const mutexTimeoutMs = envMs(envVars, "mutexTimeoutMsDefault");
29
30
  if (!Is.empty(mutexTimeoutMs)) {
30
31
  Mutex.setDefaultTimeoutMs(mutexTimeoutMs);
31
32
  }
@@ -81,7 +82,7 @@ async function configureEntityStorage(coreConfig, envVars) {
81
82
  type: EntityStorageConnectorType.Memory,
82
83
  options: {
83
84
  config: {
84
- mutexTimeoutMs: Coerce.integer(envVars.entityStorageMemoryMutexTimeout)
85
+ mutexTimeoutMs: envMs(envVars, "entityStorageMutexTimeout")
85
86
  }
86
87
  }
87
88
  });
@@ -92,7 +93,7 @@ async function configureEntityStorage(coreConfig, envVars) {
92
93
  options: {
93
94
  config: {
94
95
  directory: envVars.storageFileRoot ?? "",
95
- mutexTimeoutMs: Coerce.integer(envVars.entityStorageFileMutexTimeout)
96
+ mutexTimeoutMs: envMs(envVars, "entityStorageMutexTimeout")
96
97
  },
97
98
  folderPrefix: envVars.entityStorageTablePrefix
98
99
  }
@@ -108,7 +109,7 @@ async function configureEntityStorage(coreConfig, envVars) {
108
109
  accessKeyId: envVars.awsDynamodbAccessKeyId,
109
110
  secretAccessKey: envVars.awsDynamodbSecretAccessKey,
110
111
  endpoint: envVars.awsDynamodbEndpoint,
111
- connectionTimeoutMs: Coerce.integer(envVars.awsDynamodbConnectionTimeout)
112
+ connectionTimeoutMs: envMs(envVars, "awsDynamodbConnectionTimeout")
112
113
  },
113
114
  tablePrefix: envVars.entityStorageTablePrefix
114
115
  }
@@ -151,7 +152,7 @@ async function configureEntityStorage(coreConfig, envVars) {
151
152
  hosts: commaSeparatedListToArray(envVars.scylladbHosts),
152
153
  localDataCenter: envVars.scylladbLocalDataCenter ?? "",
153
154
  keyspace: envVars.scylladbKeyspace ?? "",
154
- port: Coerce.integer(envVars.scylladbPort)
155
+ port: envInteger(envVars, "scylladbPort")
155
156
  },
156
157
  tablePrefix: envVars.entityStorageTablePrefix
157
158
  }
@@ -163,7 +164,7 @@ async function configureEntityStorage(coreConfig, envVars) {
163
164
  options: {
164
165
  config: {
165
166
  host: envVars.mySqlHost ?? "",
166
- port: Coerce.integer(envVars.mySqlPort),
167
+ port: envInteger(envVars, "mySqlPort"),
167
168
  user: envVars.mySqlUser ?? "",
168
169
  password: envVars.mySqlPassword ?? "",
169
170
  database: envVars.mySqlDatabase ?? ""
@@ -178,7 +179,7 @@ async function configureEntityStorage(coreConfig, envVars) {
178
179
  options: {
179
180
  config: {
180
181
  host: envVars.mongoDbHost ?? "",
181
- port: Coerce.integer(envVars.mongoDbPort),
182
+ port: envInteger(envVars, "mongoDbPort"),
182
183
  user: envVars.mongoDbUser ?? "",
183
184
  password: envVars.mongoDbPassword ?? "",
184
185
  database: envVars.mongoDbDatabase ?? ""
@@ -193,7 +194,7 @@ async function configureEntityStorage(coreConfig, envVars) {
193
194
  options: {
194
195
  config: {
195
196
  host: envVars.postgreSqlHost ?? "",
196
- port: Coerce.integer(envVars.postgreSqlPort),
197
+ port: envInteger(envVars, "postgreSqlPort"),
197
198
  user: envVars.postgreSqlUser ?? "",
198
199
  password: envVars.postgreSqlPassword ?? "",
199
200
  database: envVars.postgreSqlDatabase ?? ""
@@ -344,13 +345,13 @@ async function configureLogging(coreConfig, envVars) {
344
345
  type: LoggingConnectorType.EntityStorage,
345
346
  options: {
346
347
  config: {
347
- batchSize: Coerce.integer(envVars.loggingBatchSize),
348
- batchIntervalMs: (Coerce.integer(envVars.loggingBatchFlushInterval) ?? 5) * 1000,
349
- retainForMs: (Coerce.integer(envVars.loggingRetainFor) ?? 2880) * 60_000,
350
- maxEntries: Coerce.integer(envVars.loggingMaxEntries),
351
- retentionIntervalMs: (Coerce.integer(envVars.loggingRetentionInterval) ?? 5) * 60_000,
352
- retentionBatchSize: Coerce.integer(envVars.loggingRetentionBatchSize),
353
- mutexTimeoutMs: Coerce.integer(envVars.loggingMutexTimeout)
348
+ batchSize: envCount(envVars, "loggingBatchSize"),
349
+ batchIntervalMs: envSecToMs(envVars, "loggingBatchFlushInterval"),
350
+ retainForMs: envMinToMs(envVars, "loggingRetainFor"),
351
+ maxEntries: envCount(envVars, "loggingMaxEntries"),
352
+ retentionIntervalMs: envMinToMs(envVars, "loggingRetentionInterval"),
353
+ retentionBatchSize: envCount(envVars, "loggingRetentionBatchSize"),
354
+ mutexTimeoutMs: envMs(envVars, "loggingMutexTimeout")
354
355
  }
355
356
  }
356
357
  });
@@ -386,9 +387,9 @@ async function configureLogging(coreConfig, envVars) {
386
387
  config: {
387
388
  directory: envVars.loggingFileDirectory ?? envVars.storageFileRoot ?? "",
388
389
  filename: envVars.loggingFileFilename,
389
- maxFileSizeBytes: Coerce.integer(envVars.loggingFileMaxFileSizeBytes),
390
- maxRetainedFiles: Coerce.integer(envVars.loggingFileMaxRetainedFiles),
391
- mutexTimeoutMs: Coerce.integer(envVars.loggingMutexTimeout)
390
+ maxFileSizeBytes: envCount(envVars, "loggingFileMaxFileSizeBytes"),
391
+ maxRetainedFiles: envCount(envVars, "loggingFileMaxRetainedFiles"),
392
+ mutexTimeoutMs: envMs(envVars, "loggingMutexTimeout")
392
393
  }
393
394
  }
394
395
  });
@@ -494,7 +495,7 @@ async function configureTelemetry(coreConfig, envVars) {
494
495
  type: TelemetryConnectorType.EntityStorage,
495
496
  options: {
496
497
  config: {
497
- mutexTimeoutMs: Coerce.integer(envVars.telemetryMutexTimeout)
498
+ mutexTimeoutMs: envMs(envVars, "telemetryMutexTimeout")
498
499
  }
499
500
  }
500
501
  });
@@ -505,7 +506,7 @@ async function configureTelemetry(coreConfig, envVars) {
505
506
  readers = {
506
507
  prometheus: {
507
508
  type: OpenTelemetryReaderTypes.Prometheus,
508
- port: Coerce.integer(envVars.openTelemetryPrometheusPort)
509
+ port: envCount(envVars, "openTelemetryPrometheusPort")
509
510
  }
510
511
  };
511
512
  }
@@ -513,7 +514,7 @@ async function configureTelemetry(coreConfig, envVars) {
513
514
  type: TelemetryConnectorType.OpenTelemetry,
514
515
  options: {
515
516
  config: {
516
- mutexTimeoutMs: Coerce.integer(envVars.telemetryMutexTimeout),
517
+ mutexTimeoutMs: envMs(envVars, "telemetryMutexTimeout"),
517
518
  meterName: envVars.openTelemetryMeterName,
518
519
  meterVersion: envVars.openTelemetryMeterVersion,
519
520
  readers
@@ -534,21 +535,23 @@ async function configureTelemetry(coreConfig, envVars) {
534
535
  */
535
536
  async function configureMetricsCollector(coreConfig, envVars) {
536
537
  if (isTelemetryRequired(envVars)) {
537
- const intervalSec = Coerce.integer(envVars.telemetryMetricsCollectorInterval) ?? 60;
538
538
  coreConfig.types.metricsCollectorComponent ??= [];
539
539
  coreConfig.types.metricsCollectorComponent.push({
540
540
  type: MetricsCollectorComponentType.Service,
541
- options: { config: { intervalMs: intervalSec * 1000 } },
541
+ options: {
542
+ config: {
543
+ intervalMs: envSecToMs(envVars, "telemetryMetricsCollectorInterval")
544
+ }
545
+ },
542
546
  isCloneable: false
543
547
  });
544
- const maxHistory = Coerce.integer(envVars.telemetryMetricsProducerMaxHistory) ?? 1440;
545
548
  coreConfig.types.metricsProducerComponent ??= [];
546
549
  const metricsProducers = commaSeparatedListToArray(envVars.telemetryMetricsProducers ??
547
550
  [MetricsProducerComponentType.System, MetricsProducerComponentType.Process].join(","));
548
551
  for (const producerType of metricsProducers) {
549
552
  coreConfig.types.metricsProducerComponent.push({
550
553
  type: producerType,
551
- options: { maxHistory },
554
+ options: { maxHistory: envCount(envVars, "telemetryMetricsProducerMaxHistory") },
552
555
  isCloneable: false
553
556
  });
554
557
  }
@@ -567,7 +570,7 @@ async function configureTracing(coreConfig, envVars) {
567
570
  type: TracingConnectorType.EntityStorage,
568
571
  options: {
569
572
  config: {
570
- mutexTimeoutMs: Coerce.integer(envVars.tracingMutexTimeout)
573
+ mutexTimeoutMs: envMs(envVars, "tracingMutexTimeout")
571
574
  }
572
575
  }
573
576
  });
@@ -630,14 +633,14 @@ async function configureAutomation(coreConfig, envVars) {
630
633
  */
631
634
  async function configureHealth(coreConfig, envVars) {
632
635
  coreConfig.types.healthComponent ??= [];
633
- if (Coerce.boolean(envVars.healthEnabled) ?? false) {
636
+ if (envBoolean(envVars, "healthEnabled", false)) {
634
637
  coreConfig.types.healthComponent.push({
635
638
  type: HealthComponentType.Service,
636
639
  options: {
637
640
  config: {
638
- healthCheckInterval: (Coerce.integer(envVars.healthInterval) ?? 60) * 1000,
639
- healthCheckApplicationInterval: (Coerce.integer(envVars.healthApplicationInterval) ?? 300) * 1000,
640
- initialInterval: (Coerce.integer(envVars.healthStartupInterval) ?? 2) * 1000
641
+ healthCheckInterval: envSecToMs(envVars, "healthInterval"),
642
+ healthCheckApplicationInterval: envSecToMs(envVars, "healthApplicationInterval"),
643
+ initialInterval: envSecToMs(envVars, "healthStartupInterval")
641
644
  }
642
645
  },
643
646
  isCloneable: false
@@ -651,7 +654,7 @@ async function configureHealth(coreConfig, envVars) {
651
654
  * @returns A promise that resolves when the schema migration configuration has been applied.
652
655
  */
653
656
  async function configureSchemaMigration(coreConfig, envVars) {
654
- const isSchemaMigrationEnabled = Coerce.boolean(envVars.schemaMigrationEnabled) ?? true;
657
+ const isSchemaMigrationEnabled = envBoolean(envVars, "schemaMigrationEnabled", true);
655
658
  if (isSchemaMigrationEnabled) {
656
659
  coreConfig.types.schemaVersionMigrationComponent ??= [];
657
660
  coreConfig.types.schemaVersionMigrationComponent.push({
@@ -667,7 +670,7 @@ async function configureSchemaMigration(coreConfig, envVars) {
667
670
  * @returns A promise that resolves when the platform configuration has been applied.
668
671
  */
669
672
  async function configurePlatform(coreConfig, envVars) {
670
- const isTenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;
673
+ const isTenantEnabled = envBoolean(envVars, "tenantEnabled", false);
671
674
  coreConfig.types.platformComponent ??= [];
672
675
  coreConfig.types.platformComponent.push({
673
676
  type: PlatformComponentType.Service,
@@ -685,7 +688,7 @@ async function configurePlatform(coreConfig, envVars) {
685
688
  * @returns A promise that resolves when the tenant configuration has been applied.
686
689
  */
687
690
  async function configureTenant(coreConfig, envVars) {
688
- const isTenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;
691
+ const isTenantEnabled = envBoolean(envVars, "tenantEnabled", false);
689
692
  if (isTenantEnabled) {
690
693
  coreConfig.types.tenantAdminComponent ??= [];
691
694
  coreConfig.types.tenantAdminComponent.push({
@@ -705,7 +708,7 @@ async function configureContextIdHandlers(coreConfig, envVars) {
705
708
  type: ContextIdHandlerComponentType.Did,
706
709
  features: [CONTEXT_ID_HANDLER_FEATURE_DID]
707
710
  });
708
- if (Coerce.boolean(envVars.tenantEnabled) ?? false) {
711
+ if (envBoolean(envVars, "tenantEnabled", false)) {
709
712
  coreConfig.types.contextIdHandlerComponent.push({
710
713
  type: ContextIdHandlerComponentType.Tenant,
711
714
  features: [CONTEXT_ID_HANDLER_FEATURE_TENANT]
@@ -719,7 +722,7 @@ async function configureContextIdHandlers(coreConfig, envVars) {
719
722
  * @returns A promise that resolves when the messaging configuration has been applied.
720
723
  */
721
724
  async function configureMessaging(coreConfig, envVars) {
722
- if (Coerce.boolean(envVars.messagingEnabled) ?? false) {
725
+ if (envBoolean(envVars, "messagingEnabled", false)) {
723
726
  coreConfig.types.messagingEmailConnector ??= [];
724
727
  coreConfig.types.messagingSmsConnector ??= [];
725
728
  coreConfig.types.messagingPushNotificationConnector ??= [];
@@ -923,9 +926,15 @@ async function configureImmutableProof(coreConfig, envVars) {
923
926
  options: {
924
927
  config: {
925
928
  verificationMethodId: envVars.immutableProofVerificationMethodId,
926
- taskRetryCount: Coerce.integer(envVars.immutableProofTaskRetryCount),
927
- taskRetryInterval: (Coerce.integer(envVars.immutableProofTaskRetryInterval) ?? 5) * 1000,
928
- taskFailureRetainFor: (Coerce.integer(envVars.immutableProofTaskFailureRetainFor) ?? 10080) * 60_000
929
+ taskRetryCount: envCount(envVars, "immutableProofTaskRetryCount"),
930
+ taskRetryInterval: envSecToMs(envVars, "immutableProofTaskRetryInterval"),
931
+ taskFailureRetainFor: envMinToMs(envVars, "immutableProofTaskFailureRetainFor"),
932
+ sweepIntervalMinutes: envMinutes(envVars, "immutableProofSweepInterval"),
933
+ sweepStaleThresholdMs: envMinToMs(envVars, "immutableProofSweepStaleThreshold"),
934
+ sweepMaxAttempts: envCount(envVars, "immutableProofSweepMaxAttempts"),
935
+ sweepBatchLimit: envCount(envVars, "immutableProofSweepBatchLimit"),
936
+ sweepBackoffMs: envMinToMs(envVars, "immutableProofSweepBackoff"),
937
+ sweepAssumeRetryableBefore: envDateTime(envVars, "immutableProofSweepAssumeRetryableBefore")
929
938
  }
930
939
  }
931
940
  });
@@ -954,8 +963,8 @@ async function configureIdentity(coreConfig, envVars) {
954
963
  identityPkgId: Is.stringValue(envVars.iotaIdentityPackageId)
955
964
  ? envVars.iotaIdentityPackageId
956
965
  : undefined,
957
- walletAddressIndex: Coerce.integer(envVars.identityWalletAddressIndex) ?? 0,
958
- didResolutionCacheTtlMs: Coerce.integer(envVars.identityDidResolutionCacheTtlMs)
966
+ walletAddressIndex: envCount(envVars, "identityWalletAddressIndex") ?? 0,
967
+ didResolutionCacheTtlMs: envMs(envVars, "identityDidResolutionCacheTtlMs")
959
968
  }
960
969
  }
961
970
  });
@@ -1059,13 +1068,13 @@ async function configureAttestation(coreConfig, envVars) {
1059
1068
  * @returns A promise that resolves when the auditable item graph configuration has been applied.
1060
1069
  */
1061
1070
  async function configureAuditableItemGraph(coreConfig, envVars) {
1062
- if (Coerce.boolean(envVars.auditableItemGraphEnabled) ?? false) {
1071
+ if (envBoolean(envVars, "auditableItemGraphEnabled", false)) {
1063
1072
  coreConfig.types.auditableItemGraphComponent ??= [];
1064
1073
  coreConfig.types.auditableItemGraphComponent.push({
1065
1074
  type: AuditableItemGraphComponentType.Service,
1066
1075
  options: {
1067
1076
  config: {
1068
- mutexTimeoutMs: Coerce.integer(envVars.auditableItemGraphMutexTimeout)
1077
+ mutexTimeoutMs: envMs(envVars, "auditableItemGraphMutexTimeout")
1069
1078
  }
1070
1079
  }
1071
1080
  });
@@ -1078,13 +1087,13 @@ async function configureAuditableItemGraph(coreConfig, envVars) {
1078
1087
  * @returns A promise that resolves when the auditable item stream configuration has been applied.
1079
1088
  */
1080
1089
  async function configureAuditableItemStream(coreConfig, envVars) {
1081
- if (Coerce.boolean(envVars.auditableItemStreamEnabled) ?? false) {
1090
+ if (envBoolean(envVars, "auditableItemStreamEnabled", false)) {
1082
1091
  coreConfig.types.auditableItemStreamComponent ??= [];
1083
1092
  coreConfig.types.auditableItemStreamComponent.push({
1084
1093
  type: AuditableItemStreamComponentType.Service,
1085
1094
  options: {
1086
1095
  config: {
1087
- mutexTimeoutMs: Coerce.integer(envVars.auditableItemStreamMutexTimeout)
1096
+ mutexTimeoutMs: envMs(envVars, "auditableItemStreamMutexTimeout")
1088
1097
  }
1089
1098
  }
1090
1099
  });
@@ -1097,7 +1106,7 @@ async function configureAuditableItemStream(coreConfig, envVars) {
1097
1106
  * @returns A promise that resolves when the data processing configuration has been applied.
1098
1107
  */
1099
1108
  async function configureDataProcessing(coreConfig, envVars) {
1100
- if (Coerce.boolean(envVars.dataProcessingEnabled) ?? false) {
1109
+ if (envBoolean(envVars, "dataProcessingEnabled", false)) {
1101
1110
  coreConfig.types.dataProcessingComponent ??= [];
1102
1111
  coreConfig.types.dataProcessingComponent.push({ type: DataProcessingComponentType.Service });
1103
1112
  coreConfig.types.dataConverterConnector ??= [];
@@ -1123,13 +1132,13 @@ async function configureDataProcessing(coreConfig, envVars) {
1123
1132
  * @returns A promise that resolves when the document management configuration has been applied.
1124
1133
  */
1125
1134
  async function configureDocumentManagement(coreConfig, envVars) {
1126
- if (Coerce.boolean(envVars.documentManagementEnabled) ?? false) {
1135
+ if (envBoolean(envVars, "documentManagementEnabled", false)) {
1127
1136
  coreConfig.types.documentManagementComponent ??= [];
1128
1137
  coreConfig.types.documentManagementComponent.push({
1129
1138
  type: DocumentManagementComponentType.Service,
1130
1139
  options: {
1131
1140
  config: {
1132
- mutexTimeoutMs: Coerce.integer(envVars.documentManagementMutexTimeout)
1141
+ mutexTimeoutMs: envMs(envVars, "documentManagementMutexTimeout")
1133
1142
  }
1134
1143
  }
1135
1144
  });
@@ -1155,7 +1164,7 @@ async function configureTrust(coreConfig, envVars) {
1155
1164
  options: {
1156
1165
  config: {
1157
1166
  verificationMethodId: envVars.trustVerificationMethodId ?? "",
1158
- tokenTtlInSeconds: Coerce.integer(envVars.trustJwtTtl)
1167
+ tokenTtlInSeconds: envCount(envVars, "trustJwtTtl")
1159
1168
  }
1160
1169
  }
1161
1170
  });
@@ -1240,7 +1249,7 @@ async function configureRightsManagement(coreConfig, envVars) {
1240
1249
  config: {
1241
1250
  callbackPath: rightsManagementPath,
1242
1251
  includeErrorDetails: coreConfig.debug ?? false,
1243
- mutexTimeoutMs: Coerce.integer(envVars.rightsManagementMutexTimeout)
1252
+ mutexTimeoutMs: envMs(envVars, "rightsManagementMutexTimeout")
1244
1253
  }
1245
1254
  },
1246
1255
  isDefault: true
@@ -1250,7 +1259,7 @@ async function configureRightsManagement(coreConfig, envVars) {
1250
1259
  type: RightsManagementPnapComponentType.Service,
1251
1260
  options: {
1252
1261
  config: {
1253
- mutexTimeoutMs: Coerce.integer(envVars.rightsManagementMutexTimeout)
1262
+ mutexTimeoutMs: envMs(envVars, "rightsManagementMutexTimeout")
1254
1263
  }
1255
1264
  }
1256
1265
  });
@@ -1342,7 +1351,7 @@ async function configureFederatedCatalogue(coreConfig, envVars) {
1342
1351
  type: FederatedCatalogueComponentType.Service,
1343
1352
  options: {
1344
1353
  config: {
1345
- mutexTimeoutMs: Coerce.integer(envVars.federatedCatalogueMutexTimeout)
1354
+ mutexTimeoutMs: envMs(envVars, "federatedCatalogueMutexTimeout")
1346
1355
  }
1347
1356
  }
1348
1357
  });
@@ -1364,7 +1373,7 @@ async function configureFederatedCatalogue(coreConfig, envVars) {
1364
1373
  * @returns A promise that resolves when the dataspace configuration has been applied.
1365
1374
  */
1366
1375
  async function configureDataspace(coreConfig, envVars) {
1367
- if (Coerce.boolean(envVars.dataspaceEnabled) ?? false) {
1376
+ if (envBoolean(envVars, "dataspaceEnabled", false)) {
1368
1377
  coreConfig.types.dataspaceControlPlaneComponent ??= [];
1369
1378
  // We add a multi instance REST client for remote/consumer-initiated transfers.
1370
1379
  coreConfig.types.dataspaceControlPlaneComponent.push({
@@ -1375,8 +1384,6 @@ async function configureDataspace(coreConfig, envVars) {
1375
1384
  isMultiInstance: true,
1376
1385
  features: ["remote"]
1377
1386
  });
1378
- const stalledNegotiationTimeout = Coerce.integer(envVars.dataspaceStalledNegotiationTimeout);
1379
- const stalledTransferTimeout = Coerce.integer(envVars.dataspaceStalledTransferTimeout);
1380
1387
  coreConfig.types.dataspaceControlPlaneComponent.push({
1381
1388
  type: DataspaceControlPlaneComponentType.Service,
1382
1389
  options: {
@@ -1387,30 +1394,22 @@ async function configureDataspace(coreConfig, envVars) {
1387
1394
  // Base mount path of the data plane only; the transfer handlers append the
1388
1395
  // sub-paths themselves (`/entities` for PULL, `/inbox` for PUSH).
1389
1396
  dataPlanePath: envVars.dataspaceDataPlanePath,
1390
- autoStartTransfers: Coerce.boolean(envVars.dataspaceAutoStartTransfers),
1391
- stalledNegotiationTimeoutMs: !Is.empty(stalledNegotiationTimeout)
1392
- ? stalledNegotiationTimeout * 1000
1393
- : undefined,
1394
- stalledTransferTimeoutMs: !Is.empty(stalledTransferTimeout)
1395
- ? stalledTransferTimeout * 1000
1396
- : undefined
1397
+ autoStartTransfers: envBoolean(envVars, "dataspaceAutoStartTransfers", false),
1398
+ stalledNegotiationTimeoutMs: envSecToMs(envVars, "dataspaceStalledNegotiationTimeout"),
1399
+ stalledTransferTimeoutMs: envSecToMs(envVars, "dataspaceStalledTransferTimeout"),
1400
+ providerTransferIdleTimeoutMs: envSecToMs(envVars, "dataspaceProviderTransferIdleTimeout"),
1401
+ providerTransferPolicySweepIntervalMs: envSecToMs(envVars, "dataspaceProviderTransferPolicySweepInterval")
1397
1402
  }
1398
1403
  },
1399
1404
  isDefault: true
1400
1405
  });
1401
- const retainActivityLogsFor = Coerce.integer(envVars.dataspaceRetainActivityLogsFor);
1402
- const activityLogsCleanUpInterval = Coerce.integer(envVars.dataspaceActivityLogsCleanupInterval);
1403
1406
  coreConfig.types.dataspaceDataPlaneComponent ??= [];
1404
1407
  coreConfig.types.dataspaceDataPlaneComponent.push({
1405
1408
  type: DataspaceDataPlaneComponentType.Service,
1406
1409
  options: {
1407
1410
  config: {
1408
- retainActivityLogsForMs: !Is.empty(retainActivityLogsFor)
1409
- ? retainActivityLogsFor * 1000
1410
- : undefined,
1411
- activityLogsCleanUpIntervalMs: !Is.empty(activityLogsCleanUpInterval)
1412
- ? activityLogsCleanUpInterval * 1000
1413
- : undefined
1411
+ retainActivityLogsForMs: envSecToMs(envVars, "dataspaceRetainActivityLogsFor"),
1412
+ activityLogsCleanUpIntervalMs: envSecToMs(envVars, "dataspaceActivityLogsCleanupInterval")
1414
1413
  }
1415
1414
  }
1416
1415
  });
@@ -1442,26 +1441,15 @@ async function configureDlt(coreConfig, envVars) {
1442
1441
  url: envVars.iotaNodeEndpoint ?? ""
1443
1442
  },
1444
1443
  network: envVars.iotaNetwork ?? "",
1445
- coinType: Coerce.integer(envVars.iotaCoinType),
1444
+ coinType: envCount(envVars, "iotaCoinType"),
1446
1445
  gasStation: gasStationConfig,
1447
- gasBudget: Coerce.integer(envVars.iotaGasBudget),
1448
- gasReservationDuration: Coerce.integer(envVars.iotaGasReservationDuration)
1446
+ gasBudget: envCount(envVars, "iotaGasBudget"),
1447
+ gasReservationDuration: envSeconds(envVars, "iotaGasReservationDuration")
1449
1448
  }
1450
1449
  }
1451
1450
  });
1452
1451
  }
1453
1452
  }
1454
- /**
1455
- * Converts a comma separated list to an array.
1456
- * @param value The comma separated list.
1457
- * @returns The array.
1458
- */
1459
- function commaSeparatedListToArray(value) {
1460
- return (value ?? "")
1461
- .split(",")
1462
- .map(item => item.trim())
1463
- .filter(item => item.length > 0);
1464
- }
1465
1453
  /**
1466
1454
  * Checks if the trust subsystem is required.
1467
1455
  * Returns true when any component that depends on the trust subsystem is enabled.
@@ -1470,7 +1458,7 @@ function commaSeparatedListToArray(value) {
1470
1458
  */
1471
1459
  export function isTrustRequired(envVars) {
1472
1460
  return (isRightsManagementRequired(envVars) ||
1473
- (Coerce.boolean(envVars.dataspaceEnabled) ?? false) ||
1461
+ envBoolean(envVars, "dataspaceEnabled", false) ||
1474
1462
  isFederatedCatalogueRequired(envVars));
1475
1463
  }
1476
1464
  /**
@@ -1480,7 +1468,7 @@ export function isTrustRequired(envVars) {
1480
1468
  * @returns True if dataspace or verifiable storage is enabled.
1481
1469
  */
1482
1470
  export function isBackgroundTasksRequired(envVars) {
1483
- return (Coerce.boolean(envVars.dataspaceEnabled) ?? false) || isImmutableProofRequired(envVars);
1471
+ return envBoolean(envVars, "dataspaceEnabled", false) || isImmutableProofRequired(envVars);
1484
1472
  }
1485
1473
  /**
1486
1474
  * Checks if the immutable proof subsystem is required.
@@ -1489,9 +1477,9 @@ export function isBackgroundTasksRequired(envVars) {
1489
1477
  * @returns True if verifiable storage is enabled.
1490
1478
  */
1491
1479
  export function isImmutableProofRequired(envVars) {
1492
- return ((Coerce.boolean(envVars.auditableItemGraphEnabled) ?? false) ||
1493
- (Coerce.boolean(envVars.auditableItemStreamEnabled) ?? false) ||
1494
- (Coerce.boolean(envVars.documentManagementEnabled) ?? false));
1480
+ return (envBoolean(envVars, "auditableItemGraphEnabled", false) ||
1481
+ envBoolean(envVars, "auditableItemStreamEnabled", false) ||
1482
+ envBoolean(envVars, "documentManagementEnabled", false));
1495
1483
  }
1496
1484
  /**
1497
1485
  * Checks if the federated catalogue subsystem is required.
@@ -1500,10 +1488,10 @@ export function isImmutableProofRequired(envVars) {
1500
1488
  * @returns True if the federated catalogue is required.
1501
1489
  */
1502
1490
  export function isFederatedCatalogueRequired(envVars) {
1503
- return ((Coerce.boolean(envVars.federatedCatalogueEnabled) ?? false) ||
1491
+ return (envBoolean(envVars, "federatedCatalogueEnabled", false) ||
1504
1492
  Is.stringValue(envVars.federatedCatalogueRemoteEndpoint) ||
1505
1493
  Is.stringValue(envVars.federatedCatalogueFilters) ||
1506
- (Coerce.boolean(envVars.dataspaceEnabled) ?? false));
1494
+ envBoolean(envVars, "dataspaceEnabled", false));
1507
1495
  }
1508
1496
  /**
1509
1497
  * Checks if the rights management subsystem is required.
@@ -1515,7 +1503,7 @@ export function isFederatedCatalogueRequired(envVars) {
1515
1503
  * @returns True if rights management is enabled.
1516
1504
  */
1517
1505
  export function isRightsManagementRequired(envVars) {
1518
- return Coerce.boolean(envVars.dataspaceEnabled) ?? false;
1506
+ return envBoolean(envVars, "dataspaceEnabled", false);
1519
1507
  }
1520
1508
  /**
1521
1509
  * Checks if the task scheduler subsystem is required.
@@ -1524,8 +1512,8 @@ export function isRightsManagementRequired(envVars) {
1524
1512
  * @returns True if task scheduler is enabled.
1525
1513
  */
1526
1514
  export function isTaskSchedulerRequired(envVars) {
1527
- return ((Coerce.boolean(envVars.taskSchedulerEnabled) ?? false) ||
1528
- (Coerce.boolean(envVars.dataspaceEnabled) ?? false) ||
1515
+ return (envBoolean(envVars, "taskSchedulerEnabled", false) ||
1516
+ envBoolean(envVars, "dataspaceEnabled", false) ||
1529
1517
  isRightsManagementRequired(envVars) ||
1530
1518
  isAuthEntityStorageRequired(envVars) ||
1531
1519
  isImmutableProofRequired(envVars));