@twin.org/node-core 0.0.3-next.9 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/README.md +3 -1
  2. package/dist/es/builders/engineEnvBuilder.js +470 -174
  3. package/dist/es/builders/engineEnvBuilder.js.map +1 -1
  4. package/dist/es/builders/engineServerEnvBuilder.js +87 -39
  5. package/dist/es/builders/engineServerEnvBuilder.js.map +1 -1
  6. package/dist/es/builders/extensionsBuilder.js +3 -3
  7. package/dist/es/builders/extensionsBuilder.js.map +1 -1
  8. package/dist/es/cli.js +254 -0
  9. package/dist/es/cli.js.map +1 -0
  10. package/dist/es/commands/bootstrapLegacy.js +312 -0
  11. package/dist/es/commands/bootstrapLegacy.js.map +1 -0
  12. package/dist/es/commands/help.js +86 -0
  13. package/dist/es/commands/help.js.map +1 -0
  14. package/dist/es/commands/identityCreate.js +377 -0
  15. package/dist/es/commands/identityCreate.js.map +1 -0
  16. package/dist/es/commands/identityImports.js +83 -0
  17. package/dist/es/commands/identityImports.js.map +1 -0
  18. package/dist/es/commands/identityVerifiableCredentialCreate.js +146 -0
  19. package/dist/es/commands/identityVerifiableCredentialCreate.js.map +1 -0
  20. package/dist/es/commands/identityVerificationMethodCreate.js +231 -0
  21. package/dist/es/commands/identityVerificationMethodCreate.js.map +1 -0
  22. package/dist/es/commands/identityVerificationMethodImport.js +127 -0
  23. package/dist/es/commands/identityVerificationMethodImport.js.map +1 -0
  24. package/dist/es/commands/nodeSetIdentity.js +69 -0
  25. package/dist/es/commands/nodeSetIdentity.js.map +1 -0
  26. package/dist/es/commands/removeTenantOrgAlias.js +83 -0
  27. package/dist/es/commands/removeTenantOrgAlias.js.map +1 -0
  28. package/dist/es/commands/setNodeOrgId.js +62 -0
  29. package/dist/es/commands/setNodeOrgId.js.map +1 -0
  30. package/dist/es/commands/setTenantOrgId.js +99 -0
  31. package/dist/es/commands/setTenantOrgId.js.map +1 -0
  32. package/dist/es/commands/tenantCreate.js +165 -0
  33. package/dist/es/commands/tenantCreate.js.map +1 -0
  34. package/dist/es/commands/tenantImport.js +108 -0
  35. package/dist/es/commands/tenantImport.js.map +1 -0
  36. package/dist/es/commands/tenantUpdate.js +108 -0
  37. package/dist/es/commands/tenantUpdate.js.map +1 -0
  38. package/dist/es/commands/userCreate.js +239 -0
  39. package/dist/es/commands/userCreate.js.map +1 -0
  40. package/dist/es/commands/userUpdate.js +154 -0
  41. package/dist/es/commands/userUpdate.js.map +1 -0
  42. package/dist/es/commands/vaultKeyCreate.js +191 -0
  43. package/dist/es/commands/vaultKeyCreate.js.map +1 -0
  44. package/dist/es/commands/vaultKeyImport.js +105 -0
  45. package/dist/es/commands/vaultKeyImport.js.map +1 -0
  46. package/dist/es/defaults.js +37 -2
  47. package/dist/es/defaults.js.map +1 -1
  48. package/dist/es/index.js +13 -4
  49. package/dist/es/index.js.map +1 -1
  50. package/dist/es/models/IBootstrapLegacyEnvironmentVariables.js +4 -0
  51. package/dist/es/models/IBootstrapLegacyEnvironmentVariables.js.map +1 -0
  52. package/dist/es/models/ICliArgs.js +4 -0
  53. package/dist/es/models/ICliArgs.js.map +1 -0
  54. package/dist/es/models/ICliCommand.js +2 -0
  55. package/dist/es/models/ICliCommand.js.map +1 -0
  56. package/dist/es/models/ICliCommandDefinition.js +2 -0
  57. package/dist/es/models/ICliCommandDefinition.js.map +1 -0
  58. package/dist/es/models/ICliCommandDefinitionParam.js +2 -0
  59. package/dist/es/models/ICliCommandDefinitionParam.js.map +1 -0
  60. package/dist/es/models/IEngineEnvironmentVariables.js.map +1 -1
  61. package/dist/es/models/IEngineServerEnvironmentVariables.js +2 -0
  62. package/dist/es/models/IEngineServerEnvironmentVariables.js.map +1 -1
  63. package/dist/es/models/IEnvironmentVariables.js +2 -0
  64. package/dist/es/models/IEnvironmentVariables.js.map +1 -0
  65. package/dist/es/models/INodeEngineState.js.map +1 -1
  66. package/dist/es/models/INodeEnvironmentVariables.js +2 -0
  67. package/dist/es/models/INodeEnvironmentVariables.js.map +1 -1
  68. package/dist/es/models/INodeOptions.js.map +1 -1
  69. package/dist/es/models/bootstrapLegacyEnvironmentVariableKeys.js +24 -0
  70. package/dist/es/models/bootstrapLegacyEnvironmentVariableKeys.js.map +1 -0
  71. package/dist/es/models/cliCommandParamType.js +4 -0
  72. package/dist/es/models/cliCommandParamType.js.map +1 -0
  73. package/dist/es/models/engineEnvironmentVariableKeys.js +202 -0
  74. package/dist/es/models/engineEnvironmentVariableKeys.js.map +1 -0
  75. package/dist/es/models/engineServerEnvironmentVariableKeys.js +35 -0
  76. package/dist/es/models/engineServerEnvironmentVariableKeys.js.map +1 -0
  77. package/dist/es/models/nodeEnvironmentVariableKeys.js +18 -0
  78. package/dist/es/models/nodeEnvironmentVariableKeys.js.map +1 -0
  79. package/dist/es/models/nodeExtensionInitialiseEngineMethod.js +2 -0
  80. package/dist/es/models/nodeExtensionInitialiseEngineMethod.js.map +1 -0
  81. package/dist/es/models/nodeExtensionInitialiseEngineServerMethod.js +2 -0
  82. package/dist/es/models/nodeExtensionInitialiseEngineServerMethod.js.map +1 -0
  83. package/dist/es/models/nodeExtensionInitialiseMethod.js +2 -0
  84. package/dist/es/models/nodeExtensionInitialiseMethod.js.map +1 -0
  85. package/dist/es/models/nodeExtensionShutdownMethod.js +4 -0
  86. package/dist/es/models/nodeExtensionShutdownMethod.js.map +1 -0
  87. package/dist/es/node.js +180 -42
  88. package/dist/es/node.js.map +1 -1
  89. package/dist/es/start.js +189 -0
  90. package/dist/es/start.js.map +1 -0
  91. package/dist/es/utils.js +24 -27
  92. package/dist/es/utils.js.map +1 -1
  93. package/dist/types/builders/engineEnvBuilder.d.ts +60 -5
  94. package/dist/types/builders/engineServerEnvBuilder.d.ts +12 -3
  95. package/dist/types/builders/extensionsBuilder.d.ts +8 -8
  96. package/dist/types/cli.d.ts +56 -0
  97. package/dist/types/commands/bootstrapLegacy.d.ts +20 -0
  98. package/dist/types/commands/help.d.ts +24 -0
  99. package/dist/types/commands/identityCreate.d.ts +45 -0
  100. package/dist/types/commands/identityImports.d.ts +25 -0
  101. package/dist/types/commands/identityVerifiableCredentialCreate.d.ts +43 -0
  102. package/dist/types/commands/identityVerificationMethodCreate.d.ts +47 -0
  103. package/dist/types/commands/identityVerificationMethodImport.d.ts +32 -0
  104. package/dist/types/commands/nodeSetIdentity.d.ts +23 -0
  105. package/dist/types/commands/removeTenantOrgAlias.d.ts +24 -0
  106. package/dist/types/commands/setNodeOrgId.d.ts +24 -0
  107. package/dist/types/commands/setTenantOrgId.d.ts +38 -0
  108. package/dist/types/commands/tenantCreate.d.ts +41 -0
  109. package/dist/types/commands/tenantImport.d.ts +29 -0
  110. package/dist/types/commands/tenantUpdate.d.ts +29 -0
  111. package/dist/types/commands/userCreate.d.ts +51 -0
  112. package/dist/types/commands/userUpdate.d.ts +40 -0
  113. package/dist/types/commands/vaultKeyCreate.d.ts +43 -0
  114. package/dist/types/commands/vaultKeyImport.d.ts +29 -0
  115. package/dist/types/defaults.d.ts +30 -2
  116. package/dist/types/index.d.ts +13 -4
  117. package/dist/types/models/IBootstrapLegacyEnvironmentVariables.d.ts +56 -0
  118. package/dist/types/models/ICliArgs.d.ts +20 -0
  119. package/dist/types/models/ICliCommand.d.ts +17 -0
  120. package/dist/types/models/ICliCommandDefinition.d.ts +46 -0
  121. package/dist/types/models/ICliCommandDefinitionParam.d.ts +35 -0
  122. package/dist/types/models/IEngineEnvironmentVariables.d.ts +199 -96
  123. package/dist/types/models/IEngineServerEnvironmentVariables.d.ts +9 -2
  124. package/dist/types/models/IEnvironmentVariables.d.ts +8 -0
  125. package/dist/types/models/INodeEngineState.d.ts +2 -9
  126. package/dist/types/models/INodeEnvironmentVariables.d.ts +1 -40
  127. package/dist/types/models/INodeOptions.d.ts +9 -5
  128. package/dist/types/models/bootstrapLegacyEnvironmentVariableKeys.d.ts +4 -0
  129. package/dist/types/models/cliCommandParamType.d.ts +4 -0
  130. package/dist/types/models/engineEnvironmentVariableKeys.d.ts +4 -0
  131. package/dist/types/models/engineServerEnvironmentVariableKeys.d.ts +7 -0
  132. package/dist/types/models/nodeEnvironmentVariableKeys.d.ts +5 -0
  133. package/dist/types/models/nodeExtensionInitialiseEngineMethod.d.ts +8 -0
  134. package/dist/types/models/nodeExtensionInitialiseEngineServerMethod.d.ts +9 -0
  135. package/dist/types/models/nodeExtensionInitialiseMethod.d.ts +9 -0
  136. package/dist/types/models/nodeExtensionShutdownMethod.d.ts +6 -0
  137. package/dist/types/node.d.ts +8 -7
  138. package/dist/types/{server.d.ts → start.d.ts} +6 -3
  139. package/dist/types/utils.d.ts +9 -10
  140. package/docs/changelog.md +883 -186
  141. package/docs/examples.md +99 -1
  142. package/docs/reference/functions/buildConfiguration.md +3 -3
  143. package/docs/reference/functions/buildEngineConfiguration.md +1 -7
  144. package/docs/reference/functions/buildEngineServerConfiguration.md +1 -1
  145. package/docs/reference/functions/constructCliCommand.md +27 -0
  146. package/docs/reference/functions/executeCommand.md +29 -0
  147. package/docs/reference/functions/extensionsConfiguration.md +1 -1
  148. package/docs/reference/functions/extensionsInitialiseEngine.md +2 -2
  149. package/docs/reference/functions/extensionsInitialiseEngineServer.md +2 -2
  150. package/docs/reference/functions/getEnvDefaults.md +19 -0
  151. package/docs/reference/functions/getScriptDirectory.md +19 -0
  152. package/docs/reference/functions/initialiseLocales.md +2 -0
  153. package/docs/reference/functions/isAuthEntityStorageRequired.md +20 -0
  154. package/docs/reference/functions/isAutomationRequired.md +20 -0
  155. package/docs/reference/functions/isBackgroundTasksRequired.md +20 -0
  156. package/docs/reference/functions/isFederatedCatalogueRequired.md +20 -0
  157. package/docs/reference/functions/isImmutableProofRequired.md +20 -0
  158. package/docs/reference/functions/isRightsManagementRequired.md +23 -0
  159. package/docs/reference/functions/isTaskSchedulerRequired.md +20 -0
  160. package/docs/reference/functions/isTelemetryRequired.md +20 -0
  161. package/docs/reference/functions/isTrustRequired.md +20 -0
  162. package/docs/reference/functions/loadJsonFile.md +1 -1
  163. package/docs/reference/functions/loadTextFile.md +1 -1
  164. package/docs/reference/functions/overrideModuleImport.md +1 -1
  165. package/docs/reference/functions/parseCommandLineArgs.md +19 -0
  166. package/docs/reference/functions/processEnvOptions.md +27 -0
  167. package/docs/reference/functions/registerCommands.md +9 -0
  168. package/docs/reference/functions/resolvePackageEntryPoint.md +2 -2
  169. package/docs/reference/functions/run.md +8 -2
  170. package/docs/reference/functions/shutdownExtensions.md +2 -2
  171. package/docs/reference/functions/start.md +10 -4
  172. package/docs/reference/functions/substituteEnvOptions.md +25 -0
  173. package/docs/reference/index.md +26 -14
  174. package/docs/reference/interfaces/IBootstrapLegacyEnvironmentVariables.md +117 -0
  175. package/docs/reference/interfaces/ICacheMetadata.md +3 -3
  176. package/docs/reference/interfaces/ICliArgs.md +35 -0
  177. package/docs/reference/interfaces/ICliCommand.md +23 -0
  178. package/docs/reference/interfaces/ICliCommandDefinition.md +101 -0
  179. package/docs/reference/interfaces/ICliCommandDefinitionParam.md +65 -0
  180. package/docs/reference/interfaces/IEngineEnvironmentVariables.md +553 -365
  181. package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +41 -1746
  182. package/docs/reference/interfaces/IModuleProtocol.md +3 -3
  183. package/docs/reference/interfaces/INodeEngineState.md +6 -21
  184. package/docs/reference/interfaces/INodeEnvironmentVariables.md +10 -1967
  185. package/docs/reference/interfaces/INodeOptions.md +46 -38
  186. package/docs/reference/interfaces/IProtocolHandlerResult.md +2 -2
  187. package/docs/reference/type-aliases/CliCommandParamType.md +5 -0
  188. package/docs/reference/type-aliases/IEnvironmentVariables.md +5 -0
  189. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineMethod.md +3 -1
  190. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineServerMethod.md +3 -1
  191. package/docs/reference/type-aliases/NodeExtensionInitialiseMethod.md +4 -2
  192. package/docs/reference/type-aliases/NodeExtensionShutdownMethod.md +3 -1
  193. package/docs/reference/variables/ATTESTATION_VERIFICATION_METHOD_ID.md +2 -0
  194. package/docs/reference/variables/AUTH_SIGNING_KEY_ID.md +2 -0
  195. package/docs/reference/variables/BLOB_STORAGE_ENCRYPTION_KEY_ID.md +2 -0
  196. package/docs/reference/variables/CONTEXT_ID_HANDLER_FEATURE_DID.md +2 -0
  197. package/docs/reference/variables/CONTEXT_ID_HANDLER_FEATURE_TENANT.md +2 -0
  198. package/docs/reference/variables/IMMUTABLE_PROOF_VERIFICATION_METHOD_ID.md +2 -0
  199. package/docs/reference/variables/ModuleProtocol.md +5 -5
  200. package/docs/reference/variables/TRUST_VERIFICATION_METHOD_ID.md +5 -0
  201. package/locales/en.json +680 -30
  202. package/package.json +30 -27
  203. package/dist/es/bootstrap.js +0 -383
  204. package/dist/es/bootstrap.js.map +0 -1
  205. package/dist/es/identity.js +0 -182
  206. package/dist/es/identity.js.map +0 -1
  207. package/dist/es/models/nodeExtensionMethods.js +0 -2
  208. package/dist/es/models/nodeExtensionMethods.js.map +0 -1
  209. package/dist/es/models/nodeFeatures.js +0 -21
  210. package/dist/es/models/nodeFeatures.js.map +0 -1
  211. package/dist/es/server.js +0 -81
  212. package/dist/es/server.js.map +0 -1
  213. package/dist/types/bootstrap.d.ts +0 -68
  214. package/dist/types/identity.d.ts +0 -14
  215. package/dist/types/models/nodeExtensionMethods.d.ts +0 -27
  216. package/dist/types/models/nodeFeatures.d.ts +0 -21
  217. package/docs/detailed-guide.md +0 -129
  218. package/docs/reference/functions/bootstrap.md +0 -29
  219. package/docs/reference/functions/bootstrapAuth.md +0 -35
  220. package/docs/reference/functions/bootstrapBlobEncryption.md +0 -35
  221. package/docs/reference/functions/bootstrapImmutableProofMethod.md +0 -35
  222. package/docs/reference/functions/bootstrapNodeAdminUser.md +0 -35
  223. package/docs/reference/functions/bootstrapNodeId.md +0 -35
  224. package/docs/reference/functions/bootstrapSynchronisedStorage.md +0 -35
  225. package/docs/reference/functions/bootstrapTenantId.md +0 -35
  226. package/docs/reference/functions/getFeatures.md +0 -19
  227. package/docs/reference/type-aliases/NodeFeatures.md +0 -5
  228. package/docs/reference/variables/NodeFeatures.md +0 -25
  229. package/docs/reference/variables/SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID.md +0 -3
  230. package/docs/reference/variables/VC_AUTHENTICATION_VERIFICATION_METHOD_ID.md +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { CLIDisplay } from \"@twin.org/cli-core\";\nimport { ContextIdStore } from \"@twin.org/context\";\nimport { Coerce, GeneralError, I18n, Is, StringHelper } from \"@twin.org/core\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport * as dotenv from \"dotenv\";\nimport { getCommandDefinitionBootstrapLegacy } from \"./commands/bootstrapLegacy.js\";\nimport { getCommandDefinitionHelp } from \"./commands/help.js\";\nimport { getCommandDefinitionIdentityCreate } from \"./commands/identityCreate.js\";\nimport { getCommandDefinitionIdentityImport } from \"./commands/identityImports.js\";\nimport { getCommandDefinitionIdentityVerifiableCredentialCreate } from \"./commands/identityVerifiableCredentialCreate.js\";\nimport { getCommandDefinitionIdentityVerificationMethodCreate } from \"./commands/identityVerificationMethodCreate.js\";\nimport { getCommandDefinitionIdentityVerificationMethodImport } from \"./commands/identityVerificationMethodImport.js\";\nimport { getCommandDefinitionNodeSetIdentity } from \"./commands/nodeSetIdentity.js\";\nimport { getCommandDefinitionRemoveTenantOrgAlias } from \"./commands/removeTenantOrgAlias.js\";\nimport { getCommandDefinitionSetNodeOrgId } from \"./commands/setNodeOrgId.js\";\nimport { getCommandDefinitionSetTenantOrgId } from \"./commands/setTenantOrgId.js\";\nimport { getCommandDefinitionTenantCreate } from \"./commands/tenantCreate.js\";\nimport { getCommandDefinitionTenantImport } from \"./commands/tenantImport.js\";\nimport { getCommandDefinitionTenantUpdate } from \"./commands/tenantUpdate.js\";\nimport { getCommandDefinitionUserCreate } from \"./commands/userCreate.js\";\nimport { getCommandDefinitionUserUpdate } from \"./commands/userUpdate.js\";\nimport { getCommandDefinitionVaultKeyCreate } from \"./commands/vaultKeyCreate.js\";\nimport { getCommandDefinitionVaultKeyImport } from \"./commands/vaultKeyImport.js\";\nimport type { CliCommandParamType } from \"./models/cliCommandParamType.js\";\nimport type { ICliArgs } from \"./models/ICliArgs.js\";\nimport type { ICliCommand } from \"./models/ICliCommand.js\";\nimport type { ICliCommandDefinition } from \"./models/ICliCommandDefinition.js\";\nimport type { IEnvironmentVariables } from \"./models/IEnvironmentVariables.js\";\n\nconst commandDefinitions: { [id: string]: ICliCommandDefinition } = {};\n\n/**\n * Parse command line arguments.\n * @param args The command line arguments.\n * @returns The parsed command line arguments.\n */\nexport function parseCommandLineArgs(args?: string[]): ICliArgs {\n\tlet nodePath;\n\tlet scriptPath;\n\tlet options:\n\t\t| {\n\t\t\t\tkey: string;\n\t\t\t\tvalue: string;\n\t\t }[]\n\t\t| undefined;\n\n\tif (Is.arrayValue(args)) {\n\t\tif (args.length > 0) {\n\t\t\tnodePath = args[0];\n\t\t}\n\t\tif (args.length > 1) {\n\t\t\tscriptPath = args[1];\n\t\t}\n\t\tif (args.length > 2) {\n\t\t\toptions = [];\n\n\t\t\tfor (let i = 2; i < args.length; i++) {\n\t\t\t\tconst arg = args[i];\n\t\t\t\tconst equalIndex = arg.indexOf(\"=\");\n\t\t\t\tif (equalIndex > 0) {\n\t\t\t\t\tconst key = arg.slice(0, equalIndex).trim();\n\t\t\t\t\tconst value = arg.slice(equalIndex + 1).trim();\n\t\t\t\t\tif (key.startsWith(\"--\")) {\n\t\t\t\t\t\toptions.push({ key: key.slice(2), value });\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\toptions.push({ key: arg, value: \"\" });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tnodePath,\n\t\tscriptPath,\n\t\toptions\n\t};\n}\n\n/**\n * Construct the CLI command from the parsed arguments.\n * @param processEnv The environment variables from the process.\n * @param cliArgs The parsed CLI arguments.\n * @returns The constructed CLI command.\n * @throws GeneralError if the command is missing.\n */\nexport function constructCliCommand(\n\tprocessEnv: {\n\t\t[id: string]: string;\n\t},\n\tcliArgs: ICliArgs\n): ICliCommand | undefined {\n\tif (Is.arrayValue(cliArgs.options)) {\n\t\tconst command = cliArgs.options[0];\n\n\t\t// If the first option is --help, we can display help for all commands\n\t\tif (command.key === \"--help\") {\n\t\t\treturn {\n\t\t\t\tdefinition: commandDefinitions.help,\n\t\t\t\tparams: {}\n\t\t\t};\n\t\t}\n\n\t\t// In cases where no command but env-prefix is provided, we just return\n\t\tif (command.key === \"env-prefix\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (!commandDefinitions[command.key]) {\n\t\t\tthrow new GeneralError(\"node\", \"cliCommandMissing\", { command: command.key });\n\t\t}\n\n\t\t// We have a valid command, check for --help for that command\n\t\tconst hasHelp = cliArgs.options.find(option => option.key === \"--help\");\n\t\tif (hasHelp) {\n\t\t\treturn {\n\t\t\t\tdefinition: commandDefinitions.help,\n\t\t\t\tparams: {\n\t\t\t\t\tcommand: command.key\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tprocessEnvOptions(processEnv, cliArgs.options);\n\n\t\tconst cliParams: { [id: string]: CliCommandParamType } = {};\n\t\tconst allParamKeys = cliArgs.options\n\t\t\t.map(option => option.key)\n\t\t\t.filter(key => key !== command.key);\n\n\t\tfor (const commandDefParam of commandDefinitions[command.key].params) {\n\t\t\tconst foundParamIndex =\n\t\t\t\tcliArgs.options?.findIndex(option => option.key === commandDefParam.key) ?? -1;\n\t\t\tconst foundParam = foundParamIndex >= 0 ? cliArgs.options?.[foundParamIndex] : undefined;\n\n\t\t\tlet paramValue;\n\t\t\tif (commandDefParam.type === \"number\") {\n\t\t\t\tparamValue = Coerce.number(foundParam?.value ?? commandDefParam.defaultValue);\n\t\t\t} else if (commandDefParam.type === \"boolean\") {\n\t\t\t\tparamValue = Coerce.boolean(foundParam?.value ?? commandDefParam.defaultValue);\n\t\t\t} else {\n\t\t\t\tparamValue = Coerce.string(foundParam?.value ?? commandDefParam.defaultValue);\n\t\t\t}\n\n\t\t\tconst required = commandDefParam.required ?? true;\n\t\t\tif (Is.empty(paramValue) && required) {\n\t\t\t\tthrow new GeneralError(\"node\", \"cliCommandParamMissing\", {\n\t\t\t\t\tcommand: command.key,\n\t\t\t\t\tparam: commandDefParam.key\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!Is.empty(paramValue)) {\n\t\t\t\tcliParams[StringHelper.camelCase(commandDefParam.key)] = paramValue;\n\t\t\t}\n\n\t\t\tif (foundParamIndex >= 0) {\n\t\t\t\tconst paramIndex = allParamKeys.indexOf(commandDefParam.key);\n\t\t\t\tif (paramIndex >= 0) {\n\t\t\t\t\tallParamKeys.splice(paramIndex, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (allParamKeys.length > 0) {\n\t\t\tthrow new GeneralError(\"node\", \"cliCommandParamExtra\", {\n\t\t\t\tcommand: command.key,\n\t\t\t\tparams: allParamKeys.join(\", \")\n\t\t\t});\n\t\t}\n\n\t\tif (commandDefinitions[command.key].params.find(param => param.key === \"output-env-prefix\")) {\n\t\t\tcliParams.outputEnvPrefix = (Coerce.string(cliParams.outputEnvPrefix) ?? \"\").toUpperCase();\n\t\t\tcliParams.outputEnvPrefix =\n\t\t\t\tcliParams.outputEnvPrefix.length > 0 && !cliParams.outputEnvPrefix.endsWith(\"_\")\n\t\t\t\t\t? `${cliParams.outputEnvPrefix}_`\n\t\t\t\t\t: cliParams.outputEnvPrefix;\n\t\t}\n\n\t\treturn {\n\t\t\tdefinition: commandDefinitions[command.key],\n\t\t\tparams: cliParams\n\t\t};\n\t}\n}\n\n/**\n * Execute the CLI command.\n * @param engineCore The engine core.\n * @param envVars The environment variables for the node.\n * @param cliCommand The CLI command to execute.\n */\nexport async function executeCommand(\n\tengineCore: IEngineCore,\n\tenvVars: IEnvironmentVariables,\n\tcliCommand: ICliCommand\n): Promise<void> {\n\tconst requiresEngineStarted = cliCommand.definition.requiresEngineStarted ?? true;\n\n\ttry {\n\t\tif (requiresEngineStarted) {\n\t\t\tawait engineCore.start(true);\n\t\t}\n\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"node.cli.commands.command\"),\n\t\t\tcliCommand.definition.command\n\t\t);\n\t\tfor (const paramKey in cliCommand.params) {\n\t\t\tCLIDisplay.value(paramKey, Coerce.string(cliCommand.params[paramKey]), 1);\n\t\t}\n\t\tCLIDisplay.break();\n\n\t\tawait ContextIdStore.run(engineCore.getContextIds() ?? {}, async () => {\n\t\t\tawait cliCommand.definition.action(engineCore, envVars, cliCommand.params);\n\t\t});\n\t} catch (error) {\n\t\tCLIDisplay.spinnerStop();\n\n\t\tthrow error;\n\t} finally {\n\t\tif (requiresEngineStarted) {\n\t\t\tCLIDisplay.break();\n\t\t\tawait engineCore.stop();\n\t\t}\n\t}\n}\n\n/**\n * Load the env files and process the options.\n * @param processEnv The environment variables from the process.\n * @param options The options.\n * @returns The substituted options, mutated in place with env variable values resolved.\n * @throws GeneralError if an env file has errors.\n */\nexport function processEnvOptions(\n\tprocessEnv: {\n\t\t[id: string]: string;\n\t},\n\toptions: {\n\t\tkey: string;\n\t\tvalue: string;\n\t}[]\n): void {\n\tconst inputEnv = options.find(option => option.key === \"load-env\")?.value;\n\n\tif (Is.stringValue(inputEnv)) {\n\t\tconst envFiles = inputEnv.split(\",\").map(f => f.trim());\n\t\tfor (const envFile of envFiles) {\n\t\t\tconst output = dotenv.config({\n\t\t\t\tpath: envFile,\n\t\t\t\tquiet: true\n\t\t\t});\n\n\t\t\tif (output.error) {\n\t\t\t\tthrow output.error;\n\t\t\t}\n\n\t\t\tif (Is.objectValue(output.parsed)) {\n\t\t\t\tfor (const key in output.parsed) {\n\t\t\t\t\tprocessEnv[key] = output.parsed[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn substituteEnvOptions(processEnv, options);\n}\n\n/**\n * Process options and replace any env variables with their values.\n * @param processEnv The environment variables from the process.\n * @param options The options.\n * @throws GeneralError if an env variable is missing.\n */\nexport function substituteEnvOptions(\n\tprocessEnv: {\n\t\t[id: string]: string;\n\t},\n\toptions: {\n\t\tkey: string;\n\t\tvalue: string;\n\t}[]\n): void {\n\tfor (const option of options) {\n\t\tif (option.value.startsWith(\"!\")) {\n\t\t\tconst envVar = processEnv[option.value.slice(1)];\n\t\t\tif (!Is.stringValue(envVar)) {\n\t\t\t\tthrow new GeneralError(\"node\", \"cliEnvVarMissing\", { envVar: option.value.slice(1) });\n\t\t\t}\n\t\t\toption.value = envVar;\n\t\t}\n\t}\n}\n\n/**\n * Register all built-in CLI command definitions into the shared command map.\n */\nexport function registerCommands(): void {\n\tgetCommandDefinitionHelp(commandDefinitions);\n\tgetCommandDefinitionBootstrapLegacy(commandDefinitions);\n\tgetCommandDefinitionIdentityCreate(commandDefinitions);\n\tgetCommandDefinitionIdentityImport(commandDefinitions);\n\tgetCommandDefinitionIdentityVerificationMethodCreate(commandDefinitions);\n\tgetCommandDefinitionIdentityVerificationMethodImport(commandDefinitions);\n\tgetCommandDefinitionIdentityVerifiableCredentialCreate(commandDefinitions);\n\tgetCommandDefinitionNodeSetIdentity(commandDefinitions);\n\tgetCommandDefinitionSetNodeOrgId(commandDefinitions);\n\tgetCommandDefinitionSetTenantOrgId(commandDefinitions);\n\tgetCommandDefinitionRemoveTenantOrgAlias(commandDefinitions);\n\tgetCommandDefinitionTenantCreate(commandDefinitions);\n\tgetCommandDefinitionTenantImport(commandDefinitions);\n\tgetCommandDefinitionTenantUpdate(commandDefinitions);\n\tgetCommandDefinitionUserCreate(commandDefinitions);\n\tgetCommandDefinitionUserUpdate(commandDefinitions);\n\tgetCommandDefinitionVaultKeyCreate(commandDefinitions);\n\tgetCommandDefinitionVaultKeyImport(commandDefinitions);\n}\n"]}
