@ductape/sdk 0.0.4-v5 → 0.0.4-v51
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/README.md +1 -1
- package/dist/api/services/appApi.service.d.ts +48 -2
- package/dist/api/services/appApi.service.js +101 -2
- package/dist/api/services/appApi.service.js.map +1 -1
- package/dist/api/services/pricingApi.service.d.ts +10 -0
- package/dist/api/services/pricingApi.service.js +34 -0
- package/dist/api/services/pricingApi.service.js.map +1 -0
- package/dist/api/services/processorApi.service.d.ts +12 -2
- package/dist/api/services/processorApi.service.js +12 -2
- package/dist/api/services/processorApi.service.js.map +1 -1
- package/dist/api/services/productsApi.service.d.ts +40 -1
- package/dist/api/services/productsApi.service.js +105 -1
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/api/services/userApi.service.js +1 -0
- package/dist/api/services/userApi.service.js.map +1 -1
- package/dist/api/services/workspaceApi.service.js +1 -0
- package/dist/api/services/workspaceApi.service.js.map +1 -1
- package/dist/api/services/workspaceSecretsApi.service.d.ts +75 -0
- package/dist/api/services/workspaceSecretsApi.service.js +62 -0
- package/dist/api/services/workspaceSecretsApi.service.js.map +1 -0
- package/dist/api/urls.d.ts +6 -1
- package/dist/api/urls.js +12 -2
- package/dist/api/urls.js.map +1 -1
- package/dist/api/utils/cache.utils.d.ts +1 -1
- package/dist/api/utils/cache.utils.js +10 -4
- package/dist/api/utils/cache.utils.js.map +1 -1
- package/dist/api/utils/strings.utils.d.ts +2 -0
- package/dist/api/utils/strings.utils.js +14 -0
- package/dist/api/utils/strings.utils.js.map +1 -1
- package/dist/apps/services/app.service.d.ts +51 -33
- package/dist/apps/services/app.service.js +488 -244
- package/dist/apps/services/app.service.js.map +1 -1
- package/dist/apps/validators/joi-validators/create.appAction.validator.d.ts +1 -2
- package/dist/apps/validators/joi-validators/create.appAction.validator.js +21 -2
- package/dist/apps/validators/joi-validators/create.appAction.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.d.ts +1 -2
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.js +2 -15
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appAction.validator.js +11 -1
- package/dist/apps/validators/joi-validators/update.appAction.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.d.ts +1 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js +34 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.d.ts +1 -2
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.js +2 -14
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.js.map +1 -1
- package/dist/clients/pricing.client.d.ts +3 -0
- package/dist/clients/pricing.client.js +33 -0
- package/dist/clients/pricing.client.js.map +1 -0
- package/dist/database/adapters/base.adapter.d.ts +176 -0
- package/dist/database/adapters/base.adapter.js +31 -0
- package/dist/database/adapters/base.adapter.js.map +1 -0
- package/dist/database/adapters/dynamodb.adapter.d.ts +91 -0
- package/dist/database/adapters/dynamodb.adapter.js +1608 -0
- package/dist/database/adapters/dynamodb.adapter.js.map +1 -0
- package/dist/database/adapters/mongodb.adapter.d.ts +71 -0
- package/dist/database/adapters/mongodb.adapter.js +1072 -0
- package/dist/database/adapters/mongodb.adapter.js.map +1 -0
- package/dist/database/adapters/mysql.adapter.d.ts +146 -0
- package/dist/database/adapters/mysql.adapter.js +1492 -0
- package/dist/database/adapters/mysql.adapter.js.map +1 -0
- package/dist/database/adapters/postgresql.adapter.d.ts +147 -0
- package/dist/database/adapters/postgresql.adapter.js +1603 -0
- package/dist/database/adapters/postgresql.adapter.js.map +1 -0
- package/dist/database/database.service.d.ts +232 -0
- package/dist/database/database.service.js +802 -0
- package/dist/database/database.service.js.map +1 -0
- package/dist/database/index.d.ts +18 -0
- package/dist/database/index.js +98 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/types/aggregation.types.d.ts +261 -0
- package/dist/database/types/aggregation.types.js +21 -0
- package/dist/database/types/aggregation.types.js.map +1 -0
- package/dist/database/types/connection.types.d.ts +132 -0
- package/dist/database/types/connection.types.js +6 -0
- package/dist/database/types/connection.types.js.map +1 -0
- package/dist/database/types/database.types.d.ts +175 -0
- package/dist/database/types/database.types.js +75 -0
- package/dist/database/types/database.types.js.map +1 -0
- package/dist/database/types/index.d.ts +12 -0
- package/dist/database/types/index.js +37 -0
- package/dist/database/types/index.js.map +1 -0
- package/dist/database/types/index.types.d.ts +220 -0
- package/dist/database/types/index.types.js +27 -0
- package/dist/database/types/index.types.js.map +1 -0
- package/dist/database/types/migration.types.d.ts +205 -0
- package/dist/database/types/migration.types.js +44 -0
- package/dist/database/types/migration.types.js.map +1 -0
- package/dist/database/types/query.types.d.ts +305 -0
- package/dist/database/types/query.types.js +57 -0
- package/dist/database/types/query.types.js.map +1 -0
- package/dist/database/types/result.types.d.ts +220 -0
- package/dist/database/types/result.types.js +6 -0
- package/dist/database/types/result.types.js.map +1 -0
- package/dist/database/types/schema.types.d.ts +190 -0
- package/dist/database/types/schema.types.js +69 -0
- package/dist/database/types/schema.types.js.map +1 -0
- package/dist/database/utils/helpers.d.ts +66 -0
- package/dist/database/utils/helpers.js +501 -0
- package/dist/database/utils/helpers.js.map +1 -0
- package/dist/database/utils/migration.utils.d.ts +151 -0
- package/dist/database/utils/migration.utils.js +476 -0
- package/dist/database/utils/migration.utils.js.map +1 -0
- package/dist/database/utils/transaction.d.ts +64 -0
- package/dist/database/utils/transaction.js +130 -0
- package/dist/database/utils/transaction.js.map +1 -0
- package/dist/database/validators/connection.validator.d.ts +20 -0
- package/dist/database/validators/connection.validator.js +267 -0
- package/dist/database/validators/connection.validator.js.map +1 -0
- package/dist/database/validators/query.validator.d.ts +31 -0
- package/dist/database/validators/query.validator.js +305 -0
- package/dist/database/validators/query.validator.js.map +1 -0
- package/dist/database/validators/schema.validator.d.ts +31 -0
- package/dist/database/validators/schema.validator.js +334 -0
- package/dist/database/validators/schema.validator.js.map +1 -0
- package/dist/graph/adapters/arangodb.adapter.d.ts +80 -0
- package/dist/graph/adapters/arangodb.adapter.js +1393 -0
- package/dist/graph/adapters/arangodb.adapter.js.map +1 -0
- package/dist/graph/adapters/base.adapter.d.ts +228 -0
- package/dist/graph/adapters/base.adapter.js +38 -0
- package/dist/graph/adapters/base.adapter.js.map +1 -0
- package/dist/graph/adapters/index.d.ts +10 -0
- package/dist/graph/adapters/index.js +23 -0
- package/dist/graph/adapters/index.js.map +1 -0
- package/dist/graph/adapters/memgraph.adapter.d.ts +85 -0
- package/dist/graph/adapters/memgraph.adapter.js +1491 -0
- package/dist/graph/adapters/memgraph.adapter.js.map +1 -0
- package/dist/graph/adapters/neo4j.adapter.d.ts +88 -0
- package/dist/graph/adapters/neo4j.adapter.js +1861 -0
- package/dist/graph/adapters/neo4j.adapter.js.map +1 -0
- package/dist/graph/adapters/neptune.adapter.d.ts +87 -0
- package/dist/graph/adapters/neptune.adapter.js +1430 -0
- package/dist/graph/adapters/neptune.adapter.js.map +1 -0
- package/dist/graph/graph.service.d.ts +278 -0
- package/dist/graph/graph.service.js +687 -0
- package/dist/graph/graph.service.js.map +1 -0
- package/dist/graph/index.d.ts +11 -0
- package/dist/graph/index.js +42 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/types/connection.types.d.ts +158 -0
- package/dist/graph/types/connection.types.js +43 -0
- package/dist/graph/types/connection.types.js.map +1 -0
- package/dist/graph/types/graph.types.d.ts +144 -0
- package/dist/graph/types/graph.types.js +84 -0
- package/dist/graph/types/graph.types.js.map +1 -0
- package/dist/graph/types/index.d.ts +11 -0
- package/dist/graph/types/index.js +35 -0
- package/dist/graph/types/index.js.map +1 -0
- package/dist/graph/types/node.types.d.ts +193 -0
- package/dist/graph/types/node.types.js +49 -0
- package/dist/graph/types/node.types.js.map +1 -0
- package/dist/graph/types/path.types.d.ts +224 -0
- package/dist/graph/types/path.types.js +38 -0
- package/dist/graph/types/path.types.js.map +1 -0
- package/dist/graph/types/query.types.d.ts +247 -0
- package/dist/graph/types/query.types.js +23 -0
- package/dist/graph/types/query.types.js.map +1 -0
- package/dist/graph/types/relationship.types.d.ts +224 -0
- package/dist/graph/types/relationship.types.js +35 -0
- package/dist/graph/types/relationship.types.js.map +1 -0
- package/dist/graph/types/result.types.d.ts +237 -0
- package/dist/graph/types/result.types.js +7 -0
- package/dist/graph/types/result.types.js.map +1 -0
- package/dist/graph/validators/index.d.ts +81 -0
- package/dist/graph/validators/index.js +243 -0
- package/dist/graph/validators/index.js.map +1 -0
- package/dist/imports/imports.service.d.ts +3 -3
- package/dist/imports/imports.service.js +7 -7
- package/dist/imports/imports.service.js.map +1 -1
- package/dist/imports/imports.types.d.ts +8 -0
- package/dist/imports/repos/postmanV21.repo.d.ts +1 -1
- package/dist/imports/repos/postmanV21.repo.js +29 -2
- package/dist/imports/repos/postmanV21.repo.js.map +1 -1
- package/dist/index.d.ts +1244 -150
- package/dist/index.js +1309 -209
- package/dist/index.js.map +1 -1
- package/dist/inputs/inputs.service.js +2 -2
- package/dist/inputs/inputs.service.js.map +1 -1
- package/dist/inputs/utils/inputs.utils.create.js +1 -1
- package/dist/inputs/utils/inputs.utils.create.js.map +1 -1
- package/dist/logs/logs.types.d.ts +5 -0
- package/dist/logs/logs.types.js +1 -0
- package/dist/logs/logs.types.js.map +1 -1
- package/dist/parsers/index.d.ts +3 -0
- package/dist/parsers/index.js +27 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/pipelines/postman.pipelines.d.ts +15 -0
- package/dist/parsers/pipelines/postman.pipelines.js +103 -0
- package/dist/parsers/pipelines/postman.pipelines.js.map +1 -0
- package/dist/parsers/types/postman.types.d.ts +200 -0
- package/dist/parsers/types/postman.types.js +3 -0
- package/dist/parsers/types/postman.types.js.map +1 -0
- package/dist/parsers/utils/postman.utils.d.ts +12 -0
- package/dist/parsers/utils/postman.utils.js +116 -0
- package/dist/parsers/utils/postman.utils.js.map +1 -0
- package/dist/parsers/validators/postman-auth.validators.d.ts +10 -0
- package/dist/parsers/validators/postman-auth.validators.js +127 -0
- package/dist/parsers/validators/postman-auth.validators.js.map +1 -0
- package/dist/parsers/validators/postman-request.validators.d.ts +13 -0
- package/dist/parsers/validators/postman-request.validators.js +139 -0
- package/dist/parsers/validators/postman-request.validators.js.map +1 -0
- package/dist/parsers/validators/postman-response.validators.d.ts +13 -0
- package/dist/parsers/validators/postman-response.validators.js +150 -0
- package/dist/parsers/validators/postman-response.validators.js.map +1 -0
- package/dist/parsers/validators/postman-variable.validators.d.ts +14 -0
- package/dist/parsers/validators/postman-variable.validators.js +163 -0
- package/dist/parsers/validators/postman-variable.validators.js.map +1 -0
- package/dist/pricing/pricing.repo.d.ts +0 -0
- package/dist/pricing/pricing.repo.js +1 -0
- package/dist/pricing/pricing.repo.js.map +1 -0
- package/dist/pricing/pricing.service.d.ts +24 -0
- package/dist/pricing/pricing.service.js +51 -0
- package/dist/pricing/pricing.service.js.map +1 -0
- package/dist/pricing/pricing.types.d.ts +76 -0
- package/dist/pricing/pricing.types.js +21 -0
- package/dist/pricing/pricing.types.js.map +1 -0
- package/dist/pricing/utils/string.utils.d.ts +1 -0
- package/dist/pricing/utils/string.utils.js +9 -0
- package/dist/pricing/utils/string.utils.js.map +1 -0
- package/dist/processor/repos/sms.repo.d.ts +4 -4
- package/dist/processor/repos/sms.repo.js +23 -10
- package/dist/processor/repos/sms.repo.js.map +1 -1
- package/dist/processor/services/messagebrokers/kafka.service.js +0 -2
- package/dist/processor/services/messagebrokers/kafka.service.js.map +1 -1
- package/dist/processor/services/messagebrokers/rabbitmq.service.d.ts +9 -1
- package/dist/processor/services/messagebrokers/rabbitmq.service.js +40 -11
- package/dist/processor/services/messagebrokers/rabbitmq.service.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +38 -10
- package/dist/processor/services/processor.service.js +533 -248
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/processor/services/request.service.d.ts +36 -0
- package/dist/processor/services/request.service.js +304 -0
- package/dist/processor/services/request.service.js.map +1 -0
- package/dist/processor/types/request.types.d.ts +14 -0
- package/dist/processor/types/request.types.js +3 -0
- package/dist/processor/types/request.types.js.map +1 -0
- package/dist/processor/utils/processor.utils.d.ts +3 -0
- package/dist/processor/utils/processor.utils.js +84 -22
- package/dist/processor/utils/processor.utils.js.map +1 -1
- package/dist/processor/utils/request.utils.d.ts +20 -0
- package/dist/processor/utils/request.utils.js +113 -0
- package/dist/processor/utils/request.utils.js.map +1 -0
- package/dist/products/services/products.service.d.ts +114 -77
- package/dist/products/services/products.service.js +805 -362
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/services/utils/crypt.utils.d.ts +1 -0
- package/dist/products/services/utils/crypt.utils.js +17 -0
- package/dist/products/services/utils/crypt.utils.js.map +1 -0
- package/dist/products/services/utils/functions.utils.d.ts +13 -0
- package/dist/products/services/utils/functions.utils.js +289 -0
- package/dist/products/services/utils/functions.utils.js.map +1 -0
- package/dist/products/services/utils/objects.utils.d.ts +13 -0
- package/dist/products/services/utils/objects.utils.js +89 -0
- package/dist/products/services/utils/objects.utils.js.map +1 -0
- package/dist/products/services/utils/string.utils.d.ts +12 -0
- package/dist/products/services/utils/string.utils.js +168 -0
- package/dist/products/services/utils/string.utils.js.map +1 -0
- package/dist/products/utils/string.utils.d.ts +1 -1
- package/dist/products/utils/string.utils.js +14 -2
- package/dist/products/utils/string.utils.js.map +1 -1
- package/dist/products/validators/index.d.ts +4 -1
- package/dist/products/validators/index.js +7 -1
- package/dist/products/validators/index.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.d.ts +15 -4
- package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js +501 -109
- package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productEnv.validator.js +1 -0
- package/dist/products/validators/joi-validators/create.productEnv.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productGraph.validator.d.ts +3 -0
- package/dist/products/validators/joi-validators/create.productGraph.validator.js +82 -0
- package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.productGraphAction.validator.d.ts +14 -0
- package/dist/products/validators/joi-validators/create.productGraphAction.validator.js +696 -0
- package/dist/products/validators/joi-validators/create.productGraphAction.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.d.ts +4 -0
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js +58 -0
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js +1 -0
- package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js +9 -4
- package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productNotification.validator.js +5 -2
- package/dist/products/validators/joi-validators/create.productNotification.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.userAuth.validator.js +1 -0
- package/dist/products/validators/joi-validators/create.userAuth.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.dataValue.validator.js +1 -0
- package/dist/products/validators/joi-validators/update.dataValue.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.d.ts +6 -0
- package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js +28 -26
- package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productEnv.validator.js +3 -0
- package/dist/products/validators/joi-validators/update.productEnv.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productGraph.validator.d.ts +3 -0
- package/dist/products/validators/joi-validators/update.productGraph.validator.js +87 -0
- package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/update.productGraphAction.validator.d.ts +7 -0
- package/dist/products/validators/joi-validators/update.productGraphAction.validator.js +72 -0
- package/dist/products/validators/joi-validators/update.productGraphAction.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js +1 -0
- package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.userAuth.validator.js +1 -0
- package/dist/products/validators/joi-validators/update.userAuth.validator.js.map +1 -1
- package/dist/test/test.health.d.ts +1 -0
- package/dist/test/test.health.js +49 -0
- package/dist/test/test.health.js.map +1 -0
- package/dist/test/test.import.js +51 -4
- package/dist/test/test.import.js.map +1 -1
- package/dist/test/test.imports.js +22 -7
- package/dist/test/test.imports.js.map +1 -1
- package/dist/test/test.notifiers.d.ts +1 -0
- package/dist/test/test.notifiers.js +85 -0
- package/dist/test/test.notifiers.js.map +1 -0
- package/dist/test/test.processor.js +30 -115
- package/dist/test/test.processor.js.map +1 -1
- package/dist/test/test.products.d.ts +1 -0
- package/dist/test/test.products.js +49 -0
- package/dist/test/test.products.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/appBuilder.types.d.ts +5 -12
- package/dist/types/enums.d.ts +4 -1
- package/dist/types/enums.js +3 -0
- package/dist/types/enums.js.map +1 -1
- package/dist/types/index.types.d.ts +4 -0
- package/dist/types/pricing.types.d.ts +4 -0
- package/dist/types/pricing.types.js +3 -0
- package/dist/types/pricing.types.js.map +1 -0
- package/dist/types/processor.types.d.ts +67 -11
- package/dist/types/processor.types.js.map +1 -1
- package/dist/types/productsBuilder.types.d.ts +132 -14
- package/dist/types/productsBuilder.types.js +69 -4
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/dist/types/request-tracker.interface.d.ts +0 -0
- package/dist/types/request-tracker.interface.js +1 -0
- package/dist/types/request-tracker.interface.js.map +1 -0
- package/dist/utils/constants.d.ts +1 -0
- package/dist/utils/constants.js +5 -0
- package/dist/utils/constants.js.map +1 -0
- package/package.json +17 -3
|
@@ -0,0 +1,1393 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ArangoDB Graph Database Adapter
|
|
4
|
+
* Implements the BaseGraphAdapter for ArangoDB using AQL (ArangoDB Query Language)
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
40
|
+
var t = {};
|
|
41
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
42
|
+
t[p] = s[p];
|
|
43
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
44
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
45
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
46
|
+
t[p[i]] = s[p[i]];
|
|
47
|
+
}
|
|
48
|
+
return t;
|
|
49
|
+
};
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.ArangoDBAdapter = void 0;
|
|
52
|
+
const base_adapter_1 = require("./base.adapter");
|
|
53
|
+
const graph_types_1 = require("../types/graph.types");
|
|
54
|
+
const node_types_1 = require("../types/node.types");
|
|
55
|
+
const relationship_types_1 = require("../types/relationship.types");
|
|
56
|
+
/**
|
|
57
|
+
* ArangoDB connection implementation
|
|
58
|
+
*/
|
|
59
|
+
class ArangoDBConnection {
|
|
60
|
+
constructor(config, id) {
|
|
61
|
+
this.config = config;
|
|
62
|
+
this.type = graph_types_1.GraphDatabaseType.ARANGODB;
|
|
63
|
+
this.status = graph_types_1.GraphConnectionStatus.DISCONNECTED;
|
|
64
|
+
this.queryLanguage = graph_types_1.GraphQueryLanguage.AQL;
|
|
65
|
+
this.db = null;
|
|
66
|
+
this.graphName = null;
|
|
67
|
+
this.id = id || `arangodb-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
68
|
+
this.createdAt = new Date();
|
|
69
|
+
}
|
|
70
|
+
async connect() {
|
|
71
|
+
if (this.status === graph_types_1.GraphConnectionStatus.CONNECTED) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
this.status = graph_types_1.GraphConnectionStatus.CONNECTING;
|
|
75
|
+
try {
|
|
76
|
+
// Dynamic import for arangojs
|
|
77
|
+
const arangojs = await Promise.resolve().then(() => __importStar(require('arangojs')));
|
|
78
|
+
const { Database } = arangojs;
|
|
79
|
+
const dbConfig = {
|
|
80
|
+
url: this.config.url,
|
|
81
|
+
databaseName: this.config.database,
|
|
82
|
+
};
|
|
83
|
+
if (this.config.token) {
|
|
84
|
+
dbConfig.auth = { bearer: this.config.token };
|
|
85
|
+
}
|
|
86
|
+
else if (this.config.username) {
|
|
87
|
+
dbConfig.auth = {
|
|
88
|
+
username: this.config.username,
|
|
89
|
+
password: this.config.password || '',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (this.config.agentOptions) {
|
|
93
|
+
dbConfig.agentOptions = this.config.agentOptions;
|
|
94
|
+
}
|
|
95
|
+
if (this.config.headers) {
|
|
96
|
+
dbConfig.headers = this.config.headers;
|
|
97
|
+
}
|
|
98
|
+
const db = new Database(dbConfig);
|
|
99
|
+
// Verify connectivity
|
|
100
|
+
const exists = await db.exists();
|
|
101
|
+
if (!exists) {
|
|
102
|
+
throw new Error(`Database '${this.config.database}' does not exist`);
|
|
103
|
+
}
|
|
104
|
+
this.db = db;
|
|
105
|
+
this.status = graph_types_1.GraphConnectionStatus.CONNECTED;
|
|
106
|
+
this.lastUsedAt = new Date();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
this.status = graph_types_1.GraphConnectionStatus.ERROR;
|
|
110
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.CONNECTION_ERROR, `Failed to connect to ArangoDB: ${error.message}`, error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async disconnect() {
|
|
114
|
+
this.db = null;
|
|
115
|
+
this.status = graph_types_1.GraphConnectionStatus.DISCONNECTED;
|
|
116
|
+
}
|
|
117
|
+
isConnected() {
|
|
118
|
+
return this.status === graph_types_1.GraphConnectionStatus.CONNECTED && this.db !== null;
|
|
119
|
+
}
|
|
120
|
+
getClient() {
|
|
121
|
+
if (!this.db) {
|
|
122
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.CONNECTION_ERROR, 'ArangoDB client not initialized. Call connect() first.');
|
|
123
|
+
}
|
|
124
|
+
return this.db;
|
|
125
|
+
}
|
|
126
|
+
getSession() {
|
|
127
|
+
return this.getClient();
|
|
128
|
+
}
|
|
129
|
+
getConfig() {
|
|
130
|
+
return this.config;
|
|
131
|
+
}
|
|
132
|
+
setGraphName(name) {
|
|
133
|
+
this.graphName = name;
|
|
134
|
+
}
|
|
135
|
+
getGraphName() {
|
|
136
|
+
return this.graphName;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* ArangoDB transaction implementation
|
|
141
|
+
*/
|
|
142
|
+
class ArangoDBTransaction {
|
|
143
|
+
constructor(connection, transaction) {
|
|
144
|
+
this.connection = connection;
|
|
145
|
+
this.status = graph_types_1.GraphTransactionStatus.PENDING;
|
|
146
|
+
this.id = `tx-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
147
|
+
this.createdAt = new Date();
|
|
148
|
+
this.native = transaction;
|
|
149
|
+
this.status = graph_types_1.GraphTransactionStatus.ACTIVE;
|
|
150
|
+
}
|
|
151
|
+
async commit() {
|
|
152
|
+
if (this.status !== graph_types_1.GraphTransactionStatus.ACTIVE) {
|
|
153
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.TRANSACTION_ERROR, `Cannot commit transaction in ${this.status} state`);
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
if (this.native && this.native.commit) {
|
|
157
|
+
await this.native.commit();
|
|
158
|
+
}
|
|
159
|
+
this.status = graph_types_1.GraphTransactionStatus.COMMITTED;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
this.status = graph_types_1.GraphTransactionStatus.FAILED;
|
|
163
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.TRANSACTION_ERROR, `Failed to commit transaction: ${error.message}`, error);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async rollback() {
|
|
167
|
+
if (this.status !== graph_types_1.GraphTransactionStatus.ACTIVE) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
if (this.native && this.native.abort) {
|
|
172
|
+
await this.native.abort();
|
|
173
|
+
}
|
|
174
|
+
this.status = graph_types_1.GraphTransactionStatus.ROLLED_BACK;
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
this.status = graph_types_1.GraphTransactionStatus.FAILED;
|
|
178
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.TRANSACTION_ERROR, `Failed to rollback transaction: ${error.message}`, error);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
isActive() {
|
|
182
|
+
return this.status === graph_types_1.GraphTransactionStatus.ACTIVE;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* ArangoDB Graph Database Adapter
|
|
187
|
+
*/
|
|
188
|
+
class ArangoDBAdapter extends base_adapter_1.BaseGraphAdapter {
|
|
189
|
+
constructor() {
|
|
190
|
+
super(...arguments);
|
|
191
|
+
this.type = graph_types_1.GraphDatabaseType.ARANGODB;
|
|
192
|
+
this.supportedLanguages = [graph_types_1.GraphQueryLanguage.AQL];
|
|
193
|
+
this.defaultLanguage = graph_types_1.GraphQueryLanguage.AQL;
|
|
194
|
+
// Default collection names
|
|
195
|
+
this.defaultVertexCollection = 'vertices';
|
|
196
|
+
this.defaultEdgeCollection = 'edges';
|
|
197
|
+
}
|
|
198
|
+
// ==================== CONNECTION METHODS ====================
|
|
199
|
+
async connect(config) {
|
|
200
|
+
if (config.type !== graph_types_1.GraphDatabaseType.ARANGODB) {
|
|
201
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.VALIDATION_ERROR, `Invalid config type ${config.type}. Expected ${graph_types_1.GraphDatabaseType.ARANGODB}`);
|
|
202
|
+
}
|
|
203
|
+
const connection = new ArangoDBConnection(config);
|
|
204
|
+
await connection.connect();
|
|
205
|
+
return connection;
|
|
206
|
+
}
|
|
207
|
+
async disconnect(connection) {
|
|
208
|
+
await connection.disconnect();
|
|
209
|
+
}
|
|
210
|
+
async testConnection(connection) {
|
|
211
|
+
const startTime = Date.now();
|
|
212
|
+
try {
|
|
213
|
+
const db = connection.getClient();
|
|
214
|
+
const versionInfo = await db.version();
|
|
215
|
+
return {
|
|
216
|
+
connected: true,
|
|
217
|
+
message: 'Connection successful',
|
|
218
|
+
databaseType: graph_types_1.GraphDatabaseType.ARANGODB,
|
|
219
|
+
queryLanguage: graph_types_1.GraphQueryLanguage.AQL,
|
|
220
|
+
version: versionInfo.version,
|
|
221
|
+
responseTime: Date.now() - startTime,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
return {
|
|
226
|
+
connected: false,
|
|
227
|
+
message: 'Connection failed',
|
|
228
|
+
databaseType: graph_types_1.GraphDatabaseType.ARANGODB,
|
|
229
|
+
queryLanguage: graph_types_1.GraphQueryLanguage.AQL,
|
|
230
|
+
responseTime: Date.now() - startTime,
|
|
231
|
+
error: error.message,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async getDatabaseInfo(connection) {
|
|
236
|
+
const db = connection.getClient();
|
|
237
|
+
const versionInfo = await db.version();
|
|
238
|
+
return {
|
|
239
|
+
version: versionInfo.version,
|
|
240
|
+
edition: versionInfo.server,
|
|
241
|
+
features: ['graphs', 'full-text-search', 'geo-spatial'],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
// ==================== TRANSACTION METHODS ====================
|
|
245
|
+
async beginTransaction(connection, options) {
|
|
246
|
+
const db = connection.getClient();
|
|
247
|
+
const collections = {
|
|
248
|
+
read: [this.defaultVertexCollection, this.defaultEdgeCollection],
|
|
249
|
+
write: [this.defaultVertexCollection, this.defaultEdgeCollection],
|
|
250
|
+
};
|
|
251
|
+
const trx = await db.beginTransaction(collections);
|
|
252
|
+
return new ArangoDBTransaction(connection, trx);
|
|
253
|
+
}
|
|
254
|
+
async commitTransaction(connection, transaction) {
|
|
255
|
+
await transaction.commit();
|
|
256
|
+
}
|
|
257
|
+
async rollbackTransaction(connection, transaction) {
|
|
258
|
+
await transaction.rollback();
|
|
259
|
+
}
|
|
260
|
+
// ==================== RAW QUERY METHODS ====================
|
|
261
|
+
async executeRaw(connection, options, transaction) {
|
|
262
|
+
const startTime = Date.now();
|
|
263
|
+
const db = connection.getClient();
|
|
264
|
+
try {
|
|
265
|
+
const cursor = await db.query(options.query, options.params || {});
|
|
266
|
+
const data = await cursor.all();
|
|
267
|
+
return {
|
|
268
|
+
success: true,
|
|
269
|
+
executionTime: Date.now() - startTime,
|
|
270
|
+
data: data,
|
|
271
|
+
count: data.length,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
throw this.wrapError(error, graph_types_1.GraphErrorType.QUERY_ERROR, `Query execution failed: ${error.message}`, options.query, options.params);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// ==================== NODE OPERATIONS ====================
|
|
279
|
+
async createNode(connection, options, transaction) {
|
|
280
|
+
const startTime = Date.now();
|
|
281
|
+
const labels = this.normalizeLabels(options.labels);
|
|
282
|
+
const collection = this.getVertexCollection(labels[0]);
|
|
283
|
+
// Add labels to properties for ArangoDB
|
|
284
|
+
const doc = Object.assign(Object.assign({}, options.properties), { _labels: labels });
|
|
285
|
+
const query = `
|
|
286
|
+
INSERT @doc INTO @@collection
|
|
287
|
+
RETURN NEW
|
|
288
|
+
`;
|
|
289
|
+
const result = await this.executeRaw(connection, {
|
|
290
|
+
query,
|
|
291
|
+
params: {
|
|
292
|
+
doc,
|
|
293
|
+
'@collection': collection,
|
|
294
|
+
},
|
|
295
|
+
}, transaction);
|
|
296
|
+
return {
|
|
297
|
+
success: true,
|
|
298
|
+
executionTime: Date.now() - startTime,
|
|
299
|
+
node: result.data.length > 0 ? this.parseNode(result.data[0]) : undefined,
|
|
300
|
+
created: true,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
async findNodes(connection, options, transaction) {
|
|
304
|
+
const startTime = Date.now();
|
|
305
|
+
const labels = options.labels ? this.normalizeLabels(options.labels) : [];
|
|
306
|
+
const collection = labels.length > 0 ? this.getVertexCollection(labels[0]) : this.defaultVertexCollection;
|
|
307
|
+
let query = `FOR doc IN @@collection`;
|
|
308
|
+
const params = { '@collection': collection };
|
|
309
|
+
// Build filter conditions
|
|
310
|
+
const filters = [];
|
|
311
|
+
if (labels.length > 0) {
|
|
312
|
+
filters.push(`@labels ALL IN doc._labels`);
|
|
313
|
+
params.labels = labels;
|
|
314
|
+
}
|
|
315
|
+
if (options.properties) {
|
|
316
|
+
Object.entries(options.properties).forEach(([key, value], index) => {
|
|
317
|
+
const paramName = `prop_${index}`;
|
|
318
|
+
filters.push(`doc.${key} == @${paramName}`);
|
|
319
|
+
params[paramName] = value;
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (options.where) {
|
|
323
|
+
const filterClause = this.buildAQLFilter(options.where, 'doc', params);
|
|
324
|
+
filters.push(filterClause);
|
|
325
|
+
}
|
|
326
|
+
if (filters.length > 0) {
|
|
327
|
+
query += ` FILTER ${filters.join(' AND ')}`;
|
|
328
|
+
}
|
|
329
|
+
// ORDER BY
|
|
330
|
+
if (options.orderBy && options.orderBy.length > 0) {
|
|
331
|
+
const sortParts = options.orderBy.map(o => `doc.${o.property} ${o.direction}`);
|
|
332
|
+
query += ` SORT ${sortParts.join(', ')}`;
|
|
333
|
+
}
|
|
334
|
+
// LIMIT with offset
|
|
335
|
+
if (options.skip !== undefined || options.limit !== undefined) {
|
|
336
|
+
const skip = options.skip || 0;
|
|
337
|
+
const limit = options.limit || 100;
|
|
338
|
+
query += ` LIMIT ${skip}, ${limit}`;
|
|
339
|
+
}
|
|
340
|
+
query += ` RETURN doc`;
|
|
341
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
342
|
+
const nodes = result.data.map(doc => this.parseNode(doc));
|
|
343
|
+
return {
|
|
344
|
+
success: true,
|
|
345
|
+
executionTime: Date.now() - startTime,
|
|
346
|
+
nodes,
|
|
347
|
+
count: nodes.length,
|
|
348
|
+
hasMore: options.limit !== undefined && nodes.length === options.limit,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
async findNodeById(connection, id, transaction) {
|
|
352
|
+
const query = `
|
|
353
|
+
FOR doc IN @@collection
|
|
354
|
+
FILTER doc._key == @id OR doc._id == @id
|
|
355
|
+
RETURN doc
|
|
356
|
+
`;
|
|
357
|
+
const result = await this.executeRaw(connection, {
|
|
358
|
+
query,
|
|
359
|
+
params: { id: String(id), '@collection': this.defaultVertexCollection },
|
|
360
|
+
}, transaction);
|
|
361
|
+
if (result.data.length === 0) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
return this.parseNode(result.data[0]);
|
|
365
|
+
}
|
|
366
|
+
async updateNode(connection, options, transaction) {
|
|
367
|
+
const startTime = Date.now();
|
|
368
|
+
const params = {};
|
|
369
|
+
let query;
|
|
370
|
+
if (options.id !== undefined) {
|
|
371
|
+
// Update by ID
|
|
372
|
+
const updates = {};
|
|
373
|
+
if (options.set) {
|
|
374
|
+
Object.assign(updates, options.set);
|
|
375
|
+
}
|
|
376
|
+
if (options.addLabels) {
|
|
377
|
+
// Will handle label merging in AQL
|
|
378
|
+
}
|
|
379
|
+
query = `
|
|
380
|
+
UPDATE { _key: @id } WITH @updates IN @@collection
|
|
381
|
+
RETURN NEW
|
|
382
|
+
`;
|
|
383
|
+
params.id = String(options.id);
|
|
384
|
+
params.updates = updates;
|
|
385
|
+
params['@collection'] = this.defaultVertexCollection;
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
// Update by filter
|
|
389
|
+
const filters = [];
|
|
390
|
+
if (options.labels) {
|
|
391
|
+
const labels = this.normalizeLabels(options.labels);
|
|
392
|
+
filters.push(`@labels ALL IN doc._labels`);
|
|
393
|
+
params.labels = labels;
|
|
394
|
+
}
|
|
395
|
+
if (options.where) {
|
|
396
|
+
const filterClause = this.buildAQLFilter(options.where, 'doc', params);
|
|
397
|
+
filters.push(filterClause);
|
|
398
|
+
}
|
|
399
|
+
query = `
|
|
400
|
+
FOR doc IN @@collection
|
|
401
|
+
${filters.length > 0 ? `FILTER ${filters.join(' AND ')}` : ''}
|
|
402
|
+
UPDATE doc WITH @updates IN @@collection
|
|
403
|
+
RETURN NEW
|
|
404
|
+
`;
|
|
405
|
+
params.updates = options.set || {};
|
|
406
|
+
params['@collection'] = this.defaultVertexCollection;
|
|
407
|
+
}
|
|
408
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
409
|
+
return {
|
|
410
|
+
success: true,
|
|
411
|
+
executionTime: Date.now() - startTime,
|
|
412
|
+
node: result.data.length > 0 ? this.parseNode(result.data[0]) : undefined,
|
|
413
|
+
updated: result.data.length > 0,
|
|
414
|
+
matchedCount: result.data.length,
|
|
415
|
+
modifiedCount: result.data.length,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
async deleteNode(connection, options, transaction) {
|
|
419
|
+
const startTime = Date.now();
|
|
420
|
+
const params = {};
|
|
421
|
+
let query;
|
|
422
|
+
if (options.id !== undefined) {
|
|
423
|
+
if (options.detach) {
|
|
424
|
+
// Delete edges first
|
|
425
|
+
query = `
|
|
426
|
+
LET doc = DOCUMENT(@@collection, @id)
|
|
427
|
+
LET edges = (
|
|
428
|
+
FOR e IN @@edges
|
|
429
|
+
FILTER e._from == doc._id OR e._to == doc._id
|
|
430
|
+
REMOVE e IN @@edges
|
|
431
|
+
RETURN 1
|
|
432
|
+
)
|
|
433
|
+
REMOVE doc IN @@collection
|
|
434
|
+
RETURN { deleted: 1, edgesDeleted: LENGTH(edges) }
|
|
435
|
+
`;
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
query = `
|
|
439
|
+
REMOVE { _key: @id } IN @@collection
|
|
440
|
+
RETURN { deleted: 1 }
|
|
441
|
+
`;
|
|
442
|
+
}
|
|
443
|
+
params.id = String(options.id);
|
|
444
|
+
params['@collection'] = this.defaultVertexCollection;
|
|
445
|
+
params['@edges'] = this.defaultEdgeCollection;
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
const filters = [];
|
|
449
|
+
if (options.labels) {
|
|
450
|
+
const labels = this.normalizeLabels(options.labels);
|
|
451
|
+
filters.push(`@labels ALL IN doc._labels`);
|
|
452
|
+
params.labels = labels;
|
|
453
|
+
}
|
|
454
|
+
if (options.where) {
|
|
455
|
+
const filterClause = this.buildAQLFilter(options.where, 'doc', params);
|
|
456
|
+
filters.push(filterClause);
|
|
457
|
+
}
|
|
458
|
+
query = `
|
|
459
|
+
FOR doc IN @@collection
|
|
460
|
+
${filters.length > 0 ? `FILTER ${filters.join(' AND ')}` : ''}
|
|
461
|
+
${options.detach ? `
|
|
462
|
+
LET edges = (
|
|
463
|
+
FOR e IN @@edges
|
|
464
|
+
FILTER e._from == doc._id OR e._to == doc._id
|
|
465
|
+
REMOVE e IN @@edges
|
|
466
|
+
RETURN 1
|
|
467
|
+
)
|
|
468
|
+
` : ''}
|
|
469
|
+
REMOVE doc IN @@collection
|
|
470
|
+
RETURN 1
|
|
471
|
+
`;
|
|
472
|
+
params['@collection'] = this.defaultVertexCollection;
|
|
473
|
+
params['@edges'] = this.defaultEdgeCollection;
|
|
474
|
+
}
|
|
475
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
476
|
+
return {
|
|
477
|
+
success: true,
|
|
478
|
+
executionTime: Date.now() - startTime,
|
|
479
|
+
deletedCount: result.data.length,
|
|
480
|
+
deletedRelationshipsCount: 0, // Could be calculated from detach query
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
async mergeNode(connection, options, transaction) {
|
|
484
|
+
var _a, _b;
|
|
485
|
+
const startTime = Date.now();
|
|
486
|
+
const labels = this.normalizeLabels(options.labels);
|
|
487
|
+
const collection = this.getVertexCollection(labels[0]);
|
|
488
|
+
// Build match filter
|
|
489
|
+
const matchFilters = [];
|
|
490
|
+
const params = { '@collection': collection };
|
|
491
|
+
matchFilters.push(`@labels ALL IN doc._labels`);
|
|
492
|
+
params.labels = labels;
|
|
493
|
+
Object.entries(options.matchProperties).forEach(([key, value], index) => {
|
|
494
|
+
const paramName = `match_${index}`;
|
|
495
|
+
matchFilters.push(`doc.${key} == @${paramName}`);
|
|
496
|
+
params[paramName] = value;
|
|
497
|
+
});
|
|
498
|
+
const onCreate = Object.assign(Object.assign(Object.assign({}, options.matchProperties), options.onCreate), { _labels: labels });
|
|
499
|
+
const onMatch = options.onMatch || {};
|
|
500
|
+
const query = `
|
|
501
|
+
UPSERT { ${Object.keys(options.matchProperties).map(k => `${k}: @match_${Object.keys(options.matchProperties).indexOf(k)}`).join(', ')}, _labels: @labels }
|
|
502
|
+
INSERT @onCreate
|
|
503
|
+
UPDATE @onMatch
|
|
504
|
+
IN @@collection
|
|
505
|
+
RETURN { doc: NEW, created: OLD ? false : true }
|
|
506
|
+
`;
|
|
507
|
+
params.onCreate = onCreate;
|
|
508
|
+
params.onMatch = onMatch;
|
|
509
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
510
|
+
return {
|
|
511
|
+
success: true,
|
|
512
|
+
executionTime: Date.now() - startTime,
|
|
513
|
+
node: result.data.length > 0 ? this.parseNode(result.data[0].doc) : undefined,
|
|
514
|
+
created: ((_a = result.data[0]) === null || _a === void 0 ? void 0 : _a.created) || false,
|
|
515
|
+
matched: !((_b = result.data[0]) === null || _b === void 0 ? void 0 : _b.created),
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
// ==================== RELATIONSHIP OPERATIONS ====================
|
|
519
|
+
async createRelationship(connection, options, transaction) {
|
|
520
|
+
const startTime = Date.now();
|
|
521
|
+
const fromId = this.resolveNodeId(options.fromNode);
|
|
522
|
+
const toId = this.resolveNodeId(options.toNode);
|
|
523
|
+
const edge = Object.assign({ _from: fromId, _to: toId, _type: options.type }, options.properties);
|
|
524
|
+
const query = `
|
|
525
|
+
INSERT @edge INTO @@collection
|
|
526
|
+
RETURN NEW
|
|
527
|
+
`;
|
|
528
|
+
const result = await this.executeRaw(connection, {
|
|
529
|
+
query,
|
|
530
|
+
params: {
|
|
531
|
+
edge,
|
|
532
|
+
'@collection': this.defaultEdgeCollection,
|
|
533
|
+
},
|
|
534
|
+
}, transaction);
|
|
535
|
+
return {
|
|
536
|
+
success: true,
|
|
537
|
+
executionTime: Date.now() - startTime,
|
|
538
|
+
relationship: result.data.length > 0 ? this.parseRelationship(result.data[0]) : undefined,
|
|
539
|
+
created: true,
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
async findRelationships(connection, options, transaction) {
|
|
543
|
+
const startTime = Date.now();
|
|
544
|
+
let query = `FOR edge IN @@collection`;
|
|
545
|
+
const params = { '@collection': this.defaultEdgeCollection };
|
|
546
|
+
const filters = [];
|
|
547
|
+
if (options.type) {
|
|
548
|
+
const types = Array.isArray(options.type) ? options.type : [options.type];
|
|
549
|
+
filters.push(`edge._type IN @types`);
|
|
550
|
+
params.types = types;
|
|
551
|
+
}
|
|
552
|
+
if (options.fromNode && options.fromNode.id) {
|
|
553
|
+
filters.push(`edge._from == @fromId`);
|
|
554
|
+
params.fromId = this.resolveNodeId(options.fromNode);
|
|
555
|
+
}
|
|
556
|
+
if (options.toNode && options.toNode.id) {
|
|
557
|
+
filters.push(`edge._to == @toId`);
|
|
558
|
+
params.toId = this.resolveNodeId(options.toNode);
|
|
559
|
+
}
|
|
560
|
+
if (options.properties) {
|
|
561
|
+
Object.entries(options.properties).forEach(([key, value], index) => {
|
|
562
|
+
const paramName = `prop_${index}`;
|
|
563
|
+
filters.push(`edge.${key} == @${paramName}`);
|
|
564
|
+
params[paramName] = value;
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
if (filters.length > 0) {
|
|
568
|
+
query += ` FILTER ${filters.join(' AND ')}`;
|
|
569
|
+
}
|
|
570
|
+
// ORDER BY
|
|
571
|
+
if (options.orderBy && options.orderBy.length > 0) {
|
|
572
|
+
const sortParts = options.orderBy.map(o => `edge.${o.property} ${o.direction}`);
|
|
573
|
+
query += ` SORT ${sortParts.join(', ')}`;
|
|
574
|
+
}
|
|
575
|
+
// LIMIT
|
|
576
|
+
if (options.skip !== undefined || options.limit !== undefined) {
|
|
577
|
+
const skip = options.skip || 0;
|
|
578
|
+
const limit = options.limit || 100;
|
|
579
|
+
query += ` LIMIT ${skip}, ${limit}`;
|
|
580
|
+
}
|
|
581
|
+
query += ` RETURN edge`;
|
|
582
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
583
|
+
const relationships = result.data.map(doc => this.parseRelationship(doc));
|
|
584
|
+
return {
|
|
585
|
+
success: true,
|
|
586
|
+
executionTime: Date.now() - startTime,
|
|
587
|
+
relationships,
|
|
588
|
+
count: relationships.length,
|
|
589
|
+
hasMore: options.limit !== undefined && relationships.length === options.limit,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
async findRelationshipById(connection, id, transaction) {
|
|
593
|
+
const query = `
|
|
594
|
+
FOR edge IN @@collection
|
|
595
|
+
FILTER edge._key == @id OR edge._id == @id
|
|
596
|
+
RETURN edge
|
|
597
|
+
`;
|
|
598
|
+
const result = await this.executeRaw(connection, {
|
|
599
|
+
query,
|
|
600
|
+
params: { id: String(id), '@collection': this.defaultEdgeCollection },
|
|
601
|
+
}, transaction);
|
|
602
|
+
if (result.data.length === 0) {
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
return this.parseRelationship(result.data[0]);
|
|
606
|
+
}
|
|
607
|
+
async updateRelationship(connection, options, transaction) {
|
|
608
|
+
const startTime = Date.now();
|
|
609
|
+
const query = `
|
|
610
|
+
UPDATE { _key: @id } WITH @updates IN @@collection
|
|
611
|
+
RETURN NEW
|
|
612
|
+
`;
|
|
613
|
+
const result = await this.executeRaw(connection, {
|
|
614
|
+
query,
|
|
615
|
+
params: {
|
|
616
|
+
id: String(options.id),
|
|
617
|
+
updates: options.set || {},
|
|
618
|
+
'@collection': this.defaultEdgeCollection,
|
|
619
|
+
},
|
|
620
|
+
}, transaction);
|
|
621
|
+
return {
|
|
622
|
+
success: true,
|
|
623
|
+
executionTime: Date.now() - startTime,
|
|
624
|
+
relationship: result.data.length > 0 ? this.parseRelationship(result.data[0]) : undefined,
|
|
625
|
+
updated: result.data.length > 0,
|
|
626
|
+
matchedCount: result.data.length,
|
|
627
|
+
modifiedCount: result.data.length,
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
async deleteRelationship(connection, options, transaction) {
|
|
631
|
+
const startTime = Date.now();
|
|
632
|
+
const params = { '@collection': this.defaultEdgeCollection };
|
|
633
|
+
let query;
|
|
634
|
+
if (options.id !== undefined) {
|
|
635
|
+
query = `
|
|
636
|
+
REMOVE { _key: @id } IN @@collection
|
|
637
|
+
RETURN 1
|
|
638
|
+
`;
|
|
639
|
+
params.id = String(options.id);
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
const filters = [];
|
|
643
|
+
if (options.type) {
|
|
644
|
+
const types = Array.isArray(options.type) ? options.type : [options.type];
|
|
645
|
+
filters.push(`edge._type IN @types`);
|
|
646
|
+
params.types = types;
|
|
647
|
+
}
|
|
648
|
+
query = `
|
|
649
|
+
FOR edge IN @@collection
|
|
650
|
+
${filters.length > 0 ? `FILTER ${filters.join(' AND ')}` : ''}
|
|
651
|
+
REMOVE edge IN @@collection
|
|
652
|
+
RETURN 1
|
|
653
|
+
`;
|
|
654
|
+
}
|
|
655
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
656
|
+
return {
|
|
657
|
+
success: true,
|
|
658
|
+
executionTime: Date.now() - startTime,
|
|
659
|
+
deletedCount: result.data.length,
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
async mergeRelationship(connection, options, transaction) {
|
|
663
|
+
var _a, _b;
|
|
664
|
+
const startTime = Date.now();
|
|
665
|
+
const fromId = this.resolveNodeId(options.fromNode);
|
|
666
|
+
const toId = this.resolveNodeId(options.toNode);
|
|
667
|
+
const matchDoc = Object.assign({ _from: fromId, _to: toId, _type: options.type }, options.matchProperties);
|
|
668
|
+
const insertDoc = Object.assign(Object.assign({}, matchDoc), options.onCreate);
|
|
669
|
+
const updateDoc = options.onMatch || {};
|
|
670
|
+
const query = `
|
|
671
|
+
UPSERT @matchDoc
|
|
672
|
+
INSERT @insertDoc
|
|
673
|
+
UPDATE @updateDoc
|
|
674
|
+
IN @@collection
|
|
675
|
+
RETURN { doc: NEW, created: OLD ? false : true }
|
|
676
|
+
`;
|
|
677
|
+
const result = await this.executeRaw(connection, {
|
|
678
|
+
query,
|
|
679
|
+
params: {
|
|
680
|
+
matchDoc,
|
|
681
|
+
insertDoc,
|
|
682
|
+
updateDoc,
|
|
683
|
+
'@collection': this.defaultEdgeCollection,
|
|
684
|
+
},
|
|
685
|
+
}, transaction);
|
|
686
|
+
return {
|
|
687
|
+
success: true,
|
|
688
|
+
executionTime: Date.now() - startTime,
|
|
689
|
+
relationship: result.data.length > 0 ? this.parseRelationship(result.data[0].doc) : undefined,
|
|
690
|
+
created: ((_a = result.data[0]) === null || _a === void 0 ? void 0 : _a.created) || false,
|
|
691
|
+
matched: !((_b = result.data[0]) === null || _b === void 0 ? void 0 : _b.created),
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
// ==================== PATH & TRAVERSAL OPERATIONS ====================
|
|
695
|
+
async traverse(connection, options, transaction) {
|
|
696
|
+
const startTime = Date.now();
|
|
697
|
+
const startId = this.resolveNodeId(options.startNode);
|
|
698
|
+
const minDepth = options.minDepth || 1;
|
|
699
|
+
const maxDepth = options.maxDepth || 10;
|
|
700
|
+
const direction = options.direction === relationship_types_1.RelationshipDirection.INCOMING ? 'INBOUND' :
|
|
701
|
+
options.direction === relationship_types_1.RelationshipDirection.OUTGOING ? 'OUTBOUND' : 'ANY';
|
|
702
|
+
let edgeCollections = this.defaultEdgeCollection;
|
|
703
|
+
if (options.relationships) {
|
|
704
|
+
const patterns = Array.isArray(options.relationships) ? options.relationships : [options.relationships];
|
|
705
|
+
const types = patterns.filter(p => p.type).map(p => p.type);
|
|
706
|
+
if (types.length > 0) {
|
|
707
|
+
// In ArangoDB, you'd filter by edge type within the traversal
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
const query = `
|
|
711
|
+
FOR vertex, edge, path IN ${minDepth}..${maxDepth} ${direction} @startId
|
|
712
|
+
GRAPH @graphName
|
|
713
|
+
${options.limit ? `LIMIT ${options.limit}` : ''}
|
|
714
|
+
RETURN { vertex, edge, path }
|
|
715
|
+
`;
|
|
716
|
+
const arangoConn = connection;
|
|
717
|
+
const graphName = arangoConn.getGraphName() || 'defaultGraph';
|
|
718
|
+
const result = await this.executeRaw(connection, {
|
|
719
|
+
query,
|
|
720
|
+
params: { startId, graphName },
|
|
721
|
+
}, transaction);
|
|
722
|
+
const nodesMap = new Map();
|
|
723
|
+
const relsMap = new Map();
|
|
724
|
+
const paths = [];
|
|
725
|
+
result.data.forEach(row => {
|
|
726
|
+
if (row.vertex) {
|
|
727
|
+
const node = this.parseNode(row.vertex);
|
|
728
|
+
nodesMap.set(String(node.id), node);
|
|
729
|
+
}
|
|
730
|
+
if (row.edge) {
|
|
731
|
+
const rel = this.parseRelationship(row.edge);
|
|
732
|
+
relsMap.set(String(rel.id), rel);
|
|
733
|
+
}
|
|
734
|
+
if (row.path && options.returnPaths) {
|
|
735
|
+
paths.push(this.parsePath(row.path));
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
return {
|
|
739
|
+
success: true,
|
|
740
|
+
executionTime: Date.now() - startTime,
|
|
741
|
+
paths: options.returnPaths ? paths : undefined,
|
|
742
|
+
nodes: options.returnNodes ? Array.from(nodesMap.values()) : undefined,
|
|
743
|
+
relationships: Array.from(relsMap.values()),
|
|
744
|
+
count: result.data.length,
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
async shortestPath(connection, options, transaction) {
|
|
748
|
+
const startTime = Date.now();
|
|
749
|
+
const startId = this.resolveNodeId(options.startNode);
|
|
750
|
+
const endId = this.resolveNodeId(options.endNode);
|
|
751
|
+
const direction = options.direction === relationship_types_1.RelationshipDirection.INCOMING ? 'INBOUND' :
|
|
752
|
+
options.direction === relationship_types_1.RelationshipDirection.OUTGOING ? 'OUTBOUND' : 'ANY';
|
|
753
|
+
let query;
|
|
754
|
+
if (options.weightProperty) {
|
|
755
|
+
// Weighted shortest path using SHORTEST_PATH with weight
|
|
756
|
+
query = `
|
|
757
|
+
FOR path IN ${direction} SHORTEST_PATH @startId TO @endId
|
|
758
|
+
GRAPH @graphName
|
|
759
|
+
OPTIONS { weightAttribute: @weightProp }
|
|
760
|
+
RETURN path
|
|
761
|
+
`;
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
query = `
|
|
765
|
+
FOR path IN ${direction} SHORTEST_PATH @startId TO @endId
|
|
766
|
+
GRAPH @graphName
|
|
767
|
+
RETURN path
|
|
768
|
+
`;
|
|
769
|
+
}
|
|
770
|
+
const arangoConn = connection;
|
|
771
|
+
const graphName = arangoConn.getGraphName() || 'defaultGraph';
|
|
772
|
+
const result = await this.executeRaw(connection, {
|
|
773
|
+
query,
|
|
774
|
+
params: {
|
|
775
|
+
startId,
|
|
776
|
+
endId,
|
|
777
|
+
graphName,
|
|
778
|
+
weightProp: options.weightProperty || 'weight',
|
|
779
|
+
},
|
|
780
|
+
}, transaction);
|
|
781
|
+
if (result.data.length === 0 || !result.data[0]) {
|
|
782
|
+
return {
|
|
783
|
+
success: true,
|
|
784
|
+
executionTime: Date.now() - startTime,
|
|
785
|
+
found: false,
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
const path = this.parsePath(result.data[0]);
|
|
789
|
+
return {
|
|
790
|
+
success: true,
|
|
791
|
+
executionTime: Date.now() - startTime,
|
|
792
|
+
path,
|
|
793
|
+
found: true,
|
|
794
|
+
length: path.length,
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
async allPaths(connection, options, transaction) {
|
|
798
|
+
const startTime = Date.now();
|
|
799
|
+
const startId = this.resolveNodeId(options.startNode);
|
|
800
|
+
const endId = this.resolveNodeId(options.endNode);
|
|
801
|
+
const minDepth = options.minDepth || 1;
|
|
802
|
+
const maxDepth = options.maxDepth || 10;
|
|
803
|
+
const direction = options.direction === relationship_types_1.RelationshipDirection.INCOMING ? 'INBOUND' :
|
|
804
|
+
options.direction === relationship_types_1.RelationshipDirection.OUTGOING ? 'OUTBOUND' : 'ANY';
|
|
805
|
+
const query = `
|
|
806
|
+
FOR vertex, edge, path IN ${minDepth}..${maxDepth} ${direction} @startId
|
|
807
|
+
GRAPH @graphName
|
|
808
|
+
FILTER vertex._id == @endId
|
|
809
|
+
${options.limit ? `LIMIT ${options.limit}` : ''}
|
|
810
|
+
RETURN path
|
|
811
|
+
`;
|
|
812
|
+
const arangoConn = connection;
|
|
813
|
+
const graphName = arangoConn.getGraphName() || 'defaultGraph';
|
|
814
|
+
const result = await this.executeRaw(connection, {
|
|
815
|
+
query,
|
|
816
|
+
params: { startId, endId, graphName },
|
|
817
|
+
}, transaction);
|
|
818
|
+
const paths = result.data.map(p => this.parsePath(p));
|
|
819
|
+
return {
|
|
820
|
+
success: true,
|
|
821
|
+
executionTime: Date.now() - startTime,
|
|
822
|
+
paths,
|
|
823
|
+
count: paths.length,
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
async matchPattern(connection, options, transaction) {
|
|
827
|
+
const startTime = Date.now();
|
|
828
|
+
const { pattern } = options;
|
|
829
|
+
// Build AQL query from pattern
|
|
830
|
+
const forClauses = [];
|
|
831
|
+
const filters = [];
|
|
832
|
+
const params = {};
|
|
833
|
+
pattern.nodes.forEach((node, index) => {
|
|
834
|
+
forClauses.push(`FOR ${node.variable} IN @@vertices_${index}`);
|
|
835
|
+
params[`@vertices_${index}`] = this.defaultVertexCollection;
|
|
836
|
+
if (node.labels) {
|
|
837
|
+
const labels = Array.isArray(node.labels) ? node.labels : [node.labels];
|
|
838
|
+
filters.push(`@labels_${index} ALL IN ${node.variable}._labels`);
|
|
839
|
+
params[`labels_${index}`] = labels;
|
|
840
|
+
}
|
|
841
|
+
if (node.properties) {
|
|
842
|
+
Object.entries(node.properties).forEach(([key, value], propIndex) => {
|
|
843
|
+
const paramName = `node_${index}_prop_${propIndex}`;
|
|
844
|
+
filters.push(`${node.variable}.${key} == @${paramName}`);
|
|
845
|
+
params[paramName] = value;
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
// Handle relationships
|
|
850
|
+
pattern.relationships.forEach((rel, index) => {
|
|
851
|
+
forClauses.push(`FOR ${rel.variable || `_edge_${index}`} IN @@edges_${index}`);
|
|
852
|
+
params[`@edges_${index}`] = this.defaultEdgeCollection;
|
|
853
|
+
const edgeVar = rel.variable || `_edge_${index}`;
|
|
854
|
+
filters.push(`${edgeVar}._from == ${rel.startNode}._id`);
|
|
855
|
+
filters.push(`${edgeVar}._to == ${rel.endNode}._id`);
|
|
856
|
+
if (rel.type) {
|
|
857
|
+
const types = Array.isArray(rel.type) ? rel.type : [rel.type];
|
|
858
|
+
filters.push(`${edgeVar}._type IN @relTypes_${index}`);
|
|
859
|
+
params[`relTypes_${index}`] = types;
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
const returnVars = options.return || pattern.nodes.map(n => n.variable);
|
|
863
|
+
let query = forClauses.join('\n');
|
|
864
|
+
if (filters.length > 0) {
|
|
865
|
+
query += `\nFILTER ${filters.join(' AND ')}`;
|
|
866
|
+
}
|
|
867
|
+
if (options.limit) {
|
|
868
|
+
query += `\nLIMIT ${options.skip || 0}, ${options.limit}`;
|
|
869
|
+
}
|
|
870
|
+
query += `\nRETURN { ${returnVars.map(v => `${v}: ${v}`).join(', ')} }`;
|
|
871
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
872
|
+
return {
|
|
873
|
+
success: true,
|
|
874
|
+
executionTime: Date.now() - startTime,
|
|
875
|
+
matches: result.data,
|
|
876
|
+
count: result.data.length,
|
|
877
|
+
hasMore: options.limit !== undefined && result.data.length === options.limit,
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
async extractSubgraph(connection, options, transaction) {
|
|
881
|
+
const startTime = Date.now();
|
|
882
|
+
const startNodes = Array.isArray(options.startNodes) ? options.startNodes : [options.startNodes];
|
|
883
|
+
const startIds = startNodes.map(n => this.resolveNodeId(n));
|
|
884
|
+
const maxDepth = options.maxDepth || 3;
|
|
885
|
+
const direction = options.direction === relationship_types_1.RelationshipDirection.INCOMING ? 'INBOUND' :
|
|
886
|
+
options.direction === relationship_types_1.RelationshipDirection.OUTGOING ? 'OUTBOUND' : 'ANY';
|
|
887
|
+
const query = `
|
|
888
|
+
LET startNodes = @startIds
|
|
889
|
+
LET subgraphNodes = (
|
|
890
|
+
FOR startId IN startNodes
|
|
891
|
+
FOR vertex IN 0..@maxDepth ${direction} startId
|
|
892
|
+
GRAPH @graphName
|
|
893
|
+
RETURN DISTINCT vertex
|
|
894
|
+
)
|
|
895
|
+
LET subgraphEdges = (
|
|
896
|
+
FOR startId IN startNodes
|
|
897
|
+
FOR vertex, edge IN 1..@maxDepth ${direction} startId
|
|
898
|
+
GRAPH @graphName
|
|
899
|
+
RETURN DISTINCT edge
|
|
900
|
+
)
|
|
901
|
+
RETURN { nodes: subgraphNodes, edges: subgraphEdges }
|
|
902
|
+
`;
|
|
903
|
+
const arangoConn = connection;
|
|
904
|
+
const graphName = arangoConn.getGraphName() || 'defaultGraph';
|
|
905
|
+
const result = await this.executeRaw(connection, {
|
|
906
|
+
query,
|
|
907
|
+
params: { startIds, maxDepth, graphName },
|
|
908
|
+
}, transaction);
|
|
909
|
+
const nodes = [];
|
|
910
|
+
const relationships = [];
|
|
911
|
+
if (result.data.length > 0) {
|
|
912
|
+
const row = result.data[0];
|
|
913
|
+
if (row.nodes) {
|
|
914
|
+
row.nodes.forEach((n) => nodes.push(this.parseNode(n)));
|
|
915
|
+
}
|
|
916
|
+
if (row.edges) {
|
|
917
|
+
row.edges.filter((e) => e).forEach((e) => relationships.push(this.parseRelationship(e)));
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
return {
|
|
921
|
+
success: true,
|
|
922
|
+
executionTime: Date.now() - startTime,
|
|
923
|
+
subgraph: {
|
|
924
|
+
nodes,
|
|
925
|
+
relationships,
|
|
926
|
+
nodeCount: nodes.length,
|
|
927
|
+
relationshipCount: relationships.length,
|
|
928
|
+
},
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
async getNeighborhood(connection, options, transaction) {
|
|
932
|
+
const startTime = Date.now();
|
|
933
|
+
const nodeId = this.resolveNodeId(options.node);
|
|
934
|
+
const depth = options.depth || 1;
|
|
935
|
+
const direction = options.direction === relationship_types_1.RelationshipDirection.INCOMING ? 'INBOUND' :
|
|
936
|
+
options.direction === relationship_types_1.RelationshipDirection.OUTGOING ? 'OUTBOUND' : 'ANY';
|
|
937
|
+
const query = `
|
|
938
|
+
FOR vertex, edge IN 0..@depth ${direction} @nodeId
|
|
939
|
+
GRAPH @graphName
|
|
940
|
+
RETURN { vertex, edge }
|
|
941
|
+
`;
|
|
942
|
+
const arangoConn = connection;
|
|
943
|
+
const graphName = arangoConn.getGraphName() || 'defaultGraph';
|
|
944
|
+
const result = await this.executeRaw(connection, {
|
|
945
|
+
query,
|
|
946
|
+
params: { nodeId, depth, graphName },
|
|
947
|
+
}, transaction);
|
|
948
|
+
const nodesMap = new Map();
|
|
949
|
+
const relsMap = new Map();
|
|
950
|
+
result.data.forEach(row => {
|
|
951
|
+
if (row.vertex) {
|
|
952
|
+
const node = this.parseNode(row.vertex);
|
|
953
|
+
nodesMap.set(String(node.id), node);
|
|
954
|
+
}
|
|
955
|
+
if (row.edge) {
|
|
956
|
+
const rel = this.parseRelationship(row.edge);
|
|
957
|
+
relsMap.set(String(rel.id), rel);
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
return {
|
|
961
|
+
success: true,
|
|
962
|
+
executionTime: Date.now() - startTime,
|
|
963
|
+
nodes: Array.from(nodesMap.values()),
|
|
964
|
+
relationships: Array.from(relsMap.values()),
|
|
965
|
+
levels: new Map(),
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
async findConnectedComponents(connection, options, transaction) {
|
|
969
|
+
const startTime = Date.now();
|
|
970
|
+
// ArangoDB doesn't have built-in connected components
|
|
971
|
+
// This would require Pregel or custom implementation
|
|
972
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.VALIDATION_ERROR, 'Connected components analysis requires ArangoDB Pregel or custom implementation');
|
|
973
|
+
}
|
|
974
|
+
// ==================== AGGREGATION OPERATIONS ====================
|
|
975
|
+
async countNodes(connection, labels, where, transaction) {
|
|
976
|
+
const startTime = Date.now();
|
|
977
|
+
let query = `RETURN COUNT(FOR doc IN @@collection`;
|
|
978
|
+
const params = { '@collection': this.defaultVertexCollection };
|
|
979
|
+
const filters = [];
|
|
980
|
+
if (labels) {
|
|
981
|
+
const labelArr = Array.isArray(labels) ? labels : [labels];
|
|
982
|
+
filters.push(`@labels ALL IN doc._labels`);
|
|
983
|
+
params.labels = labelArr;
|
|
984
|
+
}
|
|
985
|
+
if (where) {
|
|
986
|
+
Object.entries(where).forEach(([key, value], index) => {
|
|
987
|
+
const paramName = `where_${index}`;
|
|
988
|
+
filters.push(`doc.${key} == @${paramName}`);
|
|
989
|
+
params[paramName] = value;
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
if (filters.length > 0) {
|
|
993
|
+
query += ` FILTER ${filters.join(' AND ')}`;
|
|
994
|
+
}
|
|
995
|
+
query += ` RETURN 1)`;
|
|
996
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
997
|
+
return {
|
|
998
|
+
success: true,
|
|
999
|
+
executionTime: Date.now() - startTime,
|
|
1000
|
+
count: result.data[0] || 0,
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
async countRelationships(connection, type, where, transaction) {
|
|
1004
|
+
const startTime = Date.now();
|
|
1005
|
+
let query = `RETURN COUNT(FOR edge IN @@collection`;
|
|
1006
|
+
const params = { '@collection': this.defaultEdgeCollection };
|
|
1007
|
+
const filters = [];
|
|
1008
|
+
if (type) {
|
|
1009
|
+
const typeArr = Array.isArray(type) ? type : [type];
|
|
1010
|
+
filters.push(`edge._type IN @types`);
|
|
1011
|
+
params.types = typeArr;
|
|
1012
|
+
}
|
|
1013
|
+
if (where) {
|
|
1014
|
+
Object.entries(where).forEach(([key, value], index) => {
|
|
1015
|
+
const paramName = `where_${index}`;
|
|
1016
|
+
filters.push(`edge.${key} == @${paramName}`);
|
|
1017
|
+
params[paramName] = value;
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
if (filters.length > 0) {
|
|
1021
|
+
query += ` FILTER ${filters.join(' AND ')}`;
|
|
1022
|
+
}
|
|
1023
|
+
query += ` RETURN 1)`;
|
|
1024
|
+
const result = await this.executeRaw(connection, { query, params }, transaction);
|
|
1025
|
+
return {
|
|
1026
|
+
success: true,
|
|
1027
|
+
executionTime: Date.now() - startTime,
|
|
1028
|
+
count: result.data[0] || 0,
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
async getStatistics(connection, transaction) {
|
|
1032
|
+
const startTime = Date.now();
|
|
1033
|
+
const nodeCountResult = await this.countNodes(connection, undefined, undefined, transaction);
|
|
1034
|
+
const relCountResult = await this.countRelationships(connection, undefined, undefined, transaction);
|
|
1035
|
+
return {
|
|
1036
|
+
success: true,
|
|
1037
|
+
executionTime: Date.now() - startTime,
|
|
1038
|
+
nodeCount: nodeCountResult.count,
|
|
1039
|
+
relationshipCount: relCountResult.count,
|
|
1040
|
+
labelCounts: {},
|
|
1041
|
+
relationshipTypeCounts: {},
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
// ==================== SEARCH OPERATIONS ====================
|
|
1045
|
+
async fullTextSearch(connection, options, transaction) {
|
|
1046
|
+
const startTime = Date.now();
|
|
1047
|
+
// ArangoDB uses ArangoSearch for full-text search
|
|
1048
|
+
const query = `
|
|
1049
|
+
FOR doc IN @@view
|
|
1050
|
+
SEARCH ANALYZER(doc.${options.index} IN TOKENS(@searchQuery, "text_en"), "text_en")
|
|
1051
|
+
${options.labels ? `FILTER @labels ALL IN doc._labels` : ''}
|
|
1052
|
+
${options.limit ? `LIMIT ${options.limit}` : ''}
|
|
1053
|
+
${options.score ? `RETURN MERGE(doc, { score: BM25(doc) })` : `RETURN doc`}
|
|
1054
|
+
`;
|
|
1055
|
+
const result = await this.executeRaw(connection, {
|
|
1056
|
+
query,
|
|
1057
|
+
params: {
|
|
1058
|
+
'@view': `${this.defaultVertexCollection}_search`,
|
|
1059
|
+
searchQuery: options.query,
|
|
1060
|
+
labels: options.labels || [],
|
|
1061
|
+
},
|
|
1062
|
+
}, transaction);
|
|
1063
|
+
const nodes = result.data.map(doc => {
|
|
1064
|
+
const node = this.parseNode(doc);
|
|
1065
|
+
if (options.score && doc.score !== undefined) {
|
|
1066
|
+
return Object.assign(Object.assign({}, node), { score: doc.score });
|
|
1067
|
+
}
|
|
1068
|
+
return node;
|
|
1069
|
+
});
|
|
1070
|
+
return {
|
|
1071
|
+
success: true,
|
|
1072
|
+
executionTime: Date.now() - startTime,
|
|
1073
|
+
nodes,
|
|
1074
|
+
count: nodes.length,
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
async vectorSearch(connection, options, transaction) {
|
|
1078
|
+
// ArangoDB requires ArangoSearch with custom analyzers for vector similarity
|
|
1079
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.VALIDATION_ERROR, 'Vector search requires ArangoDB Enterprise with custom vector analyzer configuration');
|
|
1080
|
+
}
|
|
1081
|
+
// ==================== SCHEMA OPERATIONS ====================
|
|
1082
|
+
async createNodeConstraint(connection, constraint, transaction) {
|
|
1083
|
+
const startTime = Date.now();
|
|
1084
|
+
const db = connection.getClient();
|
|
1085
|
+
const collection = this.getVertexCollection(constraint.label);
|
|
1086
|
+
const coll = db.collection(collection);
|
|
1087
|
+
// ArangoDB uses unique indexes for constraints
|
|
1088
|
+
if (constraint.type === node_types_1.NodeConstraintType.UNIQUE) {
|
|
1089
|
+
await coll.ensureIndex({
|
|
1090
|
+
type: 'persistent',
|
|
1091
|
+
fields: constraint.properties,
|
|
1092
|
+
unique: true,
|
|
1093
|
+
name: constraint.name,
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
return {
|
|
1097
|
+
success: true,
|
|
1098
|
+
executionTime: Date.now() - startTime,
|
|
1099
|
+
name: constraint.name,
|
|
1100
|
+
created: true,
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
async createRelationshipConstraint(connection, constraint, transaction) {
|
|
1104
|
+
const startTime = Date.now();
|
|
1105
|
+
const db = connection.getClient();
|
|
1106
|
+
const coll = db.collection(this.defaultEdgeCollection);
|
|
1107
|
+
await coll.ensureIndex({
|
|
1108
|
+
type: 'persistent',
|
|
1109
|
+
fields: constraint.properties,
|
|
1110
|
+
unique: true,
|
|
1111
|
+
name: constraint.name,
|
|
1112
|
+
});
|
|
1113
|
+
return {
|
|
1114
|
+
success: true,
|
|
1115
|
+
executionTime: Date.now() - startTime,
|
|
1116
|
+
name: constraint.name,
|
|
1117
|
+
created: true,
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
async dropConstraint(connection, name, transaction) {
|
|
1121
|
+
const startTime = Date.now();
|
|
1122
|
+
const db = connection.getClient();
|
|
1123
|
+
// ArangoDB drops constraints via dropIndex
|
|
1124
|
+
const coll = db.collection(this.defaultVertexCollection);
|
|
1125
|
+
await coll.dropIndex(name);
|
|
1126
|
+
return {
|
|
1127
|
+
success: true,
|
|
1128
|
+
executionTime: Date.now() - startTime,
|
|
1129
|
+
name,
|
|
1130
|
+
dropped: true,
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
async listConstraints(connection, transaction) {
|
|
1134
|
+
const startTime = Date.now();
|
|
1135
|
+
const db = connection.getClient();
|
|
1136
|
+
const coll = db.collection(this.defaultVertexCollection);
|
|
1137
|
+
const indexes = await coll.indexes();
|
|
1138
|
+
const constraints = indexes
|
|
1139
|
+
.filter((idx) => idx.unique)
|
|
1140
|
+
.map((idx) => ({
|
|
1141
|
+
name: idx.name,
|
|
1142
|
+
type: 'UNIQUE',
|
|
1143
|
+
entityType: 'NODE',
|
|
1144
|
+
labelsOrTypes: [],
|
|
1145
|
+
properties: idx.fields,
|
|
1146
|
+
}));
|
|
1147
|
+
return {
|
|
1148
|
+
success: true,
|
|
1149
|
+
executionTime: Date.now() - startTime,
|
|
1150
|
+
constraints,
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
async createNodeIndex(connection, index, transaction) {
|
|
1154
|
+
const startTime = Date.now();
|
|
1155
|
+
const db = connection.getClient();
|
|
1156
|
+
const collection = this.getVertexCollection(index.label);
|
|
1157
|
+
const coll = db.collection(collection);
|
|
1158
|
+
let indexType = 'persistent';
|
|
1159
|
+
const options = {
|
|
1160
|
+
fields: index.properties,
|
|
1161
|
+
name: index.name,
|
|
1162
|
+
};
|
|
1163
|
+
switch (index.type) {
|
|
1164
|
+
case node_types_1.NodeIndexType.FULLTEXT:
|
|
1165
|
+
indexType = 'fulltext';
|
|
1166
|
+
break;
|
|
1167
|
+
case node_types_1.NodeIndexType.POINT:
|
|
1168
|
+
indexType = 'geo';
|
|
1169
|
+
break;
|
|
1170
|
+
default:
|
|
1171
|
+
indexType = 'persistent';
|
|
1172
|
+
}
|
|
1173
|
+
options.type = indexType;
|
|
1174
|
+
await coll.ensureIndex(options);
|
|
1175
|
+
return {
|
|
1176
|
+
success: true,
|
|
1177
|
+
executionTime: Date.now() - startTime,
|
|
1178
|
+
name: index.name,
|
|
1179
|
+
created: true,
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
async createRelationshipIndex(connection, index, transaction) {
|
|
1183
|
+
const startTime = Date.now();
|
|
1184
|
+
const db = connection.getClient();
|
|
1185
|
+
const coll = db.collection(this.defaultEdgeCollection);
|
|
1186
|
+
await coll.ensureIndex({
|
|
1187
|
+
type: 'persistent',
|
|
1188
|
+
fields: index.properties,
|
|
1189
|
+
name: index.name,
|
|
1190
|
+
});
|
|
1191
|
+
return {
|
|
1192
|
+
success: true,
|
|
1193
|
+
executionTime: Date.now() - startTime,
|
|
1194
|
+
name: index.name,
|
|
1195
|
+
created: true,
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
async dropIndex(connection, name, transaction) {
|
|
1199
|
+
const startTime = Date.now();
|
|
1200
|
+
const db = connection.getClient();
|
|
1201
|
+
const coll = db.collection(this.defaultVertexCollection);
|
|
1202
|
+
await coll.dropIndex(name);
|
|
1203
|
+
return {
|
|
1204
|
+
success: true,
|
|
1205
|
+
executionTime: Date.now() - startTime,
|
|
1206
|
+
name,
|
|
1207
|
+
dropped: true,
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
async listIndexes(connection, transaction) {
|
|
1211
|
+
const startTime = Date.now();
|
|
1212
|
+
const db = connection.getClient();
|
|
1213
|
+
const coll = db.collection(this.defaultVertexCollection);
|
|
1214
|
+
const indexes = await coll.indexes();
|
|
1215
|
+
const indexList = indexes.map((idx) => ({
|
|
1216
|
+
name: idx.name,
|
|
1217
|
+
type: idx.type,
|
|
1218
|
+
entityType: 'NODE',
|
|
1219
|
+
labelsOrTypes: [],
|
|
1220
|
+
properties: idx.fields,
|
|
1221
|
+
state: 'ONLINE',
|
|
1222
|
+
uniqueness: idx.unique ? 'UNIQUE' : 'NONUNIQUE',
|
|
1223
|
+
}));
|
|
1224
|
+
return {
|
|
1225
|
+
success: true,
|
|
1226
|
+
executionTime: Date.now() - startTime,
|
|
1227
|
+
indexes: indexList,
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
// ==================== UTILITY METHODS ====================
|
|
1231
|
+
escapeIdentifier(identifier) {
|
|
1232
|
+
return identifier.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
1233
|
+
}
|
|
1234
|
+
escapeValue(value) {
|
|
1235
|
+
if (value === null)
|
|
1236
|
+
return 'null';
|
|
1237
|
+
if (typeof value === 'string')
|
|
1238
|
+
return `"${value.replace(/"/g, '\\"')}"`;
|
|
1239
|
+
if (typeof value === 'number')
|
|
1240
|
+
return String(value);
|
|
1241
|
+
if (typeof value === 'boolean')
|
|
1242
|
+
return value ? 'true' : 'false';
|
|
1243
|
+
if (value instanceof Date)
|
|
1244
|
+
return `"${value.toISOString()}"`;
|
|
1245
|
+
if (Array.isArray(value))
|
|
1246
|
+
return `[${value.map(v => this.escapeValue(v)).join(', ')}]`;
|
|
1247
|
+
return JSON.stringify(value);
|
|
1248
|
+
}
|
|
1249
|
+
buildWhereClause(where, variableName = 'doc') {
|
|
1250
|
+
const params = {};
|
|
1251
|
+
const parts = [];
|
|
1252
|
+
Object.entries(where).forEach(([key, value], index) => {
|
|
1253
|
+
const paramName = `where_${index}`;
|
|
1254
|
+
parts.push(`${variableName}.${key} == @${paramName}`);
|
|
1255
|
+
params[paramName] = value;
|
|
1256
|
+
});
|
|
1257
|
+
return {
|
|
1258
|
+
clause: parts.join(' AND '),
|
|
1259
|
+
params,
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
// ==================== PROTECTED PARSER METHODS ====================
|
|
1263
|
+
parseNode(nativeNode) {
|
|
1264
|
+
if (!nativeNode) {
|
|
1265
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.NODE_ERROR, 'Cannot parse null node');
|
|
1266
|
+
}
|
|
1267
|
+
const { _key, _id, _rev, _labels } = nativeNode, properties = __rest(nativeNode, ["_key", "_id", "_rev", "_labels"]);
|
|
1268
|
+
return {
|
|
1269
|
+
id: _key || _id,
|
|
1270
|
+
labels: _labels || [],
|
|
1271
|
+
properties: properties,
|
|
1272
|
+
elementId: _id,
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
parseRelationship(nativeRelationship) {
|
|
1276
|
+
if (!nativeRelationship) {
|
|
1277
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.RELATIONSHIP_ERROR, 'Cannot parse null relationship');
|
|
1278
|
+
}
|
|
1279
|
+
const { _key, _id, _rev, _from, _to, _type } = nativeRelationship, properties = __rest(nativeRelationship, ["_key", "_id", "_rev", "_from", "_to", "_type"]);
|
|
1280
|
+
return {
|
|
1281
|
+
id: _key || _id,
|
|
1282
|
+
type: _type || '',
|
|
1283
|
+
startNodeId: _from,
|
|
1284
|
+
endNodeId: _to,
|
|
1285
|
+
properties: properties,
|
|
1286
|
+
elementId: _id,
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
parsePath(nativePath) {
|
|
1290
|
+
if (!nativePath) {
|
|
1291
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.PATH_ERROR, 'Cannot parse null path');
|
|
1292
|
+
}
|
|
1293
|
+
const nodes = [];
|
|
1294
|
+
const relationships = [];
|
|
1295
|
+
if (nativePath.vertices) {
|
|
1296
|
+
nativePath.vertices.forEach((v) => nodes.push(this.parseNode(v)));
|
|
1297
|
+
}
|
|
1298
|
+
if (nativePath.edges) {
|
|
1299
|
+
nativePath.edges.forEach((e) => {
|
|
1300
|
+
if (e)
|
|
1301
|
+
relationships.push(this.parseRelationship(e));
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
return {
|
|
1305
|
+
nodes,
|
|
1306
|
+
relationships,
|
|
1307
|
+
length: relationships.length,
|
|
1308
|
+
start: nodes[0],
|
|
1309
|
+
end: nodes[nodes.length - 1],
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
// ==================== PRIVATE HELPER METHODS ====================
|
|
1313
|
+
normalizeLabels(labels) {
|
|
1314
|
+
return Array.isArray(labels) ? labels : [labels];
|
|
1315
|
+
}
|
|
1316
|
+
getVertexCollection(label) {
|
|
1317
|
+
// In ArangoDB, you might use different collections per label
|
|
1318
|
+
// For simplicity, using default collection
|
|
1319
|
+
return this.defaultVertexCollection;
|
|
1320
|
+
}
|
|
1321
|
+
resolveNodeId(ref) {
|
|
1322
|
+
if (typeof ref === 'string')
|
|
1323
|
+
return ref;
|
|
1324
|
+
if (ref.id) {
|
|
1325
|
+
const id = String(ref.id);
|
|
1326
|
+
// If it's not already a full document ID, prefix it
|
|
1327
|
+
if (!id.includes('/')) {
|
|
1328
|
+
return `${this.defaultVertexCollection}/${id}`;
|
|
1329
|
+
}
|
|
1330
|
+
return id;
|
|
1331
|
+
}
|
|
1332
|
+
throw new graph_types_1.GraphError(graph_types_1.GraphErrorType.VALIDATION_ERROR, 'Node reference must have an id');
|
|
1333
|
+
}
|
|
1334
|
+
buildAQLFilter(where, alias, params, prefix = '') {
|
|
1335
|
+
const paramName = `${prefix}filter_${Object.keys(params).length}`;
|
|
1336
|
+
let operator;
|
|
1337
|
+
switch (where.operator) {
|
|
1338
|
+
case node_types_1.NodeComparisonOperator.EQUALS:
|
|
1339
|
+
operator = '==';
|
|
1340
|
+
break;
|
|
1341
|
+
case node_types_1.NodeComparisonOperator.NOT_EQUALS:
|
|
1342
|
+
operator = '!=';
|
|
1343
|
+
break;
|
|
1344
|
+
case node_types_1.NodeComparisonOperator.GREATER_THAN:
|
|
1345
|
+
operator = '>';
|
|
1346
|
+
break;
|
|
1347
|
+
case node_types_1.NodeComparisonOperator.GREATER_THAN_OR_EQUAL:
|
|
1348
|
+
operator = '>=';
|
|
1349
|
+
break;
|
|
1350
|
+
case node_types_1.NodeComparisonOperator.LESS_THAN:
|
|
1351
|
+
operator = '<';
|
|
1352
|
+
break;
|
|
1353
|
+
case node_types_1.NodeComparisonOperator.LESS_THAN_OR_EQUAL:
|
|
1354
|
+
operator = '<=';
|
|
1355
|
+
break;
|
|
1356
|
+
case node_types_1.NodeComparisonOperator.IN:
|
|
1357
|
+
operator = 'IN';
|
|
1358
|
+
break;
|
|
1359
|
+
case node_types_1.NodeComparisonOperator.NOT_IN:
|
|
1360
|
+
operator = 'NOT IN';
|
|
1361
|
+
break;
|
|
1362
|
+
case node_types_1.NodeComparisonOperator.CONTAINS:
|
|
1363
|
+
params[paramName] = where.value;
|
|
1364
|
+
return `CONTAINS(${alias}.${where.property}, @${paramName})`;
|
|
1365
|
+
case node_types_1.NodeComparisonOperator.STARTS_WITH:
|
|
1366
|
+
params[paramName] = where.value;
|
|
1367
|
+
return `STARTS_WITH(${alias}.${where.property}, @${paramName})`;
|
|
1368
|
+
case node_types_1.NodeComparisonOperator.IS_NULL:
|
|
1369
|
+
return `${alias}.${where.property} == null`;
|
|
1370
|
+
case node_types_1.NodeComparisonOperator.IS_NOT_NULL:
|
|
1371
|
+
return `${alias}.${where.property} != null`;
|
|
1372
|
+
case node_types_1.NodeComparisonOperator.REGEX:
|
|
1373
|
+
params[paramName] = where.value;
|
|
1374
|
+
return `REGEX_TEST(${alias}.${where.property}, @${paramName})`;
|
|
1375
|
+
default:
|
|
1376
|
+
operator = '==';
|
|
1377
|
+
}
|
|
1378
|
+
params[paramName] = where.value;
|
|
1379
|
+
let condition = `${alias}.${where.property} ${operator} @${paramName}`;
|
|
1380
|
+
if (where.and && where.and.length > 0) {
|
|
1381
|
+
const andClauses = where.and.map((w, i) => this.buildAQLFilter(w, alias, params, `${prefix}and${i}_`));
|
|
1382
|
+
condition = `(${condition} AND ${andClauses.join(' AND ')})`;
|
|
1383
|
+
}
|
|
1384
|
+
if (where.or && where.or.length > 0) {
|
|
1385
|
+
const orClauses = where.or.map((w, i) => this.buildAQLFilter(w, alias, params, `${prefix}or${i}_`));
|
|
1386
|
+
condition = `(${condition} OR ${orClauses.join(' OR ')})`;
|
|
1387
|
+
}
|
|
1388
|
+
return condition;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
exports.ArangoDBAdapter = ArangoDBAdapter;
|
|
1392
|
+
exports.default = ArangoDBAdapter;
|
|
1393
|
+
//# sourceMappingURL=arangodb.adapter.js.map
|