@twin.org/node-core 0.0.1-next.8 → 0.0.1
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.
- package/dist/cjs/index.cjs +1168 -70
- package/dist/esm/index.mjs +1169 -74
- package/dist/types/bootstrap.d.ts +9 -10
- package/dist/types/builders/engineEnvBuilder.d.ts +8 -0
- package/dist/types/builders/engineServerEnvBuilder.d.ts +13 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/models/IEngineEnvironmentVariables.d.ts +389 -0
- package/dist/types/models/IEngineServerEnvironmentVariables.d.ts +49 -0
- package/dist/types/models/{INodeVariables.d.ts → INodeEnvironmentVariables.d.ts} +3 -3
- package/dist/types/models/{IRunOptions.d.ts → INodeOptions.d.ts} +17 -1
- package/dist/types/node.d.ts +22 -3
- package/dist/types/server.d.ts +7 -14
- package/dist/types/utils.d.ts +8 -2
- package/docs/changelog.md +49 -0
- package/docs/reference/functions/bootstrap.md +2 -2
- package/docs/reference/functions/bootstrapAttestationMethod.md +2 -2
- package/docs/reference/functions/bootstrapAuth.md +2 -2
- package/docs/reference/functions/bootstrapBlobEncryption.md +2 -2
- package/docs/reference/functions/bootstrapImmutableProofMethod.md +2 -2
- package/docs/reference/functions/bootstrapNodeIdentity.md +2 -2
- package/docs/reference/functions/bootstrapNodeUser.md +2 -2
- package/docs/reference/functions/buildConfiguration.md +30 -0
- package/docs/reference/functions/buildEngineConfiguration.md +19 -0
- package/docs/reference/functions/getFeatures.md +1 -1
- package/docs/reference/functions/loadJsonFile.md +25 -0
- package/docs/reference/functions/run.md +3 -3
- package/docs/reference/functions/start.md +9 -39
- package/docs/reference/index.md +7 -3
- package/docs/reference/interfaces/IEngineEnvironmentVariables.md +775 -0
- package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +95 -0
- package/docs/reference/interfaces/INodeEnvironmentVariables.md +1343 -0
- package/docs/reference/interfaces/{IRunOptions.md → INodeOptions.md} +38 -1
- package/locales/en.json +14 -14
- package/package.json +15 -15
- package/dist/types/models/INodeState.d.ts +0 -10
- package/docs/reference/interfaces/INodeState.md +0 -15
- package/docs/reference/interfaces/INodeVariables.md +0 -59
package/dist/esm/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PasswordHelper } from '@twin.org/api-auth-entity-storage-service';
|
|
2
|
-
import { I18n, Is, Converter, RandomHelper, StringHelper, Coerce, Urn, GeneralError,
|
|
2
|
+
import { I18n, Is, Converter, RandomHelper, StringHelper, Coerce, Urn, GeneralError, ErrorHelper, EnvHelper } from '@twin.org/core';
|
|
3
3
|
import { PasswordGenerator, Bip39 } from '@twin.org/crypto';
|
|
4
|
-
import { WalletConnectorType, IdentityConnectorType, EntityStorageConnectorType, BlobStorageConnectorType } from '@twin.org/engine-types';
|
|
4
|
+
import { WalletConnectorType, IdentityConnectorType, EntityStorageConnectorType, BlobStorageConnectorType, BlobStorageComponentType, VaultConnectorType, DltConfigType, LoggingConnectorType, LoggingComponentType, BackgroundTaskConnectorType, EventBusConnectorType, EventBusComponentType, TelemetryConnectorType, TelemetryComponentType, MessagingEmailConnectorType, MessagingSmsConnectorType, MessagingPushNotificationConnectorType, MessagingComponentType, FaucetConnectorType, NftConnectorType, NftComponentType, VerifiableStorageConnectorType, VerifiableStorageComponentType, ImmutableProofComponentType, AuditableItemGraphComponentType, AuditableItemStreamComponentType, IdentityComponentType, IdentityResolverConnectorType, IdentityResolverComponentType, IdentityProfileConnectorType, IdentityProfileComponentType, AttestationConnectorType, AttestationComponentType, DataConverterConnectorType, DataExtractorConnectorType, DataProcessingComponentType, DocumentManagementComponentType, FederatedCatalogueComponentType, RightsManagementPapComponentType, RightsManagementComponentType, TaskSchedulerComponentType } from '@twin.org/engine-types';
|
|
5
5
|
import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
|
|
6
6
|
import { IdentityProfileConnectorFactory, IdentityConnectorFactory, IdentityResolverConnectorFactory, DocumentHelper } from '@twin.org/identity-models';
|
|
7
7
|
import { VaultConnectorFactory, VaultKeyType } from '@twin.org/vault-models';
|
|
@@ -9,10 +9,11 @@ import { WalletConnectorFactory } from '@twin.org/wallet-models';
|
|
|
9
9
|
import { readFile, stat } from 'node:fs/promises';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import * as dotenv from 'dotenv';
|
|
12
|
-
import {
|
|
12
|
+
import { addDefaultRestPaths, addDefaultSocketPaths, EngineServer } from '@twin.org/engine-server';
|
|
13
|
+
import { InformationComponentType, RestRouteProcessorType, SocketRouteProcessorType, AuthenticationAdminComponentType, AuthenticationComponentType } from '@twin.org/engine-server-types';
|
|
14
|
+
import { Engine } from '@twin.org/engine';
|
|
13
15
|
import { FileStateStorage } from '@twin.org/engine-core';
|
|
14
16
|
import { EngineCoreFactory } from '@twin.org/engine-models';
|
|
15
|
-
import { buildEngineServerConfiguration, EngineServer } from '@twin.org/engine-server';
|
|
16
17
|
|
|
17
18
|
// Copyright 2024 IOTA Stiftung.
|
|
18
19
|
// SPDX-License-Identifier: Apache-2.0.
|
|
@@ -70,6 +71,15 @@ async function fileExists(filename) {
|
|
|
70
71
|
return false;
|
|
71
72
|
}
|
|
72
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Load the JSON file.
|
|
76
|
+
* @param filename The filename of the JSON file to load.
|
|
77
|
+
* @returns The contents of the JSON file or null if it could not be loaded.
|
|
78
|
+
*/
|
|
79
|
+
async function loadJsonFile(filename) {
|
|
80
|
+
const content = await readFile(filename, "utf8");
|
|
81
|
+
return JSON.parse(content);
|
|
82
|
+
}
|
|
73
83
|
/**
|
|
74
84
|
* Get the features that are enabled on the node.
|
|
75
85
|
* @param env The environment variables for the node.
|
|
@@ -134,7 +144,6 @@ async function bootstrapNodeIdentity(engineCore, context, envVars, features) {
|
|
|
134
144
|
await finaliseWallet(engineCore, envVars, features, finalIdentity, addresses);
|
|
135
145
|
await finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity);
|
|
136
146
|
context.state.nodeIdentity = finalIdentity;
|
|
137
|
-
context.state.addresses = addresses;
|
|
138
147
|
context.stateDirty = true;
|
|
139
148
|
engineCore.logInfo(I18n.formatMessage("node.nodeIdentity", {
|
|
140
149
|
identity: context.state.nodeIdentity
|
|
@@ -158,12 +167,13 @@ async function bootstrapIdentity(engineCore, envVars, features, nodeIdentity) {
|
|
|
158
167
|
try {
|
|
159
168
|
const identityResolverConnector = IdentityResolverConnectorFactory.get(engineDefaultTypes.identityResolverConnector);
|
|
160
169
|
identityDocument = await identityResolverConnector.resolveDocument(nodeIdentity);
|
|
161
|
-
engineCore.logInfo(I18n.formatMessage("node.existingNodeIdentity"));
|
|
170
|
+
engineCore.logInfo(I18n.formatMessage("node.existingNodeIdentity", { identity: nodeIdentity }));
|
|
162
171
|
}
|
|
163
172
|
catch { }
|
|
164
173
|
if (Is.empty(identityDocument)) {
|
|
165
174
|
engineCore.logInfo(I18n.formatMessage("node.generatingNodeIdentity"));
|
|
166
175
|
identityDocument = await identityConnector.createDocument(nodeIdentity);
|
|
176
|
+
engineCore.logInfo(I18n.formatMessage("node.createdNodeIdentity", { identity: identityDocument.id }));
|
|
167
177
|
}
|
|
168
178
|
if (engineDefaultTypes.identityConnector === IdentityConnectorType.Iota) {
|
|
169
179
|
const didUrn = Urn.fromValidString(identityDocument.id);
|
|
@@ -288,7 +298,7 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
|
|
|
288
298
|
const email = envVars.username ?? DEFAULT_NODE_USERNAME;
|
|
289
299
|
let nodeAdminUser = await authUserEntityStorage.get(email);
|
|
290
300
|
if (Is.empty(nodeAdminUser)) {
|
|
291
|
-
engineCore.logInfo(I18n.formatMessage("node.creatingNodeUser"));
|
|
301
|
+
engineCore.logInfo(I18n.formatMessage("node.creatingNodeUser", { email }));
|
|
292
302
|
const generatedPassword = envVars.password ?? PasswordGenerator.generate(16);
|
|
293
303
|
const passwordBytes = Converter.utf8ToBytes(generatedPassword);
|
|
294
304
|
const saltBytes = RandomHelper.generate(16);
|
|
@@ -304,7 +314,7 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
|
|
|
304
314
|
await authUserEntityStorage.set(nodeAdminUser);
|
|
305
315
|
}
|
|
306
316
|
else {
|
|
307
|
-
engineCore.logInfo(I18n.formatMessage("node.existingNodeUser"));
|
|
317
|
+
engineCore.logInfo(I18n.formatMessage("node.existingNodeUser", { email }));
|
|
308
318
|
// The user already exists, so double check the other details match
|
|
309
319
|
let needsUpdate = false;
|
|
310
320
|
if (nodeAdminUser.identity !== context.state.nodeIdentity) {
|
|
@@ -333,7 +343,7 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
|
|
|
333
343
|
}
|
|
334
344
|
catch { }
|
|
335
345
|
if (Is.empty(userProfile)) {
|
|
336
|
-
engineCore.logInfo(I18n.formatMessage("node.creatingUserProfile"));
|
|
346
|
+
engineCore.logInfo(I18n.formatMessage("node.creatingUserProfile", { identity: context.state.nodeIdentity }));
|
|
337
347
|
const publicProfile = {
|
|
338
348
|
"@context": "https://schema.org",
|
|
339
349
|
"@type": "Person",
|
|
@@ -349,7 +359,7 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
|
|
|
349
359
|
await identityProfileConnector.create(context.state.nodeIdentity, publicProfile, privateProfile);
|
|
350
360
|
}
|
|
351
361
|
else {
|
|
352
|
-
engineCore.logInfo(I18n.formatMessage("node.existingUserProfile"));
|
|
362
|
+
engineCore.logInfo(I18n.formatMessage("node.existingUserProfile", { identity: context.state.nodeIdentity }));
|
|
353
363
|
}
|
|
354
364
|
}
|
|
355
365
|
}
|
|
@@ -370,20 +380,25 @@ async function bootstrapAttestationMethod(engineCore, context, envVars, features
|
|
|
370
380
|
const identityConnector = IdentityConnectorFactory.get(engineDefaultTypes.identityConnector);
|
|
371
381
|
const identityResolverConnector = IdentityResolverConnectorFactory.get(engineDefaultTypes.identityResolverConnector);
|
|
372
382
|
const identityDocument = await identityResolverConnector.resolveDocument(context.state.nodeIdentity);
|
|
383
|
+
const fullMethodId = `${identityDocument.id}#${envVars.attestationVerificationMethodId}`;
|
|
373
384
|
let createVm = true;
|
|
374
385
|
try {
|
|
375
|
-
DocumentHelper.getVerificationMethod(identityDocument,
|
|
386
|
+
DocumentHelper.getVerificationMethod(identityDocument, fullMethodId, "assertionMethod");
|
|
376
387
|
createVm = false;
|
|
377
388
|
}
|
|
378
389
|
catch { }
|
|
379
390
|
if (createVm) {
|
|
380
391
|
// Add attestation verification method to DID, the correct node context is now in place
|
|
381
392
|
// so the keys for the verification method will be stored correctly
|
|
382
|
-
engineCore.logInfo(I18n.formatMessage("node.addingAttestation"
|
|
393
|
+
engineCore.logInfo(I18n.formatMessage("node.addingAttestation", {
|
|
394
|
+
methodId: fullMethodId
|
|
395
|
+
}));
|
|
383
396
|
await identityConnector.addVerificationMethod(context.state.nodeIdentity, context.state.nodeIdentity, "assertionMethod", envVars.attestationVerificationMethodId);
|
|
384
397
|
}
|
|
385
398
|
else {
|
|
386
|
-
engineCore.logInfo(I18n.formatMessage("node.existingAttestation"
|
|
399
|
+
engineCore.logInfo(I18n.formatMessage("node.existingAttestation", {
|
|
400
|
+
methodId: fullMethodId
|
|
401
|
+
}));
|
|
387
402
|
}
|
|
388
403
|
}
|
|
389
404
|
}
|
|
@@ -402,20 +417,25 @@ async function bootstrapImmutableProofMethod(engineCore, context, envVars, featu
|
|
|
402
417
|
const identityConnector = IdentityConnectorFactory.get(engineDefaultTypes.identityConnector);
|
|
403
418
|
const identityResolverConnector = IdentityResolverConnectorFactory.get(engineDefaultTypes.identityResolverConnector);
|
|
404
419
|
const identityDocument = await identityResolverConnector.resolveDocument(context.state.nodeIdentity);
|
|
420
|
+
const fullMethodId = `${identityDocument.id}#${envVars.immutableProofVerificationMethodId}`;
|
|
405
421
|
let createVm = true;
|
|
406
422
|
try {
|
|
407
|
-
DocumentHelper.getVerificationMethod(identityDocument,
|
|
423
|
+
DocumentHelper.getVerificationMethod(identityDocument, fullMethodId, "assertionMethod");
|
|
408
424
|
createVm = false;
|
|
409
425
|
}
|
|
410
426
|
catch { }
|
|
411
427
|
if (createVm) {
|
|
412
428
|
// Add AIG verification method to DID, the correct node context is now in place
|
|
413
429
|
// so the keys for the verification method will be stored correctly
|
|
414
|
-
engineCore.logInfo(I18n.formatMessage("node.addingImmutableProof"
|
|
430
|
+
engineCore.logInfo(I18n.formatMessage("node.addingImmutableProof", {
|
|
431
|
+
methodId: fullMethodId
|
|
432
|
+
}));
|
|
415
433
|
await identityConnector.addVerificationMethod(context.state.nodeIdentity, context.state.nodeIdentity, "assertionMethod", envVars.immutableProofVerificationMethodId);
|
|
416
434
|
}
|
|
417
435
|
else {
|
|
418
|
-
engineCore.logInfo(I18n.formatMessage("node.existingImmutableProof"
|
|
436
|
+
engineCore.logInfo(I18n.formatMessage("node.existingImmutableProof", {
|
|
437
|
+
methodId: fullMethodId
|
|
438
|
+
}));
|
|
419
439
|
}
|
|
420
440
|
}
|
|
421
441
|
}
|
|
@@ -439,11 +459,11 @@ async function bootstrapBlobEncryption(engineCore, context, envVars, features) {
|
|
|
439
459
|
}
|
|
440
460
|
catch { }
|
|
441
461
|
if (Is.empty(existingKey)) {
|
|
442
|
-
engineCore.logInfo(I18n.formatMessage("node.creatingBlobEncryptionKey"));
|
|
443
|
-
await vaultConnector.createKey(
|
|
462
|
+
engineCore.logInfo(I18n.formatMessage("node.creatingBlobEncryptionKey", { keyName }));
|
|
463
|
+
await vaultConnector.createKey(keyName, VaultKeyType.ChaCha20Poly1305);
|
|
444
464
|
}
|
|
445
465
|
else {
|
|
446
|
-
engineCore.logInfo(I18n.formatMessage("node.existingBlobEncryptionKey"));
|
|
466
|
+
engineCore.logInfo(I18n.formatMessage("node.existingBlobEncryptionKey", { keyName }));
|
|
447
467
|
}
|
|
448
468
|
}
|
|
449
469
|
}
|
|
@@ -467,60 +487,1070 @@ async function bootstrapAuth(engineCore, context, envVars, features) {
|
|
|
467
487
|
}
|
|
468
488
|
catch { }
|
|
469
489
|
if (Is.empty(existingKey)) {
|
|
470
|
-
engineCore.logInfo(I18n.formatMessage("node.creatingAuthKey"));
|
|
471
|
-
await vaultConnector.createKey(
|
|
490
|
+
engineCore.logInfo(I18n.formatMessage("node.creatingAuthKey", { keyName }));
|
|
491
|
+
await vaultConnector.createKey(keyName, VaultKeyType.Ed25519);
|
|
472
492
|
}
|
|
473
493
|
else {
|
|
474
|
-
engineCore.logInfo(I18n.formatMessage("node.existingAuthKey"));
|
|
494
|
+
engineCore.logInfo(I18n.formatMessage("node.existingAuthKey", { keyName }));
|
|
475
495
|
}
|
|
476
496
|
}
|
|
477
497
|
}
|
|
478
498
|
|
|
499
|
+
// Copyright 2024 IOTA Stiftung.
|
|
500
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
479
501
|
/**
|
|
480
|
-
*
|
|
502
|
+
* Build the engine core configuration from environment variables.
|
|
503
|
+
* @param envVars The environment variables.
|
|
504
|
+
* @returns The config for the core.
|
|
505
|
+
*/
|
|
506
|
+
function buildEngineConfiguration(envVars) {
|
|
507
|
+
if (Is.stringValue(envVars.storageFileRoot)) {
|
|
508
|
+
envVars.stateFilename ??= "engine-state.json";
|
|
509
|
+
envVars.storageFileRoot = path.resolve(envVars.storageFileRoot);
|
|
510
|
+
envVars.stateFilename = path.join(envVars.storageFileRoot, envVars.stateFilename);
|
|
511
|
+
}
|
|
512
|
+
envVars.attestationVerificationMethodId ??= "attestation-assertion";
|
|
513
|
+
envVars.immutableProofVerificationMethodId ??= "immutable-proof-assertion";
|
|
514
|
+
envVars.blobStorageEnableEncryption ??= "false";
|
|
515
|
+
envVars.blobStorageEncryptionKey ??= "blob-encryption";
|
|
516
|
+
const coreConfig = {
|
|
517
|
+
debug: Coerce.boolean(envVars.debug) ?? false,
|
|
518
|
+
types: {}
|
|
519
|
+
};
|
|
520
|
+
configureEntityStorage(coreConfig, envVars);
|
|
521
|
+
configureBlobStorage(coreConfig, envVars);
|
|
522
|
+
configureVault(coreConfig, envVars);
|
|
523
|
+
configureDlt(coreConfig, envVars);
|
|
524
|
+
configureLogging(coreConfig, envVars);
|
|
525
|
+
configureBackgroundTask(coreConfig, envVars);
|
|
526
|
+
configureEventBus(coreConfig, envVars);
|
|
527
|
+
configureTelemetry(coreConfig, envVars);
|
|
528
|
+
configureMessaging(coreConfig, envVars);
|
|
529
|
+
configureFaucet(coreConfig, envVars);
|
|
530
|
+
configureWallet(coreConfig, envVars);
|
|
531
|
+
configureNft(coreConfig, envVars);
|
|
532
|
+
configureVerifiableStorage(coreConfig, envVars);
|
|
533
|
+
configureIdentity(coreConfig, envVars);
|
|
534
|
+
configureIdentityResolver(coreConfig, envVars);
|
|
535
|
+
configureIdentityProfile(coreConfig, envVars);
|
|
536
|
+
configureAttestation(coreConfig, envVars);
|
|
537
|
+
configureDataProcessing(coreConfig, envVars);
|
|
538
|
+
configureAuditableItemGraph(coreConfig);
|
|
539
|
+
configureAuditableItemStream(coreConfig);
|
|
540
|
+
configureDocumentManagement(coreConfig);
|
|
541
|
+
configureFederatedCatalogue(coreConfig, envVars);
|
|
542
|
+
configureRightsManagement(coreConfig, envVars);
|
|
543
|
+
configureTaskScheduler(coreConfig, envVars);
|
|
544
|
+
return coreConfig;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Helper function to get IOTA configuration from centralized dltConfig.
|
|
548
|
+
* @param coreConfig The core config.
|
|
549
|
+
* @returns The IOTA configuration if found, undefined otherwise.
|
|
550
|
+
*/
|
|
551
|
+
function getIotaConfig(coreConfig) {
|
|
552
|
+
const dltConfig = coreConfig.types.dltConfig?.find(config => config.type === DltConfigType.Iota && config.isDefault);
|
|
553
|
+
return dltConfig?.options?.config;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Configures the entity storage.
|
|
557
|
+
* @param coreConfig The core config.
|
|
558
|
+
* @param envVars The environment variables.
|
|
559
|
+
*/
|
|
560
|
+
function configureEntityStorage(coreConfig, envVars) {
|
|
561
|
+
coreConfig.types ??= {};
|
|
562
|
+
coreConfig.types.entityStorageConnector ??= [];
|
|
563
|
+
if ((Coerce.boolean(envVars.entityMemoryEnable) ?? false) ||
|
|
564
|
+
envVars.entityStorageConnectorType === EntityStorageConnectorType.Memory) {
|
|
565
|
+
coreConfig.types.entityStorageConnector.push({
|
|
566
|
+
type: EntityStorageConnectorType.Memory
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
if ((Coerce.boolean(envVars.entityFileEnable) ?? false) ||
|
|
570
|
+
envVars.entityStorageConnectorType === EntityStorageConnectorType.File) {
|
|
571
|
+
coreConfig.types.entityStorageConnector.push({
|
|
572
|
+
type: EntityStorageConnectorType.File,
|
|
573
|
+
options: {
|
|
574
|
+
config: { directory: envVars.storageFileRoot ?? "" },
|
|
575
|
+
folderPrefix: envVars.entityStorageTablePrefix
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
if (Is.stringValue(envVars.awsDynamodbAccessKeyId)) {
|
|
580
|
+
coreConfig.types.entityStorageConnector.push({
|
|
581
|
+
type: EntityStorageConnectorType.AwsDynamoDb,
|
|
582
|
+
options: {
|
|
583
|
+
config: {
|
|
584
|
+
region: envVars.awsDynamodbRegion ?? "",
|
|
585
|
+
accessKeyId: envVars.awsDynamodbAccessKeyId ?? "",
|
|
586
|
+
secretAccessKey: envVars.awsDynamodbSecretAccessKey ?? "",
|
|
587
|
+
endpoint: envVars.awsDynamodbEndpoint ?? ""
|
|
588
|
+
},
|
|
589
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
if (Is.stringValue(envVars.azureCosmosdbKey)) {
|
|
594
|
+
coreConfig.types.entityStorageConnector.push({
|
|
595
|
+
type: EntityStorageConnectorType.AzureCosmosDb,
|
|
596
|
+
options: {
|
|
597
|
+
config: {
|
|
598
|
+
endpoint: envVars.azureCosmosdbEndpoint ?? "",
|
|
599
|
+
key: envVars.azureCosmosdbKey ?? "",
|
|
600
|
+
databaseId: envVars.azureCosmosdbDatabaseId ?? "",
|
|
601
|
+
containerId: envVars.azureCosmosdbContainerId ?? ""
|
|
602
|
+
},
|
|
603
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
if (Is.stringValue(envVars.gcpFirestoreCredentials)) {
|
|
608
|
+
coreConfig.types.entityStorageConnector.push({
|
|
609
|
+
type: EntityStorageConnectorType.GcpFirestoreDb,
|
|
610
|
+
options: {
|
|
611
|
+
config: {
|
|
612
|
+
projectId: envVars.gcpFirestoreProjectId ?? "",
|
|
613
|
+
credentials: envVars.gcpFirestoreCredentials ?? "",
|
|
614
|
+
databaseId: envVars.gcpFirestoreDatabaseId ?? "",
|
|
615
|
+
collectionName: envVars.gcpFirestoreCollectionName ?? "",
|
|
616
|
+
endpoint: envVars.gcpFirestoreApiEndpoint ?? ""
|
|
617
|
+
},
|
|
618
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
if (Is.stringValue(envVars.scylladbHosts)) {
|
|
623
|
+
coreConfig.types.entityStorageConnector.push({
|
|
624
|
+
type: EntityStorageConnectorType.ScyllaDb,
|
|
625
|
+
options: {
|
|
626
|
+
config: {
|
|
627
|
+
hosts: envVars.scylladbHosts.split(",") ?? "",
|
|
628
|
+
localDataCenter: envVars.scylladbLocalDataCenter ?? "",
|
|
629
|
+
keyspace: envVars.scylladbKeyspace ?? ""
|
|
630
|
+
},
|
|
631
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
if (Is.stringValue(envVars.mySqlHost)) {
|
|
636
|
+
coreConfig.types.entityStorageConnector.push({
|
|
637
|
+
type: EntityStorageConnectorType.MySqlDb,
|
|
638
|
+
options: {
|
|
639
|
+
config: {
|
|
640
|
+
host: envVars.mySqlHost,
|
|
641
|
+
port: envVars.mySqlPort ?? 3306,
|
|
642
|
+
user: envVars.mySqlUser ?? "",
|
|
643
|
+
password: envVars.mySqlPassword ?? "",
|
|
644
|
+
database: envVars.mySqlDatabase ?? ""
|
|
645
|
+
},
|
|
646
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
if (Is.stringValue(envVars.mySqlHost)) {
|
|
651
|
+
coreConfig.types.entityStorageConnector.push({
|
|
652
|
+
type: EntityStorageConnectorType.MySqlDb,
|
|
653
|
+
options: {
|
|
654
|
+
config: {
|
|
655
|
+
host: envVars.mySqlHost,
|
|
656
|
+
port: envVars.mySqlPort ?? 3306,
|
|
657
|
+
user: envVars.mySqlUser ?? "",
|
|
658
|
+
password: envVars.mySqlPassword ?? "",
|
|
659
|
+
database: envVars.mySqlDatabase ?? ""
|
|
660
|
+
},
|
|
661
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
if (Is.stringValue(envVars.mongoDbHost)) {
|
|
666
|
+
coreConfig.types.entityStorageConnector.push({
|
|
667
|
+
type: EntityStorageConnectorType.MongoDb,
|
|
668
|
+
options: {
|
|
669
|
+
config: {
|
|
670
|
+
host: envVars.mongoDbHost,
|
|
671
|
+
port: envVars.mongoDbPort,
|
|
672
|
+
user: envVars.mongoDbUser ?? "",
|
|
673
|
+
password: envVars.mongoDbPassword ?? "",
|
|
674
|
+
database: envVars.mongoDbDatabase ?? ""
|
|
675
|
+
},
|
|
676
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
if (Is.stringValue(envVars.postgreSqlHost)) {
|
|
681
|
+
coreConfig.types.entityStorageConnector.push({
|
|
682
|
+
type: EntityStorageConnectorType.PostgreSql,
|
|
683
|
+
options: {
|
|
684
|
+
config: {
|
|
685
|
+
host: envVars.postgreSqlHost,
|
|
686
|
+
port: envVars.postgreSqlPort,
|
|
687
|
+
user: envVars.postgreSqlUser ?? "",
|
|
688
|
+
password: envVars.postgreSqlPassword ?? "",
|
|
689
|
+
database: envVars.postgreSqlDatabase ?? ""
|
|
690
|
+
},
|
|
691
|
+
tablePrefix: envVars.entityStorageTablePrefix
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
const defaultStorageConnector = envVars.entityStorageConnectorType;
|
|
696
|
+
if (Is.stringValue(defaultStorageConnector)) {
|
|
697
|
+
for (const config of coreConfig.types.entityStorageConnector) {
|
|
698
|
+
if (config.type === defaultStorageConnector) {
|
|
699
|
+
config.isDefault = true;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Configures the blob storage.
|
|
706
|
+
* @param coreConfig The core config.
|
|
707
|
+
* @param envVars The environment variables.
|
|
708
|
+
*/
|
|
709
|
+
function configureBlobStorage(coreConfig, envVars) {
|
|
710
|
+
coreConfig.types.blobStorageConnector ??= [];
|
|
711
|
+
if ((Coerce.boolean(envVars.blobMemoryEnable) ?? false) ||
|
|
712
|
+
envVars.blobStorageConnectorType === BlobStorageConnectorType.Memory) {
|
|
713
|
+
coreConfig.types.blobStorageConnector.push({
|
|
714
|
+
type: BlobStorageConnectorType.Memory
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
if ((Coerce.boolean(envVars.blobFileEnable) ?? false) ||
|
|
718
|
+
envVars.blobStorageConnectorType === BlobStorageConnectorType.File) {
|
|
719
|
+
coreConfig.types.blobStorageConnector.push({
|
|
720
|
+
type: BlobStorageConnectorType.File,
|
|
721
|
+
options: {
|
|
722
|
+
config: {
|
|
723
|
+
directory: Is.stringValue(envVars.storageFileRoot)
|
|
724
|
+
? path.join(envVars.storageFileRoot, "blob-storage")
|
|
725
|
+
: ""
|
|
726
|
+
},
|
|
727
|
+
storagePrefix: envVars.blobStoragePrefix
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
if (Is.stringValue(envVars.ipfsApiUrl)) {
|
|
732
|
+
coreConfig.types.blobStorageConnector.push({
|
|
733
|
+
type: BlobStorageConnectorType.Ipfs,
|
|
734
|
+
options: {
|
|
735
|
+
config: {
|
|
736
|
+
apiUrl: envVars.ipfsApiUrl,
|
|
737
|
+
bearerToken: envVars.ipfsBearerToken
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
if (Is.stringValue(envVars.awsS3AccessKeyId)) {
|
|
743
|
+
coreConfig.types.blobStorageConnector.push({
|
|
744
|
+
type: BlobStorageConnectorType.AwsS3,
|
|
745
|
+
options: {
|
|
746
|
+
config: {
|
|
747
|
+
region: envVars.awsS3Region ?? "",
|
|
748
|
+
bucketName: envVars.awsS3BucketName ?? "",
|
|
749
|
+
accessKeyId: envVars.awsS3AccessKeyId ?? "",
|
|
750
|
+
secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
|
|
751
|
+
endpoint: envVars.awsS3Endpoint ?? ""
|
|
752
|
+
},
|
|
753
|
+
storagePrefix: envVars.blobStoragePrefix
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
if (Is.stringValue(envVars.azureStorageAccountKey)) {
|
|
758
|
+
coreConfig.types.blobStorageConnector.push({
|
|
759
|
+
type: BlobStorageConnectorType.AzureStorage,
|
|
760
|
+
options: {
|
|
761
|
+
config: {
|
|
762
|
+
accountName: envVars.azureStorageAccountName ?? "",
|
|
763
|
+
accountKey: envVars.azureStorageAccountKey ?? "",
|
|
764
|
+
containerName: envVars.azureStorageContainerName ?? "",
|
|
765
|
+
endpoint: envVars.azureStorageEndpoint ?? ""
|
|
766
|
+
},
|
|
767
|
+
storagePrefix: envVars.blobStoragePrefix
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
if (Is.stringValue(envVars.gcpStorageCredentials)) {
|
|
772
|
+
coreConfig.types.blobStorageConnector.push({
|
|
773
|
+
type: BlobStorageConnectorType.GcpStorage,
|
|
774
|
+
options: {
|
|
775
|
+
config: {
|
|
776
|
+
projectId: envVars.gcpStorageProjectId ?? "",
|
|
777
|
+
credentials: envVars.gcpStorageCredentials ?? "",
|
|
778
|
+
bucketName: envVars.gcpStorageBucketName ?? "",
|
|
779
|
+
apiEndpoint: envVars.gcpFirestoreApiEndpoint
|
|
780
|
+
},
|
|
781
|
+
storagePrefix: envVars.blobStoragePrefix
|
|
782
|
+
}
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
const defaultStorageConnectorType = envVars.blobStorageConnectorType;
|
|
786
|
+
if (Is.stringValue(defaultStorageConnectorType)) {
|
|
787
|
+
for (const config of coreConfig.types.blobStorageConnector) {
|
|
788
|
+
if (config.type === defaultStorageConnectorType) {
|
|
789
|
+
config.isDefault = true;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if (coreConfig.types.blobStorageConnector.length > 0) {
|
|
794
|
+
coreConfig.types.blobStorageComponent ??= [];
|
|
795
|
+
coreConfig.types.blobStorageComponent.push({
|
|
796
|
+
type: BlobStorageComponentType.Service,
|
|
797
|
+
options: {
|
|
798
|
+
config: {
|
|
799
|
+
vaultKeyId: (envVars.blobStorageEnableEncryption ?? false)
|
|
800
|
+
? envVars.blobStorageEncryptionKey
|
|
801
|
+
: undefined
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Configures the logging.
|
|
809
|
+
* @param coreConfig The core config.
|
|
810
|
+
* @param envVars The environment variables.
|
|
811
|
+
*/
|
|
812
|
+
function configureLogging(coreConfig, envVars) {
|
|
813
|
+
coreConfig.types.loggingConnector ??= [];
|
|
814
|
+
const loggingConnectors = (envVars.loggingConnector ?? "").split(",");
|
|
815
|
+
for (const loggingConnector of loggingConnectors) {
|
|
816
|
+
if (loggingConnector === LoggingConnectorType.Console) {
|
|
817
|
+
coreConfig.types.loggingConnector?.push({
|
|
818
|
+
type: LoggingConnectorType.Console,
|
|
819
|
+
options: {
|
|
820
|
+
config: {
|
|
821
|
+
translateMessages: true,
|
|
822
|
+
hideGroups: true
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
isDefault: loggingConnectors.length === 1
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
else if (loggingConnector === LoggingConnectorType.EntityStorage) {
|
|
829
|
+
coreConfig.types.loggingConnector?.push({
|
|
830
|
+
type: LoggingConnectorType.EntityStorage,
|
|
831
|
+
isDefault: loggingConnectors.length === 1
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (loggingConnectors.length > 1) {
|
|
836
|
+
coreConfig.types.loggingConnector?.push({
|
|
837
|
+
type: LoggingConnectorType.Multi,
|
|
838
|
+
isDefault: true,
|
|
839
|
+
options: {
|
|
840
|
+
loggingConnectorTypes: loggingConnectors
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
if (loggingConnectors.length > 0) {
|
|
845
|
+
coreConfig.types.loggingComponent ??= [];
|
|
846
|
+
coreConfig.types.loggingComponent.push({ type: LoggingComponentType.Service });
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Configures the vault.
|
|
851
|
+
* @param coreConfig The core config.
|
|
852
|
+
* @param envVars The environment variables.
|
|
853
|
+
*/
|
|
854
|
+
function configureVault(coreConfig, envVars) {
|
|
855
|
+
coreConfig.types.vaultConnector ??= [];
|
|
856
|
+
if (envVars.vaultConnector === VaultConnectorType.EntityStorage) {
|
|
857
|
+
coreConfig.types.vaultConnector.push({
|
|
858
|
+
type: VaultConnectorType.EntityStorage
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
else if (envVars.vaultConnector === VaultConnectorType.Hashicorp) {
|
|
862
|
+
coreConfig.types.vaultConnector.push({
|
|
863
|
+
type: VaultConnectorType.Hashicorp,
|
|
864
|
+
options: {
|
|
865
|
+
config: {
|
|
866
|
+
endpoint: envVars.hashicorpVaultEndpoint ?? "",
|
|
867
|
+
token: envVars.hashicorpVaultToken ?? ""
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Configures the background task.
|
|
875
|
+
* @param coreConfig The core config.
|
|
876
|
+
* @param envVars The environment variables.
|
|
877
|
+
*/
|
|
878
|
+
function configureBackgroundTask(coreConfig, envVars) {
|
|
879
|
+
coreConfig.types.backgroundTaskConnector ??= [];
|
|
880
|
+
if (envVars.backgroundTaskConnector === BackgroundTaskConnectorType.EntityStorage) {
|
|
881
|
+
coreConfig.types.backgroundTaskConnector.push({
|
|
882
|
+
type: BackgroundTaskConnectorType.EntityStorage
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Configures the event bud.
|
|
888
|
+
* @param coreConfig The core config.
|
|
889
|
+
* @param envVars The environment variables.
|
|
890
|
+
*/
|
|
891
|
+
function configureEventBus(coreConfig, envVars) {
|
|
892
|
+
coreConfig.types.eventBusConnector ??= [];
|
|
893
|
+
if (envVars.eventBusConnector === EventBusConnectorType.Local) {
|
|
894
|
+
coreConfig.types.eventBusConnector.push({
|
|
895
|
+
type: EventBusConnectorType.Local
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
if (coreConfig.types.eventBusConnector.length > 0) {
|
|
899
|
+
coreConfig.types.eventBusComponent ??= [];
|
|
900
|
+
coreConfig.types.eventBusComponent.push({ type: EventBusComponentType.Service });
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Configures the telemetry.
|
|
905
|
+
* @param coreConfig The core config.
|
|
906
|
+
* @param envVars The environment variables.
|
|
907
|
+
*/
|
|
908
|
+
function configureTelemetry(coreConfig, envVars) {
|
|
909
|
+
coreConfig.types.telemetryConnector ??= [];
|
|
910
|
+
if (envVars.telemetryConnector === TelemetryConnectorType.EntityStorage) {
|
|
911
|
+
coreConfig.types.telemetryConnector.push({
|
|
912
|
+
type: TelemetryConnectorType.EntityStorage
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
if (coreConfig.types.telemetryConnector.length > 0) {
|
|
916
|
+
coreConfig.types.telemetryComponent ??= [];
|
|
917
|
+
coreConfig.types.telemetryComponent.push({ type: TelemetryComponentType.Service });
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Configures the messaging.
|
|
922
|
+
* @param coreConfig The core config.
|
|
923
|
+
* @param envVars The environment variables.
|
|
924
|
+
*/
|
|
925
|
+
function configureMessaging(coreConfig, envVars) {
|
|
926
|
+
coreConfig.types.messagingEmailConnector ??= [];
|
|
927
|
+
coreConfig.types.messagingSmsConnector ??= [];
|
|
928
|
+
coreConfig.types.messagingPushNotificationConnector ??= [];
|
|
929
|
+
if (envVars.messagingEmailConnector === MessagingEmailConnectorType.EntityStorage) {
|
|
930
|
+
coreConfig.types.messagingEmailConnector.push({
|
|
931
|
+
type: MessagingEmailConnectorType.EntityStorage
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
else if (envVars.messagingEmailConnector === MessagingEmailConnectorType.Aws) {
|
|
935
|
+
coreConfig.types.messagingEmailConnector.push({
|
|
936
|
+
type: MessagingEmailConnectorType.Aws,
|
|
937
|
+
options: {
|
|
938
|
+
config: {
|
|
939
|
+
region: envVars.awsS3Region ?? "",
|
|
940
|
+
accessKeyId: envVars.awsS3AccessKeyId ?? "",
|
|
941
|
+
secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
|
|
942
|
+
endpoint: envVars.awsS3Endpoint ?? ""
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
if (envVars.messagingSmsConnector === MessagingSmsConnectorType.EntityStorage) {
|
|
948
|
+
coreConfig.types.messagingSmsConnector.push({
|
|
949
|
+
type: MessagingSmsConnectorType.EntityStorage
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
else if (envVars.messagingSmsConnector === MessagingSmsConnectorType.Aws) {
|
|
953
|
+
coreConfig.types.messagingSmsConnector.push({
|
|
954
|
+
type: MessagingSmsConnectorType.Aws,
|
|
955
|
+
options: {
|
|
956
|
+
config: {
|
|
957
|
+
region: envVars.awsS3Region ?? "",
|
|
958
|
+
accessKeyId: envVars.awsS3AccessKeyId ?? "",
|
|
959
|
+
secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
|
|
960
|
+
endpoint: envVars.awsS3Endpoint ?? ""
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
if (envVars.messagingPushNotificationConnector ===
|
|
966
|
+
MessagingPushNotificationConnectorType.EntityStorage) {
|
|
967
|
+
coreConfig.types.messagingPushNotificationConnector.push({
|
|
968
|
+
type: MessagingPushNotificationConnectorType.EntityStorage
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
else if (envVars.messagingPushNotificationConnector === MessagingPushNotificationConnectorType.Aws) {
|
|
972
|
+
coreConfig.types.messagingPushNotificationConnector.push({
|
|
973
|
+
type: MessagingPushNotificationConnectorType.Aws,
|
|
974
|
+
options: {
|
|
975
|
+
config: {
|
|
976
|
+
region: envVars.awsS3Region ?? "",
|
|
977
|
+
accessKeyId: envVars.awsS3AccessKeyId ?? "",
|
|
978
|
+
secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
|
|
979
|
+
endpoint: envVars.awsS3Endpoint ?? "",
|
|
980
|
+
applicationsSettings: Is.json(envVars.awsMessagingPushNotificationApplications)
|
|
981
|
+
? JSON.parse(envVars.awsMessagingPushNotificationApplications)
|
|
982
|
+
: []
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
if (coreConfig.types.messagingEmailConnector.length > 0 ||
|
|
988
|
+
coreConfig.types.messagingSmsConnector.length > 0 ||
|
|
989
|
+
coreConfig.types.messagingPushNotificationConnector.length > 0) {
|
|
990
|
+
coreConfig.types.messagingComponent ??= [];
|
|
991
|
+
coreConfig.types.messagingComponent.push({ type: MessagingComponentType.Service });
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* Configures the faucet.
|
|
996
|
+
* @param coreConfig The core config.
|
|
997
|
+
* @param envVars The environment variables.
|
|
998
|
+
*/
|
|
999
|
+
function configureFaucet(coreConfig, envVars) {
|
|
1000
|
+
coreConfig.types.faucetConnector ??= [];
|
|
1001
|
+
if (envVars.faucetConnector === FaucetConnectorType.EntityStorage) {
|
|
1002
|
+
coreConfig.types.faucetConnector.push({
|
|
1003
|
+
type: FaucetConnectorType.EntityStorage
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
else if (envVars.faucetConnector === FaucetConnectorType.Iota) {
|
|
1007
|
+
const iotaConfig = getIotaConfig(coreConfig);
|
|
1008
|
+
coreConfig.types.faucetConnector.push({
|
|
1009
|
+
type: FaucetConnectorType.Iota,
|
|
1010
|
+
options: {
|
|
1011
|
+
config: {
|
|
1012
|
+
endpoint: envVars.iotaFaucetEndpoint ?? "",
|
|
1013
|
+
clientOptions: iotaConfig?.clientOptions ?? { url: "" },
|
|
1014
|
+
network: iotaConfig?.network ?? ""
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Configures the wallet.
|
|
1022
|
+
* @param coreConfig The core config.
|
|
1023
|
+
* @param envVars The environment variables.
|
|
1024
|
+
*/
|
|
1025
|
+
function configureWallet(coreConfig, envVars) {
|
|
1026
|
+
coreConfig.types.walletConnector ??= [];
|
|
1027
|
+
if (envVars.walletConnector === WalletConnectorType.EntityStorage) {
|
|
1028
|
+
coreConfig.types.walletConnector.push({
|
|
1029
|
+
type: WalletConnectorType.EntityStorage
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
else if (envVars.walletConnector === WalletConnectorType.Iota) {
|
|
1033
|
+
const iotaConfig = getIotaConfig(coreConfig);
|
|
1034
|
+
coreConfig.types.walletConnector.push({
|
|
1035
|
+
type: WalletConnectorType.Iota,
|
|
1036
|
+
options: {
|
|
1037
|
+
config: iotaConfig ?? {}
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Configures the NFT.
|
|
1044
|
+
* @param coreConfig The core config.
|
|
1045
|
+
* @param envVars The environment variables.
|
|
1046
|
+
*/
|
|
1047
|
+
function configureNft(coreConfig, envVars) {
|
|
1048
|
+
coreConfig.types.nftConnector ??= [];
|
|
1049
|
+
if (envVars.nftConnector === NftConnectorType.EntityStorage) {
|
|
1050
|
+
coreConfig.types.nftConnector.push({
|
|
1051
|
+
type: NftConnectorType.EntityStorage
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
else if (envVars.nftConnector === NftConnectorType.Iota) {
|
|
1055
|
+
const iotaConfig = getIotaConfig(coreConfig);
|
|
1056
|
+
coreConfig.types.nftConnector.push({
|
|
1057
|
+
type: NftConnectorType.Iota,
|
|
1058
|
+
options: {
|
|
1059
|
+
config: iotaConfig ?? {}
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
if (coreConfig.types.nftConnector.length > 0) {
|
|
1064
|
+
coreConfig.types.nftComponent ??= [];
|
|
1065
|
+
coreConfig.types.nftComponent.push({ type: NftComponentType.Service });
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Configures the verifiable storage.
|
|
1070
|
+
* @param coreConfig The core config.
|
|
1071
|
+
* @param envVars The environment variables.
|
|
1072
|
+
*/
|
|
1073
|
+
function configureVerifiableStorage(coreConfig, envVars) {
|
|
1074
|
+
coreConfig.types.verifiableStorageConnector ??= [];
|
|
1075
|
+
if (envVars.verifiableStorageConnector === VerifiableStorageConnectorType.EntityStorage) {
|
|
1076
|
+
coreConfig.types.verifiableStorageConnector.push({
|
|
1077
|
+
type: VerifiableStorageConnectorType.EntityStorage
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
else if (envVars.verifiableStorageConnector === VerifiableStorageConnectorType.Iota) {
|
|
1081
|
+
const iotaConfig = getIotaConfig(coreConfig);
|
|
1082
|
+
coreConfig.types.verifiableStorageConnector.push({
|
|
1083
|
+
type: VerifiableStorageConnectorType.Iota,
|
|
1084
|
+
options: {
|
|
1085
|
+
config: iotaConfig ?? {}
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
if (coreConfig.types.verifiableStorageConnector.length > 0) {
|
|
1090
|
+
coreConfig.types.verifiableStorageComponent ??= [];
|
|
1091
|
+
coreConfig.types.verifiableStorageComponent.push({
|
|
1092
|
+
type: VerifiableStorageComponentType.Service
|
|
1093
|
+
});
|
|
1094
|
+
coreConfig.types.immutableProofComponent ??= [];
|
|
1095
|
+
coreConfig.types.immutableProofComponent.push({
|
|
1096
|
+
type: ImmutableProofComponentType.Service,
|
|
1097
|
+
options: {
|
|
1098
|
+
config: {
|
|
1099
|
+
verificationMethodId: envVars.immutableProofVerificationMethodId
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
coreConfig.types.auditableItemGraphComponent ??= [];
|
|
1104
|
+
coreConfig.types.auditableItemGraphComponent.push({
|
|
1105
|
+
type: AuditableItemGraphComponentType.Service
|
|
1106
|
+
});
|
|
1107
|
+
coreConfig.types.auditableItemStreamComponent ??= [];
|
|
1108
|
+
coreConfig.types.auditableItemStreamComponent.push({
|
|
1109
|
+
type: AuditableItemStreamComponentType.Service
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
/**
|
|
1114
|
+
* Configures the identity.
|
|
1115
|
+
* @param coreConfig The core config.
|
|
1116
|
+
* @param envVars The environment variables.
|
|
1117
|
+
*/
|
|
1118
|
+
function configureIdentity(coreConfig, envVars) {
|
|
1119
|
+
coreConfig.types.identityConnector ??= [];
|
|
1120
|
+
if (envVars.identityConnector === IdentityConnectorType.EntityStorage) {
|
|
1121
|
+
coreConfig.types.identityConnector.push({
|
|
1122
|
+
type: IdentityConnectorType.EntityStorage
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
else if (envVars.identityConnector === IdentityConnectorType.Iota) {
|
|
1126
|
+
const iotaConfig = getIotaConfig(coreConfig);
|
|
1127
|
+
coreConfig.types.identityConnector.push({
|
|
1128
|
+
type: IdentityConnectorType.Iota,
|
|
1129
|
+
options: {
|
|
1130
|
+
config: iotaConfig ?? {}
|
|
1131
|
+
}
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
if (coreConfig.types.identityConnector.length > 0) {
|
|
1135
|
+
coreConfig.types.identityComponent ??= [];
|
|
1136
|
+
coreConfig.types.identityComponent.push({ type: IdentityComponentType.Service });
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Configures the identity resolver.
|
|
1141
|
+
* @param coreConfig The core config.
|
|
1142
|
+
* @param envVars The environment variables.
|
|
1143
|
+
*/
|
|
1144
|
+
function configureIdentityResolver(coreConfig, envVars) {
|
|
1145
|
+
coreConfig.types.identityResolverConnector ??= [];
|
|
1146
|
+
if (envVars.identityResolverConnector === IdentityResolverConnectorType.EntityStorage) {
|
|
1147
|
+
coreConfig.types.identityResolverConnector.push({
|
|
1148
|
+
type: IdentityResolverConnectorType.EntityStorage
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
else if (envVars.identityResolverConnector === IdentityResolverConnectorType.Iota) {
|
|
1152
|
+
const iotaConfig = getIotaConfig(coreConfig);
|
|
1153
|
+
coreConfig.types.identityResolverConnector.push({
|
|
1154
|
+
type: IdentityResolverConnectorType.Iota,
|
|
1155
|
+
options: {
|
|
1156
|
+
config: iotaConfig ?? {}
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
else if (envVars.identityResolverConnector === IdentityResolverConnectorType.Universal) {
|
|
1161
|
+
coreConfig.types.identityResolverConnector.push({
|
|
1162
|
+
type: IdentityResolverConnectorType.Universal,
|
|
1163
|
+
options: {
|
|
1164
|
+
config: {
|
|
1165
|
+
endpoint: envVars.universalResolverEndpoint ?? ""
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
if (coreConfig.types.identityResolverConnector.length > 0) {
|
|
1171
|
+
coreConfig.types.identityResolverComponent ??= [];
|
|
1172
|
+
coreConfig.types.identityResolverComponent.push({
|
|
1173
|
+
type: IdentityResolverComponentType.Service
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
/**
|
|
1178
|
+
* Configures the identity profile.
|
|
1179
|
+
* @param coreConfig The core config.
|
|
1180
|
+
* @param envVars The environment variables.
|
|
1181
|
+
*/
|
|
1182
|
+
function configureIdentityProfile(coreConfig, envVars) {
|
|
1183
|
+
coreConfig.types.identityProfileConnector ??= [];
|
|
1184
|
+
if (envVars.identityProfileConnector === IdentityConnectorType.EntityStorage) {
|
|
1185
|
+
coreConfig.types.identityProfileConnector.push({
|
|
1186
|
+
type: IdentityProfileConnectorType.EntityStorage
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
if (coreConfig.types.identityProfileConnector.length > 0) {
|
|
1190
|
+
coreConfig.types.identityProfileComponent ??= [];
|
|
1191
|
+
coreConfig.types.identityProfileComponent.push({ type: IdentityProfileComponentType.Service });
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Configures the attestation.
|
|
1196
|
+
* @param coreConfig The core config.
|
|
1197
|
+
* @param envVars The environment variables.
|
|
1198
|
+
*/
|
|
1199
|
+
function configureAttestation(coreConfig, envVars) {
|
|
1200
|
+
coreConfig.types.attestationConnector ??= [];
|
|
1201
|
+
if (envVars.attestationConnector === AttestationConnectorType.Nft) {
|
|
1202
|
+
coreConfig.types.attestationConnector.push({
|
|
1203
|
+
type: AttestationConnectorType.Nft
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
if (coreConfig.types.attestationConnector.length > 0) {
|
|
1207
|
+
coreConfig.types.attestationComponent ??= [];
|
|
1208
|
+
coreConfig.types.attestationComponent.push({
|
|
1209
|
+
type: AttestationComponentType.Service,
|
|
1210
|
+
options: {
|
|
1211
|
+
config: {
|
|
1212
|
+
verificationMethodId: envVars.attestationVerificationMethodId
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Configures the auditable item graph.
|
|
1220
|
+
* @param coreConfig The core config.
|
|
1221
|
+
* @param envVars The environment variables.
|
|
1222
|
+
*/
|
|
1223
|
+
function configureAuditableItemGraph(coreConfig, envVars) {
|
|
1224
|
+
if (Is.arrayValue(coreConfig.types.verifiableStorageConnector)) {
|
|
1225
|
+
coreConfig.types.auditableItemGraphComponent ??= [];
|
|
1226
|
+
coreConfig.types.auditableItemGraphComponent.push({
|
|
1227
|
+
type: AuditableItemGraphComponentType.Service
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* Configures the auditable item stream.
|
|
1233
|
+
* @param coreConfig The core config.
|
|
1234
|
+
* @param envVars The environment variables.
|
|
1235
|
+
*/
|
|
1236
|
+
function configureAuditableItemStream(coreConfig, envVars) {
|
|
1237
|
+
if (Is.arrayValue(coreConfig.types.verifiableStorageConnector)) {
|
|
1238
|
+
coreConfig.types.auditableItemStreamComponent ??= [];
|
|
1239
|
+
coreConfig.types.auditableItemStreamComponent.push({
|
|
1240
|
+
type: AuditableItemStreamComponentType.Service
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* Configures the data processing.
|
|
1246
|
+
* @param coreConfig The core config.
|
|
1247
|
+
* @param envVars The environment variables.
|
|
1248
|
+
*/
|
|
1249
|
+
function configureDataProcessing(coreConfig, envVars) {
|
|
1250
|
+
coreConfig.types.dataConverterConnector ??= [];
|
|
1251
|
+
coreConfig.types.dataExtractorConnector ??= [];
|
|
1252
|
+
const converterConnectors = envVars.dataConverterConnectors?.split(",") ?? [];
|
|
1253
|
+
for (const converterConnector of converterConnectors) {
|
|
1254
|
+
if (converterConnector === DataConverterConnectorType.Json) {
|
|
1255
|
+
coreConfig.types.dataConverterConnector.push({
|
|
1256
|
+
type: DataConverterConnectorType.Json
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
else if (converterConnector === DataConverterConnectorType.Xml) {
|
|
1260
|
+
coreConfig.types.dataConverterConnector.push({
|
|
1261
|
+
type: DataConverterConnectorType.Xml
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
const extractorConnectors = envVars.dataExtractorConnectors?.split(",") ?? [];
|
|
1266
|
+
for (const extractorConnector of extractorConnectors) {
|
|
1267
|
+
if (extractorConnector === DataExtractorConnectorType.JsonPath) {
|
|
1268
|
+
coreConfig.types.dataExtractorConnector.push({
|
|
1269
|
+
type: DataExtractorConnectorType.JsonPath
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
if (coreConfig.types.dataConverterConnector.length > 0 ||
|
|
1274
|
+
coreConfig.types.dataExtractorConnector.length > 0) {
|
|
1275
|
+
coreConfig.types.dataProcessingComponent ??= [];
|
|
1276
|
+
coreConfig.types.dataProcessingComponent.push({ type: DataProcessingComponentType.Service });
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
1280
|
+
* Configures the document management.
|
|
1281
|
+
* @param coreConfig The core config.
|
|
1282
|
+
* @param envVars The environment variables.
|
|
1283
|
+
*/
|
|
1284
|
+
function configureDocumentManagement(coreConfig, envVars) {
|
|
1285
|
+
if (Is.arrayValue(coreConfig.types.auditableItemGraphComponent) &&
|
|
1286
|
+
Is.arrayValue(coreConfig.types.blobStorageComponent) &&
|
|
1287
|
+
Is.arrayValue(coreConfig.types.attestationComponent)) {
|
|
1288
|
+
coreConfig.types.documentManagementComponent ??= [];
|
|
1289
|
+
coreConfig.types.documentManagementComponent.push({
|
|
1290
|
+
type: DocumentManagementComponentType.Service
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Configures the federated catalogue.
|
|
1296
|
+
* @param coreConfig The core config.
|
|
1297
|
+
* @param envVars The environment variables.
|
|
1298
|
+
*/
|
|
1299
|
+
function configureFederatedCatalogue(coreConfig, envVars) {
|
|
1300
|
+
if (Is.arrayValue(coreConfig.types.identityResolverComponent)) {
|
|
1301
|
+
coreConfig.types.federatedCatalogueComponent ??= [];
|
|
1302
|
+
coreConfig.types.federatedCatalogueComponent.push({
|
|
1303
|
+
type: FederatedCatalogueComponentType.Service,
|
|
1304
|
+
options: {
|
|
1305
|
+
config: {
|
|
1306
|
+
subResourceCacheTtlMs: Coerce.number(envVars.federatedCatalogueCacheTtlMs),
|
|
1307
|
+
clearingHouseApproverList: Coerce.object(envVars.federatedCatalogueClearingHouseApproverList) ?? []
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Configures the rights management.
|
|
1315
|
+
* @param coreConfig The core config.
|
|
1316
|
+
* @param envVars The environment variables.
|
|
1317
|
+
*/
|
|
1318
|
+
function configureRightsManagement(coreConfig, envVars) {
|
|
1319
|
+
if (Coerce.boolean(envVars.rightsManagementEnabled) ?? false) {
|
|
1320
|
+
coreConfig.types.rightsManagementPapComponent ??= [];
|
|
1321
|
+
coreConfig.types.rightsManagementPapComponent.push({
|
|
1322
|
+
type: RightsManagementPapComponentType.Service
|
|
1323
|
+
});
|
|
1324
|
+
coreConfig.types.rightsManagementComponent ??= [];
|
|
1325
|
+
coreConfig.types.rightsManagementComponent.push({
|
|
1326
|
+
type: RightsManagementComponentType.Service
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
/**
|
|
1331
|
+
* Configures the task scheduler.
|
|
1332
|
+
* @param coreConfig The core config.
|
|
1333
|
+
* @param envVars The environment variables.
|
|
1334
|
+
*/
|
|
1335
|
+
function configureTaskScheduler(coreConfig, envVars) {
|
|
1336
|
+
if (Coerce.boolean(envVars.taskSchedulerEnabled) ?? true) {
|
|
1337
|
+
coreConfig.types.taskSchedulerComponent ??= [];
|
|
1338
|
+
coreConfig.types.taskSchedulerComponent.push({
|
|
1339
|
+
type: TaskSchedulerComponentType.Default
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Configures the DLT.
|
|
1345
|
+
* @param coreConfig The core config.
|
|
1346
|
+
* @param envVars The environment variables.
|
|
1347
|
+
*/
|
|
1348
|
+
function configureDlt(coreConfig, envVars) {
|
|
1349
|
+
// Create centralized DLT configuration for IOTA if essential IOTA variables are set
|
|
1350
|
+
if (Is.stringValue(envVars.iotaNodeEndpoint) && Is.stringValue(envVars.iotaNetwork)) {
|
|
1351
|
+
coreConfig.types.dltConfig ??= [];
|
|
1352
|
+
const gasStationConfig = Is.stringValue(envVars.iotaGasStationEndpoint) &&
|
|
1353
|
+
Is.stringValue(envVars.iotaGasStationAuthToken)
|
|
1354
|
+
? {
|
|
1355
|
+
gasStationUrl: envVars.iotaGasStationEndpoint,
|
|
1356
|
+
gasStationAuthToken: envVars.iotaGasStationAuthToken
|
|
1357
|
+
}
|
|
1358
|
+
: undefined;
|
|
1359
|
+
coreConfig.types.dltConfig.push({
|
|
1360
|
+
type: DltConfigType.Iota,
|
|
1361
|
+
isDefault: true,
|
|
1362
|
+
options: {
|
|
1363
|
+
config: {
|
|
1364
|
+
clientOptions: {
|
|
1365
|
+
url: envVars.iotaNodeEndpoint ?? ""
|
|
1366
|
+
},
|
|
1367
|
+
network: envVars.iotaNetwork ?? "",
|
|
1368
|
+
coinType: Coerce.number(envVars.iotaCoinType),
|
|
1369
|
+
gasStation: gasStationConfig
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/**
|
|
1377
|
+
* Handles the configuration of the server.
|
|
1378
|
+
* @param envVars The environment variables for the engine server.
|
|
1379
|
+
* @param coreEngineConfig The core engine config.
|
|
481
1380
|
* @param serverInfo The server information.
|
|
482
|
-
* @param
|
|
1381
|
+
* @param openApiSpecPath The path to the open api spec.
|
|
1382
|
+
* @returns The the config for the core and the server.
|
|
1383
|
+
*/
|
|
1384
|
+
function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath) {
|
|
1385
|
+
envVars.authSigningKeyId ??= "auth-signing";
|
|
1386
|
+
const webServerOptions = {
|
|
1387
|
+
port: Coerce.number(envVars.port),
|
|
1388
|
+
host: Coerce.string(envVars.host),
|
|
1389
|
+
methods: Is.stringValue(envVars.httpMethods)
|
|
1390
|
+
? envVars.httpMethods.split(",")
|
|
1391
|
+
: undefined,
|
|
1392
|
+
allowedHeaders: Is.stringValue(envVars.httpAllowedHeaders)
|
|
1393
|
+
? envVars.httpAllowedHeaders.split(",")
|
|
1394
|
+
: undefined,
|
|
1395
|
+
exposedHeaders: Is.stringValue(envVars.httpExposedHeaders)
|
|
1396
|
+
? envVars.httpExposedHeaders.split(",")
|
|
1397
|
+
: undefined,
|
|
1398
|
+
corsOrigins: Is.stringValue(envVars.corsOrigins) ? envVars.corsOrigins.split(",") : undefined
|
|
1399
|
+
};
|
|
1400
|
+
const serverConfig = {
|
|
1401
|
+
...coreEngineConfig,
|
|
1402
|
+
web: webServerOptions,
|
|
1403
|
+
types: {
|
|
1404
|
+
...coreEngineConfig.types,
|
|
1405
|
+
informationComponent: [
|
|
1406
|
+
{
|
|
1407
|
+
type: InformationComponentType.Service,
|
|
1408
|
+
options: {
|
|
1409
|
+
config: {
|
|
1410
|
+
serverInfo,
|
|
1411
|
+
openApiSpecPath
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
]
|
|
1416
|
+
}
|
|
1417
|
+
};
|
|
1418
|
+
if (Is.stringValue(envVars.mimeTypeProcessors)) {
|
|
1419
|
+
const mimeTypeProcessors = envVars.mimeTypeProcessors.split(",");
|
|
1420
|
+
if (Is.arrayValue(mimeTypeProcessors)) {
|
|
1421
|
+
serverConfig.types.mimeTypeProcessor ??= [];
|
|
1422
|
+
for (const mimeTypeProcessor of mimeTypeProcessors) {
|
|
1423
|
+
serverConfig.types.mimeTypeProcessor.push({
|
|
1424
|
+
type: mimeTypeProcessor
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
serverConfig.types.restRouteProcessor ??= [];
|
|
1430
|
+
serverConfig.types.socketRouteProcessor ??= [];
|
|
1431
|
+
const disableNodeIdentity = Coerce.boolean(envVars.disableNodeIdentity);
|
|
1432
|
+
if (!disableNodeIdentity) {
|
|
1433
|
+
serverConfig.types.restRouteProcessor.push({
|
|
1434
|
+
type: RestRouteProcessorType.NodeIdentity
|
|
1435
|
+
});
|
|
1436
|
+
serverConfig.types.socketRouteProcessor.push({
|
|
1437
|
+
type: SocketRouteProcessorType.NodeIdentity
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
if (!coreEngineConfig.silent) {
|
|
1441
|
+
serverConfig.types.restRouteProcessor.push({
|
|
1442
|
+
type: RestRouteProcessorType.Logging,
|
|
1443
|
+
options: {
|
|
1444
|
+
config: {
|
|
1445
|
+
includeBody: coreEngineConfig.debug
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
serverConfig.types.socketRouteProcessor.push({
|
|
1450
|
+
type: SocketRouteProcessorType.Logging,
|
|
1451
|
+
options: {
|
|
1452
|
+
config: {
|
|
1453
|
+
includeBody: coreEngineConfig.debug
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
});
|
|
1457
|
+
}
|
|
1458
|
+
serverConfig.types.restRouteProcessor.push({
|
|
1459
|
+
type: RestRouteProcessorType.RestRoute,
|
|
1460
|
+
options: {
|
|
1461
|
+
config: {
|
|
1462
|
+
includeErrorStack: coreEngineConfig.debug
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
});
|
|
1466
|
+
serverConfig.types.socketRouteProcessor.push({
|
|
1467
|
+
type: SocketRouteProcessorType.SocketRoute,
|
|
1468
|
+
options: {
|
|
1469
|
+
config: {
|
|
1470
|
+
includeErrorStack: coreEngineConfig.debug
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
});
|
|
1474
|
+
const authAdminProcessorType = envVars.authAdminProcessorType;
|
|
1475
|
+
if (authAdminProcessorType === AuthenticationAdminComponentType.EntityStorage) {
|
|
1476
|
+
serverConfig.types.authenticationAdminComponent ??= [];
|
|
1477
|
+
serverConfig.types.authenticationAdminComponent.push({
|
|
1478
|
+
type: AuthenticationAdminComponentType.EntityStorage,
|
|
1479
|
+
options: {
|
|
1480
|
+
config: {}
|
|
1481
|
+
}
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
const authProcessorType = envVars.authProcessorType;
|
|
1485
|
+
if (authProcessorType === AuthenticationComponentType.EntityStorage) {
|
|
1486
|
+
serverConfig.types.authenticationComponent ??= [];
|
|
1487
|
+
serverConfig.types.authenticationComponent.push({
|
|
1488
|
+
type: AuthenticationComponentType.EntityStorage,
|
|
1489
|
+
options: {
|
|
1490
|
+
config: {
|
|
1491
|
+
signingKeyName: envVars.authSigningKeyId
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
});
|
|
1495
|
+
serverConfig.types.restRouteProcessor.push({
|
|
1496
|
+
type: RestRouteProcessorType.AuthHeader,
|
|
1497
|
+
options: {
|
|
1498
|
+
config: {
|
|
1499
|
+
signingKeyName: envVars.authSigningKeyId
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
serverConfig.types.socketRouteProcessor.push({
|
|
1504
|
+
type: SocketRouteProcessorType.AuthHeader,
|
|
1505
|
+
options: {
|
|
1506
|
+
config: {
|
|
1507
|
+
signingKeyName: envVars.authSigningKeyId
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1512
|
+
addDefaultRestPaths(serverConfig);
|
|
1513
|
+
addDefaultSocketPaths(serverConfig);
|
|
1514
|
+
return serverConfig;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
// Copyright 2024 IOTA Stiftung.
|
|
1518
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
1519
|
+
/* eslint-disable no-console */
|
|
1520
|
+
/**
|
|
1521
|
+
* Start the engine server.
|
|
1522
|
+
* @param nodeOptions Optional run options for the engine server.
|
|
1523
|
+
* @param engineServerConfig The configuration for the engine server.
|
|
483
1524
|
* @param envVars The environment variables.
|
|
484
|
-
* @param openApiSpecFile Path to the OpenAPI spec file.
|
|
485
|
-
* @param stateStorage The state storage.
|
|
486
|
-
* @param extendConfig Extends the engine configuration with any additional custom configuration.
|
|
487
|
-
* @param extendEngine Extends the engine with any additional options.
|
|
488
|
-
* @param extendEngineServer Extends the engine server with any additional options.
|
|
489
1525
|
* @returns The engine server.
|
|
490
1526
|
*/
|
|
491
|
-
async function start(
|
|
1527
|
+
async function start(nodeOptions, engineServerConfig, envVars) {
|
|
492
1528
|
envVars.storageFileRoot ??= "";
|
|
493
1529
|
if ((envVars.entityStorageConnectorType === EntityStorageConnectorType.File ||
|
|
494
1530
|
envVars.blobStorageConnectorType === BlobStorageConnectorType.File ||
|
|
495
|
-
Is.empty(stateStorage)) &&
|
|
1531
|
+
Is.empty(nodeOptions?.stateStorage)) &&
|
|
496
1532
|
!Is.stringValue(envVars.storageFileRoot)) {
|
|
497
1533
|
throw new GeneralError("node", "storageFileRootNotSet", {
|
|
498
|
-
storageFileRoot: `${
|
|
1534
|
+
storageFileRoot: `${nodeOptions?.envPrefix ?? ""}_STORAGE_FILE_ROOT`
|
|
499
1535
|
});
|
|
500
1536
|
}
|
|
501
|
-
// Build the engine configuration from the environment variables.
|
|
502
|
-
const engineConfig = buildEngineConfiguration(envVars);
|
|
503
|
-
// Extend the engine configuration with a custom type.
|
|
504
|
-
if (Is.function(extendConfig)) {
|
|
505
|
-
await extendConfig(engineConfig);
|
|
506
|
-
}
|
|
507
|
-
// Build the server configuration from the environment variables.
|
|
508
|
-
const serverConfig = buildEngineServerConfiguration(envVars, engineConfig, serverInfo, openApiSpecFile);
|
|
509
1537
|
// Create the engine instance using file state storage and custom bootstrap.
|
|
510
1538
|
const engine = new Engine({
|
|
511
|
-
config:
|
|
512
|
-
stateStorage: stateStorage ?? new FileStateStorage(envVars.stateFilename ?? ""),
|
|
1539
|
+
config: engineServerConfig,
|
|
1540
|
+
stateStorage: nodeOptions?.stateStorage ?? new FileStateStorage(envVars.stateFilename ?? ""),
|
|
513
1541
|
customBootstrap: async (core, engineContext) => bootstrap(core, engineContext, envVars)
|
|
514
1542
|
});
|
|
515
1543
|
// Extend the engine.
|
|
516
|
-
if (Is.function(extendEngine)) {
|
|
517
|
-
|
|
1544
|
+
if (Is.function(nodeOptions?.extendEngine)) {
|
|
1545
|
+
console.info("Extending Engine");
|
|
1546
|
+
await nodeOptions.extendEngine(engine);
|
|
518
1547
|
}
|
|
519
1548
|
// Construct the server with the engine.
|
|
520
1549
|
const server = new EngineServer({ engineCore: engine });
|
|
521
1550
|
// Extend the engine server.
|
|
522
|
-
if (Is.function(extendEngineServer)) {
|
|
523
|
-
|
|
1551
|
+
if (Is.function(nodeOptions?.extendEngineServer)) {
|
|
1552
|
+
console.info("Extending Engine Server");
|
|
1553
|
+
await nodeOptions?.extendEngineServer(server);
|
|
524
1554
|
}
|
|
525
1555
|
// Need to register the engine with the factory so that background tasks
|
|
526
1556
|
// can clone it to spawn new instances.
|
|
@@ -540,44 +1570,39 @@ async function start(serverInfo, envVarsPrefix, envVars, openApiSpecFile, stateS
|
|
|
540
1570
|
/* eslint-disable no-console */
|
|
541
1571
|
/**
|
|
542
1572
|
* Run the TWIN Node server.
|
|
543
|
-
* @param
|
|
1573
|
+
* @param nodeOptions Optional configuration options for running the server.
|
|
544
1574
|
* @returns A promise that resolves when the server is started.
|
|
545
1575
|
*/
|
|
546
|
-
async function run(
|
|
1576
|
+
async function run(nodeOptions) {
|
|
547
1577
|
try {
|
|
1578
|
+
nodeOptions ??= {};
|
|
548
1579
|
const serverInfo = {
|
|
549
|
-
name:
|
|
550
|
-
version:
|
|
1580
|
+
name: nodeOptions?.serverName ?? "TWIN Node Server",
|
|
1581
|
+
version: nodeOptions?.serverVersion ?? "0.0.1-next.11" // x-release-please-version
|
|
551
1582
|
};
|
|
552
1583
|
console.log(`\u001B[4m🌩️ ${serverInfo.name} v${serverInfo.version}\u001B[24m\n`);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
1584
|
+
if (!Is.stringValue(nodeOptions?.executionDirectory)) {
|
|
1585
|
+
nodeOptions.executionDirectory = getExecutionDirectory();
|
|
1586
|
+
}
|
|
1587
|
+
console.info("Execution Directory:", nodeOptions.executionDirectory);
|
|
1588
|
+
nodeOptions.localesDirectory =
|
|
1589
|
+
nodeOptions?.localesDirectory ??
|
|
1590
|
+
path.resolve(path.join(nodeOptions.executionDirectory, "dist", "locales"));
|
|
1591
|
+
console.info("Locales Directory:", nodeOptions.localesDirectory);
|
|
1592
|
+
await initialiseLocales(nodeOptions.localesDirectory);
|
|
1593
|
+
if (Is.empty(nodeOptions?.openApiSpecFile)) {
|
|
1594
|
+
const specFile = path.resolve(path.join(nodeOptions.executionDirectory, "docs", "open-api", "spec.json"));
|
|
558
1595
|
console.info("Default OpenAPI Spec File:", specFile);
|
|
559
1596
|
if (await fileExists(specFile)) {
|
|
560
|
-
|
|
561
|
-
|
|
1597
|
+
nodeOptions ??= {};
|
|
1598
|
+
nodeOptions.openApiSpecFile = specFile;
|
|
562
1599
|
}
|
|
563
1600
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
options ??= {};
|
|
568
|
-
options.envFilenames = [envFile];
|
|
569
|
-
}
|
|
570
|
-
dotenv.config({
|
|
571
|
-
path: options?.envFilenames
|
|
572
|
-
});
|
|
573
|
-
const envPrefix = options?.envPrefix ?? "TWIN_NODE_";
|
|
574
|
-
console.info("Environment Prefix:", envPrefix);
|
|
575
|
-
const envVars = EnvHelper.envToJson(process.env, envPrefix);
|
|
576
|
-
if (Object.keys(envVars).length === 0) {
|
|
577
|
-
throw new GeneralError("node", "noEnvVars", { prefix: envPrefix });
|
|
578
|
-
}
|
|
1601
|
+
nodeOptions.envPrefix ??= "TWIN_NODE_";
|
|
1602
|
+
console.info("Environment Prefix:", nodeOptions.envPrefix);
|
|
1603
|
+
const { engineServerConfig, nodeEnvVars: envVars } = await buildConfiguration(process.env, nodeOptions, serverInfo);
|
|
579
1604
|
console.info();
|
|
580
|
-
const startResult = await start(
|
|
1605
|
+
const startResult = await start(nodeOptions, engineServerConfig, envVars);
|
|
581
1606
|
if (!Is.empty(startResult)) {
|
|
582
1607
|
for (const signal of ["SIGHUP", "SIGINT", "SIGTERM"]) {
|
|
583
1608
|
process.on(signal, async () => {
|
|
@@ -592,5 +1617,75 @@ async function run(options) {
|
|
|
592
1617
|
process.exit(1);
|
|
593
1618
|
}
|
|
594
1619
|
}
|
|
1620
|
+
/**
|
|
1621
|
+
* Build the configuration for the TWIN Node server.
|
|
1622
|
+
* @param processEnv The environment variables from the process.
|
|
1623
|
+
* @param options The options for running the server.
|
|
1624
|
+
* @param serverInfo The server information.
|
|
1625
|
+
* @returns A promise that resolves to the engine server configuration, environment prefix, environment variables,
|
|
1626
|
+
* and options.
|
|
1627
|
+
*/
|
|
1628
|
+
async function buildConfiguration(processEnv, options, serverInfo) {
|
|
1629
|
+
let defaultEnvOnly = false;
|
|
1630
|
+
if (Is.empty(options?.envFilenames)) {
|
|
1631
|
+
const envFile = path.resolve(path.join(options.executionDirectory ?? "", ".env"));
|
|
1632
|
+
console.info("Default Environment File:", envFile);
|
|
1633
|
+
options ??= {};
|
|
1634
|
+
options.envFilenames = [envFile];
|
|
1635
|
+
defaultEnvOnly = true;
|
|
1636
|
+
}
|
|
1637
|
+
if (Is.arrayValue(options?.envFilenames)) {
|
|
1638
|
+
const output = dotenv.config({
|
|
1639
|
+
path: options?.envFilenames
|
|
1640
|
+
});
|
|
1641
|
+
// We don't want to throw an error if the default environment file is not found.
|
|
1642
|
+
// Only if we have custom environment files.
|
|
1643
|
+
if (!defaultEnvOnly && output.error) {
|
|
1644
|
+
throw output.error;
|
|
1645
|
+
}
|
|
1646
|
+
if (Is.objectValue(output.parsed)) {
|
|
1647
|
+
Object.assign(processEnv, output.parsed);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
const envVars = EnvHelper.envToJson(processEnv, options.envPrefix ?? "");
|
|
1651
|
+
// Expand any environment variables that use the @file: syntax
|
|
1652
|
+
const keys = Object.keys(envVars);
|
|
1653
|
+
for (const key of keys) {
|
|
1654
|
+
if (Is.stringValue(envVars[key]) && envVars[key].startsWith("@file:")) {
|
|
1655
|
+
const filePath = envVars[key].slice(6).trim();
|
|
1656
|
+
const embeddedFile = path.resolve(path.join(options.executionDirectory ?? "", filePath));
|
|
1657
|
+
console.info(`Expanding Environment Variable: ${key} from file: ${embeddedFile}`);
|
|
1658
|
+
const fileContent = await loadJsonFile(embeddedFile);
|
|
1659
|
+
envVars[key] = fileContent;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
// Extend the environment variables with any additional custom configuration.
|
|
1663
|
+
if (Is.function(options?.extendEnvVars)) {
|
|
1664
|
+
console.info("Extending Environment Variables");
|
|
1665
|
+
await options.extendEnvVars(envVars);
|
|
1666
|
+
}
|
|
1667
|
+
// Build the engine configuration from the environment variables.
|
|
1668
|
+
const coreConfig = buildEngineConfiguration(envVars);
|
|
1669
|
+
const engineServerConfig = buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile);
|
|
1670
|
+
// Merge any custom configuration provided in the options.
|
|
1671
|
+
if (Is.arrayValue(options?.configFilenames)) {
|
|
1672
|
+
for (const configFile of options.configFilenames) {
|
|
1673
|
+
console.info("Loading Configuration File:", configFile);
|
|
1674
|
+
const configFilePath = path.resolve(path.join(options.executionDirectory ?? "", configFile));
|
|
1675
|
+
const config = await loadJsonFile(configFilePath);
|
|
1676
|
+
Object.assign(engineServerConfig, config);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
if (Is.objectValue(options?.config)) {
|
|
1680
|
+
console.info("Merging Custom Configuration");
|
|
1681
|
+
Object.assign(engineServerConfig, options.config);
|
|
1682
|
+
}
|
|
1683
|
+
// Merge any custom configuration provided in the options.
|
|
1684
|
+
if (Is.function(options?.extendConfig)) {
|
|
1685
|
+
console.info("Extending Configuration");
|
|
1686
|
+
await options.extendConfig(engineServerConfig);
|
|
1687
|
+
}
|
|
1688
|
+
return { engineServerConfig, nodeEnvVars: envVars };
|
|
1689
|
+
}
|
|
595
1690
|
|
|
596
|
-
export { NodeFeatures, bootstrap, bootstrapAttestationMethod, bootstrapAuth, bootstrapBlobEncryption, bootstrapImmutableProofMethod, bootstrapNodeIdentity, bootstrapNodeUser, fileExists, getExecutionDirectory, getFeatures, initialiseLocales, run, start };
|
|
1691
|
+
export { NodeFeatures, bootstrap, bootstrapAttestationMethod, bootstrapAuth, bootstrapBlobEncryption, bootstrapImmutableProofMethod, bootstrapNodeIdentity, bootstrapNodeUser, buildConfiguration, buildEngineConfiguration, fileExists, getExecutionDirectory, getFeatures, initialiseLocales, loadJsonFile, run, start };
|