ts-prorm-orm 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/CHANGELOG.md +1111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +573 -0
  4. package/dist/audit/history-query.js +180 -0
  5. package/dist/audit/index.js +23 -0
  6. package/dist/audit/logger.js +236 -0
  7. package/dist/cache/cache-manager.js +84 -0
  8. package/dist/cache/index.js +16 -0
  9. package/dist/cache/redis-cluster-cache.js +557 -0
  10. package/dist/cli.js +2200 -0
  11. package/dist/compliance/audit-trail.js +68 -0
  12. package/dist/compliance/backup-verification.js +685 -0
  13. package/dist/compliance/breach-detector.js +505 -0
  14. package/dist/compliance/consent-record.js +227 -0
  15. package/dist/compliance/consent-versioning.js +331 -0
  16. package/dist/compliance/cross-border-log.js +530 -0
  17. package/dist/compliance/data-classifier.js +258 -0
  18. package/dist/compliance/data-lineage.js +565 -0
  19. package/dist/compliance/data-masker.js +303 -0
  20. package/dist/compliance/data-portability.js +265 -0
  21. package/dist/compliance/data-retention.js +195 -0
  22. package/dist/compliance/dsar-workflow.js +342 -0
  23. package/dist/compliance/field-encryption.js +223 -0
  24. package/dist/compliance/immutable-record.js +148 -0
  25. package/dist/compliance/index.js +260 -0
  26. package/dist/compliance/privacy-impact-assessment.js +364 -0
  27. package/dist/compliance/pseudonymization.js +269 -0
  28. package/dist/compliance/query-firewall.js +1182 -0
  29. package/dist/compliance/rate-limiter.js +580 -0
  30. package/dist/compliance/right-to-erasure.js +117 -0
  31. package/dist/compliance/row-level-security.js +246 -0
  32. package/dist/compliance/security-decorator.js +574 -0
  33. package/dist/compliance/security-monitor.js +525 -0
  34. package/dist/compliance/sensitive-data-discovery.js +476 -0
  35. package/dist/compliance/session-isolation.js +472 -0
  36. package/dist/compliance/tls-enforcer.js +108 -0
  37. package/dist/compliance/worm-storage.js +712 -0
  38. package/dist/connection-manager.js +198 -0
  39. package/dist/connection-pool.js +519 -0
  40. package/dist/decorators/audit.js +136 -0
  41. package/dist/decorators/belongs-to-many.js +115 -0
  42. package/dist/decorators/belongs-to.js +115 -0
  43. package/dist/decorators/check.js +435 -0
  44. package/dist/decorators/collate.js +329 -0
  45. package/dist/decorators/comment.js +205 -0
  46. package/dist/decorators/database-settings.js +236 -0
  47. package/dist/decorators/default.js +244 -0
  48. package/dist/decorators/encryption.js +235 -0
  49. package/dist/decorators/engine.js +97 -0
  50. package/dist/decorators/fk-constraints.js +594 -0
  51. package/dist/decorators/foreign-table.js +136 -0
  52. package/dist/decorators/generated.js +274 -0
  53. package/dist/decorators/has-many.js +127 -0
  54. package/dist/decorators/has-one.js +116 -0
  55. package/dist/decorators/hstore.js +129 -0
  56. package/dist/decorators/index.js +355 -0
  57. package/dist/decorators/json-column.js +83 -0
  58. package/dist/decorators/jsonb.js +101 -0
  59. package/dist/decorators/orm-decorators.js +425 -0
  60. package/dist/decorators/permissions.js +294 -0
  61. package/dist/decorators/procedure.js +210 -0
  62. package/dist/decorators/query-options.js +556 -0
  63. package/dist/decorators/range.js +167 -0
  64. package/dist/decorators/set-column.js +83 -0
  65. package/dist/decorators/spatial.js +114 -0
  66. package/dist/decorators/storage.js +580 -0
  67. package/dist/decorators/timezone.js +512 -0
  68. package/dist/decorators/trigger.js +90 -0
  69. package/dist/decorators/uuid.js +135 -0
  70. package/dist/decorators/view.js +258 -0
  71. package/dist/diagrams/chen-diagram.js +354 -0
  72. package/dist/diagrams/class-diagram.js +384 -0
  73. package/dist/diagrams/dependency-diagram.js +432 -0
  74. package/dist/diagrams/er-diagram.js +605 -0
  75. package/dist/diagrams/flow-diagram.js +394 -0
  76. package/dist/diagrams/gantt-diagram.js +411 -0
  77. package/dist/diagrams/index-diagram.js +353 -0
  78. package/dist/diagrams/index.js +184 -0
  79. package/dist/diagrams/migration-diagram.js +316 -0
  80. package/dist/diagrams/model-diagram.js +616 -0
  81. package/dist/diagrams/package-diagram.js +376 -0
  82. package/dist/diagrams/palette.js +85 -0
  83. package/dist/diagrams/relational-diagram.js +455 -0
  84. package/dist/diagrams/schemadoc-diagram.js +309 -0
  85. package/dist/diagrams/sequence-diagram.js +307 -0
  86. package/dist/diagrams/state-diagram.js +344 -0
  87. package/dist/diagrams/svg-dom.js +111 -0
  88. package/dist/diagrams/tree-diagram.js +250 -0
  89. package/dist/dialects/clickhouse/index.js +1742 -0
  90. package/dist/dialects/cockroachdb/index.js +4677 -0
  91. package/dist/dialects/cratedb/index.js +441 -0
  92. package/dist/dialects/databricks/index.js +517 -0
  93. package/dist/dialects/db2/index.js +2225 -0
  94. package/dist/dialects/dialect.js +720 -0
  95. package/dist/dialects/duckdb/index.js +2014 -0
  96. package/dist/dialects/exasol/index.js +357 -0
  97. package/dist/dialects/firebird/index.js +495 -0
  98. package/dist/dialects/greenplum/index.js +457 -0
  99. package/dist/dialects/hana/index.js +1741 -0
  100. package/dist/dialects/mariadb/index.js +3590 -0
  101. package/dist/dialects/mssql/index.js +2296 -0
  102. package/dist/dialects/mysql/index.js +4058 -0
  103. package/dist/dialects/oracle/index.js +2999 -0
  104. package/dist/dialects/postgres/index.js +5319 -0
  105. package/dist/dialects/query-stream-helper.js +152 -0
  106. package/dist/dialects/questdb/index.js +433 -0
  107. package/dist/dialects/redshift/index.js +2277 -0
  108. package/dist/dialects/singlestore/index.js +354 -0
  109. package/dist/dialects/snowflake/index.js +2082 -0
  110. package/dist/dialects/spanner/index.js +1768 -0
  111. package/dist/dialects/sqlite/index.js +3382 -0
  112. package/dist/dialects/tidb/index.js +377 -0
  113. package/dist/dialects/timescaledb/index.js +164 -0
  114. package/dist/dialects/trino/index.js +420 -0
  115. package/dist/dialects/turso/index.js +227 -0
  116. package/dist/dialects/vertica/index.js +317 -0
  117. package/dist/dialects/yugabytedb/index.js +424 -0
  118. package/dist/errors/index.js +472 -0
  119. package/dist/errors/utils.js +340 -0
  120. package/dist/errors.js +21 -0
  121. package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
  122. package/dist/extensions/catalog/mssql-features.js +147 -0
  123. package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
  124. package/dist/extensions/catalog/oracle-db2-features.js +196 -0
  125. package/dist/extensions/catalog/postgres-extensions.js +516 -0
  126. package/dist/extensions/index.js +71 -0
  127. package/dist/extensions/types.js +13 -0
  128. package/dist/foreign-data.js +173 -0
  129. package/dist/hooks/hooks-manager.js +350 -0
  130. package/dist/hooks/index.js +37 -0
  131. package/dist/index.js +463 -0
  132. package/dist/logging.js +335 -0
  133. package/dist/migrations/index.js +40 -0
  134. package/dist/migrations/migration.js +196 -0
  135. package/dist/migrations/migrator.js +411 -0
  136. package/dist/migrations/prormmigration.js +275 -0
  137. package/dist/migrations/query-interface.js +435 -0
  138. package/dist/migrations/seeder.js +353 -0
  139. package/dist/models/associations.js +852 -0
  140. package/dist/models/constraints.js +288 -0
  141. package/dist/models/data-types.js +2518 -0
  142. package/dist/models/decorators.js +445 -0
  143. package/dist/models/index.js +33 -0
  144. package/dist/models/indexes.js +531 -0
  145. package/dist/models/methods.js +382 -0
  146. package/dist/models/model-manager.js +103 -0
  147. package/dist/models/model.js +5349 -0
  148. package/dist/models/operators.js +67 -0
  149. package/dist/models/scopes.js +189 -0
  150. package/dist/models/typescript-types.js +26 -0
  151. package/dist/nosql/aerospike/index.js +205 -0
  152. package/dist/nosql/allegrograph/index.js +169 -0
  153. package/dist/nosql/arangodb/index.js +364 -0
  154. package/dist/nosql/azure-blob/index.js +206 -0
  155. package/dist/nosql/beanstalkd/index.js +231 -0
  156. package/dist/nosql/beequeue/index.js +210 -0
  157. package/dist/nosql/bigchaindb/index.js +195 -0
  158. package/dist/nosql/bigtable/index.js +224 -0
  159. package/dist/nosql/blazegraph/index.js +173 -0
  160. package/dist/nosql/bullmq/index.js +191 -0
  161. package/dist/nosql/cassandra/index.js +174 -0
  162. package/dist/nosql/chroma/index.js +190 -0
  163. package/dist/nosql/cloudflare-kv/index.js +220 -0
  164. package/dist/nosql/coherence/index.js +200 -0
  165. package/dist/nosql/cosmosdb/index.js +157 -0
  166. package/dist/nosql/couchbase/index.js +213 -0
  167. package/dist/nosql/dax/index.js +212 -0
  168. package/dist/nosql/deno-kv/index.js +206 -0
  169. package/dist/nosql/dgraph/index.js +171 -0
  170. package/dist/nosql/doris/index.js +169 -0
  171. package/dist/nosql/druid/index.js +162 -0
  172. package/dist/nosql/dynamodb/index.js +937 -0
  173. package/dist/nosql/elasticsearch/index.js +377 -0
  174. package/dist/nosql/etcd/index.js +502 -0
  175. package/dist/nosql/eventhubs/index.js +213 -0
  176. package/dist/nosql/eventstore/index.js +254 -0
  177. package/dist/nosql/faunadb/index.js +188 -0
  178. package/dist/nosql/firestore/index.js +177 -0
  179. package/dist/nosql/fluree/index.js +148 -0
  180. package/dist/nosql/fuseki/index.js +170 -0
  181. package/dist/nosql/gcs/index.js +172 -0
  182. package/dist/nosql/gearman/index.js +160 -0
  183. package/dist/nosql/geode/index.js +196 -0
  184. package/dist/nosql/graphdb/index.js +169 -0
  185. package/dist/nosql/graylog/index.js +188 -0
  186. package/dist/nosql/gridgain/index.js +171 -0
  187. package/dist/nosql/hazelcast/index.js +162 -0
  188. package/dist/nosql/hbase/index.js +230 -0
  189. package/dist/nosql/ignite/index.js +173 -0
  190. package/dist/nosql/immudb/index.js +184 -0
  191. package/dist/nosql/index.js +232 -0
  192. package/dist/nosql/infinispan/index.js +200 -0
  193. package/dist/nosql/influxdb/index.js +0 -0
  194. package/dist/nosql/kafka/index.js +234 -0
  195. package/dist/nosql/keyspaces/index.js +189 -0
  196. package/dist/nosql/kinesis/index.js +253 -0
  197. package/dist/nosql/leveldb/index.js +153 -0
  198. package/dist/nosql/lmdb/index.js +160 -0
  199. package/dist/nosql/loki/index.js +201 -0
  200. package/dist/nosql/marklogic/index.js +204 -0
  201. package/dist/nosql/materialize/index.js +145 -0
  202. package/dist/nosql/meilisearch/index.js +154 -0
  203. package/dist/nosql/memcached/index.js +223 -0
  204. package/dist/nosql/milvus/index.js +410 -0
  205. package/dist/nosql/minio/index.js +265 -0
  206. package/dist/nosql/momento/index.js +179 -0
  207. package/dist/nosql/mongodb/index.js +461 -0
  208. package/dist/nosql/nats/index.js +247 -0
  209. package/dist/nosql/nedb/index.js +164 -0
  210. package/dist/nosql/neo4j/index.js +450 -0
  211. package/dist/nosql/neptune/index.js +470 -0
  212. package/dist/nosql/nsq/index.js +200 -0
  213. package/dist/nosql/opensearch/index.js +186 -0
  214. package/dist/nosql/orientdb/index.js +175 -0
  215. package/dist/nosql/papertrail/index.js +200 -0
  216. package/dist/nosql/pinecone/index.js +0 -0
  217. package/dist/nosql/pinot/index.js +133 -0
  218. package/dist/nosql/pouchdb/index.js +172 -0
  219. package/dist/nosql/prometheus/index.js +174 -0
  220. package/dist/nosql/provendb/index.js +147 -0
  221. package/dist/nosql/pubsub/index.js +187 -0
  222. package/dist/nosql/pulsar/index.js +232 -0
  223. package/dist/nosql/qdrant/index.js +295 -0
  224. package/dist/nosql/qldb/index.js +192 -0
  225. package/dist/nosql/r2/index.js +281 -0
  226. package/dist/nosql/rabbitmq/index.js +237 -0
  227. package/dist/nosql/ravendb/index.js +175 -0
  228. package/dist/nosql/redis/index.js +607 -0
  229. package/dist/nosql/redpanda/index.js +237 -0
  230. package/dist/nosql/resque/index.js +203 -0
  231. package/dist/nosql/rethinkdb/index.js +232 -0
  232. package/dist/nosql/rocksdb/index.js +152 -0
  233. package/dist/nosql/rockset/index.js +126 -0
  234. package/dist/nosql/s3/index.js +298 -0
  235. package/dist/nosql/scylladb/index.js +178 -0
  236. package/dist/nosql/signoz/index.js +227 -0
  237. package/dist/nosql/sns/index.js +201 -0
  238. package/dist/nosql/solr/index.js +231 -0
  239. package/dist/nosql/splunk/index.js +227 -0
  240. package/dist/nosql/sqs/index.js +246 -0
  241. package/dist/nosql/stardog/index.js +169 -0
  242. package/dist/nosql/starrocks/index.js +170 -0
  243. package/dist/nosql/store.js +2 -0
  244. package/dist/nosql/sumologic/index.js +213 -0
  245. package/dist/nosql/surrealdb/index.js +179 -0
  246. package/dist/nosql/terminusdb/index.js +151 -0
  247. package/dist/nosql/tigergraph/index.js +469 -0
  248. package/dist/nosql/typesense/index.js +148 -0
  249. package/dist/nosql/unqlite/index.js +157 -0
  250. package/dist/nosql/upstash/index.js +167 -0
  251. package/dist/nosql/vercel-kv/index.js +166 -0
  252. package/dist/nosql/victoriametrics/index.js +213 -0
  253. package/dist/nosql/virtuoso/index.js +169 -0
  254. package/dist/nosql/weaviate/index.js +276 -0
  255. package/dist/operators/index.js +108 -0
  256. package/dist/operators.js +2690 -0
  257. package/dist/prisma-migrate/index.js +38 -0
  258. package/dist/prisma-migrate/migration-generator.js +125 -0
  259. package/dist/prisma-migrate/model-generator.js +172 -0
  260. package/dist/prisma-migrate/relations.js +100 -0
  261. package/dist/prisma-migrate/schema-parser.js +167 -0
  262. package/dist/prisma-migrate/type-mapper.js +40 -0
  263. package/dist/prorm.js +6832 -0
  264. package/dist/query-builders/cte-builder.js +80 -0
  265. package/dist/query-builders/functions/aggregate.js +390 -0
  266. package/dist/query-builders/functions/conditional.js +503 -0
  267. package/dist/query-builders/functions/datetime.js +695 -0
  268. package/dist/query-builders/functions/fulltext.js +439 -0
  269. package/dist/query-builders/functions/index.js +93 -0
  270. package/dist/query-builders/functions/json.js +427 -0
  271. package/dist/query-builders/functions/math.js +399 -0
  272. package/dist/query-builders/functions/string.js +518 -0
  273. package/dist/query-builders/functions/window.js +328 -0
  274. package/dist/query-builders/include-builder.js +323 -0
  275. package/dist/query-builders/index-expression-builder.js +242 -0
  276. package/dist/query-builders/index.js +161 -0
  277. package/dist/query-builders/insert-builder.js +164 -0
  278. package/dist/query-builders/model-helpers.js +38 -0
  279. package/dist/query-builders/order-limit-builder.js +239 -0
  280. package/dist/query-builders/sql-compiler.js +2040 -0
  281. package/dist/query-builders/subquery-builder.js +152 -0
  282. package/dist/query-builders/update-builder.js +182 -0
  283. package/dist/query-builders/view-builder.js +218 -0
  284. package/dist/query-builders/where-builder.js +1532 -0
  285. package/dist/query-interface.js +622 -0
  286. package/dist/query-optimizers/batch-optimizer.js +426 -0
  287. package/dist/query-optimizers/explain-plans.js +415 -0
  288. package/dist/query-optimizers/index.js +51 -0
  289. package/dist/query-optimizers/prepared-statement-cache.js +423 -0
  290. package/dist/query-optimizers/query-hints.js +438 -0
  291. package/dist/query-optimizers/query-optimizer.js +278 -0
  292. package/dist/query-optimizers/slow-query-logger.js +271 -0
  293. package/dist/replica-manager.js +507 -0
  294. package/dist/schema/index.js +15 -0
  295. package/dist/schema/migration-generator.js +374 -0
  296. package/dist/schema/schema-differ.js +549 -0
  297. package/dist/schema/types.js +6 -0
  298. package/dist/sql-constants.js +300 -0
  299. package/dist/sqlite-advanced.js +1047 -0
  300. package/dist/streams/index.js +12 -0
  301. package/dist/streams/transforms.js +178 -0
  302. package/dist/transaction.js +456 -0
  303. package/dist/types/index.js +180 -0
  304. package/dist/user-management.js +127 -0
  305. package/dist/utils/date.js +300 -0
  306. package/dist/utils/index.js +1079 -0
  307. package/dist/utils/string.js +161 -0
  308. package/dist/validators/index.js +19 -0
  309. package/dist/validators/validator.js +911 -0
  310. package/package.json +190 -0
