@harperfast/harper 5.0.0-alpha.10 → 5.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/BinObjects.js +17 -0
- package/bin/cliOperations.js +157 -0
- package/bin/copyDb.ts +280 -0
- package/bin/harper.js +156 -0
- package/bin/install.js +15 -0
- package/bin/lite.js +5 -0
- package/bin/restart.js +201 -0
- package/bin/run.js +409 -0
- package/bin/status.js +65 -0
- package/bin/stop.js +22 -0
- package/bin/upgrade.js +134 -0
- package/components/Application.ts +646 -0
- package/components/ApplicationScope.ts +49 -0
- package/components/Component.ts +53 -0
- package/components/ComponentV1.ts +342 -0
- package/components/DEFAULT_CONFIG.ts +18 -0
- package/components/EntryHandler.ts +227 -0
- package/components/Logger.ts +14 -0
- package/components/OptionsWatcher.ts +354 -0
- package/components/PluginModule.ts +6 -0
- package/components/Scope.ts +329 -0
- package/components/componentLoader.ts +529 -0
- package/components/deriveCommonPatternBase.ts +31 -0
- package/components/deriveGlobOptions.ts +44 -0
- package/components/deriveURLPath.ts +57 -0
- package/components/operations.js +658 -0
- package/components/operationsValidation.js +246 -0
- package/components/packageComponent.ts +39 -0
- package/components/requestRestart.ts +26 -0
- package/components/resolveBaseURLPath.ts +38 -0
- package/components/status/ComponentStatus.ts +110 -0
- package/components/status/ComponentStatusRegistry.ts +251 -0
- package/components/status/api.ts +153 -0
- package/components/status/crossThread.ts +405 -0
- package/components/status/errors.ts +152 -0
- package/components/status/index.ts +44 -0
- package/components/status/internal.ts +65 -0
- package/components/status/registry.ts +12 -0
- package/components/status/types.ts +96 -0
- package/config/RootConfigWatcher.ts +59 -0
- package/config/configHelpers.ts +11 -0
- package/config/configUtils.js +967 -0
- package/config/harperConfigEnvVars.ts +641 -0
- package/dataLayer/CreateAttributeObject.js +25 -0
- package/dataLayer/CreateTableObject.js +11 -0
- package/dataLayer/DataLayerObjects.js +43 -0
- package/dataLayer/DeleteBeforeObject.js +22 -0
- package/dataLayer/DeleteObject.js +25 -0
- package/dataLayer/DropAttributeObject.js +11 -0
- package/dataLayer/GetBackupObject.js +22 -0
- package/dataLayer/InsertObject.js +24 -0
- package/dataLayer/ReadAuditLogObject.js +24 -0
- package/dataLayer/SQLSearch.js +1335 -0
- package/dataLayer/SearchByConditionsObject.js +61 -0
- package/dataLayer/SearchByHashObject.js +21 -0
- package/dataLayer/SearchObject.js +45 -0
- package/dataLayer/SqlSearchObject.js +14 -0
- package/dataLayer/UpdateObject.js +23 -0
- package/dataLayer/UpsertObject.js +23 -0
- package/dataLayer/bulkLoad.js +813 -0
- package/dataLayer/dataObjects/BulkLoadObjects.js +27 -0
- package/dataLayer/dataObjects/UpsertObject.js +23 -0
- package/dataLayer/delete.js +164 -0
- package/dataLayer/export.js +381 -0
- package/dataLayer/getBackup.js +40 -0
- package/dataLayer/harperBridge/BridgeMethods.js +81 -0
- package/dataLayer/harperBridge/ResourceBridge.ts +633 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateReturnObj.js +28 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateValidate.js +88 -0
- package/dataLayer/harperBridge/harperBridge.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/LMDBBridge.js +119 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.js +112 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.js +67 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.js +31 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteAuditLogsBefore.js +98 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.js +89 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.js +109 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.js +107 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.js +137 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbFlush.js +35 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetBackup.js +111 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.js +28 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.js +29 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadAuditLog.js +207 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.js +156 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.js +30 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbTransaction.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.js +64 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.js +70 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +157 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsAuditEnvironment.js +39 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.js +100 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.js +371 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.js +109 -0
- package/dataLayer/hdbInfoController.js +254 -0
- package/dataLayer/insert.js +266 -0
- package/dataLayer/readAuditLog.js +59 -0
- package/dataLayer/schema.js +366 -0
- package/dataLayer/schemaDescribe.js +289 -0
- package/dataLayer/search.js +60 -0
- package/dataLayer/transaction.js +17 -0
- package/dataLayer/update.js +124 -0
- package/dist/components/Logger.d.ts +12 -0
- package/dist/{resources/ResourceInterfaceV2.js → components/Logger.js} +1 -1
- package/dist/components/Logger.js.map +1 -0
- package/dist/components/Scope.d.ts +14 -4
- package/dist/components/Scope.js +18 -10
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/componentLoader.js +17 -10
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/operations.js +2 -2
- package/dist/components/operations.js.map +1 -1
- package/dist/config/configUtils.d.ts +1 -1
- package/dist/config/configUtils.js +1 -1
- package/dist/config/configUtils.js.map +1 -1
- package/dist/dataLayer/CreateTableObject.d.ts +2 -2
- package/dist/dataLayer/CreateTableObject.js +2 -2
- package/dist/dataLayer/CreateTableObject.js.map +1 -1
- package/dist/dataLayer/delete.d.ts +1 -1
- package/dist/dataLayer/schema.js +6 -5
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +1 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resources/DatabaseTransaction.d.ts +1 -1
- package/dist/resources/IterableEventQueue.d.ts +1 -1
- package/dist/resources/LMDBTransaction.d.ts +5 -1
- package/dist/resources/Resource.d.ts +1 -1
- package/dist/resources/ResourceInterface.d.ts +1 -1
- package/dist/resources/RocksIndexStore.d.ts +3 -3
- package/dist/resources/RocksTransactionLogStore.d.ts +6 -3
- package/dist/resources/Table.d.ts +15 -6
- package/dist/resources/Table.js +12 -4
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/read.js +32 -22
- package/dist/resources/analytics/read.js.map +1 -1
- package/dist/resources/analytics/write.js +3 -6
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/auditStore.d.ts +3 -3
- package/dist/resources/blob.d.ts +25 -2
- package/dist/resources/databases.d.ts +12 -2
- package/dist/resources/databases.js +22 -19
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/search.js +11 -5
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/transaction.d.ts +2 -1
- package/dist/security/auth.js +1 -1
- package/dist/security/auth.js.map +1 -1
- package/dist/security/cryptoHash.d.ts +2 -2
- package/dist/security/jsLoader.js +265 -73
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +11 -12
- package/dist/security/keys.js.map +1 -1
- package/dist/security/user.js +3 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/REST.js +16 -2
- package/dist/server/REST.js.map +1 -1
- package/dist/server/Server.d.ts +2 -1
- package/dist/server/Server.js.map +1 -1
- package/dist/server/fastifyRoutes/plugins/hdbCore.d.ts +6 -1
- package/dist/server/fastifyRoutes.js +2 -0
- package/dist/server/fastifyRoutes.js.map +1 -1
- package/dist/server/http.js +12 -6
- package/dist/server/http.js.map +1 -1
- package/dist/server/jobs/JobObject.d.ts +3 -3
- package/dist/server/loadRootComponents.js +1 -0
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/operationsServer.js +3 -1
- package/dist/server/operationsServer.js.map +1 -1
- package/dist/server/serverHelpers/JSONStream.d.ts +3 -3
- package/dist/server/serverHelpers/Request.d.ts +5 -5
- package/dist/server/serverHelpers/requestTimePlugin.d.ts +1 -1
- package/dist/server/threads/manageThreads.d.ts +2 -2
- package/dist/server/threads/manageThreads.js +52 -35
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.d.ts +1 -1
- package/dist/sqlTranslator/deleteTranslator.d.ts +1 -1
- package/dist/utility/AWS/AWSConnector.d.ts +3 -2
- package/dist/utility/common_utils.d.ts +3 -3
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/functions/date/dateFunctions.d.ts +11 -11
- package/dist/utility/globalSchema.d.ts +1 -1
- package/dist/utility/hdbTerms.d.ts +3 -0
- package/dist/utility/hdbTerms.js +3 -0
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/installation.d.ts +2 -4
- package/dist/utility/installation.js.map +1 -1
- package/dist/utility/lmdb/commonUtility.d.ts +2 -1
- package/dist/utility/lmdb/commonUtility.js +20 -13
- package/dist/utility/lmdb/commonUtility.js.map +1 -1
- package/dist/utility/lmdb/deleteUtility.d.ts +1 -0
- package/dist/utility/lmdb/environmentUtility.d.ts +1 -0
- package/dist/utility/lmdb/searchUtility.d.ts +2 -1
- package/dist/utility/lmdb/writeUtility.d.ts +1 -0
- package/dist/utility/logging/harper_logger.d.ts +6 -6
- package/dist/utility/processManagement/processManagement.d.ts +1 -1
- package/dist/utility/processManagement/servicesConfig.d.ts +12 -6
- package/dist/validation/common_validators.d.ts +4 -3
- package/dist/validation/configValidator.d.ts +3 -2
- package/index.d.ts +56 -0
- package/index.js +41 -0
- package/json/systemSchema.json +373 -0
- package/launchServiceScripts/launchHarperDB.js +3 -0
- package/launchServiceScripts/utility/checkNodeVersion.js +15 -0
- package/package.json +35 -16
- package/resources/DatabaseTransaction.ts +378 -0
- package/resources/ErrorResource.ts +57 -0
- package/resources/IterableEventQueue.ts +94 -0
- package/resources/LMDBTransaction.ts +349 -0
- package/resources/RecordEncoder.ts +702 -0
- package/resources/RequestTarget.ts +134 -0
- package/resources/Resource.ts +789 -0
- package/resources/ResourceInterface.ts +221 -0
- package/resources/Resources.ts +162 -0
- package/resources/RocksIndexStore.ts +70 -0
- package/resources/RocksTransactionLogStore.ts +352 -0
- package/resources/Table.ts +4531 -0
- package/resources/analytics/hostnames.ts +72 -0
- package/resources/analytics/metadata.ts +10 -0
- package/resources/analytics/read.ts +252 -0
- package/resources/analytics/write.ts +803 -0
- package/resources/auditStore.ts +556 -0
- package/resources/blob.ts +1268 -0
- package/resources/crdt.ts +125 -0
- package/resources/dataLoader.ts +527 -0
- package/resources/databases.ts +1290 -0
- package/resources/graphql.ts +221 -0
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +638 -0
- package/resources/indexes/customIndexes.ts +7 -0
- package/resources/indexes/vector.ts +38 -0
- package/resources/jsResource.ts +86 -0
- package/resources/loadEnv.ts +22 -0
- package/resources/login.ts +18 -0
- package/resources/openApi.ts +409 -0
- package/resources/registrationDeprecated.ts +8 -0
- package/resources/replayLogs.ts +136 -0
- package/resources/roles.ts +98 -0
- package/resources/search.ts +1301 -0
- package/resources/tracked.ts +584 -0
- package/resources/transaction.ts +89 -0
- package/resources/transactionBroadcast.ts +258 -0
- package/security/auth.ts +376 -0
- package/security/certificateVerification/certificateVerificationSource.ts +84 -0
- package/security/certificateVerification/configValidation.ts +107 -0
- package/security/certificateVerification/crlVerification.ts +623 -0
- package/security/certificateVerification/index.ts +121 -0
- package/security/certificateVerification/ocspVerification.ts +148 -0
- package/security/certificateVerification/pkijs-ed25519-patch.ts +188 -0
- package/security/certificateVerification/types.ts +128 -0
- package/security/certificateVerification/verificationConfig.ts +138 -0
- package/security/certificateVerification/verificationUtils.ts +447 -0
- package/security/cryptoHash.js +42 -0
- package/security/data_objects/PermissionAttributeResponseObject.js +15 -0
- package/security/data_objects/PermissionResponseObject.js +115 -0
- package/security/data_objects/PermissionTableResponseObject.js +20 -0
- package/security/fastifyAuth.js +169 -0
- package/security/impersonation.ts +160 -0
- package/security/jsLoader.ts +733 -0
- package/security/keys.js +948 -0
- package/security/permissionsTranslator.js +300 -0
- package/security/role.js +218 -0
- package/security/tokenAuthentication.ts +228 -0
- package/security/user.ts +449 -0
- package/server/DurableSubscriptionsSession.ts +503 -0
- package/server/REST.ts +407 -0
- package/server/Server.ts +89 -0
- package/server/fastifyRoutes/helpers/getCORSOptions.js +36 -0
- package/server/fastifyRoutes/helpers/getHeaderTimeoutConfig.js +15 -0
- package/server/fastifyRoutes/helpers/getServerOptions.js +33 -0
- package/server/fastifyRoutes/plugins/hdbCore.js +39 -0
- package/server/fastifyRoutes.ts +205 -0
- package/server/graphqlQuerying.ts +700 -0
- package/server/http.ts +640 -0
- package/server/itc/serverHandlers.js +161 -0
- package/server/itc/utility/ITCEventObject.js +10 -0
- package/server/jobs/JobObject.js +24 -0
- package/server/jobs/jobProcess.js +69 -0
- package/server/jobs/jobRunner.js +162 -0
- package/server/jobs/jobs.js +304 -0
- package/server/loadRootComponents.js +44 -0
- package/server/mqtt.ts +485 -0
- package/server/nodeName.ts +75 -0
- package/server/operationsServer.ts +313 -0
- package/server/serverHelpers/Headers.ts +108 -0
- package/server/serverHelpers/JSONStream.ts +269 -0
- package/server/serverHelpers/OperationFunctionObject.ts +13 -0
- package/server/serverHelpers/Request.ts +158 -0
- package/server/serverHelpers/contentTypes.ts +637 -0
- package/server/serverHelpers/requestTimePlugin.js +57 -0
- package/server/serverHelpers/serverHandlers.js +148 -0
- package/server/serverHelpers/serverUtilities.ts +473 -0
- package/server/serverRegistry.ts +8 -0
- package/server/static.ts +187 -0
- package/server/status/definitions.ts +37 -0
- package/server/status/index.ts +125 -0
- package/server/storageReclamation.ts +93 -0
- package/server/threads/itc.js +89 -0
- package/server/threads/manageThreads.js +596 -0
- package/server/threads/socketRouter.ts +360 -0
- package/server/threads/threadServer.js +279 -0
- package/server/throttle.ts +73 -0
- package/sqlTranslator/SelectValidator.js +330 -0
- package/sqlTranslator/alasqlFunctionImporter.js +62 -0
- package/sqlTranslator/deleteTranslator.js +67 -0
- package/sqlTranslator/index.js +242 -0
- package/sqlTranslator/sql_statement_bucket.js +472 -0
- package/static/defaultConfig.yaml +3 -0
- package/studio/web/HDBDogOnly.svg +78 -0
- package/studio/web/assets/PPRadioGrotesk-Bold-DDaUYG8E.woff +0 -0
- package/studio/web/assets/fa-brands-400-CEJbCg16.woff +0 -0
- package/studio/web/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
- package/studio/web/assets/fa-brands-400-DnkPfk3o.eot +0 -0
- package/studio/web/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
- package/studio/web/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
- package/studio/web/assets/fa-regular-400-BhTwtT8w.eot +0 -0
- package/studio/web/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
- package/studio/web/assets/fa-regular-400-DFnMcJPd.woff +0 -0
- package/studio/web/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
- package/studio/web/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
- package/studio/web/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
- package/studio/web/assets/fa-solid-900-B6Axprfb.eot +0 -0
- package/studio/web/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
- package/studio/web/assets/fa-solid-900-DOXgCApm.woff +0 -0
- package/studio/web/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
- package/studio/web/assets/index-C1G-Jo6n.js +37 -0
- package/studio/web/assets/index-C1G-Jo6n.js.map +1 -0
- package/studio/web/assets/index-D-CahN0-.js +2 -0
- package/studio/web/assets/index-D-CahN0-.js.map +1 -0
- package/studio/web/assets/index-DxlZI0PX.js +235 -0
- package/studio/web/assets/index-DxlZI0PX.js.map +1 -0
- package/studio/web/assets/index-Y2g_iFpU.css +1 -0
- package/studio/web/assets/index-jiPwkrsB.css +1 -0
- package/studio/web/assets/index.lazy-BUXDDqq9.js +266 -0
- package/studio/web/assets/index.lazy-BUXDDqq9.js.map +1 -0
- package/studio/web/assets/profiler-CU93QiSW.js +2 -0
- package/studio/web/assets/profiler-CU93QiSW.js.map +1 -0
- package/studio/web/assets/react-redux-B8k9Ep7e.js +6 -0
- package/studio/web/assets/react-redux-B8k9Ep7e.js.map +1 -0
- package/studio/web/assets/startRecording-DFeBXGk6.js +3 -0
- package/studio/web/assets/startRecording-DFeBXGk6.js.map +1 -0
- package/studio/web/fabric-signup-background.webp +0 -0
- package/studio/web/fabric-signup-text.png +0 -0
- package/studio/web/favicon_purple.png +0 -0
- package/studio/web/github-icon.svg +15 -0
- package/studio/web/harper-fabric_black.png +0 -0
- package/studio/web/harper-fabric_white.png +0 -0
- package/studio/web/harper-studio_white.png +0 -0
- package/studio/web/index.html +16 -0
- package/studio/web/running.css +148 -0
- package/studio/web/running.html +147 -0
- package/studio/web/running.js +111 -0
- package/upgrade/UpgradeObjects.js +13 -0
- package/upgrade/directives/directivesController.js +90 -0
- package/upgrade/directivesManager.js +139 -0
- package/upgrade/upgradePrompt.js +124 -0
- package/upgrade/upgradeUtilities.js +28 -0
- package/utility/AWS/AWSConnector.js +29 -0
- package/utility/OperationFunctionCaller.js +63 -0
- package/utility/assignCmdEnvVariables.js +62 -0
- package/utility/common_utils.js +867 -0
- package/utility/environment/environmentManager.js +208 -0
- package/utility/environment/systemInformation.js +355 -0
- package/utility/errors/commonErrors.js +267 -0
- package/utility/errors/hdbError.js +146 -0
- package/utility/functions/date/dateFunctions.js +65 -0
- package/utility/functions/geo.js +355 -0
- package/utility/functions/sql/alaSQLExtension.js +104 -0
- package/utility/globalSchema.js +35 -0
- package/utility/hdbTerms.ts +819 -0
- package/utility/install/checkJWTTokensExist.js +62 -0
- package/utility/install/harperdb.conf +15 -0
- package/utility/install/harperdb.service +14 -0
- package/utility/install/installer.js +635 -0
- package/utility/installation.ts +30 -0
- package/utility/lmdb/DBIDefinition.js +20 -0
- package/utility/lmdb/DeleteRecordsResponseObject.js +25 -0
- package/utility/lmdb/InsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/OpenDBIObject.js +31 -0
- package/utility/lmdb/OpenEnvironmentObject.js +41 -0
- package/utility/lmdb/UpdateRecordsResponseObject.js +25 -0
- package/utility/lmdb/UpsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/cleanLMDBMap.js +65 -0
- package/utility/lmdb/commonUtility.js +130 -0
- package/utility/lmdb/deleteUtility.js +128 -0
- package/utility/lmdb/environmentUtility.js +477 -0
- package/utility/lmdb/searchCursorFunctions.js +187 -0
- package/utility/lmdb/searchUtility.js +918 -0
- package/utility/lmdb/terms.js +57 -0
- package/utility/lmdb/writeUtility.js +407 -0
- package/utility/logging/harper_logger.js +876 -0
- package/utility/logging/logRotator.js +157 -0
- package/utility/logging/logger.ts +24 -0
- package/utility/logging/readLog.js +355 -0
- package/utility/logging/transactionLog.js +57 -0
- package/utility/mount_hdb.js +59 -0
- package/utility/npmUtilities.js +102 -0
- package/utility/operationPermissions.ts +112 -0
- package/utility/operation_authorization.js +836 -0
- package/utility/packageUtils.js +55 -0
- package/utility/password.ts +99 -0
- package/utility/processManagement/processManagement.js +187 -0
- package/utility/processManagement/servicesConfig.js +56 -0
- package/utility/scripts/restartHdb.js +24 -0
- package/utility/scripts/user_data.sh +13 -0
- package/utility/signalling.js +36 -0
- package/utility/terms/certificates.js +81 -0
- package/utility/when.ts +20 -0
- package/validation/bulkDeleteValidator.js +24 -0
- package/validation/check_permissions.js +19 -0
- package/validation/common_validators.js +95 -0
- package/validation/configValidator.js +331 -0
- package/validation/deleteValidator.js +15 -0
- package/validation/fileLoadValidator.js +153 -0
- package/validation/insertValidator.js +40 -0
- package/validation/installValidator.js +37 -0
- package/validation/readLogValidator.js +64 -0
- package/validation/role_validation.js +320 -0
- package/validation/schemaMetadataValidator.js +42 -0
- package/validation/searchValidator.js +166 -0
- package/validation/statusValidator.ts +66 -0
- package/validation/transactionLogValidator.js +33 -0
- package/validation/user_validation.js +55 -0
- package/validation/validationWrapper.js +105 -0
- package/dist/resources/ResourceInterfaceV2.d.ts +0 -21
- package/dist/resources/ResourceInterfaceV2.js.map +0 -1
- package/dist/resources/ResourceV2.d.ts +0 -30
- package/dist/resources/ResourceV2.js +0 -27
- package/dist/resources/ResourceV2.js.map +0 -1
- package/dist/resources/analytics/profile.d.ts +0 -2
- package/dist/resources/analytics/profile.js +0 -144
- package/dist/resources/analytics/profile.js.map +0 -1
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, existsSync, realpathSync, mkdirSync, rmSync, symlinkSync } from 'node:fs';
|
|
2
|
+
import { join, basename, dirname } from 'node:path';
|
|
3
|
+
import { isMainThread } from 'node:worker_threads';
|
|
4
|
+
import { parseDocument } from 'yaml';
|
|
5
|
+
import * as env from '../utility/environment/environmentManager.js';
|
|
6
|
+
import { PACKAGE_ROOT } from '../utility/packageUtils.js';
|
|
7
|
+
import { CONFIG_PARAMS, HDB_ROOT_DIR_NAME } from '../utility/hdbTerms.ts';
|
|
8
|
+
import * as graphqlHandler from '../resources/graphql.ts';
|
|
9
|
+
import * as graphqlQueryHandler from '../server/graphqlQuerying.ts';
|
|
10
|
+
import * as roles from '../resources/roles.ts';
|
|
11
|
+
import * as jsHandler from '../resources/jsResource.ts';
|
|
12
|
+
import * as login from '../resources/login.ts';
|
|
13
|
+
import * as REST from '../server/REST.ts';
|
|
14
|
+
import * as fastifyRoutesHandler from '../server/fastifyRoutes.ts';
|
|
15
|
+
import * as staticFiles from '../server/static.ts';
|
|
16
|
+
import * as loadEnv from '../resources/loadEnv.ts';
|
|
17
|
+
import harperLogger from '../utility/logging/harper_logger.js';
|
|
18
|
+
import * as dataLoader from '../resources/dataLoader.ts';
|
|
19
|
+
import { watchDir, getWorkerIndex } from '../server/threads/manageThreads.js';
|
|
20
|
+
import { scopedImport } from '../security/jsLoader.ts';
|
|
21
|
+
import { server } from '../server/Server.ts';
|
|
22
|
+
import { Resources } from '../resources/Resources.ts';
|
|
23
|
+
import { table } from '../resources/databases.ts';
|
|
24
|
+
import { startSocketServer } from '../server/threads/socketRouter.ts';
|
|
25
|
+
import { getHdbBasePath } from '../utility/environment/environmentManager.js';
|
|
26
|
+
import * as operationsServer from '../server/operationsServer.ts';
|
|
27
|
+
import * as auth from '../security/auth.ts';
|
|
28
|
+
import * as mqtt from '../server/mqtt.ts';
|
|
29
|
+
import { getConfigObj, resolvePath } from '../config/configUtils.js';
|
|
30
|
+
import { createReuseportFd } from '../server/serverHelpers/Request.ts';
|
|
31
|
+
import { ErrorResource } from '../resources/ErrorResource.ts';
|
|
32
|
+
import { Scope } from './Scope.ts';
|
|
33
|
+
import { ApplicationScope } from './ApplicationScope.ts';
|
|
34
|
+
import { ComponentV1, processResourceExtensionComponent } from './ComponentV1.ts';
|
|
35
|
+
import * as httpComponent from '../server/http.ts';
|
|
36
|
+
import { Status } from '../server/status/index.ts';
|
|
37
|
+
import { lifecycle as componentLifecycle } from './status/index.ts';
|
|
38
|
+
import { DEFAULT_CONFIG } from './DEFAULT_CONFIG.ts';
|
|
39
|
+
import { PluginModule } from './PluginModule.ts';
|
|
40
|
+
import { getEnvBuiltInComponents } from './Application.ts';
|
|
41
|
+
|
|
42
|
+
const CF_ROUTES_DIR = resolvePath(env.get(CONFIG_PARAMS.COMPONENTSROOT));
|
|
43
|
+
let loadedComponents = new Map<any, any>();
|
|
44
|
+
let watchesSetup;
|
|
45
|
+
let resources;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Load all the applications registered in Harper, those in the components directory as well as any directly
|
|
49
|
+
* specified to run
|
|
50
|
+
* @param loadedPluginModules
|
|
51
|
+
* @param loadedResources
|
|
52
|
+
*/
|
|
53
|
+
export function loadComponentDirectories(loadedPluginModules?: Map<any, any>, loadedResources?: Resources) {
|
|
54
|
+
if (loadedResources) resources = loadedResources;
|
|
55
|
+
if (loadedPluginModules) loadedComponents = loadedPluginModules;
|
|
56
|
+
const cfsLoaded: Promise<any>[] = [];
|
|
57
|
+
if (existsSync(CF_ROUTES_DIR)) {
|
|
58
|
+
const cfFolders = readdirSync(CF_ROUTES_DIR, { withFileTypes: true });
|
|
59
|
+
for (const appEntry of cfFolders) {
|
|
60
|
+
if (!appEntry.isDirectory() && !appEntry.isSymbolicLink()) continue;
|
|
61
|
+
const appName = appEntry.name;
|
|
62
|
+
const appFolder = join(CF_ROUTES_DIR, appName);
|
|
63
|
+
cfsLoaded.push(
|
|
64
|
+
loadComponent(appFolder, resources, HDB_ROOT_DIR_NAME, { isRoot: false, autoReload: false, appName })
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const hdbAppFolder = process.env.RUN_HDB_APP;
|
|
69
|
+
if (hdbAppFolder) {
|
|
70
|
+
cfsLoaded.push(
|
|
71
|
+
loadComponent(hdbAppFolder, resources, hdbAppFolder, {
|
|
72
|
+
isRoot: false,
|
|
73
|
+
autoReload: Boolean(process.env.DEV_MODE),
|
|
74
|
+
appName: hdbAppFolder,
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return Promise.all(cfsLoaded).then(() => {
|
|
79
|
+
watchesSetup = true;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const TRUSTED_RESOURCE_PLUGINS = {
|
|
84
|
+
REST, // for backwards compatibility with older configs
|
|
85
|
+
rest: REST,
|
|
86
|
+
graphql: graphqlQueryHandler,
|
|
87
|
+
graphqlSchema: graphqlHandler,
|
|
88
|
+
roles,
|
|
89
|
+
jsResource: jsHandler,
|
|
90
|
+
fastifyRoutes: fastifyRoutesHandler,
|
|
91
|
+
login,
|
|
92
|
+
static: staticFiles,
|
|
93
|
+
operationsApi: operationsServer,
|
|
94
|
+
customFunctions: {},
|
|
95
|
+
http: httpComponent,
|
|
96
|
+
authentication: auth,
|
|
97
|
+
mqtt,
|
|
98
|
+
loadEnv,
|
|
99
|
+
logging: harperLogger,
|
|
100
|
+
dataLoader,
|
|
101
|
+
/*
|
|
102
|
+
static: ...
|
|
103
|
+
login: ...
|
|
104
|
+
*/
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
for (const { name, packageIdentifier } of getEnvBuiltInComponents()) {
|
|
108
|
+
TRUSTED_RESOURCE_PLUGINS[name] = packageIdentifier;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const BUILT_INS = Object.keys(TRUSTED_RESOURCE_PLUGINS);
|
|
112
|
+
|
|
113
|
+
const portsStarted = [];
|
|
114
|
+
export const loadedPaths = new Map();
|
|
115
|
+
let errorReporter;
|
|
116
|
+
export function setErrorReporter(reporter) {
|
|
117
|
+
errorReporter = reporter;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
let compName: string;
|
|
121
|
+
export const getComponentName = () => compName;
|
|
122
|
+
|
|
123
|
+
function symlinkHarperModule(componentDirectory: string) {
|
|
124
|
+
return new Promise<void>((resolve, reject) => {
|
|
125
|
+
const store = Status.primaryStore;
|
|
126
|
+
// Create timeout to avoid deadlocks
|
|
127
|
+
const timeout = setTimeout(() => {
|
|
128
|
+
store.unlock(componentDirectory);
|
|
129
|
+
reject(new Error('symlinking harperdb module timed out'));
|
|
130
|
+
}, 10_000);
|
|
131
|
+
|
|
132
|
+
const callback = () => {
|
|
133
|
+
clearTimeout(timeout);
|
|
134
|
+
resolve();
|
|
135
|
+
};
|
|
136
|
+
const lockAcquired = store.tryLock(componentDirectory, callback);
|
|
137
|
+
|
|
138
|
+
if (!lockAcquired) {
|
|
139
|
+
clearTimeout(timeout);
|
|
140
|
+
} else {
|
|
141
|
+
try {
|
|
142
|
+
// validate node_modules directory exists
|
|
143
|
+
const nodeModulesDir = join(componentDirectory, 'node_modules');
|
|
144
|
+
if (!existsSync(nodeModulesDir)) {
|
|
145
|
+
// create it if not
|
|
146
|
+
mkdirSync(nodeModulesDir);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// validate harperdb module
|
|
150
|
+
const harperModule = join(nodeModulesDir, 'harper');
|
|
151
|
+
if (existsSync(harperModule)) {
|
|
152
|
+
if (realpathSync(harperModule) === realpathSync(PACKAGE_ROOT)) {
|
|
153
|
+
// if it exists and correctly linked, resolve
|
|
154
|
+
return resolve();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Otherwise remove it then link
|
|
158
|
+
rmSync(harperModule, { recursive: true, force: true });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// create link to harperdb module
|
|
162
|
+
symlinkSync(PACKAGE_ROOT, harperModule, 'dir');
|
|
163
|
+
resolve();
|
|
164
|
+
} finally {
|
|
165
|
+
// finally release the lock
|
|
166
|
+
store.unlock(componentDirectory);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* This function handles the `handleApplication` call for a plugin in a sequential manner.
|
|
174
|
+
* It ensures the execution of `handleApplication` happens on one thread at a time for a given scope.
|
|
175
|
+
* If the lock cannot be acquired, it waits for the lock to be released and retries.
|
|
176
|
+
* If the lock is not acquired within the specified timeout, it rejects with a timeout error.
|
|
177
|
+
*
|
|
178
|
+
* @param scope
|
|
179
|
+
* @param plugin
|
|
180
|
+
* @returns
|
|
181
|
+
*/
|
|
182
|
+
function sequentiallyHandleApplication(scope: Scope, plugin: PluginModule) {
|
|
183
|
+
return scope.ready.then(async () => {
|
|
184
|
+
// Timeout priority is user config, plugin default, finally 30 seconds
|
|
185
|
+
const timeout = scope.options.get(['timeout']) || plugin.defaultTimeout || 30_000; // default 30 second timeout
|
|
186
|
+
if (typeof timeout !== 'number') {
|
|
187
|
+
throw new Error(`Invalid timeout value for ${scope.pluginName}. Expected a number, received: ${typeof timeout}`);
|
|
188
|
+
}
|
|
189
|
+
let whenResolved, timer;
|
|
190
|
+
const callback = () => {
|
|
191
|
+
clearTimeout(timer);
|
|
192
|
+
whenResolved(sequentiallyHandleApplication(scope, plugin));
|
|
193
|
+
};
|
|
194
|
+
const store = Status.primaryStore;
|
|
195
|
+
const lockAcquired = store.tryLock(scope.pluginName, callback);
|
|
196
|
+
|
|
197
|
+
if (!lockAcquired) {
|
|
198
|
+
return new Promise((resolve, reject) => {
|
|
199
|
+
whenResolved = resolve;
|
|
200
|
+
timer = setTimeout(() => {
|
|
201
|
+
reject(new Error(`Timeout waiting for lock on ${scope.pluginName}`));
|
|
202
|
+
}, timeout + 5_000); // extra time for lock acquisition
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
let loadTimeout: NodeJS.Timeout;
|
|
206
|
+
try {
|
|
207
|
+
// note that handleApplication can throw sync or async errors, need to run finally block for both
|
|
208
|
+
await Promise.race([
|
|
209
|
+
Promise.resolve(plugin.handleApplication(scope)).then(async () => {
|
|
210
|
+
// Wait for any initial entry handler loads to complete
|
|
211
|
+
// This ensures all async operations (like secureImport) finish before the component is marked as loaded
|
|
212
|
+
await scope.waitForInitialLoads();
|
|
213
|
+
}),
|
|
214
|
+
new Promise(
|
|
215
|
+
(_, reject) =>
|
|
216
|
+
(loadTimeout = setTimeout(
|
|
217
|
+
() =>
|
|
218
|
+
reject(
|
|
219
|
+
new Error(
|
|
220
|
+
`handleApplication timed out after ${timeout}ms for ${scope.pluginName} on behalf of ${scope.appName}`
|
|
221
|
+
)
|
|
222
|
+
),
|
|
223
|
+
timeout
|
|
224
|
+
))
|
|
225
|
+
),
|
|
226
|
+
]);
|
|
227
|
+
} finally {
|
|
228
|
+
Status.primaryStore.unlock(scope.pluginName);
|
|
229
|
+
clearTimeout(loadTimeout);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface LoadComponentOptions {
|
|
235
|
+
isRoot?: boolean;
|
|
236
|
+
applicationScope?: ApplicationScope;
|
|
237
|
+
autoReload?: boolean;
|
|
238
|
+
providedLoadedComponents?: Map<any, any>;
|
|
239
|
+
appName?: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Load a component from the specified directory
|
|
244
|
+
* @param componentPath
|
|
245
|
+
* @param resources
|
|
246
|
+
* @param origin
|
|
247
|
+
* @param portsAllowed
|
|
248
|
+
* @param providedLoadedComponents
|
|
249
|
+
*/
|
|
250
|
+
export async function loadComponent(
|
|
251
|
+
componentDirectory: string,
|
|
252
|
+
resources: Resources,
|
|
253
|
+
origin: string,
|
|
254
|
+
options: LoadComponentOptions = {}
|
|
255
|
+
) {
|
|
256
|
+
const resolvedFolder = realpathSync(componentDirectory);
|
|
257
|
+
if (loadedPaths.has(resolvedFolder)) return loadedPaths.get(resolvedFolder);
|
|
258
|
+
loadedPaths.set(resolvedFolder, true);
|
|
259
|
+
|
|
260
|
+
const {
|
|
261
|
+
providedLoadedComponents,
|
|
262
|
+
applicationScope = new ApplicationScope(basename(componentDirectory), resources, server),
|
|
263
|
+
isRoot,
|
|
264
|
+
autoReload,
|
|
265
|
+
appName,
|
|
266
|
+
} = options;
|
|
267
|
+
applicationScope.verifyPath ??= componentDirectory;
|
|
268
|
+
if (providedLoadedComponents) loadedComponents = providedLoadedComponents;
|
|
269
|
+
try {
|
|
270
|
+
let config;
|
|
271
|
+
let configPath = join(componentDirectory, 'harper-config.yaml'); // look for the specific harperdb-config.yaml first
|
|
272
|
+
if (!existsSync(configPath) && join(componentDirectory, 'harperdb-config.yaml')) {
|
|
273
|
+
configPath = join(componentDirectory, 'harperdb-config.yaml');
|
|
274
|
+
}
|
|
275
|
+
if (existsSync(configPath)) {
|
|
276
|
+
config = isRoot ? getConfigObj() : parseDocument(readFileSync(configPath, 'utf8')).toJSON();
|
|
277
|
+
// if not found, look for the generic config.yaml, the config filename we have historically used, but only if not the root
|
|
278
|
+
} else if (!isRoot && existsSync((configPath = join(componentDirectory, 'config.yaml')))) {
|
|
279
|
+
config = parseDocument(readFileSync(configPath, 'utf8')).toJSON();
|
|
280
|
+
} else {
|
|
281
|
+
config = DEFAULT_CONFIG;
|
|
282
|
+
}
|
|
283
|
+
applicationScope.config ??= config;
|
|
284
|
+
|
|
285
|
+
if (!isRoot) {
|
|
286
|
+
try {
|
|
287
|
+
await symlinkHarperModule(componentDirectory);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
harperLogger.error('Error symlinking harperdb module', error);
|
|
290
|
+
if (error.code == 'EPERM' && process.platform === 'win32') {
|
|
291
|
+
harperLogger.error(
|
|
292
|
+
'You may need to enable developer mode in "Settings" / "System" (or "Update & Security") / "For developers", in order to enable symlinks so components can use `import from "harperdb"`'
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const parentCompName: string = compName;
|
|
299
|
+
const componentFunctionality = {};
|
|
300
|
+
// iterate through the app handlers so they can each do their own loading process
|
|
301
|
+
for (const componentName in config) {
|
|
302
|
+
// For root components, use just the component name
|
|
303
|
+
// For application components, use applicationName.componentName format (directoryName.componentName)
|
|
304
|
+
const componentStatusName = isRoot ? componentName : `${basename(componentDirectory)}.${componentName}`;
|
|
305
|
+
|
|
306
|
+
compName = componentName;
|
|
307
|
+
const componentConfig = config[componentName];
|
|
308
|
+
if (!componentConfig) continue;
|
|
309
|
+
|
|
310
|
+
// Initialize loading status for all components (applications and extensions)
|
|
311
|
+
componentLifecycle.loading(componentStatusName);
|
|
312
|
+
|
|
313
|
+
const subApplicationScope = isRoot ? new ApplicationScope(componentName, resources, server) : applicationScope;
|
|
314
|
+
|
|
315
|
+
let extensionModule: any;
|
|
316
|
+
const pkg = componentConfig.package;
|
|
317
|
+
try {
|
|
318
|
+
if (pkg) {
|
|
319
|
+
let componentPath: string | null = null;
|
|
320
|
+
if (isRoot) {
|
|
321
|
+
componentPath = join(componentDirectory, 'components', componentName);
|
|
322
|
+
} else {
|
|
323
|
+
let containerFolder = componentDirectory;
|
|
324
|
+
componentPath = join(containerFolder, 'node_modules', componentName);
|
|
325
|
+
while (!existsSync(componentPath)) {
|
|
326
|
+
containerFolder = dirname(containerFolder);
|
|
327
|
+
if (containerFolder.length < getHdbBasePath().length) {
|
|
328
|
+
componentPath = null;
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
componentPath = join(containerFolder, 'node_modules', componentName);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (componentPath) {
|
|
335
|
+
subApplicationScope.verifyPath = componentPath;
|
|
336
|
+
if (!process.env.HARPER_SAFE_MODE) {
|
|
337
|
+
extensionModule = await loadComponent(componentPath, resources, origin, {
|
|
338
|
+
isRoot: false,
|
|
339
|
+
applicationScope: subApplicationScope,
|
|
340
|
+
autoReload: false,
|
|
341
|
+
appName: appName || componentName,
|
|
342
|
+
});
|
|
343
|
+
componentFunctionality[componentName] = true;
|
|
344
|
+
}
|
|
345
|
+
} else {
|
|
346
|
+
throw new Error(`Unable to find package ${componentName}:${pkg}`);
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
const plugin = TRUSTED_RESOURCE_PLUGINS[componentName];
|
|
350
|
+
extensionModule =
|
|
351
|
+
typeof plugin === 'string'
|
|
352
|
+
? await import(plugin.startsWith('@/') ? join(PACKAGE_ROOT, plugin.slice(1)) : plugin)
|
|
353
|
+
: plugin;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (!extensionModule) {
|
|
357
|
+
// This is an application-only component (no extension module)
|
|
358
|
+
// Mark it as loaded since it exists in the config
|
|
359
|
+
componentLifecycle.loaded(componentStatusName, `Application component '${componentStatusName}' processed`);
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// our own trusted modules can be directly retrieved from our map, otherwise use the (configurable) secure module loader
|
|
364
|
+
const ensureTable = (options: any) => {
|
|
365
|
+
options.origin = origin;
|
|
366
|
+
return table(options);
|
|
367
|
+
};
|
|
368
|
+
// call the main start hook
|
|
369
|
+
const network =
|
|
370
|
+
componentConfig.network || ((componentConfig.port || componentConfig.securePort) && componentConfig);
|
|
371
|
+
const securePort =
|
|
372
|
+
network?.securePort ||
|
|
373
|
+
// legacy support for switching to securePort
|
|
374
|
+
(network?.https && network.port);
|
|
375
|
+
const port = !network?.https && network?.port;
|
|
376
|
+
|
|
377
|
+
if (
|
|
378
|
+
'handleApplication' in extensionModule &&
|
|
379
|
+
('start' in extensionModule ||
|
|
380
|
+
'startOnMainThread' in extensionModule ||
|
|
381
|
+
'handleFile' in extensionModule ||
|
|
382
|
+
'handleDirectory' in extensionModule ||
|
|
383
|
+
'setupFile' in extensionModule ||
|
|
384
|
+
'setupDirectory' in extensionModule)
|
|
385
|
+
) {
|
|
386
|
+
const error = new Error(`Plugin ${componentName} is exporting old extension APIs. Remove them.`);
|
|
387
|
+
componentLifecycle.failed(componentStatusName, error, `Component '${componentStatusName}' failed to load`);
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// New Plugin API (`handleApplication`)
|
|
392
|
+
if (resources.isWorker && extensionModule.handleApplication) {
|
|
393
|
+
const scope = new Scope(appName || 'harper', componentName, componentDirectory, configPath, applicationScope);
|
|
394
|
+
|
|
395
|
+
await sequentiallyHandleApplication(scope, extensionModule);
|
|
396
|
+
|
|
397
|
+
// Mark component as loaded after successful handleApplication call
|
|
398
|
+
componentLifecycle.loaded(componentStatusName, `Component '${componentStatusName}' loaded successfully`);
|
|
399
|
+
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Old Extension API (`start` or `startOnMainThread`)
|
|
404
|
+
if (
|
|
405
|
+
!BUILT_INS.includes(componentName) &&
|
|
406
|
+
('startOnMainThread' in extensionModule ||
|
|
407
|
+
'start' in extensionModule ||
|
|
408
|
+
'handleFile' in extensionModule ||
|
|
409
|
+
'handleDirectory' in extensionModule ||
|
|
410
|
+
'setupFile' in extensionModule ||
|
|
411
|
+
'setupDirectory' in extensionModule)
|
|
412
|
+
) {
|
|
413
|
+
harperLogger.warn?.(
|
|
414
|
+
`Component ${componentName} is using deprecated extension API. Upgrade to the new Plugin API. For more information: https://docs.harperdb.io/docs/reference/components/plugins`
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (isMainThread) {
|
|
419
|
+
extensionModule =
|
|
420
|
+
(await extensionModule.startOnMainThread?.({
|
|
421
|
+
server,
|
|
422
|
+
ensureTable,
|
|
423
|
+
port,
|
|
424
|
+
securePort,
|
|
425
|
+
resources,
|
|
426
|
+
...componentConfig,
|
|
427
|
+
})) || extensionModule;
|
|
428
|
+
if (isRoot && network) {
|
|
429
|
+
for (const possiblePort of [port, securePort]) {
|
|
430
|
+
try {
|
|
431
|
+
if (+possiblePort && !portsStarted.includes(possiblePort)) {
|
|
432
|
+
const sessionAffinity = env.get(CONFIG_PARAMS.HTTP_SESSIONAFFINITY);
|
|
433
|
+
if (sessionAffinity)
|
|
434
|
+
harperLogger.warn('Session affinity is not recommended and may cause memory leaks');
|
|
435
|
+
if (sessionAffinity || !createReuseportFd) {
|
|
436
|
+
// if there is a TCP port associated with the plugin, we set up the routing on the main thread for it
|
|
437
|
+
portsStarted.push(possiblePort);
|
|
438
|
+
startSocketServer(possiblePort, sessionAffinity);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
} catch (error) {
|
|
442
|
+
console.error('Error listening on socket', possiblePort, error, componentName);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (resources.isWorker)
|
|
448
|
+
extensionModule =
|
|
449
|
+
(await extensionModule.start?.({
|
|
450
|
+
server,
|
|
451
|
+
ensureTable,
|
|
452
|
+
port,
|
|
453
|
+
securePort,
|
|
454
|
+
resources,
|
|
455
|
+
...componentConfig,
|
|
456
|
+
})) || extensionModule;
|
|
457
|
+
loadedComponents.set(extensionModule, true);
|
|
458
|
+
|
|
459
|
+
if (
|
|
460
|
+
(extensionModule.handleFile ||
|
|
461
|
+
extensionModule.handleDirectory ||
|
|
462
|
+
extensionModule.setupFile ||
|
|
463
|
+
extensionModule.setupDirectory) &&
|
|
464
|
+
componentConfig.files != undefined
|
|
465
|
+
) {
|
|
466
|
+
const component = new ComponentV1({
|
|
467
|
+
config: componentConfig,
|
|
468
|
+
name: componentName,
|
|
469
|
+
directory: componentDirectory,
|
|
470
|
+
module: extensionModule,
|
|
471
|
+
resources,
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
componentFunctionality[componentName] = await processResourceExtensionComponent(component);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Mark component as healthy after successful loading
|
|
478
|
+
componentLifecycle.loaded(componentStatusName, `Component '${componentStatusName}' loaded successfully`);
|
|
479
|
+
} catch (error) {
|
|
480
|
+
error.message = `Could not load component '${componentName}' for application '${basename(componentDirectory)}' due to: ${
|
|
481
|
+
error.message
|
|
482
|
+
}`;
|
|
483
|
+
errorReporter?.(error);
|
|
484
|
+
(getWorkerIndex() === 0 ? console : harperLogger).error(error);
|
|
485
|
+
resources.set(componentConfig.path || '/', new ErrorResource(error), null, true);
|
|
486
|
+
componentLifecycle.failed(componentStatusName, error, `Could not load component '${componentStatusName}'`);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
compName = parentCompName;
|
|
491
|
+
// Auto restart threads on changes to any app folder. TODO: Make this configurable
|
|
492
|
+
if (isMainThread && !watchesSetup && autoReload) {
|
|
493
|
+
watchDir(componentDirectory, async () => {
|
|
494
|
+
return loadComponentDirectories(); // return the promise
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
if ((config.extensionModule || config.pluginModule) && (!isMainThread || config.runOnMainThread)) {
|
|
498
|
+
const extensionModule = await scopedImport(
|
|
499
|
+
join(componentDirectory, config.extensionModule || config.pluginModule),
|
|
500
|
+
applicationScope
|
|
501
|
+
);
|
|
502
|
+
loadedPaths.set(resolvedFolder, extensionModule);
|
|
503
|
+
return extensionModule;
|
|
504
|
+
}
|
|
505
|
+
const componentFunctionalityValues = Object.values(componentFunctionality);
|
|
506
|
+
if (
|
|
507
|
+
componentFunctionalityValues.length > 0 &&
|
|
508
|
+
componentFunctionalityValues.every((functionality) => !functionality) &&
|
|
509
|
+
resources.isWorker
|
|
510
|
+
) {
|
|
511
|
+
const errorMessage = `${componentDirectory} did not load any modules, resources, or files, is this a valid component?`;
|
|
512
|
+
errorReporter?.(new Error(errorMessage));
|
|
513
|
+
(getWorkerIndex() === 0 ? console : harperLogger).error(errorMessage);
|
|
514
|
+
componentLifecycle.failed(basename(componentDirectory), errorMessage);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
for (const [componentName, functionality] of Object.entries(componentFunctionality)) {
|
|
518
|
+
if (!functionality)
|
|
519
|
+
harperLogger.warn(
|
|
520
|
+
`Component ${componentName} from (${basename(componentDirectory)}) did not load any functionality.`
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
} catch (error) {
|
|
524
|
+
console.error(`Could not load application directory ${componentDirectory}`, error);
|
|
525
|
+
error.message = `Could not load application due to ${error.message}`;
|
|
526
|
+
errorReporter?.(error);
|
|
527
|
+
resources.set('', new ErrorResource(error));
|
|
528
|
+
}
|
|
529
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function deriveCommonPatternBase(patternBases: string[]): string {
|
|
2
|
+
if (patternBases.length === 0) return '.';
|
|
3
|
+
if (patternBases.length === 1) return patternBases[0];
|
|
4
|
+
|
|
5
|
+
// Split each pattern root into segments
|
|
6
|
+
// i.e. ['a/b/c', 'a/b/d'] -> [['a', 'b', 'c'], ['a', 'b', 'd']]
|
|
7
|
+
const pathSegments = patternBases.map((path) => path.split('/'));
|
|
8
|
+
// Find the minimum length of the segments
|
|
9
|
+
const minSegments = Math.min(...pathSegments.map((segments) => segments.length));
|
|
10
|
+
|
|
11
|
+
// Now to determine the common segments
|
|
12
|
+
const commonSegments = [];
|
|
13
|
+
// iterate up to the minimum segments length, this index is the part of the segments to compare
|
|
14
|
+
for (let i = 0; i < minSegments; i++) {
|
|
15
|
+
// Use the first path segment as a reference
|
|
16
|
+
const segment = pathSegments[0][i];
|
|
17
|
+
|
|
18
|
+
// Then iterate over all of the path segments and compare the segment at the current index
|
|
19
|
+
if (pathSegments.every((segments) => segments[i] === segment)) {
|
|
20
|
+
// If they all matched, its a common segment
|
|
21
|
+
commonSegments.push(segment);
|
|
22
|
+
} else {
|
|
23
|
+
// Otherwise, there is a mismatch. Stop here
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Now, inspect the common segments. If there are none, then use the root '.'
|
|
29
|
+
// Otherwise, join the segments with '/' and that is the common root of the set of pattern roots.
|
|
30
|
+
return commonSegments.length === 0 ? '.' : commonSegments.join('/');
|
|
31
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface FilesOptionObject {
|
|
2
|
+
source: string | string[];
|
|
3
|
+
// TODO: @Ethan-Arrowood - https://harperdb.atlassian.net/browse/CORE-2815
|
|
4
|
+
only?: 'all' | 'files' | 'directories';
|
|
5
|
+
ignore?: string | string[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type FilesOption = string | string[] | FilesOptionObject;
|
|
9
|
+
|
|
10
|
+
export type FastGlobOptions = {
|
|
11
|
+
source: string[];
|
|
12
|
+
ignore: string[];
|
|
13
|
+
onlyFiles: boolean;
|
|
14
|
+
onlyDirectories: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function deriveGlobOptions(files: FilesOption): FastGlobOptions {
|
|
18
|
+
const options: FastGlobOptions = {
|
|
19
|
+
source: [],
|
|
20
|
+
onlyFiles: false,
|
|
21
|
+
onlyDirectories: false,
|
|
22
|
+
ignore: [],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const addToArray = (target: string[], value?: string | string[]) => {
|
|
26
|
+
if (typeof value === 'string') {
|
|
27
|
+
target.push(value);
|
|
28
|
+
} else if (Array.isArray(value)) {
|
|
29
|
+
target.push(...value);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if (typeof files === 'string' || Array.isArray(files)) {
|
|
34
|
+
addToArray(options.source, files);
|
|
35
|
+
} else {
|
|
36
|
+
addToArray(options.source, files.source);
|
|
37
|
+
addToArray(options.ignore, files.ignore);
|
|
38
|
+
|
|
39
|
+
options.onlyFiles = files.only === 'files';
|
|
40
|
+
options.onlyDirectories = files.only === 'directories';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return options;
|
|
44
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import type { Component } from './Component.js';
|
|
3
|
+
import type { ComponentV1 } from './ComponentV1.js';
|
|
4
|
+
|
|
5
|
+
function pathStartsWithBase(base: string, path: string) {
|
|
6
|
+
const re = new RegExp(`^${base}(/|$)`);
|
|
7
|
+
return re.test(path);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function deriveURLPath(component: Component | ComponentV1, path: string, type: 'file' | 'directory'): string {
|
|
11
|
+
if (path.startsWith('./')) {
|
|
12
|
+
path = path.slice(2); // remove leading './'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
for (let base of component.patternBases) {
|
|
16
|
+
if (base.startsWith('./')) {
|
|
17
|
+
base = base.slice(2); // remove leading './'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (base === '') continue;
|
|
21
|
+
|
|
22
|
+
// files
|
|
23
|
+
// path, base -> result
|
|
24
|
+
// index.html, index.html -> index.html
|
|
25
|
+
// web/index.html, web -> index.html
|
|
26
|
+
// web/index.html, web/index.html -> index.html
|
|
27
|
+
// web/static/index.html, web/static/index.html -> index.html
|
|
28
|
+
// web/static/index.html, web -> static/index.html
|
|
29
|
+
if (type === 'file') {
|
|
30
|
+
if (path === base) {
|
|
31
|
+
const split = path.split('/');
|
|
32
|
+
path = split[split.length - 1]; // get the last part of the path
|
|
33
|
+
break;
|
|
34
|
+
} else if (pathStartsWithBase(base, path)) {
|
|
35
|
+
path = path.slice(base.length + 1); // +1 to remove the leading slash
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// directories
|
|
41
|
+
// path, base -> result
|
|
42
|
+
// web, web -> /
|
|
43
|
+
// web/static, web/static -> /
|
|
44
|
+
// web/static, web -> static
|
|
45
|
+
if (type === 'directory') {
|
|
46
|
+
if (path === base) {
|
|
47
|
+
path = '';
|
|
48
|
+
break; // no change needed
|
|
49
|
+
} else if (pathStartsWithBase(base, path)) {
|
|
50
|
+
path = path.slice(base.length + 1); // +1 to remove the leading slash
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return join(component.baseURLPath, path);
|
|
57
|
+
}
|