@@ -0,0 +1,312 @@
1
+ import { CLIDisplay } from "@twin.org/cli-core";
2
+ import { ContextIdKeys, ContextIdStore } from "@twin.org/context";
3
+ import { Coerce, ComponentFactory, GeneralError, I18n, Is } from "@twin.org/core";
4
+ import { identityCreate } from "./identityCreate.js";
5
+ import { identityVerificationMethodCreate } from "./identityVerificationMethodCreate.js";
6
+ import { tenantCreate } from "./tenantCreate.js";
7
+ import { userCreate } from "./userCreate.js";
8
+ import { vaultKeyCreate } from "./vaultKeyCreate.js";
9
+ const COMMAND_NAME = "bootstrap-legacy";
10
+ /**
11
+ * Get the command definition parameters.
12
+ * @param commandDefinitions The registered command definitions.
13
+ */
14
+ export function getCommandDefinitionBootstrapLegacy(commandDefinitions) {
15
+ commandDefinitions[COMMAND_NAME] = {
16
+ command: COMMAND_NAME,
17
+ description: I18n.formatMessage("node.cli.commands.bootstrap-legacy.description"),
18
+ example: I18n.formatMessage("node.cli.commands.bootstrap-legacy.example"),
19
+ requiresNodeIdentity: false,
20
+ requiresOrgIdentity: false,
21
+ params: [
22
+ {
23
+ key: "env-prefix",
24
+ type: "string",
25
+ description: I18n.formatMessage("node.cli.commands.bootstrap-legacy.params.env-prefix.description"),
26
+ required: false
27
+ },
28
+ {
29
+ key: "load-env",
30
+ type: "string",
31
+ description: I18n.formatMessage("node.cli.commands.bootstrap-legacy.params.load-env.description"),
32
+ required: false
33
+ }
34
+ ],
35
+ action: async (engineCore, envVars, params) => bootstrapLegacy(engineCore, envVars, params)
36
+ };
37
+ }
38
+ /**
39
+ * Command for legacy bootstrap.
40
+ * @param engineCore The engine core.
41
+ * @param envVars The environment variables for the node.
42
+ * @param params The parameters for the command.
43
+ * @returns A promise that resolves when the bootstrap sequence has completed.
44
+ */
45
+ export async function bootstrapLegacy(engineCore, envVars, params) {
46
+ const features = (envVars.features ?? "admin-user,wallet")
47
+ .split(",")
48
+ .map(f => f.trim())
49
+ .filter(f => f.length > 0);
50
+ const state = engineCore.getState();
51
+ const requireWallet = features.includes("wallet");
52
+ const tenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;
53
+ let nodeId = state.nodeId ?? envVars.nodeIdentity;
54
+ let organizationId = tenantEnabled ? undefined : state.nodeOrganizationId;
55
+ let tenant;
56
+ if (features.length === 0) {
57
+ throw new GeneralError("bootstrapLegacy", "noFeaturesEnabled");
58
+ }
59
+ CLIDisplay.break();
60
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.nodeIdentityCreate"));
61
+ const nodeIdentity = await identityCreate(engineCore, envVars, {
62
+ identity: nodeId,
63
+ mnemonic: envVars.nodeMnemonic,
64
+ fundWallet: requireWallet,
65
+ nodeId: true
66
+ });
67
+ nodeId = nodeIdentity.did;
68
+ CLIDisplay.break();
69
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.nodeAuthKeyCreate"));
70
+ await vaultKeyCreate(engineCore, envVars, {
71
+ identity: nodeId,
72
+ keyType: "Ed25519",
73
+ keyId: envVars.authSigningKeyId,
74
+ overwriteMode: "skip"
75
+ });
76
+ // Always create the organisation identity first so it can be associated with
77
+ // the tenant (multi-tenant) or the node (single-tenant) immediately after.
78
+ // The trust verification method is always added to the organisation identity.
79
+ await ContextIdStore.run({ [ContextIdKeys.Node]: nodeId }, async () => {
80
+ CLIDisplay.break();
81
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.organisationCreate"));
82
+ if (tenantEnabled) {
83
+ const existingTenant = Is.stringValue(envVars.tenantId)
84
+ ? await resolveTenantById(engineCore, envVars.tenantId)
85
+ : await resolveDefaultTenant(engineCore);
86
+ organizationId = existingTenant?.organizationId;
87
+ }
88
+ const organisation = await identityCreate(engineCore, envVars, {
89
+ identity: organizationId ?? envVars.organizationIdentity,
90
+ mnemonic: envVars.organizationMnemonic,
91
+ fundWallet: requireWallet
92
+ });
93
+ organizationId = organisation.did;
94
+ CLIDisplay.break();
95
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.trustVerificationMethodCreate"));
96
+ await identityVerificationMethodCreate(engineCore, envVars, {
97
+ identity: organisation.did,
98
+ verificationMethodType: "assertionMethod",
99
+ verificationMethodId: envVars.trustVerificationMethodId,
100
+ overwriteMode: "skip"
101
+ });
102
+ if (Coerce.boolean(envVars.blobStorageEnableEncryption) ?? false) {
103
+ CLIDisplay.break();
104
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.blobStorageKeyCreate"));
105
+ await vaultKeyCreate(engineCore, envVars, {
106
+ identity: organizationId,
107
+ keyType: "ChaCha20Poly1305",
108
+ keyId: envVars.blobStorageEncryptionKeyId,
109
+ overwriteMode: "skip"
110
+ });
111
+ }
112
+ const defaultAttestationConnectorType = engineCore.getRegisteredInstanceTypeOptional("attestationConnector");
113
+ if (!Is.empty(defaultAttestationConnectorType)) {
114
+ CLIDisplay.break();
115
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.attestationMethodCreate"));
116
+ await identityVerificationMethodCreate(engineCore, envVars, {
117
+ identity: organizationId,
118
+ verificationMethodType: "assertionMethod",
119
+ verificationMethodId: envVars.attestationVerificationMethodId,
120
+ overwriteMode: "skip"
121
+ });
122
+ }
123
+ const defaultImmutableProofComponentType = engineCore.getRegisteredInstanceTypeOptional("immutableProofComponent");
124
+ if (!Is.empty(defaultImmutableProofComponentType)) {
125
+ CLIDisplay.break();
126
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.immutableProofMethodCreate"));
127
+ await identityVerificationMethodCreate(engineCore, envVars, {
128
+ identity: organizationId,
129
+ verificationMethodType: "assertionMethod",
130
+ verificationMethodId: envVars.immutableProofVerificationMethodId,
131
+ overwriteMode: "skip"
132
+ });
133
+ }
134
+ // In single-tenant mode, record the org DID in state so the node can resolve its
135
+ // organisation without a tenant lookup.
136
+ if (!tenantEnabled && !Is.stringValue(state.nodeOrganizationId)) {
137
+ CLIDisplay.break();
138
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.nodeOrganizationIdSet"));
139
+ state.nodeOrganizationId = organisation.did;
140
+ engineCore.setStateDirty();
141
+ CLIDisplay.done();
142
+ }
143
+ });
144
+ if (tenantEnabled) {
145
+ await ContextIdStore.run({ [ContextIdKeys.Node]: nodeId }, async () => {
146
+ // Resolve an existing tenant so a re-run does not create a duplicate.
147
+ // When a specific tenant ID is configured, look it up directly;
148
+ // otherwise search for the first tenant labelled "Tenant".
149
+ if (Is.stringValue(envVars.tenantId)) {
150
+ tenant = await resolveTenantById(engineCore, envVars.tenantId);
151
+ }
152
+ else {
153
+ tenant = await resolveDefaultTenant(engineCore);
154
+ }
155
+ // Still empty so create a new tenant for the node and associate it with the organisation.
156
+ if (Is.empty(tenant)) {
157
+ CLIDisplay.break();
158
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.nodeTenantCreate"));
159
+ const tenantDetails = await tenantCreate(engineCore, envVars, {
160
+ tenantId: envVars.tenantId,
161
+ apiKey: envVars.tenantApiKey,
162
+ label: "Tenant",
163
+ organizationId
164
+ });
165
+ tenant = {
166
+ id: tenantDetails.tenantId,
167
+ organizationId: organizationId ?? tenantDetails.organizationId ?? ""
168
+ };
169
+ }
170
+ });
171
+ }
172
+ if (features.includes("admin-user")) {
173
+ await ContextIdStore.run({ [ContextIdKeys.Node]: nodeId, [ContextIdKeys.Tenant]: tenant?.id }, async () => {
174
+ const orgDid = await resolveOrganizationDid(engineCore, tenantEnabled, tenant?.id);
175
+ const effectiveAdminEmail = envVars.adminUserName ?? `admin@${tenantEnabled ? "tenant" : "node"}`;
176
+ const adminUser = await resolveDefaultAdminUser(engineCore, effectiveAdminEmail);
177
+ let userDid = adminUser?.userIdentity;
178
+ if (Is.empty(adminUser)) {
179
+ CLIDisplay.break();
180
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.adminIdentityCreate"));
181
+ const result = await identityCreate(engineCore, envVars, {
182
+ identity: envVars.adminUserIdentity,
183
+ mnemonic: envVars.adminUserMnemonic,
184
+ controller: orgDid
185
+ });
186
+ userDid = result.did;
187
+ }
188
+ CLIDisplay.break();
189
+ CLIDisplay.section(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.adminUserCreate"));
190
+ await userCreate(engineCore, envVars, {
191
+ userIdentity: userDid,
192
+ organizationIdentity: orgDid,
193
+ tenantId: tenant?.id,
194
+ email: envVars.adminUserName ?? `admin@${tenantEnabled ? "tenant" : "node"}`,
195
+ password: envVars.adminUserPassword,
196
+ scope: envVars.adminUserScope ??
197
+ (tenantEnabled ? ["tenant-admin", "user-admin"] : ["user-admin"]).join(","),
198
+ givenName: tenantEnabled ? "Tenant" : "Node",
199
+ familyName: "Admin",
200
+ overwriteMode: "skip"
201
+ });
202
+ });
203
+ }
204
+ }
205
+ /**
206
+ * Resolve the organisation DID from node state (single-tenant) or the tenant entry (multi-tenant).
207
+ * @param engineCore The engine core.
208
+ * @param tenantEnabled Whether multi-tenancy is enabled.
209
+ * @param tenantId The active tenant ID (multi-tenant only).
210
+ * @returns The organisation DID.
211
+ * @throws GeneralError if the organisation has not been associated yet.
212
+ * @internal
213
+ */
214
+ async function resolveOrganizationDid(engineCore, tenantEnabled, tenantId) {
215
+ if (tenantEnabled) {
216
+ if (Is.stringValue(tenantId)) {
217
+ const tenantAdminComponentType = engineCore.getRegisteredInstanceTypeOptional("tenantAdminComponent");
218
+ if (Is.stringValue(tenantAdminComponentType)) {
219
+ const tenantAdminComponent = ComponentFactory.get(tenantAdminComponentType);
220
+ const tenant = await tenantAdminComponent.get(tenantId);
221
+ if (Is.stringValue(tenant.organizationId)) {
222
+ return tenant.organizationId;
223
+ }
224
+ }
225
+ }
226
+ }
227
+ else {
228
+ const state = engineCore.getState();
229
+ if (Is.stringValue(state.nodeOrganizationId)) {
230
+ return state.nodeOrganizationId;
231
+ }
232
+ }
233
+ throw new GeneralError("bootstrapLegacy", "organizationNotSet");
234
+ }
235
+ /**
236
+ * Resolve the default tenant id for re-bootstrap when multi-tenancy is enabled.
237
+ * @param engineCore The engine core.
238
+ * @returns The tenant id if one exists in storage.
239
+ * @internal
240
+ */
241
+ async function resolveDefaultTenant(engineCore) {
242
+ const tenantAdminServiceComponentType = engineCore.getRegisteredInstanceTypeOptional("tenantAdminComponent");
243
+ if (!Is.stringValue(tenantAdminServiceComponentType)) {
244
+ return undefined;
245
+ }
246
+ const tenantAdminService = ComponentFactory.get(tenantAdminServiceComponentType);
247
+ let cursor;
248
+ let firstTenant;
249
+ do {
250
+ const result = await tenantAdminService.query(undefined, ["id", "organizationId", "label"], cursor);
251
+ const nodeTenant = result.tenants.find(tenant => tenant.label === "Tenant");
252
+ if (nodeTenant) {
253
+ return {
254
+ id: nodeTenant.id,
255
+ organizationId: nodeTenant.organizationId ?? ""
256
+ };
257
+ }
258
+ if (Is.empty(firstTenant) && Is.arrayValue(result.tenants)) {
259
+ firstTenant = {
260
+ id: result.tenants[0].id,
261
+ organizationId: result.tenants[0].organizationId ?? ""
262
+ };
263
+ }
264
+ cursor = result.cursor;
265
+ } while (Is.stringValue(cursor));
266
+ if (!Is.empty(firstTenant)) {
267
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.bootstrap-legacy.labels.tenantFallback"), firstTenant.id);
268
+ }
269
+ return firstTenant;
270
+ }
271
+ /**
272
+ * Resolve the admin user by email for idempotent re-bootstrap.
273
+ * @param engineCore The engine core.
274
+ * @param email The email address of the admin user to look up.
275
+ * @returns The admin user if one exists in storage.
276
+ * @internal
277
+ */
278
+ async function resolveDefaultAdminUser(engineCore, email) {
279
+ const defaultAuthenticationAdminComponentType = engineCore.getRegisteredInstanceType("authenticationAdminComponent");
280
+ const authenticationAdminComponent = ComponentFactory.get(defaultAuthenticationAdminComponentType);
281
+ try {
282
+ return await authenticationAdminComponent.get(email);
283
+ }
284
+ catch {
285
+ return undefined;
286
+ }
287
+ }
288
+ /**
289
+ * Resolve a tenant by its specific ID for idempotent re-bootstrap.
290
+ * @param engineCore The engine core.
291
+ * @param tenantId The tenant ID to look up.
292
+ * @returns The tenant if found, otherwise undefined.
293
+ * @internal
294
+ */
295
+ async function resolveTenantById(engineCore, tenantId) {
296
+ const tenantAdminServiceComponentType = engineCore.getRegisteredInstanceTypeOptional("tenantAdminComponent");
297
+ if (!Is.stringValue(tenantAdminServiceComponentType)) {
298
+ return undefined;
299
+ }
300
+ const tenantAdminService = ComponentFactory.get(tenantAdminServiceComponentType);
301
+ try {
302
+ const found = await tenantAdminService.get(tenantId);
303
+ return {
304
+ id: found.id,
305
+ organizationId: found.organizationId ?? ""
306
+ };
307
+ }
308
+ catch {
309
+ return undefined;
310
+ }
311
+ }
312
+ //# sourceMappingURL=bootstrapLegacy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrapLegacy.js","sourceRoot":"","sources":["../../../src/commands/bootstrapLegacy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IAuthenticationAdminComponent } from \"@twin.org/api-auth-entity-storage-models\";\nimport type { ITenantAdminComponent } from \"@twin.org/api-models\";\nimport { CLIDisplay } from \"@twin.org/cli-core\";\nimport { ContextIdKeys, ContextIdStore } from \"@twin.org/context\";\nimport { Coerce, ComponentFactory, GeneralError, I18n, Is } from \"@twin.org/core\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport { identityCreate } from \"./identityCreate.js\";\nimport { identityVerificationMethodCreate } from \"./identityVerificationMethodCreate.js\";\nimport { tenantCreate } from \"./tenantCreate.js\";\nimport { userCreate } from \"./userCreate.js\";\nimport { vaultKeyCreate } from \"./vaultKeyCreate.js\";\nimport type { ICliCommandDefinition } from \"../models/ICliCommandDefinition.js\";\nimport type { IEnvironmentVariables } from \"../models/IEnvironmentVariables.js\";\nimport type { INodeEngineConfig } from \"../models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"../models/INodeEngineState.js\";\n\nconst COMMAND_NAME = \"bootstrap-legacy\";\n\n/**\n * Get the command definition parameters.\n * @param commandDefinitions The registered command definitions.\n */\nexport function getCommandDefinitionBootstrapLegacy(commandDefinitions: {\n\t[id: string]: ICliCommandDefinition;\n}): void {\n\tcommandDefinitions[COMMAND_NAME] = {\n\t\tcommand: COMMAND_NAME,\n\t\tdescription: I18n.formatMessage(\"node.cli.commands.bootstrap-legacy.description\"),\n\t\texample: I18n.formatMessage(\"node.cli.commands.bootstrap-legacy.example\"),\n\t\trequiresNodeIdentity: false,\n\t\trequiresOrgIdentity: false,\n\t\tparams: [\n\t\t\t{\n\t\t\t\tkey: \"env-prefix\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.bootstrap-legacy.params.env-prefix.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"load-env\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.bootstrap-legacy.params.load-env.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t}\n\t\t],\n\t\taction: async (engineCore, envVars, params) => bootstrapLegacy(engineCore, envVars, params)\n\t};\n}\n\n/**\n * Command for legacy bootstrap.\n * @param engineCore The engine core.\n * @param envVars The environment variables for the node.\n * @param params The parameters for the command.\n * @returns A promise that resolves when the bootstrap sequence has completed.\n */\nexport async function bootstrapLegacy(\n\tengineCore: IEngineCore<INodeEngineConfig, INodeEngineState>,\n\tenvVars: IEnvironmentVariables,\n\tparams: {}\n): Promise<void> {\n\tconst features = (envVars.features ?? \"admin-user,wallet\")\n\t\t.split(\",\")\n\t\t.map(f => f.trim())\n\t\t.filter(f => f.length > 0);\n\n\tconst state = engineCore.getState();\n\tconst requireWallet = features.includes(\"wallet\");\n\tconst tenantEnabled = Coerce.boolean(envVars.tenantEnabled) ?? false;\n\tlet nodeId = state.nodeId ?? envVars.nodeIdentity;\n\tlet organizationId = tenantEnabled ? undefined : state.nodeOrganizationId;\n\tlet tenant: { id: string; organizationId: string } | undefined;\n\n\tif (features.length === 0) {\n\t\tthrow new GeneralError(\"bootstrapLegacy\", \"noFeaturesEnabled\");\n\t}\n\n\tCLIDisplay.break();\n\tCLIDisplay.section(\n\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.nodeIdentityCreate\")\n\t);\n\n\tconst nodeIdentity = await identityCreate(engineCore, envVars, {\n\t\tidentity: nodeId,\n\t\tmnemonic: envVars.nodeMnemonic,\n\t\tfundWallet: requireWallet,\n\t\tnodeId: true\n\t});\n\n\tnodeId = nodeIdentity.did;\n\n\tCLIDisplay.break();\n\tCLIDisplay.section(\n\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.nodeAuthKeyCreate\")\n\t);\n\tawait vaultKeyCreate(engineCore, envVars, {\n\t\tidentity: nodeId,\n\t\tkeyType: \"Ed25519\",\n\t\tkeyId: envVars.authSigningKeyId,\n\t\toverwriteMode: \"skip\"\n\t});\n\n\t// Always create the organisation identity first so it can be associated with\n\t// the tenant (multi-tenant) or the node (single-tenant) immediately after.\n\t// The trust verification method is always added to the organisation identity.\n\tawait ContextIdStore.run({ [ContextIdKeys.Node]: nodeId }, async () => {\n\t\tCLIDisplay.break();\n\t\tCLIDisplay.section(\n\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.organisationCreate\")\n\t\t);\n\n\t\tif (tenantEnabled) {\n\t\t\tconst existingTenant = Is.stringValue(envVars.tenantId)\n\t\t\t\t? await resolveTenantById(engineCore, envVars.tenantId)\n\t\t\t\t: await resolveDefaultTenant(engineCore);\n\t\t\torganizationId = existingTenant?.organizationId;\n\t\t}\n\n\t\tconst organisation = await identityCreate(engineCore, envVars, {\n\t\t\tidentity: organizationId ?? envVars.organizationIdentity,\n\t\t\tmnemonic: envVars.organizationMnemonic,\n\t\t\tfundWallet: requireWallet\n\t\t});\n\t\torganizationId = organisation.did;\n\n\t\tCLIDisplay.break();\n\t\tCLIDisplay.section(\n\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.trustVerificationMethodCreate\")\n\t\t);\n\t\tawait identityVerificationMethodCreate(engineCore, envVars, {\n\t\t\tidentity: organisation.did,\n\t\t\tverificationMethodType: \"assertionMethod\",\n\t\t\tverificationMethodId: envVars.trustVerificationMethodId,\n\t\t\toverwriteMode: \"skip\"\n\t\t});\n\n\t\tif (Coerce.boolean(envVars.blobStorageEnableEncryption) ?? false) {\n\t\t\tCLIDisplay.break();\n\t\t\tCLIDisplay.section(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.blobStorageKeyCreate\")\n\t\t\t);\n\t\t\tawait vaultKeyCreate(engineCore, envVars, {\n\t\t\t\tidentity: organizationId,\n\t\t\t\tkeyType: \"ChaCha20Poly1305\",\n\t\t\t\tkeyId: envVars.blobStorageEncryptionKeyId,\n\t\t\t\toverwriteMode: \"skip\"\n\t\t\t});\n\t\t}\n\n\t\tconst defaultAttestationConnectorType =\n\t\t\tengineCore.getRegisteredInstanceTypeOptional(\"attestationConnector\");\n\t\tif (!Is.empty(defaultAttestationConnectorType)) {\n\t\t\tCLIDisplay.break();\n\t\t\tCLIDisplay.section(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.attestationMethodCreate\")\n\t\t\t);\n\t\t\tawait identityVerificationMethodCreate(engineCore, envVars, {\n\t\t\t\tidentity: organizationId,\n\t\t\t\tverificationMethodType: \"assertionMethod\",\n\t\t\t\tverificationMethodId: envVars.attestationVerificationMethodId,\n\t\t\t\toverwriteMode: \"skip\"\n\t\t\t});\n\t\t}\n\n\t\tconst defaultImmutableProofComponentType =\n\t\t\tengineCore.getRegisteredInstanceTypeOptional(\"immutableProofComponent\");\n\n\t\tif (!Is.empty(defaultImmutableProofComponentType)) {\n\t\t\tCLIDisplay.break();\n\t\t\tCLIDisplay.section(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.immutableProofMethodCreate\")\n\t\t\t);\n\t\t\tawait identityVerificationMethodCreate(engineCore, envVars, {\n\t\t\t\tidentity: organizationId,\n\t\t\t\tverificationMethodType: \"assertionMethod\",\n\t\t\t\tverificationMethodId: envVars.immutableProofVerificationMethodId,\n\t\t\t\toverwriteMode: \"skip\"\n\t\t\t});\n\t\t}\n\n\t\t// In single-tenant mode, record the org DID in state so the node can resolve its\n\t\t// organisation without a tenant lookup.\n\t\tif (!tenantEnabled && !Is.stringValue(state.nodeOrganizationId)) {\n\t\t\tCLIDisplay.break();\n\t\t\tCLIDisplay.section(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.nodeOrganizationIdSet\")\n\t\t\t);\n\t\t\tstate.nodeOrganizationId = organisation.did;\n\t\t\tengineCore.setStateDirty();\n\t\t\tCLIDisplay.done();\n\t\t}\n\t});\n\n\tif (tenantEnabled) {\n\t\tawait ContextIdStore.run({ [ContextIdKeys.Node]: nodeId }, async () => {\n\t\t\t// Resolve an existing tenant so a re-run does not create a duplicate.\n\t\t\t// When a specific tenant ID is configured, look it up directly;\n\t\t\t// otherwise search for the first tenant labelled \"Tenant\".\n\t\t\tif (Is.stringValue(envVars.tenantId)) {\n\t\t\t\ttenant = await resolveTenantById(engineCore, envVars.tenantId);\n\t\t\t} else {\n\t\t\t\ttenant = await resolveDefaultTenant(engineCore);\n\t\t\t}\n\n\t\t\t// Still empty so create a new tenant for the node and associate it with the organisation.\n\t\t\tif (Is.empty(tenant)) {\n\t\t\t\tCLIDisplay.break();\n\t\t\t\tCLIDisplay.section(\n\t\t\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.nodeTenantCreate\")\n\t\t\t\t);\n\t\t\t\tconst tenantDetails = await tenantCreate(engineCore, envVars, {\n\t\t\t\t\ttenantId: envVars.tenantId,\n\t\t\t\t\tapiKey: envVars.tenantApiKey,\n\t\t\t\t\tlabel: \"Tenant\",\n\t\t\t\t\torganizationId\n\t\t\t\t});\n\n\t\t\t\ttenant = {\n\t\t\t\t\tid: tenantDetails.tenantId,\n\t\t\t\t\torganizationId: organizationId ?? tenantDetails.organizationId ?? \"\"\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\t}\n\n\tif (features.includes(\"admin-user\")) {\n\t\tawait ContextIdStore.run(\n\t\t\t{ [ContextIdKeys.Node]: nodeId, [ContextIdKeys.Tenant]: tenant?.id },\n\t\t\tasync () => {\n\t\t\t\tconst orgDid = await resolveOrganizationDid(engineCore, tenantEnabled, tenant?.id);\n\t\t\t\tconst effectiveAdminEmail =\n\t\t\t\t\tenvVars.adminUserName ?? `admin@${tenantEnabled ? \"tenant\" : \"node\"}`;\n\t\t\t\tconst adminUser = await resolveDefaultAdminUser(engineCore, effectiveAdminEmail);\n\t\t\t\tlet userDid = adminUser?.userIdentity;\n\n\t\t\t\tif (Is.empty(adminUser)) {\n\t\t\t\t\tCLIDisplay.break();\n\t\t\t\t\tCLIDisplay.section(\n\t\t\t\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.adminIdentityCreate\")\n\t\t\t\t\t);\n\t\t\t\t\tconst result = await identityCreate(engineCore, envVars, {\n\t\t\t\t\t\tidentity: envVars.adminUserIdentity,\n\t\t\t\t\t\tmnemonic: envVars.adminUserMnemonic,\n\t\t\t\t\t\tcontroller: orgDid\n\t\t\t\t\t});\n\n\t\t\t\t\tuserDid = result.did;\n\t\t\t\t}\n\n\t\t\t\tCLIDisplay.break();\n\t\t\t\tCLIDisplay.section(\n\t\t\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.adminUserCreate\")\n\t\t\t\t);\n\t\t\t\tawait userCreate(engineCore, envVars, {\n\t\t\t\t\tuserIdentity: userDid,\n\t\t\t\t\torganizationIdentity: orgDid,\n\t\t\t\t\ttenantId: tenant?.id,\n\t\t\t\t\temail: envVars.adminUserName ?? `admin@${tenantEnabled ? \"tenant\" : \"node\"}`,\n\t\t\t\t\tpassword: envVars.adminUserPassword,\n\t\t\t\t\tscope:\n\t\t\t\t\t\tenvVars.adminUserScope ??\n\t\t\t\t\t\t(tenantEnabled ? [\"tenant-admin\", \"user-admin\"] : [\"user-admin\"]).join(\",\"),\n\t\t\t\t\tgivenName: tenantEnabled ? \"Tenant\" : \"Node\",\n\t\t\t\t\tfamilyName: \"Admin\",\n\t\t\t\t\toverwriteMode: \"skip\"\n\t\t\t\t});\n\t\t\t}\n\t\t);\n\t}\n}\n\n/**\n * Resolve the organisation DID from node state (single-tenant) or the tenant entry (multi-tenant).\n * @param engineCore The engine core.\n * @param tenantEnabled Whether multi-tenancy is enabled.\n * @param tenantId The active tenant ID (multi-tenant only).\n * @returns The organisation DID.\n * @throws GeneralError if the organisation has not been associated yet.\n * @internal\n */\nasync function resolveOrganizationDid(\n\tengineCore: IEngineCore<INodeEngineConfig, INodeEngineState>,\n\ttenantEnabled: boolean,\n\ttenantId: string | undefined\n): Promise<string> {\n\tif (tenantEnabled) {\n\t\tif (Is.stringValue(tenantId)) {\n\t\t\tconst tenantAdminComponentType =\n\t\t\t\tengineCore.getRegisteredInstanceTypeOptional(\"tenantAdminComponent\");\n\t\t\tif (Is.stringValue(tenantAdminComponentType)) {\n\t\t\t\tconst tenantAdminComponent =\n\t\t\t\t\tComponentFactory.get<ITenantAdminComponent>(tenantAdminComponentType);\n\t\t\t\tconst tenant = await tenantAdminComponent.get(tenantId);\n\t\t\t\tif (Is.stringValue(tenant.organizationId)) {\n\t\t\t\t\treturn tenant.organizationId;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst state = engineCore.getState();\n\t\tif (Is.stringValue(state.nodeOrganizationId)) {\n\t\t\treturn state.nodeOrganizationId;\n\t\t}\n\t}\n\n\tthrow new GeneralError(\"bootstrapLegacy\", \"organizationNotSet\");\n}\n\n/**\n * Resolve the default tenant id for re-bootstrap when multi-tenancy is enabled.\n * @param engineCore The engine core.\n * @returns The tenant id if one exists in storage.\n * @internal\n */\nasync function resolveDefaultTenant(\n\tengineCore: IEngineCore<INodeEngineConfig, INodeEngineState>\n): Promise<{ id: string; organizationId: string } | undefined> {\n\tconst tenantAdminServiceComponentType =\n\t\tengineCore.getRegisteredInstanceTypeOptional(\"tenantAdminComponent\");\n\n\tif (!Is.stringValue(tenantAdminServiceComponentType)) {\n\t\treturn undefined;\n\t}\n\n\tconst tenantAdminService = ComponentFactory.get<ITenantAdminComponent>(\n\t\ttenantAdminServiceComponentType\n\t);\n\n\tlet cursor: string | undefined;\n\tlet firstTenant: { id: string; organizationId: string } | undefined;\n\n\tdo {\n\t\tconst result = await tenantAdminService.query(\n\t\t\tundefined,\n\t\t\t[\"id\", \"organizationId\", \"label\"],\n\t\t\tcursor\n\t\t);\n\t\tconst nodeTenant = result.tenants.find(tenant => tenant.label === \"Tenant\");\n\t\tif (nodeTenant) {\n\t\t\treturn {\n\t\t\t\tid: nodeTenant.id,\n\t\t\t\torganizationId: nodeTenant.organizationId ?? \"\"\n\t\t\t};\n\t\t}\n\n\t\tif (Is.empty(firstTenant) && Is.arrayValue(result.tenants)) {\n\t\t\tfirstTenant = {\n\t\t\t\tid: result.tenants[0].id,\n\t\t\t\torganizationId: result.tenants[0].organizationId ?? \"\"\n\t\t\t};\n\t\t}\n\n\t\tcursor = result.cursor;\n\t} while (Is.stringValue(cursor));\n\n\tif (!Is.empty(firstTenant)) {\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"node.cli.commands.bootstrap-legacy.labels.tenantFallback\"),\n\t\t\tfirstTenant.id\n\t\t);\n\t}\n\n\treturn firstTenant;\n}\n\n/**\n * Resolve the admin user by email for idempotent re-bootstrap.\n * @param engineCore The engine core.\n * @param email The email address of the admin user to look up.\n * @returns The admin user if one exists in storage.\n * @internal\n */\nasync function resolveDefaultAdminUser(\n\tengineCore: IEngineCore<INodeEngineConfig, INodeEngineState>,\n\temail: string\n): Promise<{ email: string; userIdentity: string; organizationIdentity: string } | undefined> {\n\tconst defaultAuthenticationAdminComponentType = engineCore.getRegisteredInstanceType(\n\t\t\"authenticationAdminComponent\"\n\t);\n\tconst authenticationAdminComponent = ComponentFactory.get<IAuthenticationAdminComponent>(\n\t\tdefaultAuthenticationAdminComponentType\n\t);\n\n\ttry {\n\t\treturn await authenticationAdminComponent.get(email);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Resolve a tenant by its specific ID for idempotent re-bootstrap.\n * @param engineCore The engine core.\n * @param tenantId The tenant ID to look up.\n * @returns The tenant if found, otherwise undefined.\n * @internal\n */\nasync function resolveTenantById(\n\tengineCore: IEngineCore<INodeEngineConfig, INodeEngineState>,\n\ttenantId: string\n): Promise<{ id: string; organizationId: string } | undefined> {\n\tconst tenantAdminServiceComponentType =\n\t\tengineCore.getRegisteredInstanceTypeOptional(\"tenantAdminComponent\");\n\n\tif (!Is.stringValue(tenantAdminServiceComponentType)) {\n\t\treturn undefined;\n\t}\n\n\tconst tenantAdminService = ComponentFactory.get<ITenantAdminComponent>(\n\t\ttenantAdminServiceComponentType\n\t);\n\n\ttry {\n\t\tconst found = await tenantAdminService.get(tenantId);\n\t\treturn {\n\t\t\tid: found.id,\n\t\t\torganizationId: found.organizationId ?? \"\"\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
@@ -0,0 +1,86 @@
1
+ // Copyright 2026 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ import { CLIDisplay } from "@twin.org/cli-core";
4
+ import { I18n, Is } from "@twin.org/core";
5
+ const COMMAND_NAME = "help";
6
+ /**
7
+ * Get the command definition parameters.
8
+ * @param commandDefinitions The registered command definitions.
9
+ */
10
+ export function getCommandDefinitionHelp(commandDefinitions) {
11
+ commandDefinitions[COMMAND_NAME] = {
12
+ command: COMMAND_NAME,
13
+ description: I18n.formatMessage("node.cli.commands.help.description"),
14
+ example: "",
15
+ params: [],
16
+ action: async (engineCore, envVars, params) => help(engineCore, envVars, params, commandDefinitions),
17
+ requiresEngineStarted: false
18
+ };
19
+ }
20
+ /**
21
+ * Command for displaying help information.
22
+ * @param engineCore The engine core.
23
+ * @param envVars The environment variables for the node.
24
+ * @param params The command parameters.
25
+ * @param params.command The command to display help for.
26
+ * @param commandDefinitions The registered command definitions.
27
+ * @returns A promise that resolves when help output has been displayed.
28
+ */
29
+ export async function help(engineCore, envVars, params, commandDefinitions) {
30
+ if (Is.stringValue(params.command)) {
31
+ const commandDefinition = commandDefinitions[params.command];
32
+ if (commandDefinition) {
33
+ displayCommandHelp(commandDefinition);
34
+ }
35
+ }
36
+ else {
37
+ CLIDisplay.value("", I18n.formatMessage("node.cli.commands.help.labels.commands"));
38
+ CLIDisplay.break();
39
+ for (const commandId in commandDefinitions) {
40
+ const commandDef = commandDefinitions[commandId];
41
+ if (commandId !== "help") {
42
+ CLIDisplay.value(commandDef.command, I18n.formatMessage(`node.cli.commands.${commandDef.command}.description`));
43
+ }
44
+ }
45
+ }
46
+ }
47
+ /**
48
+ * Display help for a specific command.
49
+ * @param commandDefinition The command definition.
50
+ */
51
+ function displayCommandHelp(commandDefinition) {
52
+ CLIDisplay.value(commandDefinition.command, commandDefinition.description);
53
+ CLIDisplay.break();
54
+ const defaultLabel = I18n.formatMessage("node.cli.commands.help.labels.default");
55
+ const optionsLabel = I18n.formatMessage("node.cli.commands.help.labels.options");
56
+ const requiredLabel = I18n.formatMessage("node.cli.commands.help.labels.required");
57
+ const optionalLabel = I18n.formatMessage("node.cli.commands.help.labels.optional");
58
+ if (commandDefinition.params.length > 0) {
59
+ for (const param of commandDefinition.params) {
60
+ const typeParts = [param.type];
61
+ if (Is.stringValue(param.extendedType)) {
62
+ typeParts.push(param.extendedType);
63
+ }
64
+ if (!Is.empty(param.defaultValue)) {
65
+ typeParts.push(`${defaultLabel}: '${param.defaultValue}'`);
66
+ }
67
+ if (param.required) {
68
+ typeParts.push(requiredLabel);
69
+ }
70
+ else {
71
+ typeParts.push(optionalLabel);
72
+ }
73
+ if (Is.arrayValue(param.options)) {
74
+ typeParts.push(`${optionsLabel}: [${param.options.join(", ")}]`);
75
+ }
76
+ CLIDisplay.value(param.key, `(${typeParts.join(", ")})`, 1);
77
+ CLIDisplay.value("", param.description, 1);
78
+ CLIDisplay.break();
79
+ }
80
+ }
81
+ if (Is.stringValue(commandDefinition.example)) {
82
+ CLIDisplay.break();
83
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.help.labels.example"), commandDefinition.example);
84
+ }
85
+ }
86
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/commands/help.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { CLIDisplay } from \"@twin.org/cli-core\";\nimport { I18n, Is } from \"@twin.org/core\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport type { ICliCommandDefinition } from \"../models/ICliCommandDefinition.js\";\nimport type { IEnvironmentVariables } from \"../models/IEnvironmentVariables.js\";\n\nconst COMMAND_NAME = \"help\";\n\n/**\n * Get the command definition parameters.\n * @param commandDefinitions The registered command definitions.\n */\nexport function getCommandDefinitionHelp(commandDefinitions: {\n\t[id: string]: ICliCommandDefinition;\n}): void {\n\tcommandDefinitions[COMMAND_NAME] = {\n\t\tcommand: COMMAND_NAME,\n\t\tdescription: I18n.formatMessage(\"node.cli.commands.help.description\"),\n\t\texample: \"\",\n\t\tparams: [],\n\t\taction: async (engineCore, envVars, params) =>\n\t\t\thelp(engineCore, envVars, params, commandDefinitions),\n\t\trequiresEngineStarted: false\n\t};\n}\n\n/**\n * Command for displaying help information.\n * @param engineCore The engine core.\n * @param envVars The environment variables for the node.\n * @param params The command parameters.\n * @param params.command The command to display help for.\n * @param commandDefinitions The registered command definitions.\n * @returns A promise that resolves when help output has been displayed.\n */\nexport async function help(\n\tengineCore: IEngineCore,\n\tenvVars: IEnvironmentVariables,\n\tparams: { command?: string },\n\tcommandDefinitions: { [id: string]: ICliCommandDefinition }\n): Promise<void> {\n\tif (Is.stringValue(params.command)) {\n\t\tconst commandDefinition = commandDefinitions[params.command];\n\t\tif (commandDefinition) {\n\t\t\tdisplayCommandHelp(commandDefinition);\n\t\t}\n\t} else {\n\t\tCLIDisplay.value(\"\", I18n.formatMessage(\"node.cli.commands.help.labels.commands\"));\n\t\tCLIDisplay.break();\n\n\t\tfor (const commandId in commandDefinitions) {\n\t\t\tconst commandDef = commandDefinitions[commandId];\n\t\t\tif (commandId !== \"help\") {\n\t\t\t\tCLIDisplay.value(\n\t\t\t\t\tcommandDef.command,\n\t\t\t\t\tI18n.formatMessage(`node.cli.commands.${commandDef.command}.description`)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Display help for a specific command.\n * @param commandDefinition The command definition.\n */\nfunction displayCommandHelp(commandDefinition: ICliCommandDefinition): void {\n\tCLIDisplay.value(commandDefinition.command, commandDefinition.description);\n\tCLIDisplay.break();\n\n\tconst defaultLabel = I18n.formatMessage(\"node.cli.commands.help.labels.default\");\n\tconst optionsLabel = I18n.formatMessage(\"node.cli.commands.help.labels.options\");\n\tconst requiredLabel = I18n.formatMessage(\"node.cli.commands.help.labels.required\");\n\tconst optionalLabel = I18n.formatMessage(\"node.cli.commands.help.labels.optional\");\n\n\tif (commandDefinition.params.length > 0) {\n\t\tfor (const param of commandDefinition.params) {\n\t\t\tconst typeParts: string[] = [param.type];\n\t\t\tif (Is.stringValue(param.extendedType)) {\n\t\t\t\ttypeParts.push(param.extendedType);\n\t\t\t}\n\t\t\tif (!Is.empty(param.defaultValue)) {\n\t\t\t\ttypeParts.push(`${defaultLabel}: '${param.defaultValue}'`);\n\t\t\t}\n\t\t\tif (param.required) {\n\t\t\t\ttypeParts.push(requiredLabel);\n\t\t\t} else {\n\t\t\t\ttypeParts.push(optionalLabel);\n\t\t\t}\n\n\t\t\tif (Is.arrayValue(param.options)) {\n\t\t\t\ttypeParts.push(`${optionsLabel}: [${param.options.join(\", \")}]`);\n\t\t\t}\n\n\t\t\tCLIDisplay.value(param.key, `(${typeParts.join(\", \")})`, 1);\n\n\t\t\tCLIDisplay.value(\"\", param.description, 1);\n\n\t\t\tCLIDisplay.break();\n\t\t}\n\t}\n\n\tif (Is.stringValue(commandDefinition.example)) {\n\t\tCLIDisplay.break();\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"node.cli.commands.help.labels.example\"),\n\t\t\tcommandDefinition.example\n\t\t);\n\t}\n}\n"]}