@@ -0,0 +1,295 @@
1
+ "use strict";
2
+ /**
3
+ * Qdrant store implementation.
4
+ *
5
+ * Qdrant is a vector-similarity search engine: collections hold points
6
+ * (an ID, one or more dense/sparse vectors, and an arbitrary JSON payload),
7
+ * and the primary query shape is "find the points whose vector is closest
8
+ * to this query vector" (optionally constrained by a payload filter) -
9
+ * not SQL, not `WHERE`, not joins. It does not fit the SQL-shaped `Dialect`
10
+ * interface used by the SQL dialects in this repo, so this class implements
11
+ * the minimal `NoSqlStore` marker interface and exposes Qdrant's real
12
+ * collection/point/payload/alias operations instead of forcing them into a
13
+ * `query(sql)` shape.
14
+ *
15
+ * Uses the official `@qdrant/js-client-rest` driver, which talks to Qdrant's
16
+ * HTTP REST API (there is also a gRPC client, `@qdrant/js-client-grpc`, not
17
+ * used here). The REST client is stateless (plain HTTP requests, no
18
+ * persistent socket) - `connect()` verifies the server is reachable and the
19
+ * API key (if any) is accepted by calling `versionInfo()`, and
20
+ * `disconnect()` simply drops the client reference.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.QdrantStore = void 0;
24
+ const js_client_rest_1 = require("@qdrant/js-client-rest");
25
+ const errors_1 = require("../../errors");
26
+ function wrapConnectionError(err, host) {
27
+ const parent = err instanceof Error ? err : new Error(String(err));
28
+ const message = /fetch failed|ECONNREFUSED/i.test(parent.message)
29
+ ? 'Connection refused'
30
+ : `Unable to connect to Qdrant: ${parent.message}`;
31
+ return new errors_1.ConnectionError(message, { parent, database: 'qdrant', host });
32
+ }
33
+ function wrapDatabaseError(err, message) {
34
+ const parent = err instanceof Error ? err : new Error(String(err));
35
+ // Keep the `action` context (e.g. "Qdrant SEARCH failed") but don't discard
36
+ // the real underlying Qdrant error text (e.g. "Collection `foo` doesn't
37
+ // exist") - append it so callers inspecting `err.message` still see what
38
+ // actually went wrong.
39
+ const combined = message ? `${message}: ${parent.message}` : parent.message;
40
+ return errors_1.DatabaseError.from(parent, { message: combined });
41
+ }
42
+ /**
43
+ * `QdrantStore` wraps a `@qdrant/js-client-rest` `QdrantClient` and exposes
44
+ * Qdrant's collection management, point upsert/search/scroll/retrieve/delete,
45
+ * payload management, and collection-alias operations as a typed,
46
+ * promise-based API.
47
+ */
48
+ class QdrantStore {
49
+ constructor(options = {}) {
50
+ this.name = 'qdrant';
51
+ this.library = '@qdrant/js-client-rest';
52
+ this.client = null;
53
+ this.connected = false;
54
+ this.options = options;
55
+ }
56
+ // ---------------------------------------------------------------------
57
+ // Connection lifecycle
58
+ // ---------------------------------------------------------------------
59
+ async connect() {
60
+ if (this.connected && this.client) {
61
+ return;
62
+ }
63
+ const client = new js_client_rest_1.QdrantClient(this.options);
64
+ try {
65
+ // The REST client has no persistent socket to open, so "connecting"
66
+ // means eagerly verifying the server is reachable and (if configured)
67
+ // that the API key is accepted, rather than deferring failures to the
68
+ // first real call.
69
+ await client.versionInfo();
70
+ this.client = client;
71
+ this.connected = true;
72
+ }
73
+ catch (err) {
74
+ this.client = null;
75
+ this.connected = false;
76
+ throw wrapConnectionError(err, this.options.host ?? this.options.url);
77
+ }
78
+ }
79
+ async disconnect() {
80
+ this.client = null;
81
+ this.connected = false;
82
+ }
83
+ isConnected() {
84
+ return this.connected && this.client !== null;
85
+ }
86
+ /** Returns the underlying `QdrantClient` for anything not wrapped here. */
87
+ getClient() {
88
+ return this.requireClient();
89
+ }
90
+ requireClient() {
91
+ if (!this.client) {
92
+ throw new errors_1.ConnectionError('Not connected to Qdrant', { database: 'qdrant' });
93
+ }
94
+ return this.client;
95
+ }
96
+ async exec(fn, action) {
97
+ const client = this.requireClient();
98
+ try {
99
+ return await fn(client);
100
+ }
101
+ catch (err) {
102
+ throw wrapDatabaseError(err, `Qdrant ${action} failed`);
103
+ }
104
+ }
105
+ // ---------------------------------------------------------------------
106
+ // Collection management
107
+ // ---------------------------------------------------------------------
108
+ /**
109
+ * Create a new, empty collection. `vectors` is either a single
110
+ * `{ size, distance }` (unnamed/default vector space) or a map of named
111
+ * vector spaces (for collections with multiple vector fields per point).
112
+ */
113
+ async createCollection(collectionName, vectors, options = {}) {
114
+ return this.exec((c) => c.createCollection(collectionName, { vectors, ...options }), 'CREATE COLLECTION');
115
+ }
116
+ /** Delete a collection and all of its data. */
117
+ async deleteCollection(collectionName, options = {}) {
118
+ return this.exec((c) => c.deleteCollection(collectionName, options), 'DELETE COLLECTION');
119
+ }
120
+ /** Detailed status, point counts, and configuration for a collection. */
121
+ async getCollection(collectionName) {
122
+ return this.exec((c) => c.getCollection(collectionName), 'GET COLLECTION');
123
+ }
124
+ /** List the names of all collections. */
125
+ async listCollections() {
126
+ return this.exec(async (c) => (await c.getCollections()).collections, 'LIST COLLECTIONS');
127
+ }
128
+ /** Whether a collection with this name exists. */
129
+ async collectionExists(collectionName) {
130
+ return this.exec(async (c) => (await c.collectionExists(collectionName)).exists, 'COLLECTION EXISTS');
131
+ }
132
+ /** Update mutable collection parameters (optimizer config, HNSW params, etc). */
133
+ async updateCollection(collectionName, args = {}) {
134
+ return this.exec((c) => c.updateCollection(collectionName, args), 'UPDATE COLLECTION');
135
+ }
136
+ /** Create an index on a payload field so filtered search on it is fast. */
137
+ async createPayloadIndex(collectionName, fieldName, fieldSchema, options = {}) {
138
+ return this.exec((c) => c.createPayloadIndex(collectionName, {
139
+ field_name: fieldName,
140
+ field_schema: fieldSchema,
141
+ ...options,
142
+ }), 'CREATE PAYLOAD INDEX');
143
+ }
144
+ /** Remove an index previously created with `createPayloadIndex()`. */
145
+ async deletePayloadIndex(collectionName, fieldName, options = {}) {
146
+ return this.exec((c) => c.deletePayloadIndex(collectionName, fieldName, options), 'DELETE PAYLOAD INDEX');
147
+ }
148
+ // ---------------------------------------------------------------------
149
+ // Point upsert
150
+ // ---------------------------------------------------------------------
151
+ /** Insert or update one or more points (matched by ID). */
152
+ async upsert(collectionName, points, options = {}) {
153
+ return this.exec((c) => c.upsert(collectionName, { points, ...options }), 'UPSERT');
154
+ }
155
+ /**
156
+ * Insert or update points given in Qdrant's columnar "batch" shape
157
+ * (`{ ids, vectors, payloads }`, index-aligned across the three arrays)
158
+ * rather than an array of `{ id, vector, payload }` objects. Equivalent
159
+ * to `upsert()`, just a more compact wire format for large batches.
160
+ */
161
+ async upsertBatch(collectionName, batch, options = {}) {
162
+ return this.exec((c) => c.upsert(collectionName, { batch, ...options }), 'UPSERT BATCH');
163
+ }
164
+ // ---------------------------------------------------------------------
165
+ // Search
166
+ // ---------------------------------------------------------------------
167
+ /** Find the points whose vector is closest to `vector`, optionally constrained by a filter. */
168
+ async search(collectionName, vector, options = {}) {
169
+ const { vectorName, withPayload, withVector, scoreThreshold, ...rest } = options;
170
+ return this.exec((c) => c.search(collectionName, {
171
+ vector: vectorName ? { name: vectorName, vector } : vector,
172
+ with_payload: withPayload,
173
+ with_vector: withVector,
174
+ score_threshold: scoreThreshold,
175
+ ...rest,
176
+ }), 'SEARCH');
177
+ }
178
+ /** Run several `search()` requests against the same collection in a single round trip. */
179
+ async searchBatch(collectionName, searches, options = {}) {
180
+ return this.exec((c) => c.searchBatch(collectionName, { searches, ...options }), 'SEARCH BATCH');
181
+ }
182
+ // ---------------------------------------------------------------------
183
+ // Scroll (paginated retrieval)
184
+ // ---------------------------------------------------------------------
185
+ /**
186
+ * Page through all (optionally filtered) points in a collection without
187
+ * doing a similarity search. Pass the returned `nextPageOffset` back in
188
+ * as `options.offset` to fetch the next page; a `null` `nextPageOffset`
189
+ * means there's no more data.
190
+ */
191
+ async scroll(collectionName, options = {}) {
192
+ const { withPayload, withVector, ...rest } = options;
193
+ const result = await this.exec((c) => c.scroll(collectionName, {
194
+ with_payload: withPayload,
195
+ with_vector: withVector,
196
+ ...rest,
197
+ }), 'SCROLL');
198
+ return { points: result.points, nextPageOffset: result.next_page_offset ?? null };
199
+ }
200
+ // ---------------------------------------------------------------------
201
+ // Retrieve / count
202
+ // ---------------------------------------------------------------------
203
+ /** Fetch specific points by ID. IDs not found are simply omitted from the result. */
204
+ async retrieve(collectionName, ids, options = {}) {
205
+ const { withPayload, withVector, ...rest } = options;
206
+ return this.exec((c) => c.retrieve(collectionName, {
207
+ ids,
208
+ with_payload: withPayload,
209
+ with_vector: withVector,
210
+ ...rest,
211
+ }), 'RETRIEVE');
212
+ }
213
+ /** Count points in a collection, optionally matching a filter. */
214
+ async count(collectionName, filter, options = {}) {
215
+ const result = await this.exec((c) => c.count(collectionName, { filter, ...options }), 'COUNT');
216
+ return result.count;
217
+ }
218
+ // ---------------------------------------------------------------------
219
+ // Delete
220
+ // ---------------------------------------------------------------------
221
+ /** Delete points by explicit ID list. */
222
+ async deleteByIds(collectionName, ids, options = {}) {
223
+ return this.exec((c) => c.delete(collectionName, { points: ids, ...options }), 'DELETE');
224
+ }
225
+ /** Delete every point matching a filter. */
226
+ async deleteByFilter(collectionName, filter, options = {}) {
227
+ return this.exec((c) => c.delete(collectionName, { filter, ...options }), 'DELETE');
228
+ }
229
+ // ---------------------------------------------------------------------
230
+ // Payload management
231
+ // ---------------------------------------------------------------------
232
+ /**
233
+ * Merge `payload` into the existing payload of the selected points
234
+ * (existing keys not present in `payload` are left untouched).
235
+ */
236
+ async setPayload(collectionName, payload, selector, options = {}) {
237
+ return this.exec((c) => c.setPayload(collectionName, { payload, ...selectorArgs(selector), ...options }), 'SET PAYLOAD');
238
+ }
239
+ /**
240
+ * Replace the entire payload of the selected points with `payload`
241
+ * (unlike `setPayload()`, keys not present in `payload` are removed).
242
+ */
243
+ async overwritePayload(collectionName, payload, selector, options = {}) {
244
+ return this.exec((c) => c.overwritePayload(collectionName, { payload, ...selectorArgs(selector), ...options }), 'OVERWRITE PAYLOAD');
245
+ }
246
+ /** Remove specific payload keys from the selected points. */
247
+ async deletePayload(collectionName, keys, selector, options = {}) {
248
+ return this.exec((c) => c.deletePayload(collectionName, { keys, ...selectorArgs(selector), ...options }), 'DELETE PAYLOAD');
249
+ }
250
+ /** Remove the entire payload (all keys) from the selected points. */
251
+ async clearPayload(collectionName, selector, options = {}) {
252
+ return this.exec((c) => c.clearPayload(collectionName, { ...selectorArgs(selector), ...options }), 'CLEAR PAYLOAD');
253
+ }
254
+ // ---------------------------------------------------------------------
255
+ // Collection aliasing
256
+ // ---------------------------------------------------------------------
257
+ /** Create an alternative name (`aliasName`) for a collection; the collection is queryable under both names. */
258
+ async createAlias(collectionName, aliasName, timeout) {
259
+ return this.exec((c) => c.updateCollectionAliases({
260
+ actions: [{ create_alias: { collection_name: collectionName, alias_name: aliasName } }],
261
+ timeout,
262
+ }), 'CREATE ALIAS');
263
+ }
264
+ /** Delete an alias (the underlying collection and its other aliases are unaffected). */
265
+ async deleteAlias(aliasName, timeout) {
266
+ return this.exec((c) => c.updateCollectionAliases({
267
+ actions: [{ delete_alias: { alias_name: aliasName } }],
268
+ timeout,
269
+ }), 'DELETE ALIAS');
270
+ }
271
+ /** Atomically rename an alias (equivalent to delete + create in one operation). */
272
+ async renameAlias(oldAliasName, newAliasName, timeout) {
273
+ return this.exec((c) => c.updateCollectionAliases({
274
+ actions: [{ rename_alias: { old_alias_name: oldAliasName, new_alias_name: newAliasName } }],
275
+ timeout,
276
+ }), 'RENAME ALIAS');
277
+ }
278
+ /** List the aliases pointing at a specific collection. */
279
+ async getCollectionAliases(collectionName) {
280
+ return this.exec((c) => c.getCollectionAliases(collectionName), 'GET COLLECTION ALIASES');
281
+ }
282
+ /** List every alias across all collections. */
283
+ async getAliases() {
284
+ return this.exec((c) => c.getAliases(), 'GET ALIASES');
285
+ }
286
+ }
287
+ exports.QdrantStore = QdrantStore;
288
+ /** Spread a `PointsSelector` (`{ points }` or `{ filter }`, plus optional `shard_key`) into request args. */
289
+ function selectorArgs(selector) {
290
+ if ('points' in selector) {
291
+ return { points: selector.points };
292
+ }
293
+ return { filter: selector.filter };
294
+ }
295
+ exports.default = QdrantStore;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ /**
3
+ * Amazon QLDB store implementation.
4
+ *
5
+ * Amazon QLDB (Quantum Ledger Database) is a fully managed, append-only,
6
+ * cryptographically verifiable ledger database. Data is written as documents
7
+ * into ledger tables and queried with PartiQL (a SQL-compatible query
8
+ * language). Every revision of every document is retained in an immutable
9
+ * journal; the built-in `history(<table>)` PartiQL function exposes prior
10
+ * revisions, and each revision carries `metadata` (document id, version,
11
+ * transaction time, and a content hash) that forms the basis of QLDB's
12
+ * tamper-evidence.
13
+ *
14
+ * QLDB is not a SQL `Dialect` (no client-side DDL escaping, no row-level
15
+ * UPDATE/DELETE semantics beyond PartiQL), so this class implements the
16
+ * minimal `NoSqlStore` marker interface plus the ledger surface shared by
17
+ * this family of stores: `append`/`get`/`history`/`verify`/`query`.
18
+ *
19
+ * ## Lazy driver loading
20
+ *
21
+ * The official `amazon-qldb-driver-nodejs` package is loaded lazily inside
22
+ * `connect()`, so importing this module never requires the driver to be
23
+ * installed. Tests (and callers with their own transport) inject a pre-built
24
+ * driver via `QldbStoreOptions.client`, which bypasses the `require` entirely.
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.QldbStore = void 0;
28
+ const errors_1 = require("../../errors");
29
+ /** A validated PartiQL identifier - QLDB cannot parameterize table names. */
30
+ const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
31
+ function assertIdentifier(name) {
32
+ if (!IDENTIFIER.test(name)) {
33
+ throw new errors_1.DatabaseError(`Invalid QLDB table name: ${JSON.stringify(name)}`, {
34
+ code: 'VALIDATION_ERROR',
35
+ });
36
+ }
37
+ return name;
38
+ }
39
+ /**
40
+ * `QldbStore` wraps an `amazon-qldb-driver-nodejs` driver behind the shared
41
+ * ledger surface. `append` inserts a new document (returning its QLDB
42
+ * document id), `get` reads the current revision by document id, `history`
43
+ * returns every prior revision via the `history()` PartiQL function,
44
+ * `verify` returns a document's revision metadata (content hash +
45
+ * block address - QLDB's tamper-evidence proof material), and `query` is the
46
+ * raw PartiQL escape hatch.
47
+ */
48
+ class QldbStore {
49
+ constructor(options) {
50
+ this.name = 'qldb';
51
+ this.library = 'amazon-qldb-driver-nodejs';
52
+ this.driver = null;
53
+ this.connected = false;
54
+ if (!options || !options.ledgerName) {
55
+ throw new errors_1.DatabaseError('QldbStore requires a `ledgerName`', {
56
+ code: 'INVALID_CONNECTION',
57
+ });
58
+ }
59
+ this.options = options;
60
+ }
61
+ // ---------------------------------------------------------------------
62
+ // Connection lifecycle
63
+ // ---------------------------------------------------------------------
64
+ async connect() {
65
+ if (this.connected && this.driver) {
66
+ return;
67
+ }
68
+ try {
69
+ if (this.options.client) {
70
+ this.driver = this.options.client;
71
+ }
72
+ else {
73
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
74
+ const mod = require('amazon-qldb-driver-nodejs');
75
+ const QldbDriver = mod.QldbDriver ?? mod.default?.QldbDriver ?? mod.default;
76
+ this.driver = new QldbDriver(this.options.ledgerName, this.options.region ? { region: this.options.region } : undefined);
77
+ }
78
+ this.connected = true;
79
+ }
80
+ catch (err) {
81
+ this.driver = null;
82
+ this.connected = false;
83
+ const parent = err instanceof Error ? err : new Error(String(err));
84
+ throw new errors_1.ConnectionError(`Unable to connect to QLDB: ${parent.message}`, {
85
+ parent,
86
+ database: 'qldb',
87
+ });
88
+ }
89
+ }
90
+ async disconnect() {
91
+ if (this.driver && typeof this.driver.close === 'function') {
92
+ try {
93
+ await this.driver.close();
94
+ }
95
+ catch {
96
+ // best-effort close
97
+ }
98
+ }
99
+ this.driver = null;
100
+ this.connected = false;
101
+ }
102
+ isConnected() {
103
+ return this.connected && this.driver !== null;
104
+ }
105
+ /** Returns the underlying `QldbDriver` for anything not wrapped here. */
106
+ getClient() {
107
+ return this.requireDriver();
108
+ }
109
+ requireDriver() {
110
+ if (!this.driver || !this.connected) {
111
+ throw new errors_1.ConnectionError('Not connected to QLDB. Call connect() first.', {
112
+ database: 'qldb',
113
+ });
114
+ }
115
+ return this.driver;
116
+ }
117
+ /** Run a PartiQL statement inside a managed transaction and return the rows. */
118
+ async execute(statement, params, action) {
119
+ const driver = this.requireDriver();
120
+ try {
121
+ return await driver.executeLambda(async (txn) => {
122
+ const result = await txn.execute(statement, ...params);
123
+ return result.getResultList();
124
+ });
125
+ }
126
+ catch (err) {
127
+ const parent = err instanceof Error ? err : new Error(String(err));
128
+ throw errors_1.DatabaseError.from(parent, { message: `QLDB ${action} failed: ${parent.message}` });
129
+ }
130
+ }
131
+ // ---------------------------------------------------------------------
132
+ // Ledger surface
133
+ // ---------------------------------------------------------------------
134
+ /**
135
+ * Insert `data` as a new document into `table`, returning its QLDB document
136
+ * id (the stable identifier every revision of the document shares). Runs
137
+ * `INSERT INTO <table> ?`.
138
+ */
139
+ async append(table, data) {
140
+ const rows = await this.execute(`INSERT INTO ${assertIdentifier(table)} ?`, [data], 'append');
141
+ const first = rows[0];
142
+ return first?.documentId ?? String(first?.documentId ?? '');
143
+ }
144
+ /**
145
+ * Read the current revision of the document with QLDB document id `id`,
146
+ * addressed via PartiQL's `BY` clause. Returns the row or `null`.
147
+ */
148
+ async get(table, id) {
149
+ const rows = await this.execute(`SELECT * FROM ${assertIdentifier(table)} BY docId WHERE docId = ?`, [id], 'get');
150
+ return rows[0] ?? null;
151
+ }
152
+ /**
153
+ * Return every revision (including deletions) of the document with id `id`
154
+ * via the `history(<table>)` PartiQL function. Each entry carries `data`,
155
+ * `metadata`, `blockAddress` and `hash`.
156
+ */
157
+ async history(table, id) {
158
+ return this.execute(`SELECT * FROM history(${assertIdentifier(table)}) AS h WHERE h.metadata.id = ?`, [id], 'history');
159
+ }
160
+ /**
161
+ * Return the tamper-evidence proof material for document `id`: its revision
162
+ * `metadata` (content hash + version) and `blockAddress` from the journal,
163
+ * pulled from `history()`. This is the data QLDB's server-side digest/proof
164
+ * APIs cryptographically verify a revision against.
165
+ */
166
+ async verify(table, id) {
167
+ const rows = await this.execute(`SELECT metadata, blockAddress, hash FROM history(${assertIdentifier(table)}) AS h WHERE h.metadata.id = ?`, [id], 'verify');
168
+ return { documentId: id, revisions: rows };
169
+ }
170
+ /** Run a raw PartiQL `statement` with optional positional `params`. */
171
+ async query(statement, params = []) {
172
+ return this.execute(statement, params, 'query');
173
+ }
174
+ /** List the active table names in the ledger (thin passthrough). */
175
+ async tableNames() {
176
+ const driver = this.requireDriver();
177
+ if (typeof driver.getTableNames !== 'function') {
178
+ throw new errors_1.DatabaseError('QLDB driver does not support getTableNames()', {
179
+ code: 'QUERY_ERROR',
180
+ });
181
+ }
182
+ try {
183
+ return await driver.getTableNames();
184
+ }
185
+ catch (err) {
186
+ const parent = err instanceof Error ? err : new Error(String(err));
187
+ throw errors_1.DatabaseError.from(parent, { message: `QLDB tableNames failed: ${parent.message}` });
188
+ }
189
+ }
190
+ }
191
+ exports.QldbStore = QldbStore;
192
+ exports.default = QldbStore;