@twin.org/node-core 0.10.0 → 0.10.1-next.2

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.
@@ -0,0 +1,145 @@
1
+ import { Converter, RandomHelper, StringHelper } from "@twin.org/core";
2
+ import { EntityStorageConnectorFactory, SchemaMigrationFactory } from "@twin.org/entity-storage-models";
3
+ import { envBoolean } from "./envHelpers.js";
4
+ /**
5
+ * Initialise schema migrations for the engine.
6
+ * @param engineCore The engine core instance.
7
+ * @param envVars The environment variables.
8
+ */
9
+ export function initialiseMigrations(engineCore, envVars) {
10
+ if (!envBoolean(envVars, "schemaMigrationEnabled", true)) {
11
+ return;
12
+ }
13
+ migrationAigIndexes();
14
+ migrationPapIndexes();
15
+ }
16
+ /**
17
+ * Finalize schema migrations by clearing any temporary data stored in the shared store.
18
+ * This should be called after all migrations have been processed to ensure that
19
+ * any temporary data used during the migration process is removed.
20
+ * @param engineCore The engine core instance.
21
+ * @param envVars The environment variables.
22
+ */
23
+ export async function finalizeMigrations(engineCore, envVars) {
24
+ // This is currently a placeholder for any finalization logic that might be needed
25
+ // after all schema migrations have been processed.
26
+ }
27
+ /**
28
+ * Perform migrations for Auditable Item Graph indexes.
29
+ */
30
+ function migrationAigIndexes() {
31
+ let aigIndexEntityStorage;
32
+ const migrationAigV1V2 = {
33
+ removeEntityProperty: async (entity, removedProperties) => {
34
+ // If the aliasIndex is being removed we should migrate both aliasIndex and resourceTypeIndex
35
+ // to the new index structure.
36
+ if (removedProperties.find(prop => prop.property === "aliasIndex") === undefined) {
37
+ return;
38
+ }
39
+ aigIndexEntityStorage ??= EntityStorageConnectorFactory.get(StringHelper.kebabCase("AuditableItemGraphVertexIndex"));
40
+ await aigIndexEntityStorage.set({
41
+ id: Converter.bytesToHex(RandomHelper.generate(16)),
42
+ vertexId: entity.id,
43
+ type: "vertex",
44
+ value: entity.id.toLowerCase(),
45
+ dateCreated: entity.dateCreated,
46
+ dateModified: entity.dateModified ?? entity.dateCreated
47
+ });
48
+ // The context ids already contain the correct partition information for the indexes.
49
+ const aliases = entity.aliasIndex
50
+ ?.split("||")
51
+ .map(alias => alias.trim())
52
+ .filter(alias => alias.length > 0) ?? [];
53
+ for (const alias of aliases) {
54
+ await aigIndexEntityStorage.set({
55
+ id: Converter.bytesToHex(RandomHelper.generate(16)),
56
+ vertexId: entity.id,
57
+ type: "alias",
58
+ value: alias.toLowerCase(),
59
+ dateCreated: entity.dateCreated,
60
+ dateModified: entity.dateModified ?? entity.dateCreated
61
+ });
62
+ }
63
+ const resourceTypes = entity.resourceTypeIndex
64
+ ?.split("||")
65
+ .map(resourceType => resourceType.trim())
66
+ .filter(resourceType => resourceType.length > 0) ?? [];
67
+ for (const resourceType of resourceTypes) {
68
+ await aigIndexEntityStorage.set({
69
+ id: Converter.bytesToHex(RandomHelper.generate(16)),
70
+ vertexId: entity.id,
71
+ type: "resourceType",
72
+ value: resourceType.toLowerCase(),
73
+ dateCreated: entity.dateCreated,
74
+ dateModified: entity.dateModified ?? entity.dateCreated
75
+ });
76
+ }
77
+ }
78
+ };
79
+ SchemaMigrationFactory.register(`${"AuditableItemGraphVertex"}_1_2`, () => migrationAigV1V2);
80
+ }
81
+ /**
82
+ * Perform migrations for Policy Administration Point indexes.
83
+ */
84
+ function migrationPapIndexes() {
85
+ let papIndexEntityStorage;
86
+ const migrationPapV0V1 = {
87
+ removeEntityProperty: async (entity, removedProperties) => {
88
+ // If the assignerIndex is being removed we should migrate all four of the pipe delimited
89
+ // indexes to the new index structure.
90
+ if (removedProperties.find(prop => prop.property === "assignerIndex") === undefined) {
91
+ return;
92
+ }
93
+ papIndexEntityStorage ??= EntityStorageConnectorFactory.get(StringHelper.kebabCase("OdrlPolicyIndex"));
94
+ // An absent dimension contributes a single undefined value, otherwise it would collapse
95
+ // the combinations to none and the policy would not be indexed at all.
96
+ const assigners = splitPolicyIndex(entity.assignerIndex);
97
+ const assignees = splitPolicyIndex(entity.assigneeIndex);
98
+ const targets = splitPolicyIndex(entity.targetIndex);
99
+ const actions = splitPolicyIndex(entity.actionIndex);
100
+ // The entries are ordered by the creation date, so a policy stored before the date was
101
+ // recorded is given the migration time rather than leaving the column empty.
102
+ const dateCreated = entity.dateCreated ?? new Date(Date.now()).toISOString();
103
+ // One entry per combination of assigner, assignee, target and action, which is what lets
104
+ // a locator covering several of those fields be answered by a single lookup.
105
+ const entries = [];
106
+ for (const assigner of assigners) {
107
+ for (const assignee of assignees) {
108
+ for (const target of targets) {
109
+ for (const action of actions) {
110
+ entries.push({
111
+ id: Converter.bytesToHex(RandomHelper.generate(16)),
112
+ policyId: entity.id,
113
+ assigner,
114
+ assignee,
115
+ target,
116
+ action,
117
+ dateCreated
118
+ });
119
+ }
120
+ }
121
+ }
122
+ }
123
+ // The context ids already contain the correct partition information for the indexes.
124
+ await papIndexEntityStorage.setBatch(entries);
125
+ }
126
+ };
127
+ SchemaMigrationFactory.register(`${"OdrlPolicy"}_0_1`, () => migrationPapV0V1);
128
+ }
129
+ /**
130
+ * Split one of the pipe delimited indexes from a v0 policy into its index dimension values.
131
+ * @param index The pipe delimited index value.
132
+ * @returns The distinct case folded values, or a single undefined when there are none.
133
+ */
134
+ function splitPolicyIndex(index) {
135
+ const values = [];
136
+ for (const part of index?.split("|") ?? []) {
137
+ // Index values are always stored case folded so lookups are case insensitive.
138
+ const folded = part.trim().toLowerCase();
139
+ if (folded.length > 0 && !values.includes(folded)) {
140
+ values.push(folded);
141
+ }
142
+ }
143
+ return values.length === 0 ? [undefined] : values;
144
+ }
145
+ //# sourceMappingURL=migrationHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrationHelper.js","sourceRoot":"","sources":["../../../../src/builders/helper/migrationHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type {\n\tAuditableItemGraphVertex,\n\tAuditableItemGraphVertexIndex,\n\tAuditableItemGraphVertexV1\n} from \"@twin.org/auditable-item-graph-service\";\nimport { Converter, RandomHelper, StringHelper } from \"@twin.org/core\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport type { IEntitySchemaProperty } from \"@twin.org/entity\";\nimport {\n\tEntityStorageConnectorFactory,\n\tSchemaMigrationFactory,\n\ttype IEntityStorageConnector,\n\ttype ISchemaMigration\n} from \"@twin.org/entity-storage-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type {\n\tOdrlPolicy,\n\tOdrlPolicyIndex,\n\tOdrlPolicyV0\n} from \"@twin.org/rights-management-pap-service\";\nimport { envBoolean } from \"./envHelpers.js\";\nimport type { IEnvironmentVariables } from \"../../models/IEnvironmentVariables.js\";\n\n/**\n * Initialise schema migrations for the engine.\n * @param engineCore The engine core instance.\n * @param envVars The environment variables.\n */\nexport function initialiseMigrations(\n\tengineCore: IEngineCore,\n\tenvVars: IEnvironmentVariables\n): void {\n\tif (!envBoolean(envVars, \"schemaMigrationEnabled\", true)) {\n\t\treturn;\n\t}\n\n\tmigrationAigIndexes();\n\tmigrationPapIndexes();\n}\n\n/**\n * Finalize schema migrations by clearing any temporary data stored in the shared store.\n * This should be called after all migrations have been processed to ensure that\n * any temporary data used during the migration process is removed.\n * @param engineCore The engine core instance.\n * @param envVars The environment variables.\n */\nexport async function finalizeMigrations(\n\tengineCore: IEngineCore,\n\tenvVars: IEnvironmentVariables\n): Promise<void> {\n\t// This is currently a placeholder for any finalization logic that might be needed\n\t// after all schema migrations have been processed.\n}\n\n/**\n * Perform migrations for Auditable Item Graph indexes.\n */\nfunction migrationAigIndexes(): void {\n\tlet aigIndexEntityStorage: IEntityStorageConnector<AuditableItemGraphVertexIndex> | undefined;\n\n\tconst migrationAigV1V2: ISchemaMigration<AuditableItemGraphVertexV1, AuditableItemGraphVertex> = {\n\t\tremoveEntityProperty: async (\n\t\t\tentity: AuditableItemGraphVertexV1,\n\t\t\tremovedProperties: IEntitySchemaProperty<AuditableItemGraphVertexV1>[]\n\t\t): Promise<void> => {\n\t\t\t// If the aliasIndex is being removed we should migrate both aliasIndex and resourceTypeIndex\n\t\t\t// to the new index structure.\n\t\t\tif (removedProperties.find(prop => prop.property === \"aliasIndex\") === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\taigIndexEntityStorage ??= EntityStorageConnectorFactory.get<\n\t\t\t\tIEntityStorageConnector<AuditableItemGraphVertexIndex>\n\t\t\t>(StringHelper.kebabCase(nameof<AuditableItemGraphVertexIndex>()));\n\n\t\t\tawait aigIndexEntityStorage.set({\n\t\t\t\tid: Converter.bytesToHex(RandomHelper.generate(16)),\n\t\t\t\tvertexId: entity.id,\n\t\t\t\ttype: \"vertex\",\n\t\t\t\tvalue: entity.id.toLowerCase(),\n\t\t\t\tdateCreated: entity.dateCreated,\n\t\t\t\tdateModified: entity.dateModified ?? entity.dateCreated\n\t\t\t});\n\n\t\t\t// The context ids already contain the correct partition information for the indexes.\n\t\t\tconst aliases: string[] =\n\t\t\t\tentity.aliasIndex\n\t\t\t\t\t?.split(\"||\")\n\t\t\t\t\t.map(alias => alias.trim())\n\t\t\t\t\t.filter(alias => alias.length > 0) ?? [];\n\n\t\t\tfor (const alias of aliases) {\n\t\t\t\tawait aigIndexEntityStorage.set({\n\t\t\t\t\tid: Converter.bytesToHex(RandomHelper.generate(16)),\n\t\t\t\t\tvertexId: entity.id,\n\t\t\t\t\ttype: \"alias\",\n\t\t\t\t\tvalue: alias.toLowerCase(),\n\t\t\t\t\tdateCreated: entity.dateCreated,\n\t\t\t\t\tdateModified: entity.dateModified ?? entity.dateCreated\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst resourceTypes: string[] =\n\t\t\t\tentity.resourceTypeIndex\n\t\t\t\t\t?.split(\"||\")\n\t\t\t\t\t.map(resourceType => resourceType.trim())\n\t\t\t\t\t.filter(resourceType => resourceType.length > 0) ?? [];\n\n\t\t\tfor (const resourceType of resourceTypes) {\n\t\t\t\tawait aigIndexEntityStorage.set({\n\t\t\t\t\tid: Converter.bytesToHex(RandomHelper.generate(16)),\n\t\t\t\t\tvertexId: entity.id,\n\t\t\t\t\ttype: \"resourceType\",\n\t\t\t\t\tvalue: resourceType.toLowerCase(),\n\t\t\t\t\tdateCreated: entity.dateCreated,\n\t\t\t\t\tdateModified: entity.dateModified ?? entity.dateCreated\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\tSchemaMigrationFactory.register(\n\t\t`${nameof<AuditableItemGraphVertex>()}_1_2`,\n\t\t() => migrationAigV1V2 as ISchemaMigration\n\t);\n}\n\n/**\n * Perform migrations for Policy Administration Point indexes.\n */\nfunction migrationPapIndexes(): void {\n\tlet papIndexEntityStorage: IEntityStorageConnector<OdrlPolicyIndex> | undefined;\n\n\tconst migrationPapV0V1: ISchemaMigration<OdrlPolicyV0, OdrlPolicy> = {\n\t\tremoveEntityProperty: async (\n\t\t\tentity: OdrlPolicyV0,\n\t\t\tremovedProperties: IEntitySchemaProperty<OdrlPolicyV0>[]\n\t\t): Promise<void> => {\n\t\t\t// If the assignerIndex is being removed we should migrate all four of the pipe delimited\n\t\t\t// indexes to the new index structure.\n\t\t\tif (removedProperties.find(prop => prop.property === \"assignerIndex\") === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpapIndexEntityStorage ??= EntityStorageConnectorFactory.get<\n\t\t\t\tIEntityStorageConnector<OdrlPolicyIndex>\n\t\t\t>(StringHelper.kebabCase(nameof<OdrlPolicyIndex>()));\n\n\t\t\t// An absent dimension contributes a single undefined value, otherwise it would collapse\n\t\t\t// the combinations to none and the policy would not be indexed at all.\n\t\t\tconst assigners = splitPolicyIndex(entity.assignerIndex);\n\t\t\tconst assignees = splitPolicyIndex(entity.assigneeIndex);\n\t\t\tconst targets = splitPolicyIndex(entity.targetIndex);\n\t\t\tconst actions = splitPolicyIndex(entity.actionIndex);\n\n\t\t\t// The entries are ordered by the creation date, so a policy stored before the date was\n\t\t\t// recorded is given the migration time rather than leaving the column empty.\n\t\t\tconst dateCreated = entity.dateCreated ?? new Date(Date.now()).toISOString();\n\n\t\t\t// One entry per combination of assigner, assignee, target and action, which is what lets\n\t\t\t// a locator covering several of those fields be answered by a single lookup.\n\t\t\tconst entries: OdrlPolicyIndex[] = [];\n\t\t\tfor (const assigner of assigners) {\n\t\t\t\tfor (const assignee of assignees) {\n\t\t\t\t\tfor (const target of targets) {\n\t\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\t\tentries.push({\n\t\t\t\t\t\t\t\tid: Converter.bytesToHex(RandomHelper.generate(16)),\n\t\t\t\t\t\t\t\tpolicyId: entity.id,\n\t\t\t\t\t\t\t\tassigner,\n\t\t\t\t\t\t\t\tassignee,\n\t\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\t\taction,\n\t\t\t\t\t\t\t\tdateCreated\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The context ids already contain the correct partition information for the indexes.\n\t\t\tawait papIndexEntityStorage.setBatch(entries);\n\t\t}\n\t};\n\tSchemaMigrationFactory.register(\n\t\t`${nameof<OdrlPolicy>()}_0_1`,\n\t\t() => migrationPapV0V1 as ISchemaMigration\n\t);\n}\n\n/**\n * Split one of the pipe delimited indexes from a v0 policy into its index dimension values.\n * @param index The pipe delimited index value.\n * @returns The distinct case folded values, or a single undefined when there are none.\n */\nfunction splitPolicyIndex(index: string | undefined): (string | undefined)[] {\n\tconst values: string[] = [];\n\n\tfor (const part of index?.split(\"|\") ?? []) {\n\t\t// Index values are always stored case folded so lookups are case insensitive.\n\t\tconst folded = part.trim().toLowerCase();\n\t\tif (folded.length > 0 && !values.includes(folded)) {\n\t\t\tvalues.push(folded);\n\t\t}\n\t}\n\n\treturn values.length === 0 ? [undefined] : values;\n}\n"]}
package/dist/es/node.js CHANGED
@@ -33,7 +33,7 @@ export async function run(nodeOptions, args) {
33
33
  nodeOptions ??= {};
34
34
  const serverInfo = {
35
35
  name: nodeOptions?.serverName ?? "TWIN Node",
36
- version: nodeOptions?.serverVersion ?? "0.10.0" // x-release-please-version
36
+ version: nodeOptions?.serverVersion ?? "0.10.1-next.2" // x-release-please-version
37
37
  };
38
38
  CLIDisplay.header(serverInfo.name, serverInfo.version, "🌩️ ");
39
39
  if (!Is.stringValue(nodeOptions?.executionDirectory)) {
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport path from \"node:path\";\nimport type { IServerInfo } from \"@twin.org/api-models\";\nimport { CLIDisplay, CLIUtils } from \"@twin.org/cli-core\";\nimport { Coerce, EnvHelper, GeneralError, Guards, I18n, Is } from \"@twin.org/core\";\nimport type { Engine } from \"@twin.org/engine\";\nimport type { EngineServer } from \"@twin.org/engine-server\";\nimport type { IEngineServerConfig } from \"@twin.org/engine-server-types\";\nimport { ModuleHelper } from \"@twin.org/modules\";\nimport * as dotenv from \"dotenv\";\nimport { buildEngineConfiguration } from \"./builders/engineEnvBuilder.js\";\nimport { buildEngineServerConfiguration } from \"./builders/engineServerEnvBuilder.js\";\nimport { extensionsConfiguration } from \"./builders/extensionsBuilder.js\";\nimport { commaSeparatedListToArray } from \"./builders/helper/envHelpers.js\";\nimport { constructCliCommand, parseCommandLineArgs, registerCommands } from \"./cli.js\";\nimport { getEnvDefaults } from \"./defaults.js\";\nimport { BOOTSTRAP_DEV_ENVIRONMENT_VARIABLE_KEYS } from \"./models/bootstrapDevEnvironmentVariableKeys.js\";\nimport { DEPRECATED_ENVIRONMENT_VARIABLE_KEYS } from \"./models/deprecatedEnvironmentVariableKeys.js\";\nimport { ENGINE_ENVIRONMENT_VARIABLE_KEYS } from \"./models/engineEnvironmentVariableKeys.js\";\nimport { ENGINE_SERVER_ENVIRONMENT_VARIABLE_KEYS } from \"./models/engineServerEnvironmentVariableKeys.js\";\nimport type { IEnvironmentVariables } from \"./models/IEnvironmentVariables.js\";\nimport type { INodeEngineConfig } from \"./models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"./models/INodeEngineState.js\";\nimport type { INodeOptions } from \"./models/INodeOptions.js\";\nimport { ModuleProtocol } from \"./models/moduleProtocol.js\";\nimport { NODE_ENVIRONMENT_VARIABLE_KEYS } from \"./models/nodeEnvironmentVariableKeys.js\";\nimport { start } from \"./start.js\";\nimport {\n\tcreateModuleImportUrl,\n\tfileExists,\n\tgetExecutionDirectory,\n\tgetExtensionsCacheDir,\n\tgetScriptDirectory,\n\thandleHttpsProtocol,\n\thandleNpmProtocol,\n\tinitialiseLocales,\n\tloadJsonFile,\n\tloadTextFile,\n\tparseModuleProtocol,\n\tresolvePackageEntryPoint\n} from \"./utils.js\";\n\nconst moduleCache: { [id: string]: unknown } = {};\n\n/**\n * Run the node.\n * @param nodeOptions Optional configuration options for running the server.\n * @param args Optional command line arguments.\n * @returns A promise that resolves when the server is started containing a shutdown method.\n */\nexport async function run(\n\tnodeOptions?: INodeOptions,\n\targs?: string[]\n): Promise<\n\t| {\n\t\t\tengine: Engine<IEngineServerConfig, INodeEngineState>;\n\t\t\tserver: EngineServer;\n\t\t\tshutdown: () => Promise<void>;\n\t }\n\t| undefined\n> {\n\tlet showErrorDetails = true;\n\tlet debugEnabled = true;\n\ttry {\n\t\tnodeOptions ??= {};\n\n\t\tconst serverInfo: IServerInfo = {\n\t\t\tname: nodeOptions?.serverName ?? \"TWIN Node\",\n\t\t\tversion: nodeOptions?.serverVersion ?? \"0.10.0\" // x-release-please-version\n\t\t};\n\n\t\tCLIDisplay.header(serverInfo.name, serverInfo.version, \"🌩️ \");\n\n\t\tif (!Is.stringValue(nodeOptions?.executionDirectory)) {\n\t\t\tnodeOptions.executionDirectory = getExecutionDirectory();\n\t\t}\n\t\tCLIDisplay.value(\"Execution Directory\", nodeOptions.executionDirectory);\n\n\t\tif (!Is.stringValue(nodeOptions?.scriptDirectory)) {\n\t\t\tnodeOptions.scriptDirectory = getScriptDirectory(args);\n\t\t}\n\t\tCLIDisplay.value(\"Script Directory\", nodeOptions.scriptDirectory);\n\n\t\tnodeOptions.localesDirectory =\n\t\t\tnodeOptions?.localesDirectory ??\n\t\t\tpath.resolve(path.join(nodeOptions.scriptDirectory, \"dist\", \"locales\"));\n\n\t\tCLIDisplay.value(\"Locales Directory\", nodeOptions.localesDirectory);\n\t\tawait initialiseLocales(nodeOptions.localesDirectory);\n\n\t\tnodeOptions.envPrefix ??= \"TWIN_\";\n\n\t\toverrideModuleImport(nodeOptions.executionDirectory ?? \"\");\n\n\t\tconst commandLineArgs = parseCommandLineArgs(args);\n\n\t\tconst hasEnvPrefix = commandLineArgs.options?.find(option => option.key === \"env-prefix\");\n\t\tif (hasEnvPrefix) {\n\t\t\tnodeOptions.envPrefix = Coerce.string(hasEnvPrefix.value) ?? nodeOptions.envPrefix;\n\t\t}\n\n\t\tCLIDisplay.value(\"Environment Variable Prefix\", nodeOptions.envPrefix);\n\n\t\t// This is the only location in the code base that should access process.env directly\n\t\t// So we can safely disable the linting rule here.\n\t\tlet finalEnvVars =\n\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\tprocess.env as {\n\t\t\t\t[id: string]: string;\n\t\t\t};\n\n\t\tif (Is.objectValue(nodeOptions?.envVars)) {\n\t\t\tfinalEnvVars = {\n\t\t\t\t...finalEnvVars,\n\t\t\t\t...nodeOptions.envVars\n\t\t\t};\n\t\t}\n\n\t\tfinalEnvVars = {\n\t\t\t...getEnvDefaults(nodeOptions.envPrefix),\n\t\t\t...finalEnvVars\n\t\t};\n\n\t\tlet cliCommand;\n\t\tif (Is.arrayValue(commandLineArgs.options)) {\n\t\t\tregisterCommands();\n\t\t\tcliCommand = constructCliCommand(finalEnvVars, commandLineArgs);\n\t\t}\n\n\t\tif (Is.object(cliCommand)) {\n\t\t\tfinalEnvVars[`${nodeOptions.envPrefix}SILENT`] ??= \"true\";\n\t\t} else {\n\t\t\tif (Is.empty(nodeOptions?.openApiSpecFile)) {\n\t\t\t\tconst specFile = path.resolve(\n\t\t\t\t\tpath.join(nodeOptions.scriptDirectory ?? \"\", \"docs\", \"open-api\", \"spec.json\")\n\t\t\t\t);\n\t\t\t\tif (await fileExists(specFile)) {\n\t\t\t\t\tnodeOptions ??= {};\n\t\t\t\t\tnodeOptions.openApiSpecFile = specFile;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Is.stringValue(nodeOptions.openApiSpecFile)) {\n\t\t\t\tCLIDisplay.value(\"OpenAPI Spec File\", nodeOptions.openApiSpecFile);\n\t\t\t}\n\n\t\t\tif (Is.empty(nodeOptions?.favIconFile)) {\n\t\t\t\tconst favIconFile = path.resolve(\n\t\t\t\t\tpath.join(nodeOptions.scriptDirectory ?? \"\", \"static\", \"favicon.png\")\n\t\t\t\t);\n\t\t\t\tif (await fileExists(favIconFile)) {\n\t\t\t\t\tnodeOptions ??= {};\n\t\t\t\t\tnodeOptions.favIconFile = favIconFile;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Is.stringValue(nodeOptions.favIconFile)) {\n\t\t\t\tCLIDisplay.value(\"Favicon File\", nodeOptions.favIconFile);\n\t\t\t}\n\t\t}\n\n\t\tconst { nodeEngineConfig, nodeEnvVars, availableContextIdKeys } = await buildConfiguration(\n\t\t\tfinalEnvVars,\n\t\t\tnodeOptions,\n\t\t\tserverInfo\n\t\t);\n\n\t\tdebugEnabled = Coerce.boolean(nodeEnvVars.debug) ?? debugEnabled;\n\n\t\tCLIDisplay.break();\n\n\t\tconst startResult = await start(\n\t\t\tnodeOptions,\n\t\t\tnodeEngineConfig,\n\t\t\tnodeEnvVars,\n\t\t\tcliCommand,\n\t\t\tavailableContextIdKeys\n\t\t);\n\n\t\tif (Is.notEmpty(startResult)) {\n\t\t\tshowErrorDetails = false;\n\n\t\t\tlet isShuttingDown = false;\n\t\t\tfor (const signal of [\"SIGHUP\", \"SIGINT\", \"SIGTERM\"]) {\n\t\t\t\tprocess.on(signal, async () => {\n\t\t\t\t\tif (!isShuttingDown) {\n\t\t\t\t\t\tisShuttingDown = true;\n\t\t\t\t\t\tCLIDisplay.value(\"Terminate Signal\", signal);\n\t\t\t\t\t\tawait startResult.shutdown();\n\t\t\t\t\t\tprocess.exit(0);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn startResult;\n\t} catch (err) {\n\t\tif (nodeOptions?.disableProcessExitOnFailure ?? false) {\n\t\t\tthrow err;\n\t\t}\n\n\t\tif (showErrorDetails) {\n\t\t\tCLIDisplay.error(err, true, { includeAdditional: true, includeStack: debugEnabled });\n\t\t}\n\n\t\t// eslint-disable-next-line unicorn/no-process-exit\n\t\tprocess.exit(1);\n\t}\n}\n\n/**\n * Test whether a camelCase key matches an entry in a pattern set.\n * Entries ending with \"*\" are treated as prefix patterns; all others require an exact match.\n * @param camelKey The camelCase key to test.\n * @param patternSet The set of exact keys and/or wildcard patterns (e.g. \"restPath*\").\n * @returns True if the key matches any entry.\n */\nfunction matchesPatternSet(\n\tcamelKey: string,\n\tpatternSet: ReadonlySet<string> | Set<string>\n): boolean {\n\tif (patternSet.has(camelKey)) {\n\t\treturn true;\n\t}\n\tfor (const pattern of patternSet) {\n\t\tif (pattern.endsWith(\"*\") && camelKey.startsWith(pattern.slice(0, -1))) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Report any environment variables which are still recognised but no longer used.\n * @param envVars The already-converted camelCase env variables.\n * @param prefix The prefix used for the environment variables (e.g. \"TWIN_\").\n */\nfunction warnDeprecatedEnvVarKeys(\n\tenvVars: { [id: string]: string | unknown },\n\tprefix: string\n): void {\n\tfor (const camelKey of Object.keys(envVars)) {\n\t\tconst replacements = DEPRECATED_ENVIRONMENT_VARIABLE_KEYS.get(camelKey);\n\t\tif (!Is.undefined(replacements)) {\n\t\t\tconst key = EnvHelper.jsonKeyToEnvVarKey(camelKey, prefix);\n\n\t\t\tif (Is.arrayValue(replacements)) {\n\t\t\t\tCLIDisplay.warning(\n\t\t\t\t\tI18n.formatMessage(\"warn.node.deprecatedEnvVar\", {\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\treplacements: replacements\n\t\t\t\t\t\t\t.map(replacement => EnvHelper.jsonKeyToEnvVarKey(replacement, prefix))\n\t\t\t\t\t\t\t.join(\", \")\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tCLIDisplay.warning(I18n.formatMessage(\"warn.node.deprecatedEnvVarNoReplacement\", { key }));\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Validate that every key in envVars maps to a recognised property.\n * All unknown keys are collected, then reported together as a single error or warning.\n * Raw env var names listed in the allow list (e.g. TWIN_MY_EXTENSION_SECRET, TWIN_REST_PATH_*) are always accepted.\n * Wildcard patterns ending with * are supported in both allow sets and the allow list.\n * @param envVars The already-converted camelCase env variables.\n * @param prefix The prefix used for the environment variables (e.g. \"TWIN_\").\n * @param allowSets An array of sets of allowed keys and/or wildcard patterns.\n * @throws GeneralError If any unknown env var properties are found and strict mode is \"error\", or if the strict mode value is invalid.\n */\nfunction validateEnvVarKeys(\n\tenvVars: { [id: string]: string | unknown },\n\tprefix: string,\n\tallowSets: ReadonlySet<string>[]\n): void {\n\tconst mode = Is.stringValue(envVars.strictEnv) ? envVars.strictEnv : \"error\";\n\tGuards.arrayOneOf(\"node\", `${prefix}STRICT_ENV`, mode, [\"error\", \"warn\", \"ignore\"]);\n\n\tif (mode === \"ignore\") {\n\t\treturn;\n\t}\n\n\tconst customSet = new Set(\n\t\tcommaSeparatedListToArray<string>(envVars.envAllowList as string).map(k =>\n\t\t\tEnvHelper.envVarKeyToJsonKey(k.trim(), prefix)\n\t\t)\n\t);\n\n\tconst unknown = Object.keys(envVars)\n\t\t.filter(\n\t\t\tcamelKey =>\n\t\t\t\t!allowSets.some(set => matchesPatternSet(camelKey, set)) &&\n\t\t\t\t!matchesPatternSet(camelKey, customSet) &&\n\t\t\t\t!DEPRECATED_ENVIRONMENT_VARIABLE_KEYS.has(camelKey)\n\t\t)\n\t\t.map(camelKey => EnvHelper.jsonKeyToEnvVarKey(camelKey, prefix));\n\n\tif (unknown.length > 0) {\n\t\tif (mode === \"error\") {\n\t\t\tthrow new GeneralError(\"node\", \"unknownEnvVars\", { keys: unknown.join(\", \"), prefix });\n\t\t}\n\t\tCLIDisplay.warning(\n\t\t\tI18n.formatMessage(\"warn.node.unknownEnvVars\", { keys: unknown.join(\", \"), prefix })\n\t\t);\n\t}\n}\n\n/**\n * Build the configuration for the TWIN Node.\n * @param processEnv The environment variables from the process.\n * @param options The options for running the server.\n * @param serverInfo The server information.\n * @returns A promise that resolves to the engine server configuration, environment prefix, environment variables,\n * and options.\n */\nexport async function buildConfiguration(\n\tprocessEnv: {\n\t\t[id: string]: string;\n\t},\n\toptions: INodeOptions,\n\tserverInfo: IServerInfo\n): Promise<{\n\tnodeEnvVars: IEnvironmentVariables & { [id: string]: string | unknown };\n\tnodeEngineConfig: INodeEngineConfig;\n\tavailableContextIdKeys: { key: string; requiredHandlerFeatures: string[] }[];\n}> {\n\tconst availableContextIdKeys: { key: string; requiredHandlerFeatures: string[] }[] = [];\n\n\tlet defaultEnvOnly = false;\n\tif (Is.empty(options?.envFilenames)) {\n\t\tconst envFile = path.resolve(path.join(options.executionDirectory ?? \"\", \".env\"));\n\t\tCLIDisplay.value(\"Default Environment File\", envFile);\n\t\toptions ??= {};\n\t\toptions.envFilenames = [envFile];\n\t\tdefaultEnvOnly = true;\n\t}\n\n\tif (Is.arrayValue(options?.envFilenames)) {\n\t\tconst output = dotenv.config({\n\t\t\tpath: options?.envFilenames,\n\t\t\tquiet: true\n\t\t});\n\n\t\t// We don't want to throw an error if the default environment file is not found.\n\t\t// Only if we have custom environment files.\n\t\tif (!defaultEnvOnly && output.error) {\n\t\t\tthrow output.error;\n\t\t}\n\n\t\tif (Is.objectValue(output.parsed)) {\n\t\t\tfor (const [key, value] of Object.entries(output.parsed)) {\n\t\t\t\t// Only set environment variables that are not already set in\n\t\t\t\t// the process environment or provided via options.envVars\n\t\t\t\tprocessEnv[key] ??= value;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst envVars = EnvHelper.envToJson<{ [id: string]: string | unknown }>(\n\t\tprocessEnv,\n\t\toptions.envPrefix ?? \"\"\n\t);\n\n\twarnDeprecatedEnvVarKeys(envVars, options.envPrefix ?? \"\");\n\n\tvalidateEnvVarKeys(envVars, options.envPrefix ?? \"\", [\n\t\tENGINE_ENVIRONMENT_VARIABLE_KEYS,\n\t\tENGINE_SERVER_ENVIRONMENT_VARIABLE_KEYS,\n\t\tNODE_ENVIRONMENT_VARIABLE_KEYS,\n\t\tBOOTSTRAP_DEV_ENVIRONMENT_VARIABLE_KEYS\n\t]);\n\n\t// Expand any environment variables that use the @file: syntax\n\tconst keys = Object.keys(envVars);\n\tfor (const key of keys) {\n\t\tif (\n\t\t\tIs.stringValue(envVars[key]) &&\n\t\t\t(envVars[key].startsWith(\"@text:\") || envVars[key].startsWith(\"@json:\"))\n\t\t) {\n\t\t\tconst filePath = envVars[key].slice(6).trim();\n\t\t\tconst embeddedFile = path.resolve(path.join(options.executionDirectory ?? \"\", filePath));\n\n\t\t\tif (envVars[key].startsWith(\"@text:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from text file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadTextFile(embeddedFile);\n\t\t\t} else if (envVars[key].startsWith(\"@json:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from JSON file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadJsonFile(embeddedFile);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Extend the environment variables with any additional custom configuration.\n\tif (Is.function(options?.extendEnvVars)) {\n\t\tCLIDisplay.task(\"Extending Environment Variables\");\n\t\tawait options.extendEnvVars(envVars);\n\t}\n\n\t// Build the engine configuration from the environment variables.\n\tconst coreConfig = await buildEngineConfiguration(envVars);\n\tconst engineServerConfig = await buildEngineServerConfiguration(\n\t\tenvVars,\n\t\tavailableContextIdKeys,\n\t\tcoreConfig,\n\t\tserverInfo,\n\t\toptions?.openApiSpecFile,\n\t\toptions?.favIconFile\n\t);\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.arrayValue(options?.configFilenames)) {\n\t\tfor (const configFile of options.configFilenames) {\n\t\t\tCLIDisplay.value(\"Loading Configuration File\", configFile);\n\t\t\tconst configFilePath = path.resolve(path.join(options.executionDirectory ?? \"\", configFile));\n\t\t\tconst config = await loadJsonFile(configFilePath);\n\t\t\tObject.assign(engineServerConfig, config);\n\t\t}\n\t}\n\n\tif (Is.objectValue(options?.config)) {\n\t\tCLIDisplay.task(\"Merging Custom Configuration\");\n\t\tObject.assign(engineServerConfig, options.config);\n\t}\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.function(options?.extendConfig)) {\n\t\tCLIDisplay.task(\"Extending Configuration\");\n\t\tawait options.extendConfig(envVars, engineServerConfig);\n\t}\n\n\tconst nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);\n\n\treturn { nodeEngineConfig, nodeEnvVars: envVars, availableContextIdKeys };\n}\n\n/**\n * Override module imports to support protocol-based loading (npm:, https:) and local files.\n * @param executionDirectory The execution directory for resolving local module paths.\n * @param envVars The environment variables containing extension configuration (optional, uses defaults if not provided).\n */\nexport function overrideModuleImport(\n\texecutionDirectory: string,\n\tenvVars?: IEnvironmentVariables\n): void {\n\tconst maxSizeMb = Coerce.number(envVars?.extensionsMaxSizeMb) ?? 10;\n\tconst cacheDirectory = envVars?.extensionsCacheDirectory;\n\n\tModuleHelper.overrideImport(async moduleName => {\n\t\tif (moduleCache[moduleName]) {\n\t\t\treturn {\n\t\t\t\tmodule: moduleCache[moduleName],\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\tconst parsed = parseModuleProtocol(moduleName);\n\t\tlet resolvedPath: string | undefined;\n\n\t\tswitch (parsed.protocol) {\n\t\t\tcase ModuleProtocol.Npm: {\n\t\t\t\tconst result = await handleNpmProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tcacheDirectory\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Https: {\n\t\t\t\tconst result = await handleHttpsProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tmaxSizeMb,\n\t\t\t\t\tcacheDirectory,\n\t\t\t\t\tenvVars?.extensionsCacheTtlHours,\n\t\t\t\t\tenvVars?.extensionsForceRefresh\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Http: {\n\t\t\t\tthrow new GeneralError(\"node\", \"insecureProtocol\", { protocol: ModuleProtocol.Http });\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Local: {\n\t\t\t\tlet localFilename = path.resolve(moduleName);\n\n\t\t\t\tlet exists = await fileExists(localFilename);\n\t\t\t\tif (!exists) {\n\t\t\t\t\tlocalFilename = path.resolve(executionDirectory, moduleName);\n\t\t\t\t\texists = await fileExists(localFilename);\n\t\t\t\t}\n\n\t\t\t\tif (exists) {\n\t\t\t\t\tresolvedPath = localFilename;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Default: {\n\t\t\t\ttry {\n\t\t\t\t\tconst packagePath = await CLIUtils.findPackageRoot(moduleName, executionDirectory);\n\t\t\t\t\tif (Is.stringValue(packagePath)) {\n\t\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\t\tif (exists) {\n\t\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Continue to fallback resolution\n\t\t\t\t}\n\n\t\t\t\t// Fallback: resolve from npm protocol cache directory (installed via handleNpmProtocol)\n\t\t\t\ttry {\n\t\t\t\t\tconst cacheNpmRoot = path.resolve(\n\t\t\t\t\t\tgetExtensionsCacheDir(executionDirectory, ModuleProtocol.Npm, cacheDirectory),\n\t\t\t\t\t\t\"node_modules\"\n\t\t\t\t\t);\n\n\t\t\t\t\tconst packagePath = path.resolve(cacheNpmRoot, moduleName);\n\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// No cached resolution either; fall through\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Common module loading and caching logic\n\t\tif (resolvedPath) {\n\t\t\tconst module = await import(createModuleImportUrl(resolvedPath));\n\t\t\tmoduleCache[moduleName] = module;\n\t\t\treturn {\n\t\t\t\tmodule,\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: undefined,\n\t\t\tuseDefault: true\n\t\t};\n\t});\n}\n"]}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport path from \"node:path\";\nimport type { IServerInfo } from \"@twin.org/api-models\";\nimport { CLIDisplay, CLIUtils } from \"@twin.org/cli-core\";\nimport { Coerce, EnvHelper, GeneralError, Guards, I18n, Is } from \"@twin.org/core\";\nimport type { Engine } from \"@twin.org/engine\";\nimport type { EngineServer } from \"@twin.org/engine-server\";\nimport type { IEngineServerConfig } from \"@twin.org/engine-server-types\";\nimport { ModuleHelper } from \"@twin.org/modules\";\nimport * as dotenv from \"dotenv\";\nimport { buildEngineConfiguration } from \"./builders/engineEnvBuilder.js\";\nimport { buildEngineServerConfiguration } from \"./builders/engineServerEnvBuilder.js\";\nimport { extensionsConfiguration } from \"./builders/extensionsBuilder.js\";\nimport { commaSeparatedListToArray } from \"./builders/helper/envHelpers.js\";\nimport { constructCliCommand, parseCommandLineArgs, registerCommands } from \"./cli.js\";\nimport { getEnvDefaults } from \"./defaults.js\";\nimport { BOOTSTRAP_DEV_ENVIRONMENT_VARIABLE_KEYS } from \"./models/bootstrapDevEnvironmentVariableKeys.js\";\nimport { DEPRECATED_ENVIRONMENT_VARIABLE_KEYS } from \"./models/deprecatedEnvironmentVariableKeys.js\";\nimport { ENGINE_ENVIRONMENT_VARIABLE_KEYS } from \"./models/engineEnvironmentVariableKeys.js\";\nimport { ENGINE_SERVER_ENVIRONMENT_VARIABLE_KEYS } from \"./models/engineServerEnvironmentVariableKeys.js\";\nimport type { IEnvironmentVariables } from \"./models/IEnvironmentVariables.js\";\nimport type { INodeEngineConfig } from \"./models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"./models/INodeEngineState.js\";\nimport type { INodeOptions } from \"./models/INodeOptions.js\";\nimport { ModuleProtocol } from \"./models/moduleProtocol.js\";\nimport { NODE_ENVIRONMENT_VARIABLE_KEYS } from \"./models/nodeEnvironmentVariableKeys.js\";\nimport { start } from \"./start.js\";\nimport {\n\tcreateModuleImportUrl,\n\tfileExists,\n\tgetExecutionDirectory,\n\tgetExtensionsCacheDir,\n\tgetScriptDirectory,\n\thandleHttpsProtocol,\n\thandleNpmProtocol,\n\tinitialiseLocales,\n\tloadJsonFile,\n\tloadTextFile,\n\tparseModuleProtocol,\n\tresolvePackageEntryPoint\n} from \"./utils.js\";\n\nconst moduleCache: { [id: string]: unknown } = {};\n\n/**\n * Run the node.\n * @param nodeOptions Optional configuration options for running the server.\n * @param args Optional command line arguments.\n * @returns A promise that resolves when the server is started containing a shutdown method.\n */\nexport async function run(\n\tnodeOptions?: INodeOptions,\n\targs?: string[]\n): Promise<\n\t| {\n\t\t\tengine: Engine<IEngineServerConfig, INodeEngineState>;\n\t\t\tserver: EngineServer;\n\t\t\tshutdown: () => Promise<void>;\n\t }\n\t| undefined\n> {\n\tlet showErrorDetails = true;\n\tlet debugEnabled = true;\n\ttry {\n\t\tnodeOptions ??= {};\n\n\t\tconst serverInfo: IServerInfo = {\n\t\t\tname: nodeOptions?.serverName ?? \"TWIN Node\",\n\t\t\tversion: nodeOptions?.serverVersion ?? \"0.10.1-next.2\" // x-release-please-version\n\t\t};\n\n\t\tCLIDisplay.header(serverInfo.name, serverInfo.version, \"🌩️ \");\n\n\t\tif (!Is.stringValue(nodeOptions?.executionDirectory)) {\n\t\t\tnodeOptions.executionDirectory = getExecutionDirectory();\n\t\t}\n\t\tCLIDisplay.value(\"Execution Directory\", nodeOptions.executionDirectory);\n\n\t\tif (!Is.stringValue(nodeOptions?.scriptDirectory)) {\n\t\t\tnodeOptions.scriptDirectory = getScriptDirectory(args);\n\t\t}\n\t\tCLIDisplay.value(\"Script Directory\", nodeOptions.scriptDirectory);\n\n\t\tnodeOptions.localesDirectory =\n\t\t\tnodeOptions?.localesDirectory ??\n\t\t\tpath.resolve(path.join(nodeOptions.scriptDirectory, \"dist\", \"locales\"));\n\n\t\tCLIDisplay.value(\"Locales Directory\", nodeOptions.localesDirectory);\n\t\tawait initialiseLocales(nodeOptions.localesDirectory);\n\n\t\tnodeOptions.envPrefix ??= \"TWIN_\";\n\n\t\toverrideModuleImport(nodeOptions.executionDirectory ?? \"\");\n\n\t\tconst commandLineArgs = parseCommandLineArgs(args);\n\n\t\tconst hasEnvPrefix = commandLineArgs.options?.find(option => option.key === \"env-prefix\");\n\t\tif (hasEnvPrefix) {\n\t\t\tnodeOptions.envPrefix = Coerce.string(hasEnvPrefix.value) ?? nodeOptions.envPrefix;\n\t\t}\n\n\t\tCLIDisplay.value(\"Environment Variable Prefix\", nodeOptions.envPrefix);\n\n\t\t// This is the only location in the code base that should access process.env directly\n\t\t// So we can safely disable the linting rule here.\n\t\tlet finalEnvVars =\n\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\tprocess.env as {\n\t\t\t\t[id: string]: string;\n\t\t\t};\n\n\t\tif (Is.objectValue(nodeOptions?.envVars)) {\n\t\t\tfinalEnvVars = {\n\t\t\t\t...finalEnvVars,\n\t\t\t\t...nodeOptions.envVars\n\t\t\t};\n\t\t}\n\n\t\tfinalEnvVars = {\n\t\t\t...getEnvDefaults(nodeOptions.envPrefix),\n\t\t\t...finalEnvVars\n\t\t};\n\n\t\tlet cliCommand;\n\t\tif (Is.arrayValue(commandLineArgs.options)) {\n\t\t\tregisterCommands();\n\t\t\tcliCommand = constructCliCommand(finalEnvVars, commandLineArgs);\n\t\t}\n\n\t\tif (Is.object(cliCommand)) {\n\t\t\tfinalEnvVars[`${nodeOptions.envPrefix}SILENT`] ??= \"true\";\n\t\t} else {\n\t\t\tif (Is.empty(nodeOptions?.openApiSpecFile)) {\n\t\t\t\tconst specFile = path.resolve(\n\t\t\t\t\tpath.join(nodeOptions.scriptDirectory ?? \"\", \"docs\", \"open-api\", \"spec.json\")\n\t\t\t\t);\n\t\t\t\tif (await fileExists(specFile)) {\n\t\t\t\t\tnodeOptions ??= {};\n\t\t\t\t\tnodeOptions.openApiSpecFile = specFile;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Is.stringValue(nodeOptions.openApiSpecFile)) {\n\t\t\t\tCLIDisplay.value(\"OpenAPI Spec File\", nodeOptions.openApiSpecFile);\n\t\t\t}\n\n\t\t\tif (Is.empty(nodeOptions?.favIconFile)) {\n\t\t\t\tconst favIconFile = path.resolve(\n\t\t\t\t\tpath.join(nodeOptions.scriptDirectory ?? \"\", \"static\", \"favicon.png\")\n\t\t\t\t);\n\t\t\t\tif (await fileExists(favIconFile)) {\n\t\t\t\t\tnodeOptions ??= {};\n\t\t\t\t\tnodeOptions.favIconFile = favIconFile;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Is.stringValue(nodeOptions.favIconFile)) {\n\t\t\t\tCLIDisplay.value(\"Favicon File\", nodeOptions.favIconFile);\n\t\t\t}\n\t\t}\n\n\t\tconst { nodeEngineConfig, nodeEnvVars, availableContextIdKeys } = await buildConfiguration(\n\t\t\tfinalEnvVars,\n\t\t\tnodeOptions,\n\t\t\tserverInfo\n\t\t);\n\n\t\tdebugEnabled = Coerce.boolean(nodeEnvVars.debug) ?? debugEnabled;\n\n\t\tCLIDisplay.break();\n\n\t\tconst startResult = await start(\n\t\t\tnodeOptions,\n\t\t\tnodeEngineConfig,\n\t\t\tnodeEnvVars,\n\t\t\tcliCommand,\n\t\t\tavailableContextIdKeys\n\t\t);\n\n\t\tif (Is.notEmpty(startResult)) {\n\t\t\tshowErrorDetails = false;\n\n\t\t\tlet isShuttingDown = false;\n\t\t\tfor (const signal of [\"SIGHUP\", \"SIGINT\", \"SIGTERM\"]) {\n\t\t\t\tprocess.on(signal, async () => {\n\t\t\t\t\tif (!isShuttingDown) {\n\t\t\t\t\t\tisShuttingDown = true;\n\t\t\t\t\t\tCLIDisplay.value(\"Terminate Signal\", signal);\n\t\t\t\t\t\tawait startResult.shutdown();\n\t\t\t\t\t\tprocess.exit(0);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn startResult;\n\t} catch (err) {\n\t\tif (nodeOptions?.disableProcessExitOnFailure ?? false) {\n\t\t\tthrow err;\n\t\t}\n\n\t\tif (showErrorDetails) {\n\t\t\tCLIDisplay.error(err, true, { includeAdditional: true, includeStack: debugEnabled });\n\t\t}\n\n\t\t// eslint-disable-next-line unicorn/no-process-exit\n\t\tprocess.exit(1);\n\t}\n}\n\n/**\n * Test whether a camelCase key matches an entry in a pattern set.\n * Entries ending with \"*\" are treated as prefix patterns; all others require an exact match.\n * @param camelKey The camelCase key to test.\n * @param patternSet The set of exact keys and/or wildcard patterns (e.g. \"restPath*\").\n * @returns True if the key matches any entry.\n */\nfunction matchesPatternSet(\n\tcamelKey: string,\n\tpatternSet: ReadonlySet<string> | Set<string>\n): boolean {\n\tif (patternSet.has(camelKey)) {\n\t\treturn true;\n\t}\n\tfor (const pattern of patternSet) {\n\t\tif (pattern.endsWith(\"*\") && camelKey.startsWith(pattern.slice(0, -1))) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Report any environment variables which are still recognised but no longer used.\n * @param envVars The already-converted camelCase env variables.\n * @param prefix The prefix used for the environment variables (e.g. \"TWIN_\").\n */\nfunction warnDeprecatedEnvVarKeys(\n\tenvVars: { [id: string]: string | unknown },\n\tprefix: string\n): void {\n\tfor (const camelKey of Object.keys(envVars)) {\n\t\tconst replacements = DEPRECATED_ENVIRONMENT_VARIABLE_KEYS.get(camelKey);\n\t\tif (!Is.undefined(replacements)) {\n\t\t\tconst key = EnvHelper.jsonKeyToEnvVarKey(camelKey, prefix);\n\n\t\t\tif (Is.arrayValue(replacements)) {\n\t\t\t\tCLIDisplay.warning(\n\t\t\t\t\tI18n.formatMessage(\"warn.node.deprecatedEnvVar\", {\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\treplacements: replacements\n\t\t\t\t\t\t\t.map(replacement => EnvHelper.jsonKeyToEnvVarKey(replacement, prefix))\n\t\t\t\t\t\t\t.join(\", \")\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tCLIDisplay.warning(I18n.formatMessage(\"warn.node.deprecatedEnvVarNoReplacement\", { key }));\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Validate that every key in envVars maps to a recognised property.\n * All unknown keys are collected, then reported together as a single error or warning.\n * Raw env var names listed in the allow list (e.g. TWIN_MY_EXTENSION_SECRET, TWIN_REST_PATH_*) are always accepted.\n * Wildcard patterns ending with * are supported in both allow sets and the allow list.\n * @param envVars The already-converted camelCase env variables.\n * @param prefix The prefix used for the environment variables (e.g. \"TWIN_\").\n * @param allowSets An array of sets of allowed keys and/or wildcard patterns.\n * @throws GeneralError If any unknown env var properties are found and strict mode is \"error\", or if the strict mode value is invalid.\n */\nfunction validateEnvVarKeys(\n\tenvVars: { [id: string]: string | unknown },\n\tprefix: string,\n\tallowSets: ReadonlySet<string>[]\n): void {\n\tconst mode = Is.stringValue(envVars.strictEnv) ? envVars.strictEnv : \"error\";\n\tGuards.arrayOneOf(\"node\", `${prefix}STRICT_ENV`, mode, [\"error\", \"warn\", \"ignore\"]);\n\n\tif (mode === \"ignore\") {\n\t\treturn;\n\t}\n\n\tconst customSet = new Set(\n\t\tcommaSeparatedListToArray<string>(envVars.envAllowList as string).map(k =>\n\t\t\tEnvHelper.envVarKeyToJsonKey(k.trim(), prefix)\n\t\t)\n\t);\n\n\tconst unknown = Object.keys(envVars)\n\t\t.filter(\n\t\t\tcamelKey =>\n\t\t\t\t!allowSets.some(set => matchesPatternSet(camelKey, set)) &&\n\t\t\t\t!matchesPatternSet(camelKey, customSet) &&\n\t\t\t\t!DEPRECATED_ENVIRONMENT_VARIABLE_KEYS.has(camelKey)\n\t\t)\n\t\t.map(camelKey => EnvHelper.jsonKeyToEnvVarKey(camelKey, prefix));\n\n\tif (unknown.length > 0) {\n\t\tif (mode === \"error\") {\n\t\t\tthrow new GeneralError(\"node\", \"unknownEnvVars\", { keys: unknown.join(\", \"), prefix });\n\t\t}\n\t\tCLIDisplay.warning(\n\t\t\tI18n.formatMessage(\"warn.node.unknownEnvVars\", { keys: unknown.join(\", \"), prefix })\n\t\t);\n\t}\n}\n\n/**\n * Build the configuration for the TWIN Node.\n * @param processEnv The environment variables from the process.\n * @param options The options for running the server.\n * @param serverInfo The server information.\n * @returns A promise that resolves to the engine server configuration, environment prefix, environment variables,\n * and options.\n */\nexport async function buildConfiguration(\n\tprocessEnv: {\n\t\t[id: string]: string;\n\t},\n\toptions: INodeOptions,\n\tserverInfo: IServerInfo\n): Promise<{\n\tnodeEnvVars: IEnvironmentVariables & { [id: string]: string | unknown };\n\tnodeEngineConfig: INodeEngineConfig;\n\tavailableContextIdKeys: { key: string; requiredHandlerFeatures: string[] }[];\n}> {\n\tconst availableContextIdKeys: { key: string; requiredHandlerFeatures: string[] }[] = [];\n\n\tlet defaultEnvOnly = false;\n\tif (Is.empty(options?.envFilenames)) {\n\t\tconst envFile = path.resolve(path.join(options.executionDirectory ?? \"\", \".env\"));\n\t\tCLIDisplay.value(\"Default Environment File\", envFile);\n\t\toptions ??= {};\n\t\toptions.envFilenames = [envFile];\n\t\tdefaultEnvOnly = true;\n\t}\n\n\tif (Is.arrayValue(options?.envFilenames)) {\n\t\tconst output = dotenv.config({\n\t\t\tpath: options?.envFilenames,\n\t\t\tquiet: true\n\t\t});\n\n\t\t// We don't want to throw an error if the default environment file is not found.\n\t\t// Only if we have custom environment files.\n\t\tif (!defaultEnvOnly && output.error) {\n\t\t\tthrow output.error;\n\t\t}\n\n\t\tif (Is.objectValue(output.parsed)) {\n\t\t\tfor (const [key, value] of Object.entries(output.parsed)) {\n\t\t\t\t// Only set environment variables that are not already set in\n\t\t\t\t// the process environment or provided via options.envVars\n\t\t\t\tprocessEnv[key] ??= value;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst envVars = EnvHelper.envToJson<{ [id: string]: string | unknown }>(\n\t\tprocessEnv,\n\t\toptions.envPrefix ?? \"\"\n\t);\n\n\twarnDeprecatedEnvVarKeys(envVars, options.envPrefix ?? \"\");\n\n\tvalidateEnvVarKeys(envVars, options.envPrefix ?? \"\", [\n\t\tENGINE_ENVIRONMENT_VARIABLE_KEYS,\n\t\tENGINE_SERVER_ENVIRONMENT_VARIABLE_KEYS,\n\t\tNODE_ENVIRONMENT_VARIABLE_KEYS,\n\t\tBOOTSTRAP_DEV_ENVIRONMENT_VARIABLE_KEYS\n\t]);\n\n\t// Expand any environment variables that use the @file: syntax\n\tconst keys = Object.keys(envVars);\n\tfor (const key of keys) {\n\t\tif (\n\t\t\tIs.stringValue(envVars[key]) &&\n\t\t\t(envVars[key].startsWith(\"@text:\") || envVars[key].startsWith(\"@json:\"))\n\t\t) {\n\t\t\tconst filePath = envVars[key].slice(6).trim();\n\t\t\tconst embeddedFile = path.resolve(path.join(options.executionDirectory ?? \"\", filePath));\n\n\t\t\tif (envVars[key].startsWith(\"@text:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from text file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadTextFile(embeddedFile);\n\t\t\t} else if (envVars[key].startsWith(\"@json:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from JSON file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadJsonFile(embeddedFile);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Extend the environment variables with any additional custom configuration.\n\tif (Is.function(options?.extendEnvVars)) {\n\t\tCLIDisplay.task(\"Extending Environment Variables\");\n\t\tawait options.extendEnvVars(envVars);\n\t}\n\n\t// Build the engine configuration from the environment variables.\n\tconst coreConfig = await buildEngineConfiguration(envVars);\n\tconst engineServerConfig = await buildEngineServerConfiguration(\n\t\tenvVars,\n\t\tavailableContextIdKeys,\n\t\tcoreConfig,\n\t\tserverInfo,\n\t\toptions?.openApiSpecFile,\n\t\toptions?.favIconFile\n\t);\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.arrayValue(options?.configFilenames)) {\n\t\tfor (const configFile of options.configFilenames) {\n\t\t\tCLIDisplay.value(\"Loading Configuration File\", configFile);\n\t\t\tconst configFilePath = path.resolve(path.join(options.executionDirectory ?? \"\", configFile));\n\t\t\tconst config = await loadJsonFile(configFilePath);\n\t\t\tObject.assign(engineServerConfig, config);\n\t\t}\n\t}\n\n\tif (Is.objectValue(options?.config)) {\n\t\tCLIDisplay.task(\"Merging Custom Configuration\");\n\t\tObject.assign(engineServerConfig, options.config);\n\t}\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.function(options?.extendConfig)) {\n\t\tCLIDisplay.task(\"Extending Configuration\");\n\t\tawait options.extendConfig(envVars, engineServerConfig);\n\t}\n\n\tconst nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);\n\n\treturn { nodeEngineConfig, nodeEnvVars: envVars, availableContextIdKeys };\n}\n\n/**\n * Override module imports to support protocol-based loading (npm:, https:) and local files.\n * @param executionDirectory The execution directory for resolving local module paths.\n * @param envVars The environment variables containing extension configuration (optional, uses defaults if not provided).\n */\nexport function overrideModuleImport(\n\texecutionDirectory: string,\n\tenvVars?: IEnvironmentVariables\n): void {\n\tconst maxSizeMb = Coerce.number(envVars?.extensionsMaxSizeMb) ?? 10;\n\tconst cacheDirectory = envVars?.extensionsCacheDirectory;\n\n\tModuleHelper.overrideImport(async moduleName => {\n\t\tif (moduleCache[moduleName]) {\n\t\t\treturn {\n\t\t\t\tmodule: moduleCache[moduleName],\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\tconst parsed = parseModuleProtocol(moduleName);\n\t\tlet resolvedPath: string | undefined;\n\n\t\tswitch (parsed.protocol) {\n\t\t\tcase ModuleProtocol.Npm: {\n\t\t\t\tconst result = await handleNpmProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tcacheDirectory\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Https: {\n\t\t\t\tconst result = await handleHttpsProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tmaxSizeMb,\n\t\t\t\t\tcacheDirectory,\n\t\t\t\t\tenvVars?.extensionsCacheTtlHours,\n\t\t\t\t\tenvVars?.extensionsForceRefresh\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Http: {\n\t\t\t\tthrow new GeneralError(\"node\", \"insecureProtocol\", { protocol: ModuleProtocol.Http });\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Local: {\n\t\t\t\tlet localFilename = path.resolve(moduleName);\n\n\t\t\t\tlet exists = await fileExists(localFilename);\n\t\t\t\tif (!exists) {\n\t\t\t\t\tlocalFilename = path.resolve(executionDirectory, moduleName);\n\t\t\t\t\texists = await fileExists(localFilename);\n\t\t\t\t}\n\n\t\t\t\tif (exists) {\n\t\t\t\t\tresolvedPath = localFilename;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Default: {\n\t\t\t\ttry {\n\t\t\t\t\tconst packagePath = await CLIUtils.findPackageRoot(moduleName, executionDirectory);\n\t\t\t\t\tif (Is.stringValue(packagePath)) {\n\t\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\t\tif (exists) {\n\t\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Continue to fallback resolution\n\t\t\t\t}\n\n\t\t\t\t// Fallback: resolve from npm protocol cache directory (installed via handleNpmProtocol)\n\t\t\t\ttry {\n\t\t\t\t\tconst cacheNpmRoot = path.resolve(\n\t\t\t\t\t\tgetExtensionsCacheDir(executionDirectory, ModuleProtocol.Npm, cacheDirectory),\n\t\t\t\t\t\t\"node_modules\"\n\t\t\t\t\t);\n\n\t\t\t\t\tconst packagePath = path.resolve(cacheNpmRoot, moduleName);\n\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// No cached resolution either; fall through\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Common module loading and caching logic\n\t\tif (resolvedPath) {\n\t\t\tconst module = await import(createModuleImportUrl(resolvedPath));\n\t\t\tmoduleCache[moduleName] = module;\n\t\t\treturn {\n\t\t\t\tmodule,\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: undefined,\n\t\t\tuseDefault: true\n\t\t};\n\t});\n}\n"]}
package/dist/es/start.js CHANGED
@@ -7,6 +7,7 @@ import { EngineServer } from "@twin.org/engine-server";
7
7
  import { BlobStorageConnectorType, EntityStorageConnectorType } from "@twin.org/engine-types";
8
8
  import { extensionsInitialiseEngine, extensionsInitialiseEngineServer, shutdownExtensions } from "./builders/extensionsBuilder.js";
9
9
  import { commaSeparatedListToArray } from "./builders/helper/envHelpers.js";
10
+ import { finalizeMigrations, initialiseMigrations } from "./builders/helper/migrationHelper.js";
10
11
  import { executeCommand } from "./cli.js";
11
12
  /**
12
13
  * Start the engine server.
@@ -72,8 +73,10 @@ export async function start(nodeOptions, nodeEngineConfig, envVars, cliCommand,
72
73
  }
73
74
  else {
74
75
  try {
76
+ initialiseMigrations(engine, envVars);
75
77
  // Start the server, which also starts the engine.
76
78
  await server.start();
79
+ await finalizeMigrations(engine, envVars);
77
80
  return {
78
81
  engine,
79
82
  server,
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/start.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenantAdminComponent } from \"@twin.org/api-models\";\nimport { ContextIdKeys, ContextIdStore } from \"@twin.org/context\";\nimport { Coerce, ComponentFactory, GeneralError, I18n, Is } from \"@twin.org/core\";\nimport { Engine } from \"@twin.org/engine\";\nimport { FileStateStorage } from \"@twin.org/engine-core\";\nimport {\n\tEngineCoreFactory,\n\ttype IEngineCore,\n\ttype IEngineCoreConfig\n} from \"@twin.org/engine-models\";\nimport { EngineServer } from \"@twin.org/engine-server\";\nimport type { IEngineServerConfig } from \"@twin.org/engine-server-types\";\nimport { BlobStorageConnectorType, EntityStorageConnectorType } from \"@twin.org/engine-types\";\nimport {\n\textensionsInitialiseEngine,\n\textensionsInitialiseEngineServer,\n\tshutdownExtensions\n} from \"./builders/extensionsBuilder.js\";\nimport { commaSeparatedListToArray } from \"./builders/helper/envHelpers.js\";\nimport { executeCommand } from \"./cli.js\";\nimport type { ICliCommand } from \"./models/ICliCommand.js\";\nimport type { IEngineEnvironmentVariables } from \"./models/IEngineEnvironmentVariables.js\";\nimport type { IEnvironmentVariables } from \"./models/IEnvironmentVariables.js\";\nimport type { INodeEngineConfig } from \"./models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"./models/INodeEngineState.js\";\nimport type { INodeOptions } from \"./models/INodeOptions.js\";\n\n/**\n * Start the engine server.\n * @param nodeOptions Optional run options for the engine server.\n * @param nodeEngineConfig The configuration for the engine server.\n * @param envVars The environment variables.\n * @param cliCommand The constructed CLI command (optional).\n * @param availableContextIdKeys The context ID keys available for operation.\n * @returns The engine server.\n */\nexport async function start(\n\tnodeOptions: INodeOptions | undefined,\n\tnodeEngineConfig: INodeEngineConfig,\n\tenvVars: IEnvironmentVariables & IEngineEnvironmentVariables,\n\tcliCommand?: ICliCommand,\n\tavailableContextIdKeys?: { key: string; requiredHandlerFeatures: string[] }[]\n): Promise<\n\t| {\n\t\t\tengine: Engine<IEngineServerConfig, INodeEngineState>;\n\t\t\tserver: EngineServer;\n\t\t\tshutdown: () => Promise<void>;\n\t }\n\t| undefined\n> {\n\tconst entityStorageConnectorType = commaSeparatedListToArray(envVars.entityStorageConnectorType);\n\tconst blobStorageConnectorType = commaSeparatedListToArray(envVars.blobStorageConnectorType);\n\n\tconst requiresEngineStarted = cliCommand?.definition?.requiresEngineStarted ?? true;\n\tconst requiresNodeIdentity = cliCommand?.definition?.requiresNodeIdentity ?? true;\n\tconst requiresOrgIdentity = cliCommand?.definition?.requiresOrgIdentity ?? true;\n\n\t// File connectors (blob/entity) and the default file-based state storage all\n\t// persist to disk under storageFileRoot, so it must be set when any of them is in use.\n\tif (\n\t\t(entityStorageConnectorType.includes(EntityStorageConnectorType.File) ||\n\t\t\tblobStorageConnectorType.includes(BlobStorageConnectorType.File) ||\n\t\t\tIs.empty(nodeOptions?.stateStorage)) &&\n\t\t!Is.stringValue(envVars.storageFileRoot) &&\n\t\trequiresEngineStarted\n\t) {\n\t\tthrow new GeneralError(\"node\", \"storageFileRootNotSet\", {\n\t\t\tstorageFileRoot: `${nodeOptions?.envPrefix ?? \"\"}STORAGE_FILE_ROOT`\n\t\t});\n\t}\n\n\t// Create the engine instance using file state storage unless one is configured in options\n\tconst engine = new Engine<IEngineServerConfig, INodeEngineState>({\n\t\tconfig: nodeEngineConfig,\n\t\tstateStorage: requiresEngineStarted\n\t\t\t? (nodeOptions?.stateStorage ?? new FileStateStorage(envVars.stateFilename ?? \"\"))\n\t\t\t: undefined,\n\t\tcustomBootstrap: async engineCore => {\n\t\t\tconfigureContextIds(\n\t\t\t\tengineCore,\n\t\t\t\tenvVars,\n\t\t\t\trequiresEngineStarted,\n\t\t\t\trequiresNodeIdentity,\n\t\t\t\trequiresOrgIdentity\n\t\t\t);\n\t\t\tif (!Is.objectValue(cliCommand) && requiresEngineStarted) {\n\t\t\t\tawait ContextIdStore.run(engineCore.getContextIds() ?? {}, async () => {\n\t\t\t\t\tawait enforceTenantOrganizationIds(engineCore, envVars);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\tconfigureContextIdKeys(engine, availableContextIdKeys);\n\n\t// Construct the server with the engine.\n\tconst server = new EngineServer({ engineCore: engine });\n\n\t// Extend the engine.\n\tif (Is.function(nodeOptions?.extendEngine)) {\n\t\tawait engine.logInfo(I18n.formatMessage(\"node.extendingEngine\"));\n\t\tawait nodeOptions.extendEngine(engine);\n\t}\n\n\tawait extensionsInitialiseEngine(envVars, engine);\n\n\t// Extend the engine server.\n\tif (Is.function(nodeOptions?.extendEngineServer)) {\n\t\tawait engine.logInfo(I18n.formatMessage(\"node.extendingEngineServer\"));\n\t\tawait nodeOptions?.extendEngineServer(server);\n\t}\n\n\tawait extensionsInitialiseEngineServer(envVars, engine, server);\n\n\t// Need to register the engine with the factory so that background tasks\n\t// can clone it to spawn new instances.\n\tEngineCoreFactory.register(\"engine\", () => engine);\n\n\tif (Is.objectValue(cliCommand)) {\n\t\tawait executeCommand(engine, envVars, cliCommand);\n\t} else {\n\t\ttry {\n\t\t\t// Start the server, which also starts the engine.\n\t\t\tawait server.start();\n\n\t\t\treturn {\n\t\t\t\tengine,\n\t\t\t\tserver,\n\t\t\t\tshutdown: async () => {\n\t\t\t\t\tawait shutdownExtensions(envVars, engine);\n\t\t\t\t\tawait server.stop();\n\t\t\t\t}\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tawait shutdownExtensions(envVars, engine);\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\n/**\n * Populate the engine context IDs from the current engine state.\n * @param engine The engine to configure.\n * @param envVars The environment variables.\n * @param requiresEngineStarted Whether the engine is required to be started.\n * @param requiresNodeIdentity Whether the node identity is required.\n * @param requiresOrgIdentity Whether the organization identity is required.\n * @throws GeneralError if the node identity or organization ID is required but not set.\n */\nfunction configureContextIds(\n\tengine: IEngineCore<IEngineCoreConfig, INodeEngineState>,\n\tenvVars: IEngineEnvironmentVariables,\n\trequiresEngineStarted: boolean,\n\trequiresNodeIdentity: boolean,\n\trequiresOrgIdentity: boolean\n): void {\n\tconst state = engine.getState();\n\n\tif (requiresEngineStarted) {\n\t\tif (Is.stringValue(state.nodeId)) {\n\t\t\tengine.addContextId(ContextIdKeys.Node, state.nodeId);\n\t\t} else if (requiresNodeIdentity) {\n\t\t\tthrow new GeneralError(\"node\", \"nodeIdentityNotSet\");\n\t\t}\n\n\t\tconst tenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;\n\t\tif (!tenantEnabled) {\n\t\t\tif (Is.stringValue(state.nodeOrganizationId)) {\n\t\t\t\tengine.addContextId(ContextIdKeys.Organization, state.nodeOrganizationId);\n\t\t\t} else if (requiresOrgIdentity) {\n\t\t\t\tthrow new GeneralError(\"node\", \"nodeOrganizationIdNotSet\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Configure the available context ID keys on the engine.\n * @param engine The engine to configure.\n * @param availableContextIdKeys The available context ID keys.\n */\nfunction configureContextIdKeys(\n\tengine: IEngineCore<IEngineCoreConfig, INodeEngineState>,\n\tavailableContextIdKeys: { key: string; requiredHandlerFeatures: string[] }[] | undefined\n): void {\n\tif (Is.arrayValue(availableContextIdKeys)) {\n\t\tconst added: string[] = [];\n\t\tfor (const availableContextIdKey of availableContextIdKeys) {\n\t\t\tif (!added.includes(availableContextIdKey.key)) {\n\t\t\t\tengine.addContextIdKey(\n\t\t\t\t\tavailableContextIdKey.key,\n\t\t\t\t\tavailableContextIdKey.requiredHandlerFeatures\n\t\t\t\t);\n\t\t\t\tadded.push(availableContextIdKey.key);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Scan all tenants for a missing organization ID.\n * If exactly one tenant is missing and the node's own organization ID is available in state,\n * the value is automatically applied and persisted (legacy migration path).\n * If multiple tenants are missing, or the single missing tenant cannot be auto-recovered,\n * startup is blocked with an error listing the affected tenant IDs.\n * @param engineCore The engine core.\n * @param envVars The environment variables.\n * @returns A promise that resolves when all tenants have valid organization IDs.\n * @throws GeneralError if multiple tenants are missing their organization ID and cannot be auto-recovered.\n */\nasync function enforceTenantOrganizationIds(\n\tengineCore: IEngineCore<IEngineCoreConfig, INodeEngineState>,\n\tenvVars: IEnvironmentVariables\n): Promise<void> {\n\tconst tenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;\n\tif (!tenantEnabled) {\n\t\treturn;\n\t}\n\n\tconst type = engineCore.getRegisteredInstanceTypeOptional(\"tenantAdminComponent\");\n\tif (!Is.stringValue(type)) {\n\t\treturn;\n\t}\n\n\tconst tenantAdminComponent = ComponentFactory.get<ITenantAdminComponent>(type);\n\tconst missingIds: string[] = [];\n\tlet cursor: string | undefined;\n\n\tdo {\n\t\tconst { tenants, cursor: next } = await tenantAdminComponent.query(\n\t\t\tundefined,\n\t\t\t[\"id\", \"organizationId\"],\n\t\t\tcursor\n\t\t);\n\t\tfor (const tenant of tenants) {\n\t\t\tif (Is.stringValue(tenant.id) && !Is.stringValue(tenant.organizationId)) {\n\t\t\t\tmissingIds.push(tenant.id);\n\t\t\t}\n\t\t}\n\t\tcursor = next;\n\t} while (Is.stringValue(cursor));\n\n\tif (missingIds.length === 0) {\n\t\treturn;\n\t}\n\n\tif (missingIds.length === 1) {\n\t\tconst state = engineCore.getState();\n\t\tif (Is.stringValue(state.nodeOrganizationId)) {\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.tenantOrganizationIdAutoAssigned\", {\n\t\t\t\t\ttenantId: missingIds[0],\n\t\t\t\t\torganizationId: state.nodeOrganizationId\n\t\t\t\t})\n\t\t\t);\n\t\t\tawait tenantAdminComponent.update({\n\t\t\t\tid: missingIds[0],\n\t\t\t\torganizationId: state.nodeOrganizationId\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t}\n\n\tthrow new GeneralError(\"node\", \"tenantsWithoutOrganizationId\", {\n\t\ttenantIds: missingIds.join(\", \")\n\t});\n}\n"]}
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/start.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenantAdminComponent } from \"@twin.org/api-models\";\nimport { ContextIdKeys, ContextIdStore } from \"@twin.org/context\";\nimport { Coerce, ComponentFactory, GeneralError, I18n, Is } from \"@twin.org/core\";\nimport { Engine } from \"@twin.org/engine\";\nimport { FileStateStorage } from \"@twin.org/engine-core\";\nimport {\n\tEngineCoreFactory,\n\ttype IEngineCore,\n\ttype IEngineCoreConfig\n} from \"@twin.org/engine-models\";\nimport { EngineServer } from \"@twin.org/engine-server\";\nimport type { IEngineServerConfig } from \"@twin.org/engine-server-types\";\nimport { BlobStorageConnectorType, EntityStorageConnectorType } from \"@twin.org/engine-types\";\nimport {\n\textensionsInitialiseEngine,\n\textensionsInitialiseEngineServer,\n\tshutdownExtensions\n} from \"./builders/extensionsBuilder.js\";\nimport { commaSeparatedListToArray } from \"./builders/helper/envHelpers.js\";\nimport { finalizeMigrations, initialiseMigrations } from \"./builders/helper/migrationHelper.js\";\nimport { executeCommand } from \"./cli.js\";\nimport type { ICliCommand } from \"./models/ICliCommand.js\";\nimport type { IEngineEnvironmentVariables } from \"./models/IEngineEnvironmentVariables.js\";\nimport type { IEnvironmentVariables } from \"./models/IEnvironmentVariables.js\";\nimport type { INodeEngineConfig } from \"./models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"./models/INodeEngineState.js\";\nimport type { INodeOptions } from \"./models/INodeOptions.js\";\n\n/**\n * Start the engine server.\n * @param nodeOptions Optional run options for the engine server.\n * @param nodeEngineConfig The configuration for the engine server.\n * @param envVars The environment variables.\n * @param cliCommand The constructed CLI command (optional).\n * @param availableContextIdKeys The context ID keys available for operation.\n * @returns The engine server.\n */\nexport async function start(\n\tnodeOptions: INodeOptions | undefined,\n\tnodeEngineConfig: INodeEngineConfig,\n\tenvVars: IEnvironmentVariables & IEngineEnvironmentVariables,\n\tcliCommand?: ICliCommand,\n\tavailableContextIdKeys?: { key: string; requiredHandlerFeatures: string[] }[]\n): Promise<\n\t| {\n\t\t\tengine: Engine<IEngineServerConfig, INodeEngineState>;\n\t\t\tserver: EngineServer;\n\t\t\tshutdown: () => Promise<void>;\n\t }\n\t| undefined\n> {\n\tconst entityStorageConnectorType = commaSeparatedListToArray(envVars.entityStorageConnectorType);\n\tconst blobStorageConnectorType = commaSeparatedListToArray(envVars.blobStorageConnectorType);\n\n\tconst requiresEngineStarted = cliCommand?.definition?.requiresEngineStarted ?? true;\n\tconst requiresNodeIdentity = cliCommand?.definition?.requiresNodeIdentity ?? true;\n\tconst requiresOrgIdentity = cliCommand?.definition?.requiresOrgIdentity ?? true;\n\n\t// File connectors (blob/entity) and the default file-based state storage all\n\t// persist to disk under storageFileRoot, so it must be set when any of them is in use.\n\tif (\n\t\t(entityStorageConnectorType.includes(EntityStorageConnectorType.File) ||\n\t\t\tblobStorageConnectorType.includes(BlobStorageConnectorType.File) ||\n\t\t\tIs.empty(nodeOptions?.stateStorage)) &&\n\t\t!Is.stringValue(envVars.storageFileRoot) &&\n\t\trequiresEngineStarted\n\t) {\n\t\tthrow new GeneralError(\"node\", \"storageFileRootNotSet\", {\n\t\t\tstorageFileRoot: `${nodeOptions?.envPrefix ?? \"\"}STORAGE_FILE_ROOT`\n\t\t});\n\t}\n\n\t// Create the engine instance using file state storage unless one is configured in options\n\tconst engine = new Engine<IEngineServerConfig, INodeEngineState>({\n\t\tconfig: nodeEngineConfig,\n\t\tstateStorage: requiresEngineStarted\n\t\t\t? (nodeOptions?.stateStorage ?? new FileStateStorage(envVars.stateFilename ?? \"\"))\n\t\t\t: undefined,\n\t\tcustomBootstrap: async engineCore => {\n\t\t\tconfigureContextIds(\n\t\t\t\tengineCore,\n\t\t\t\tenvVars,\n\t\t\t\trequiresEngineStarted,\n\t\t\t\trequiresNodeIdentity,\n\t\t\t\trequiresOrgIdentity\n\t\t\t);\n\t\t\tif (!Is.objectValue(cliCommand) && requiresEngineStarted) {\n\t\t\t\tawait ContextIdStore.run(engineCore.getContextIds() ?? {}, async () => {\n\t\t\t\t\tawait enforceTenantOrganizationIds(engineCore, envVars);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\tconfigureContextIdKeys(engine, availableContextIdKeys);\n\n\t// Construct the server with the engine.\n\tconst server = new EngineServer({ engineCore: engine });\n\n\t// Extend the engine.\n\tif (Is.function(nodeOptions?.extendEngine)) {\n\t\tawait engine.logInfo(I18n.formatMessage(\"node.extendingEngine\"));\n\t\tawait nodeOptions.extendEngine(engine);\n\t}\n\n\tawait extensionsInitialiseEngine(envVars, engine);\n\n\t// Extend the engine server.\n\tif (Is.function(nodeOptions?.extendEngineServer)) {\n\t\tawait engine.logInfo(I18n.formatMessage(\"node.extendingEngineServer\"));\n\t\tawait nodeOptions?.extendEngineServer(server);\n\t}\n\n\tawait extensionsInitialiseEngineServer(envVars, engine, server);\n\n\t// Need to register the engine with the factory so that background tasks\n\t// can clone it to spawn new instances.\n\tEngineCoreFactory.register(\"engine\", () => engine);\n\n\tif (Is.objectValue(cliCommand)) {\n\t\tawait executeCommand(engine, envVars, cliCommand);\n\t} else {\n\t\ttry {\n\t\t\tinitialiseMigrations(engine, envVars);\n\n\t\t\t// Start the server, which also starts the engine.\n\t\t\tawait server.start();\n\n\t\t\tawait finalizeMigrations(engine, envVars);\n\n\t\t\treturn {\n\t\t\t\tengine,\n\t\t\t\tserver,\n\t\t\t\tshutdown: async () => {\n\t\t\t\t\tawait shutdownExtensions(envVars, engine);\n\t\t\t\t\tawait server.stop();\n\t\t\t\t}\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tawait shutdownExtensions(envVars, engine);\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\n/**\n * Populate the engine context IDs from the current engine state.\n * @param engine The engine to configure.\n * @param envVars The environment variables.\n * @param requiresEngineStarted Whether the engine is required to be started.\n * @param requiresNodeIdentity Whether the node identity is required.\n * @param requiresOrgIdentity Whether the organization identity is required.\n * @throws GeneralError if the node identity or organization ID is required but not set.\n */\nfunction configureContextIds(\n\tengine: IEngineCore<IEngineCoreConfig, INodeEngineState>,\n\tenvVars: IEngineEnvironmentVariables,\n\trequiresEngineStarted: boolean,\n\trequiresNodeIdentity: boolean,\n\trequiresOrgIdentity: boolean\n): void {\n\tconst state = engine.getState();\n\n\tif (requiresEngineStarted) {\n\t\tif (Is.stringValue(state.nodeId)) {\n\t\t\tengine.addContextId(ContextIdKeys.Node, state.nodeId);\n\t\t} else if (requiresNodeIdentity) {\n\t\t\tthrow new GeneralError(\"node\", \"nodeIdentityNotSet\");\n\t\t}\n\n\t\tconst tenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;\n\t\tif (!tenantEnabled) {\n\t\t\tif (Is.stringValue(state.nodeOrganizationId)) {\n\t\t\t\tengine.addContextId(ContextIdKeys.Organization, state.nodeOrganizationId);\n\t\t\t} else if (requiresOrgIdentity) {\n\t\t\t\tthrow new GeneralError(\"node\", \"nodeOrganizationIdNotSet\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Configure the available context ID keys on the engine.\n * @param engine The engine to configure.\n * @param availableContextIdKeys The available context ID keys.\n */\nfunction configureContextIdKeys(\n\tengine: IEngineCore<IEngineCoreConfig, INodeEngineState>,\n\tavailableContextIdKeys: { key: string; requiredHandlerFeatures: string[] }[] | undefined\n): void {\n\tif (Is.arrayValue(availableContextIdKeys)) {\n\t\tconst added: string[] = [];\n\t\tfor (const availableContextIdKey of availableContextIdKeys) {\n\t\t\tif (!added.includes(availableContextIdKey.key)) {\n\t\t\t\tengine.addContextIdKey(\n\t\t\t\t\tavailableContextIdKey.key,\n\t\t\t\t\tavailableContextIdKey.requiredHandlerFeatures\n\t\t\t\t);\n\t\t\t\tadded.push(availableContextIdKey.key);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Scan all tenants for a missing organization ID.\n * If exactly one tenant is missing and the node's own organization ID is available in state,\n * the value is automatically applied and persisted (legacy migration path).\n * If multiple tenants are missing, or the single missing tenant cannot be auto-recovered,\n * startup is blocked with an error listing the affected tenant IDs.\n * @param engineCore The engine core.\n * @param envVars The environment variables.\n * @returns A promise that resolves when all tenants have valid organization IDs.\n * @throws GeneralError if multiple tenants are missing their organization ID and cannot be auto-recovered.\n */\nasync function enforceTenantOrganizationIds(\n\tengineCore: IEngineCore<IEngineCoreConfig, INodeEngineState>,\n\tenvVars: IEnvironmentVariables\n): Promise<void> {\n\tconst tenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;\n\tif (!tenantEnabled) {\n\t\treturn;\n\t}\n\n\tconst type = engineCore.getRegisteredInstanceTypeOptional(\"tenantAdminComponent\");\n\tif (!Is.stringValue(type)) {\n\t\treturn;\n\t}\n\n\tconst tenantAdminComponent = ComponentFactory.get<ITenantAdminComponent>(type);\n\tconst missingIds: string[] = [];\n\tlet cursor: string | undefined;\n\n\tdo {\n\t\tconst { tenants, cursor: next } = await tenantAdminComponent.query(\n\t\t\tundefined,\n\t\t\t[\"id\", \"organizationId\"],\n\t\t\tcursor\n\t\t);\n\t\tfor (const tenant of tenants) {\n\t\t\tif (Is.stringValue(tenant.id) && !Is.stringValue(tenant.organizationId)) {\n\t\t\t\tmissingIds.push(tenant.id);\n\t\t\t}\n\t\t}\n\t\tcursor = next;\n\t} while (Is.stringValue(cursor));\n\n\tif (missingIds.length === 0) {\n\t\treturn;\n\t}\n\n\tif (missingIds.length === 1) {\n\t\tconst state = engineCore.getState();\n\t\tif (Is.stringValue(state.nodeOrganizationId)) {\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.tenantOrganizationIdAutoAssigned\", {\n\t\t\t\t\ttenantId: missingIds[0],\n\t\t\t\t\torganizationId: state.nodeOrganizationId\n\t\t\t\t})\n\t\t\t);\n\t\t\tawait tenantAdminComponent.update({\n\t\t\t\tid: missingIds[0],\n\t\t\t\torganizationId: state.nodeOrganizationId\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t}\n\n\tthrow new GeneralError(\"node\", \"tenantsWithoutOrganizationId\", {\n\t\ttenantIds: missingIds.join(\", \")\n\t});\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type { IEngineCore } from "@twin.org/engine-models";
2
+ import type { IEnvironmentVariables } from "../../models/IEnvironmentVariables.js";
3
+ /**
4
+ * Initialise schema migrations for the engine.
5
+ * @param engineCore The engine core instance.
6
+ * @param envVars The environment variables.
7
+ */
8
+ export declare function initialiseMigrations(engineCore: IEngineCore, envVars: IEnvironmentVariables): void;
9
+ /**
10
+ * Finalize schema migrations by clearing any temporary data stored in the shared store.
11
+ * This should be called after all migrations have been processed to ensure that
12
+ * any temporary data used during the migration process is removed.
13
+ * @param engineCore The engine core instance.
14
+ * @param envVars The environment variables.
15
+ */
16
+ export declare function finalizeMigrations(engineCore: IEngineCore, envVars: IEnvironmentVariables): Promise<void>;
package/docs/changelog.md CHANGED
@@ -1,5 +1,173 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.1-next.2](https://github.com/iotaledger/twin-node/compare/node-core-v0.10.1-next.1...node-core-v0.10.1-next.2) (2026-09-18)
4
+
5
+
6
+ ### Features
7
+
8
+ * index migration ([#421](https://github.com/iotaledger/twin-node/issues/421)) ([b3790a9](https://github.com/iotaledger/twin-node/commit/b3790a987c4ac60b7d1e74da9aa496e7ca24c2c3))
9
+
10
+ ## [0.10.1-next.1](https://github.com/iotaledger/twin-node/compare/node-core-v0.10.1-next.0...node-core-v0.10.1-next.1) (2026-09-17)
11
+
12
+
13
+ ### Features
14
+
15
+ * add additional env vars ([#328](https://github.com/iotaledger/twin-node/issues/328)) ([6ca8718](https://github.com/iotaledger/twin-node/commit/6ca87184bc4d78829c957ea055d3c281aca6cf9f))
16
+ * add automation ([cfc63b4](https://github.com/iotaledger/twin-node/commit/cfc63b465c139280f696877df21d54dc6a065a7e))
17
+ * add background task max dispatch count ([f0965a0](https://github.com/iotaledger/twin-node/commit/f0965a004dc0e0a856fc0fe1e58330f84e09aa3b))
18
+ * add CLI commands and remove automated bootstrap code ([#69](https://github.com/iotaledger/twin-node/issues/69)) ([6e40933](https://github.com/iotaledger/twin-node/commit/6e40933d8bb820b380e1074fc88feeedca0ef7d9))
19
+ * add context id features ([#53](https://github.com/iotaledger/twin-node/issues/53)) ([827adf5](https://github.com/iotaledger/twin-node/commit/827adf52cb87fca53cec52b27e67f7a9dba2c088))
20
+ * add dataspace endpoint tests for app-datasets, transfers, and data plane ([#213](https://github.com/iotaledger/twin-node/issues/213)) ([5641a78](https://github.com/iotaledger/twin-node/commit/5641a781bf17a1914912f3162116d7c5f5c0dca2))
21
+ * add dsp sweep vars ([#340](https://github.com/iotaledger/twin-node/issues/340)) ([5487c13](https://github.com/iotaledger/twin-node/commit/5487c13197fcd386206ec37f9f342c55ec5b1176))
22
+ * add extensions support ([476d5a8](https://github.com/iotaledger/twin-node/commit/476d5a864026a2f78e5b02bc9eb81359777a4a45))
23
+ * add immutable proof task worker idle timeout env var ([#409](https://github.com/iotaledger/twin-node/issues/409)) ([12a524e](https://github.com/iotaledger/twin-node/commit/12a524e44d353cbfa690e522c139ec7083baefab))
24
+ * add isDefault flag to logging connectors ([358e839](https://github.com/iotaledger/twin-node/commit/358e8394819dab9832d3a9ebfac74b897b7d5f40))
25
+ * add logging otel ([2adf4e4](https://github.com/iotaledger/twin-node/commit/2adf4e44fd2ef4cce43f354da2187719c72cc3cd))
26
+ * add module cache and improve resolution ([482be05](https://github.com/iotaledger/twin-node/commit/482be056c37a598033250ea8a7288a33cf3470b4))
27
+ * add mutex settings ([#222](https://github.com/iotaledger/twin-node/issues/222)) ([492c55f](https://github.com/iotaledger/twin-node/commit/492c55f67d5f70c2a4a27dfdb2700a644ee87955))
28
+ * add new endpoints ([cc6e30d](https://github.com/iotaledger/twin-node/commit/cc6e30d85f7ed8018697462a7100e5c2f4e8f407))
29
+ * add notarization ([#121](https://github.com/iotaledger/twin-node/issues/121)) ([b2a11df](https://github.com/iotaledger/twin-node/commit/b2a11df92c7b5026f73f08a018c0586ebe008e92))
30
+ * add obligation enforcers and multi instance support ([#89](https://github.com/iotaledger/twin-node/issues/89)) ([d81af99](https://github.com/iotaledger/twin-node/commit/d81af99b8c4db6e9a1370b7065bf6d9d222c71ed))
31
+ * add outlook connector ([cf7ee0b](https://github.com/iotaledger/twin-node/commit/cf7ee0b73042cb33e693f3677386ca94567bb6e4))
32
+ * add rights management components ([0fc6293](https://github.com/iotaledger/twin-node/commit/0fc629332db24494bd73003625c7bf3f939a2597))
33
+ * add standalone federated catalogue example config and endpoint tests ([#235](https://github.com/iotaledger/twin-node/issues/235)) ([ffb51dd](https://github.com/iotaledger/twin-node/commit/ffb51ddda5188c2f21b8ce65343b39a28f4eee4b))
34
+ * add support for dynamodb connection timeout ([63051b0](https://github.com/iotaledger/twin-node/commit/63051b0d22138079115dfac921e7f0c45eaad34e))
35
+ * add tenant override ([#337](https://github.com/iotaledger/twin-node/issues/337)) ([b4ea765](https://github.com/iotaledger/twin-node/commit/b4ea7656e2557c19053365dd5d4af14d0d945cd5))
36
+ * add tracing ([#344](https://github.com/iotaledger/twin-node/issues/344)) ([4fa71cd](https://github.com/iotaledger/twin-node/commit/4fa71cd0eafd7d708df15c8f0a85323fecd05561))
37
+ * add tracing console connector ([#373](https://github.com/iotaledger/twin-node/issues/373)) ([fb36cb8](https://github.com/iotaledger/twin-node/commit/fb36cb8bebc2e8c1b94fa332cead8283ca5d636a))
38
+ * add tracing support ([a4986fc](https://github.com/iotaledger/twin-node/commit/a4986fc4af603ee461ec8d18ff502dddbc43edec))
39
+ * add trust and rights management plugin support ([cdeb504](https://github.com/iotaledger/twin-node/commit/cdeb504ee5986a347466162b9afa781645b4a54c))
40
+ * add trust ttl ([#73](https://github.com/iotaledger/twin-node/issues/73)) ([911cee7](https://github.com/iotaledger/twin-node/commit/911cee771bba490143bb1574ca8360f7cf8baa1a))
41
+ * add validate-locales ([1a19dcb](https://github.com/iotaledger/twin-node/commit/1a19dcb005c2f0e3103e290db28c48a3464094cb))
42
+ * add vault prefix configuration ([#75](https://github.com/iotaledger/twin-node/issues/75)) ([1d4afb1](https://github.com/iotaledger/twin-node/commit/1d4afb1b1a8aa60795898eeb9e7f5153c279527d))
43
+ * add well-known endpoint ([38cbab2](https://github.com/iotaledger/twin-node/commit/38cbab20631666d3bae8b0b5ae346a3488148b1d))
44
+ * adding npm and https protocols to load extensions ([#45](https://github.com/iotaledger/twin-node/issues/45)) ([33940b7](https://github.com/iotaledger/twin-node/commit/33940b7e771a0c5af32c18d442deb26a8631fd02))
45
+ * additional cli commands ([#269](https://github.com/iotaledger/twin-node/issues/269)) ([c9e7c93](https://github.com/iotaledger/twin-node/commit/c9e7c939aedfceed9cbe501f2dc936e84289ed62))
46
+ * additional env vars and validation ([#324](https://github.com/iotaledger/twin-node/issues/324)) ([6b01e8c](https://github.com/iotaledger/twin-node/commit/6b01e8c10f9aa7181f51f13534d8164db3e7322d))
47
+ * additional options for enabling components ([e13d772](https://github.com/iotaledger/twin-node/commit/e13d7721a0dd7143d456fff246622cbe63dbd0f1))
48
+ * additional route logging env vars ([7152c88](https://github.com/iotaledger/twin-node/commit/7152c887c3ba76778e2d9e68ba57198b8d81d802))
49
+ * additional stop interlock ([b3a2757](https://github.com/iotaledger/twin-node/commit/b3a2757325af0e7b258a9f97f1b52e86087e6301))
50
+ * align node module with dataspace rename and control plane integ… ([#95](https://github.com/iotaledger/twin-node/issues/95)) ([8129868](https://github.com/iotaledger/twin-node/commit/812986886fb5d779dd380956c4e6cc47c2d73530))
51
+ * auth fix ([a8e59e9](https://github.com/iotaledger/twin-node/commit/a8e59e947735180c9edee041f87af5e1e125e3c6))
52
+ * authentication services ([#118](https://github.com/iotaledger/twin-node/issues/118)) ([311a7f8](https://github.com/iotaledger/twin-node/commit/311a7f882db1e50a83e94d2dae32fefc68debb47))
53
+ * bootstrap legacy skip ([469d950](https://github.com/iotaledger/twin-node/commit/469d9505bd0497c271ba291641f63786200cb548))
54
+ * bootstrap-legacy rename ([#310](https://github.com/iotaledger/twin-node/issues/310)) ([53af8a2](https://github.com/iotaledger/twin-node/commit/53af8a2e797e90bb601416215247cd8649dd6220))
55
+ * bump [@twin](https://github.com/twin).org/* to latest next ([#172](https://github.com/iotaledger/twin-node/issues/172)) ([45862d5](https://github.com/iotaledger/twin-node/commit/45862d555e4958f1c12da357817b7b87642d7aba))
56
+ * bump dependencies ([#216](https://github.com/iotaledger/twin-node/issues/216)) ([a005824](https://github.com/iotaledger/twin-node/commit/a005824fe3e4a734543f613d8a7cc1275fec4572))
57
+ * cache the npm root to increase startup speed ([f10ea9e](https://github.com/iotaledger/twin-node/commit/f10ea9e22cc202f320df5fb21507b886c1f7345b))
58
+ * cli tenant-token command ([#177](https://github.com/iotaledger/twin-node/issues/177)) ([b3f68a4](https://github.com/iotaledger/twin-node/commit/b3f68a4972d065e865372230c078b4657dfabc1a))
59
+ * clone mode ([#360](https://github.com/iotaledger/twin-node/issues/360)) ([8bb56fb](https://github.com/iotaledger/twin-node/commit/8bb56fb6a4b138c2ff0d1267d1be4f8c24f492a6))
60
+ * component update ([9a3fdab](https://github.com/iotaledger/twin-node/commit/9a3fdab250e0dc8b8aa52479d5c72517de8d6c0f))
61
+ * component update ([8bf10da](https://github.com/iotaledger/twin-node/commit/8bf10da2e3e29f22afddd9cb55a26f343555e106))
62
+ * configure web server body limits from the environment ([#356](https://github.com/iotaledger/twin-node/issues/356)) ([f196ad3](https://github.com/iotaledger/twin-node/commit/f196ad368559515184e37a99d6876570074ebcd5))
63
+ * configure which factories receive tracing facades ([#412](https://github.com/iotaledger/twin-node/issues/412)) ([da56bcb](https://github.com/iotaledger/twin-node/commit/da56bcbeba04d1091b3cd237624951c31ff9c185))
64
+ * custom plugin timeout ([#395](https://github.com/iotaledger/twin-node/issues/395)) ([d4a33ba](https://github.com/iotaledger/twin-node/commit/d4a33ba10a54c6dfab0b845b386201ac326df88a))
65
+ * custom REST paths ([#99](https://github.com/iotaledger/twin-node/issues/99)) ([dcab1b2](https://github.com/iotaledger/twin-node/commit/dcab1b2b23c13b4c9f39c3c1c67284f56e732bd1))
66
+ * dataspace plane path ([#272](https://github.com/iotaledger/twin-node/issues/272)) ([5998eeb](https://github.com/iotaledger/twin-node/commit/5998eeb6fa1392ae753eb6bafeccefa1fb690573))
67
+ * don't override existing env vars with env files ([ebccac2](https://github.com/iotaledger/twin-node/commit/ebccac297c3156076f17c246a8abd994f8f20e61))
68
+ * dspace well-known endpoint test ([615bf55](https://github.com/iotaledger/twin-node/commit/615bf55de9e05ed410ed18348735cf4d6f392fe7))
69
+ * email ingestion ([#379](https://github.com/iotaledger/twin-node/issues/379)) ([12da79d](https://github.com/iotaledger/twin-node/commit/12da79dc9b167e288c555d4f1909a61c190eee4d))
70
+ * endpoints-runner ([#153](https://github.com/iotaledger/twin-node/issues/153)) ([cca42d0](https://github.com/iotaledger/twin-node/commit/cca42d07d6655d401c909308e8b73606fef05248))
71
+ * enhanced cli commands ([#288](https://github.com/iotaledger/twin-node/issues/288)) ([479fb34](https://github.com/iotaledger/twin-node/commit/479fb3448c493a134aee35b69ae39458e493a4ad))
72
+ * env var simplification ([460b0f2](https://github.com/iotaledger/twin-node/commit/460b0f20a73cb482f7443af502f261d5f9d01759))
73
+ * env var validation ([#243](https://github.com/iotaledger/twin-node/issues/243)) ([569945a](https://github.com/iotaledger/twin-node/commit/569945a751eb52d008a681777a3cba881af1b9a4))
74
+ * env vars consistency ([1823b7a](https://github.com/iotaledger/twin-node/commit/1823b7aeae5dc7484861534b851080afda64d869))
75
+ * env-prefix option and user-update cli command ([#83](https://github.com/iotaledger/twin-node/issues/83)) ([fc48efa](https://github.com/iotaledger/twin-node/commit/fc48efa7ad72173def048170c3afb5eeb9f1b292))
76
+ * envListToArray use explicitly default value ([#401](https://github.com/iotaledger/twin-node/issues/401)) ([25f6ede](https://github.com/iotaledger/twin-node/commit/25f6ede762916a986e61b28124076aa87fd4a15c))
77
+ * eslint migration to flat config ([080db74](https://github.com/iotaledger/twin-node/commit/080db746390230f78725d214bc957da2efee9eb1))
78
+ * expose gasBudget and gasReservationDuration as configurable env vars ([#286](https://github.com/iotaledger/twin-node/issues/286)) ([d678b27](https://github.com/iotaledger/twin-node/commit/d678b27d629930a6ce85eeab9caf89d1187c3461))
79
+ * federated catalogue trust mode ([#194](https://github.com/iotaledger/twin-node/issues/194)) ([c18e6fb](https://github.com/iotaledger/twin-node/commit/c18e6fbe0014eb5faf8084d16169d86f3d3b23a6))
80
+ * file logging config ([#287](https://github.com/iotaledger/twin-node/issues/287)) ([a567b25](https://github.com/iotaledger/twin-node/commit/a567b253cbb8b9af872bb0e494c013212f4f55a2))
81
+ * first metrics in the core and app for testing ([#139](https://github.com/iotaledger/twin-node/issues/139)) ([abe17bb](https://github.com/iotaledger/twin-node/commit/abe17bb9a6261dcb7fd46253221182fbb1dc2259))
82
+ * health and url transformer ([#131](https://github.com/iotaledger/twin-node/issues/131)) ([3658903](https://github.com/iotaledger/twin-node/commit/36589036b9bea120880fc395b0d123a89032cf40))
83
+ * health exclude config ([#403](https://github.com/iotaledger/twin-node/issues/403)) ([646024b](https://github.com/iotaledger/twin-node/commit/646024b0ebe0f6f11630da2ab4b48e9ea6c2970b))
84
+ * identity profile information source ([dbb53d1](https://github.com/iotaledger/twin-node/commit/dbb53d145f517070d864f37650a6dbc1f3e9c3a8))
85
+ * immutable proof config ([#307](https://github.com/iotaledger/twin-node/issues/307)) ([9257495](https://github.com/iotaledger/twin-node/commit/92574953329647756aa6ab4cca80b1707e14a33f))
86
+ * immutable proof gate and additional config ([#157](https://github.com/iotaledger/twin-node/issues/157)) ([1d1fbb7](https://github.com/iotaledger/twin-node/commit/1d1fbb7c53525af848761dc25b42e9e676929972))
87
+ * improve bootstrapping and shutdown behaviour ([#66](https://github.com/iotaledger/twin-node/issues/66)) ([65b3452](https://github.com/iotaledger/twin-node/commit/65b345240334bfff48b52e136cc486cd7ac7f290))
88
+ * improve error handling for extensions and logging ([bd84fde](https://github.com/iotaledger/twin-node/commit/bd84fde67e5a9db6ac66730397992401ca52e88c))
89
+ * improve node logging ([63d6ea6](https://github.com/iotaledger/twin-node/commit/63d6ea661c2c76985d98addb8d905ad6f0c7f164))
90
+ * improve node logging ([c25b9c6](https://github.com/iotaledger/twin-node/commit/c25b9c6779bdb76f341df072c39b4c2fae4565a3))
91
+ * improved cli commands ([#206](https://github.com/iotaledger/twin-node/issues/206)) ([cf00850](https://github.com/iotaledger/twin-node/commit/cf0085023a66e187aaaaf3889128c845c73a1faf))
92
+ * migration options ([#293](https://github.com/iotaledger/twin-node/issues/293)) ([91acc88](https://github.com/iotaledger/twin-node/commit/91acc881f665be0177b2e895e2810dd4d6145105))
93
+ * migration testing ([#199](https://github.com/iotaledger/twin-node/issues/199)) ([97a731c](https://github.com/iotaledger/twin-node/commit/97a731c520d66ab0588d80987a0f88d388ce51ae))
94
+ * multi-tenant env wiring, trust auto-enable, tenant-token vault key, engine-driven callbackPath ([#128](https://github.com/iotaledger/twin-node/issues/128)) ([0de4d35](https://github.com/iotaledger/twin-node/commit/0de4d356fb2f825afae5469005d475700f510ee4))
95
+ * new tenant auth mechanisms ([#168](https://github.com/iotaledger/twin-node/issues/168)) ([686f111](https://github.com/iotaledger/twin-node/commit/686f1118e79e6f26a8dc72a5e9172584057f4518))
96
+ * organization identifiers ([#203](https://github.com/iotaledger/twin-node/issues/203)) ([1a6b176](https://github.com/iotaledger/twin-node/commit/1a6b1760d9f8e43a769407668426c70e1c8e1aa8))
97
+ * pool env vars ([#331](https://github.com/iotaledger/twin-node/issues/331)) ([338ea61](https://github.com/iotaledger/twin-node/commit/338ea612b37aa4d15971c8a09def47bee9395d0c))
98
+ * publish nightly soak reports as a web-hosted dashboard ([#378](https://github.com/iotaledger/twin-node/issues/378)) ([e6984f9](https://github.com/iotaledger/twin-node/commit/e6984f9183e50b78e10de2124b94e3c22c7306ca))
99
+ * refactor testing ([fc28140](https://github.com/iotaledger/twin-node/commit/fc28140c6a398d31e092752ef53fa490da167794))
100
+ * register task scheduler when immutable proof is enabled ([#320](https://github.com/iotaledger/twin-node/issues/320)) ([b1d9c81](https://github.com/iotaledger/twin-node/commit/b1d9c81e0ec267292c6eaba8a6228eff1c41a9f0))
101
+ * remove dap and darp ([36c3ffb](https://github.com/iotaledger/twin-node/commit/36c3ffb31af65a0e3025859dab675efeee043155))
102
+ * remove hosting component ([#219](https://github.com/iotaledger/twin-node/issues/219)) ([fb2fea4](https://github.com/iotaledger/twin-node/commit/fb2fea46f57aab9252ee1491499e84b8ad46533e))
103
+ * remove mutex timeout from logger ([e5a5407](https://github.com/iotaledger/twin-node/commit/e5a540725fa97b523f88589f582501f41b982d5b))
104
+ * remove old mutex timeouts ([fe6444a](https://github.com/iotaledger/twin-node/commit/fe6444af1a2e53cf6bce8517dbb8352e8b07bb31))
105
+ * remove set-tenant ([#186](https://github.com/iotaledger/twin-node/issues/186)) ([1fc1909](https://github.com/iotaledger/twin-node/commit/1fc1909e6335dea51dfec3bb91fba4badaa9790a))
106
+ * rest metrics ([#341](https://github.com/iotaledger/twin-node/issues/341)) ([ebec573](https://github.com/iotaledger/twin-node/commit/ebec5736bb66adfd97f7d73912bec1ce7392e5f8))
107
+ * separate script directory from exec directory ([f6bb4db](https://github.com/iotaledger/twin-node/commit/f6bb4dbea1f1e200e0640fa154c6997ef99c99b4))
108
+ * silent telemetry and tracing options ([#351](https://github.com/iotaledger/twin-node/issues/351)) ([3a5752f](https://github.com/iotaledger/twin-node/commit/3a5752fc0bf8a028b3ebfc34878524ac799fb81e))
109
+ * support public origin and hosting service ([#77](https://github.com/iotaledger/twin-node/issues/77)) ([3b9039f](https://github.com/iotaledger/twin-node/commit/3b9039fcba7f7038c06f8fd6a5ccc9fdbbf535b3))
110
+ * telemetry and deprecated variables ([198f43f](https://github.com/iotaledger/twin-node/commit/198f43fd2d94e2f6721924365b73c0af3020e31d))
111
+ * telemetry batching ([#347](https://github.com/iotaledger/twin-node/issues/347)) ([5d5b0a9](https://github.com/iotaledger/twin-node/commit/5d5b0a91396298fe774ae26193b0595875cd118a))
112
+ * telemetry tracing multi ([#357](https://github.com/iotaledger/twin-node/issues/357)) ([b6412ac](https://github.com/iotaledger/twin-node/commit/b6412ac3141a94a0f9f7d1dd391451ac9247e862))
113
+ * tenant-id in user create and update ([#148](https://github.com/iotaledger/twin-node/issues/148)) ([1143e30](https://github.com/iotaledger/twin-node/commit/1143e30fb0d2056d113367d0c5ea251f07695da1))
114
+ * typescript 6 update ([ce2e3ca](https://github.com/iotaledger/twin-node/commit/ce2e3ca5219587709f7b9cf6c65909b48fba11b5))
115
+ * update background tasks and add fedcat filters ([1fd297e](https://github.com/iotaledger/twin-node/commit/1fd297e29f60b5bb3909638b68e326c5b0e2d77d))
116
+ * update components ([a2643b9](https://github.com/iotaledger/twin-node/commit/a2643b9ce7e338e4853237a6daba7fa58d9fc5c8))
117
+ * update components ([35cdfdc](https://github.com/iotaledger/twin-node/commit/35cdfdcba2b52599b4db3afd8c9e6dd17468b21e))
118
+ * update context usage ([2215440](https://github.com/iotaledger/twin-node/commit/2215440801dea3955885b6579ad9b98b7a5d87ea))
119
+ * update dependencies ([34a5d51](https://github.com/iotaledger/twin-node/commit/34a5d5100140f6e642e8aaa1b4da5304b8ce6f0a))
120
+ * update dependencies ([64c8ea8](https://github.com/iotaledger/twin-node/commit/64c8ea8c8b5e918f7ad419c4e3b8d08faf5e3fdd))
121
+ * update dependencies ([aab05b5](https://github.com/iotaledger/twin-node/commit/aab05b552152a208a504fb9a080603f1990d4f79))
122
+ * update dependencies ([6cb3d3a](https://github.com/iotaledger/twin-node/commit/6cb3d3a63f7b976f80074ddecfba034b7e92f919))
123
+ * update dependencies ([#178](https://github.com/iotaledger/twin-node/issues/178)) ([0d346ec](https://github.com/iotaledger/twin-node/commit/0d346ec57f43f418b73fe71fcd2b187d769a53e9))
124
+ * update dependencies ([#316](https://github.com/iotaledger/twin-node/issues/316)) ([f3fe328](https://github.com/iotaledger/twin-node/commit/f3fe3281a80f34763c923eacca58364273a550b7))
125
+ * update docs ([61e5a00](https://github.com/iotaledger/twin-node/commit/61e5a004089a0c11ec03e354b076604ecdeb4817))
126
+ * update document management components ([ed2c065](https://github.com/iotaledger/twin-node/commit/ed2c065a5030a7233f3623818d7325d85654ef0d))
127
+ * update engine ([a40b377](https://github.com/iotaledger/twin-node/commit/a40b37726c3b61c6bb40265ec0006d1071ffac7e))
128
+ * update engine ([4b438e2](https://github.com/iotaledger/twin-node/commit/4b438e22c27d784ee6cc964b7cb4401e9699ab16))
129
+ * update engine dependency ([db290df](https://github.com/iotaledger/twin-node/commit/db290df3b18374f7d86da575c6048657b98c355b))
130
+ * update engine dependency ([3494c31](https://github.com/iotaledger/twin-node/commit/3494c3144fd5ce6d3a9f2936c7890ab36795aeaa))
131
+ * update for livez endpoint ([9fc2e6a](https://github.com/iotaledger/twin-node/commit/9fc2e6ade38b3ec9591399a633d02b1e5fe07910))
132
+ * update framework components ([4bee2b9](https://github.com/iotaledger/twin-node/commit/4bee2b9d3651df09b8550a9ed226be1b46031854))
133
+ * update logging retention units in config ([0b9bb69](https://github.com/iotaledger/twin-node/commit/0b9bb696db0722f6b33e37e1ebd1f4d6ffbcf7cc))
134
+ * update order of logging ([2161938](https://github.com/iotaledger/twin-node/commit/2161938c969b18e4678459a69090287e5ccdb404))
135
+ * update order of logging ([b295f31](https://github.com/iotaledger/twin-node/commit/b295f315f7c5b611d229d9e5314d414da05828b9))
136
+ * update rights management ([5c992c6](https://github.com/iotaledger/twin-node/commit/5c992c6b0d72f3eeaa39ee267e096d9a3f477f4e))
137
+ * update rights management components ([176a0d6](https://github.com/iotaledger/twin-node/commit/176a0d611f88360fc845ae233b26ee0b43d7cb23))
138
+ * update rights management dependencies ([97ad02e](https://github.com/iotaledger/twin-node/commit/97ad02e4b74cfe5e722f74da2fc2229bbf004c0a))
139
+ * update tests ([f15bc1f](https://github.com/iotaledger/twin-node/commit/f15bc1fb9fc1a7a9b6611ad42591d9c02e078cfb))
140
+ * update tests ([633797e](https://github.com/iotaledger/twin-node/commit/633797e3c4766ad7e47c472c153456c60e1a6ba2))
141
+ * update to latest engine ([00d4974](https://github.com/iotaledger/twin-node/commit/00d4974f9cfb02bf48505cfb4af4a7aba1df4b3d))
142
+ * updated context id features ([ef7be07](https://github.com/iotaledger/twin-node/commit/ef7be07d44dccdeacf10f90cb4ffde0303faa6fa))
143
+ * updating linting ([feacd17](https://github.com/iotaledger/twin-node/commit/feacd178bb025bcd29a0ae6e4b8e79f23a989169))
144
+ * use core env helpers ([568fbc5](https://github.com/iotaledger/twin-node/commit/568fbc53906b022bc8465ffb941a160075d88e96))
145
+ * use features instead of disableNodeIdentity ([2e6109b](https://github.com/iotaledger/twin-node/commit/2e6109bd1de825e0f5396fc120d99ad7b3929852))
146
+
147
+
148
+ ### Bug Fixes
149
+
150
+ * bootstrap legacy fails on second run ([c0a4e6d](https://github.com/iotaledger/twin-node/commit/c0a4e6d6f8d1bf385412a22fed2a0974e219abaa))
151
+ * bootstrap vault key skip logic ([#112](https://github.com/iotaledger/twin-node/issues/112)) ([4084368](https://github.com/iotaledger/twin-node/commit/4084368f0762c3a1b8e214ac30f5545297c88ea6))
152
+ * bump [@twin](https://github.com/twin).org deps to next.30 stack, fix node-core route snapshot ([#159](https://github.com/iotaledger/twin-node/issues/159)) ([73ad77f](https://github.com/iotaledger/twin-node/commit/73ad77f862050cb8dfcf42c484332bdacf026092))
153
+ * example typo for vault-key-create ([eed5844](https://github.com/iotaledger/twin-node/commit/eed58448b8e6d057fa964822d337cb2898d5bb54))
154
+ * immutable proof requirements ([2940579](https://github.com/iotaledger/twin-node/commit/29405798b24053c017adaaf08a2537ea6b1c8d0f))
155
+ * improve calculation of execution directory ([106d65d](https://github.com/iotaledger/twin-node/commit/106d65d7ad5524e2e147b681d68f9476c024cfaa))
156
+ * only register DID context keys when nodeIdentityEnabled is true ([#140](https://github.com/iotaledger/twin-node/issues/140)) ([21f1c10](https://github.com/iotaledger/twin-node/commit/21f1c107adbd715518414f7255ead970b809b4b3))
157
+ * optional private key in identity create ([325ebd8](https://github.com/iotaledger/twin-node/commit/325ebd859d95b3078107e76f1806cded078a0ce1))
158
+ * org identity verification methods ([18f158b](https://github.com/iotaledger/twin-node/commit/18f158b2f63930e20e94437c17ed43421771a458))
159
+ * recover tenant id on bootstrap-legacy restart when TENANT_ID is unset ([#198](https://github.com/iotaledger/twin-node/issues/198)) ([d9451e1](https://github.com/iotaledger/twin-node/commit/d9451e188fe4fd20d5cfd0408b0dc226ddf25cd8))
160
+ * register dataspace control plane rest client as multi-instance ([#191](https://github.com/iotaledger/twin-node/issues/191)) ([4548f5c](https://github.com/iotaledger/twin-node/commit/4548f5c6e7f1d65fd147e502e57d5686e60e5195))
161
+ * set dataspace control-plane callbackPath in node env builder ([#237](https://github.com/iotaledger/twin-node/issues/237)) ([2eac214](https://github.com/iotaledger/twin-node/commit/2eac21438e9f4b4a0bf84f30ebc864bd424aac35))
162
+ * stalled timeout now is provided in seconds ([#241](https://github.com/iotaledger/twin-node/issues/241)) ([ebd827d](https://github.com/iotaledger/twin-node/commit/ebd827d02a9a4f8ad4f4c84d064d02831ef015cb))
163
+ * support load-env for tenant-token cli command ([34059c0](https://github.com/iotaledger/twin-node/commit/34059c052a685decdd689beb16d2b250e9a83643))
164
+ * synchronised storage construction ([#102](https://github.com/iotaledger/twin-node/issues/102)) ([58b61e9](https://github.com/iotaledger/twin-node/commit/58b61e9a67f499a35bea17e5d2dc6a1efc2cb893))
165
+ * test endpoints ([2b83ed0](https://github.com/iotaledger/twin-node/commit/2b83ed0d4f1da473a525a95202e01d9680c7d26c))
166
+ * test with latest dependencies ([91123b7](https://github.com/iotaledger/twin-node/commit/91123b71d0e7b51700a5d5452b2a0c9fc5c5256e))
167
+ * update dependencies ([#279](https://github.com/iotaledger/twin-node/issues/279)) ([2c0de07](https://github.com/iotaledger/twin-node/commit/2c0de07a15541e73612ba5bd62f4f566e4efca34))
168
+ * use async getStore in tests ([2189df4](https://github.com/iotaledger/twin-node/commit/2189df49a57637ba8effdee50965473f0a814c6c))
169
+ * wire includeErrorStack debug flag into auth and tenant processor configs ([#313](https://github.com/iotaledger/twin-node/issues/313)) ([3c69c51](https://github.com/iotaledger/twin-node/commit/3c69c51bfdd65305efe2fbe9da508e684a4245d1))
170
+
3
171
  ## [0.10.0](https://github.com/iotaledger/twin-node/compare/node-core-v0.10.0...node-core-v0.10.0) (2026-09-16)
4
172
 
5
173
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/node-core",
3
- "version": "0.10.0",
3
+ "version": "0.10.1-next.2",
4
4
  "description": "TWIN Node Core for serving APIs using the specified configuration",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,40 +14,41 @@
14
14
  "node": ">=24.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/api-auth-entity-storage-models": "^0.10.0",
18
- "@twin.org/api-auth-entity-storage-service": "^0.10.0",
19
- "@twin.org/api-models": "^0.10.0",
20
- "@twin.org/api-tenant-processor": "^0.10.0",
21
- "@twin.org/cli-core": "^0.10.0",
22
- "@twin.org/context": "^0.10.0",
23
- "@twin.org/core": "^0.10.0",
24
- "@twin.org/crypto": "^0.10.0",
25
- "@twin.org/data-json-ld": "^0.10.0",
26
- "@twin.org/dlt-account": "^0.10.0",
27
- "@twin.org/dlt-iota": "^0.10.0",
28
- "@twin.org/engine": "^0.10.0",
29
- "@twin.org/engine-core": "^0.10.0",
30
- "@twin.org/engine-models": "^0.10.0",
31
- "@twin.org/engine-server": "^0.10.0",
32
- "@twin.org/engine-server-types": "^0.10.0",
33
- "@twin.org/engine-types": "^0.10.0",
34
- "@twin.org/entity": "^0.10.0",
35
- "@twin.org/entity-storage-models": "^0.10.0",
36
- "@twin.org/identity-connector-entity-storage": "^0.10.0",
37
- "@twin.org/identity-models": "^0.10.0",
38
- "@twin.org/logging-connector-opentelemetry": "^0.10.0",
39
- "@twin.org/modules": "^0.10.0",
40
- "@twin.org/nameof": "^0.10.0",
41
- "@twin.org/standards-w3c-did": "^0.10.0",
42
- "@twin.org/standards-w3c-odrl": "^0.10.0",
43
- "@twin.org/telemetry-connector-opentelemetry": "^0.10.0",
44
- "@twin.org/tracing-connector-opentelemetry": "^0.10.0",
45
- "@twin.org/tracing-facades": "^0.10.0",
46
- "@twin.org/tracing-models": "^0.10.0",
47
- "@twin.org/vault-models": "^0.10.0",
48
- "@twin.org/wallet-connector-entity-storage": "^0.10.0",
49
- "@twin.org/wallet-models": "^0.10.0",
50
- "@twin.org/web": "^0.10.0",
17
+ "@twin.org/api-auth-entity-storage-models": "next",
18
+ "@twin.org/api-auth-entity-storage-service": "next",
19
+ "@twin.org/api-models": "next",
20
+ "@twin.org/api-tenant-processor": "next",
21
+ "@twin.org/auditable-item-graph-service": "next",
22
+ "@twin.org/cli-core": "next",
23
+ "@twin.org/context": "next",
24
+ "@twin.org/core": "next",
25
+ "@twin.org/crypto": "next",
26
+ "@twin.org/data-json-ld": "next",
27
+ "@twin.org/dlt-account": "next",
28
+ "@twin.org/dlt-iota": "next",
29
+ "@twin.org/engine": "next",
30
+ "@twin.org/engine-core": "next",
31
+ "@twin.org/engine-models": "next",
32
+ "@twin.org/engine-server": "next",
33
+ "@twin.org/engine-server-types": "next",
34
+ "@twin.org/engine-types": "next",
35
+ "@twin.org/entity": "next",
36
+ "@twin.org/entity-storage-models": "next",
37
+ "@twin.org/identity-connector-entity-storage": "next",
38
+ "@twin.org/identity-models": "next",
39
+ "@twin.org/logging-connector-opentelemetry": "next",
40
+ "@twin.org/modules": "next",
41
+ "@twin.org/nameof": "next",
42
+ "@twin.org/standards-w3c-did": "next",
43
+ "@twin.org/standards-w3c-odrl": "next",
44
+ "@twin.org/telemetry-connector-opentelemetry": "next",
45
+ "@twin.org/tracing-connector-opentelemetry": "next",
46
+ "@twin.org/tracing-facades": "next",
47
+ "@twin.org/tracing-models": "next",
48
+ "@twin.org/vault-models": "next",
49
+ "@twin.org/wallet-connector-entity-storage": "next",
50
+ "@twin.org/wallet-models": "next",
51
+ "@twin.org/web": "next",
51
52
  "dotenv": "17.4.2",
52
53
  "schema-dts": "2.0.0"
53
54
  },