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,230 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HBaseStore = void 0;
4
+ /**
5
+ * Apache HBase store.
6
+ *
7
+ * HBase is a wide-column, sorted-map distributed store built on top of HDFS,
8
+ * modelled on Google's Bigtable paper. Data is addressed by a `(row key,
9
+ * column family, column qualifier, timestamp)` tuple: rows are identified by
10
+ * an arbitrary byte-string row key (kept in sorted order), and each row holds
11
+ * cells grouped into a small, fixed set of column families, with an unbounded
12
+ * number of qualifiers per family created on the fly at write time. There is
13
+ * no fixed schema beyond the family list, no joins, no secondary indexes, and
14
+ * no arbitrary WHERE filtering — reads are either single-row gets by row key
15
+ * or range scans over the sorted key space. None of that fits the SQL-shaped
16
+ * `Dialect` interface (`src/dialects/dialect.ts`), so this store implements
17
+ * the minimal `NoSqlStore` marker interface (`src/nosql/store.ts`) and exposes
18
+ * HBase's own row/cell operations directly.
19
+ *
20
+ * Built on the `hbase` npm package (an HBase Stargate / REST-gateway client).
21
+ * That driver exposes a fluent surface — `client.table(name).row(key).put(...)`
22
+ * and `client.table(name).scan(...)` — with Node-style `(err, result)`
23
+ * callbacks. This store assumes that shape and promisifies each call. The
24
+ * driver is an optional peer dependency loaded lazily inside `connect()` (via
25
+ * `require`) so importing this module never forces the driver to be installed;
26
+ * tests inject a pre-built mock `client` instead.
27
+ *
28
+ * Assumed driver call surface (from the `hbase` REST client):
29
+ * client.table(name).create({ ColumnSchema: [{ name }, ...] }, cb)
30
+ * client.table(name).row(key).put(column, value, cb) // single cell
31
+ * client.table(name).row(key).put(columns, values, cb) // multi cell
32
+ * client.table(name).row(key).get(cb) // -> cells
33
+ * client.table(name).row(key).delete(cb)
34
+ * client.table(name).scan(options, cb) // -> rows
35
+ * A cell/column is addressed as `'family:qualifier'`, matching HBase's own
36
+ * column naming.
37
+ */
38
+ const errors_1 = require("../../errors");
39
+ /**
40
+ * `HBaseStore` wraps an `hbase` REST-gateway client and exposes HBase's
41
+ * row/cell surface: `put`/`get`/`deleteRow` for single-row operations, `scan`
42
+ * for range reads over the sorted key space, and `createTable` for defining a
43
+ * table's column families. Column cells are addressed as `'family:qualifier'`.
44
+ */
45
+ class HBaseStore {
46
+ constructor(options = {}) {
47
+ this.name = 'hbase';
48
+ this.library = 'hbase';
49
+ this.client = null;
50
+ this.connected = false;
51
+ this.options = options;
52
+ }
53
+ // ---------------------------------------------------------------------
54
+ // NoSqlStore lifecycle
55
+ // ---------------------------------------------------------------------
56
+ async connect() {
57
+ if (this.connected && this.client) {
58
+ return;
59
+ }
60
+ try {
61
+ let client = this.options.client;
62
+ if (!client) {
63
+ // Lazy-load the optional driver so importing this module never
64
+ // requires `hbase` to be installed. Tests inject a mock `client`
65
+ // above and never reach this branch.
66
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
67
+ const hbase = require('hbase');
68
+ client = hbase({
69
+ host: this.options.host,
70
+ port: this.options.port,
71
+ ...this.options.clientOptions,
72
+ });
73
+ }
74
+ this.client = client;
75
+ this.connected = true;
76
+ }
77
+ catch (err) {
78
+ this.client = null;
79
+ this.connected = false;
80
+ const parent = err instanceof Error ? err : new Error(String(err));
81
+ throw new errors_1.ConnectionError(`Unable to connect to HBase: ${parent.message}`, {
82
+ parent,
83
+ database: 'hbase',
84
+ host: this.options.host,
85
+ });
86
+ }
87
+ }
88
+ /**
89
+ * The `hbase` REST client is stateless (each call is an HTTP request), so
90
+ * there is no socket to tear down; `disconnect()` simply drops the reference
91
+ * and flips `connected` to false.
92
+ */
93
+ async disconnect() {
94
+ this.client = null;
95
+ this.connected = false;
96
+ }
97
+ isConnected() {
98
+ return this.connected && this.client !== null;
99
+ }
100
+ /** Returns the underlying `hbase` client for anything not wrapped here. */
101
+ getClient() {
102
+ return this.requireClient();
103
+ }
104
+ requireClient() {
105
+ if (!this.client || !this.connected) {
106
+ throw new errors_1.ConnectionError('HBase client is not connected. Call connect() first.', {
107
+ database: 'hbase',
108
+ });
109
+ }
110
+ return this.client;
111
+ }
112
+ wrapError(action, err) {
113
+ const parent = err instanceof Error ? err : new Error(String(err));
114
+ return errors_1.DatabaseError.from(parent, { message: `HBase ${action} failed: ${parent.message}` });
115
+ }
116
+ // ---------------------------------------------------------------------
117
+ // Row / cell operations
118
+ // ---------------------------------------------------------------------
119
+ /**
120
+ * Writes (puts) one or more cells into a single row. `data` maps
121
+ * `'family:qualifier'` column keys to values, e.g.
122
+ * `{ 'cf:name': 'alice', 'cf:age': 30 }`. Passed to the driver as parallel
123
+ * `columns`/`values` arrays via `table(table).row(row).put(...)`.
124
+ */
125
+ async put(table, row, data) {
126
+ const client = this.requireClient();
127
+ const columns = Object.keys(data);
128
+ if (columns.length === 0) {
129
+ throw new errors_1.DatabaseError('put() requires at least one column', {
130
+ original: 'empty put data',
131
+ });
132
+ }
133
+ const values = columns.map((c) => data[c]);
134
+ try {
135
+ return await new Promise((resolve, reject) => {
136
+ client
137
+ .table(table)
138
+ .row(row)
139
+ .put(columns, values, (err, result) => err ? reject(err) : resolve(result));
140
+ });
141
+ }
142
+ catch (err) {
143
+ throw this.wrapError(`put on '${table}' row '${row}'`, err);
144
+ }
145
+ }
146
+ /**
147
+ * Reads a single row by key via `table(table).row(row).get(...)`, returning
148
+ * the row's cells as the driver surfaces them (an array of
149
+ * `{ column, timestamp, $ }` cell descriptors for the `hbase` REST client).
150
+ */
151
+ async get(table, row) {
152
+ const client = this.requireClient();
153
+ try {
154
+ return await new Promise((resolve, reject) => {
155
+ client
156
+ .table(table)
157
+ .row(row)
158
+ .get((err, cells) => (err ? reject(err) : resolve(cells)));
159
+ });
160
+ }
161
+ catch (err) {
162
+ throw this.wrapError(`get on '${table}' row '${row}'`, err);
163
+ }
164
+ }
165
+ /** Deletes an entire row (all its cells) via `table(table).row(row).delete(...)`. */
166
+ async deleteRow(table, row) {
167
+ const client = this.requireClient();
168
+ try {
169
+ return await new Promise((resolve, reject) => {
170
+ client
171
+ .table(table)
172
+ .row(row)
173
+ .delete((err, result) => (err ? reject(err) : resolve(result)));
174
+ });
175
+ }
176
+ catch (err) {
177
+ throw this.wrapError(`deleteRow on '${table}' row '${row}'`, err);
178
+ }
179
+ }
180
+ /**
181
+ * Range-scans a table via `table(table).scan(options, ...)`, returning the
182
+ * matching rows. Since HBase keeps row keys sorted, `startRow`/`endRow`
183
+ * define an efficient contiguous range; `columns` restricts which families/
184
+ * qualifiers are read. Returns the rows as the driver surfaces them.
185
+ */
186
+ async scan(table, opts = {}) {
187
+ const client = this.requireClient();
188
+ try {
189
+ return await new Promise((resolve, reject) => {
190
+ client
191
+ .table(table)
192
+ .scan(opts, (err, rows) => (err ? reject(err) : resolve(rows)));
193
+ });
194
+ }
195
+ catch (err) {
196
+ throw this.wrapError(`scan on '${table}'`, err);
197
+ }
198
+ }
199
+ // ---------------------------------------------------------------------
200
+ // Table lifecycle
201
+ // ---------------------------------------------------------------------
202
+ /**
203
+ * Creates a table with the given column families via
204
+ * `table(table).create(...)`. `families` is the list of column family names
205
+ * (e.g. `['cf', 'meta']`); each is sent to the driver as an HBase
206
+ * `ColumnSchema` entry. A table must declare its families up front — unlike
207
+ * qualifiers, families cannot be added implicitly at write time.
208
+ */
209
+ async createTable(table, families) {
210
+ const client = this.requireClient();
211
+ if (!families || families.length === 0) {
212
+ throw new errors_1.DatabaseError('createTable() requires at least one column family', {
213
+ original: 'empty families list',
214
+ });
215
+ }
216
+ const schema = { ColumnSchema: families.map((name) => ({ name })) };
217
+ try {
218
+ return await new Promise((resolve, reject) => {
219
+ client
220
+ .table(table)
221
+ .create(schema, (err, result) => err ? reject(err) : resolve(result));
222
+ });
223
+ }
224
+ catch (err) {
225
+ throw this.wrapError(`createTable '${table}'`, err);
226
+ }
227
+ }
228
+ }
229
+ exports.HBaseStore = HBaseStore;
230
+ exports.default = HBaseStore;
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ /**
3
+ * Apache Ignite store implementation.
4
+ *
5
+ * Apache Ignite is a distributed in-memory data grid / database. Data lives
6
+ * in distributed key/value caches partitioned across cluster nodes, accessed
7
+ * here via Ignite's thin-client protocol. Although Ignite also speaks SQL,
8
+ * this store targets its distributed-cache (key/value grid) surface, which
9
+ * does not fit the SQL-shaped `Dialect` interface, so it implements the
10
+ * minimal `NoSqlStore` marker interface and exposes cache operations
11
+ * (getCache/put/get/removeKey/getKeys/getSize) as a typed, promise-based API.
12
+ *
13
+ * Uses the `apache-ignite-client` driver (the official Node.js thin client).
14
+ * The driver is loaded lazily inside `connect()` (or supplied pre-built via
15
+ * the `client` option) so importing this module never requires
16
+ * `apache-ignite-client` to be installed unless an Ignite store is actually
17
+ * connected. Tests inject a mock client this way.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.IgniteStore = exports.IGNITE_DB = void 0;
21
+ const errors_1 = require("../../errors");
22
+ /** Slug + human label for error/message context. Shared with `GridGainStore`. */
23
+ exports.IGNITE_DB = 'ignite';
24
+ function wrapConnectionError(err, database = exports.IGNITE_DB, label = 'Ignite') {
25
+ const parent = err instanceof Error ? err : new Error(String(err));
26
+ const message = /econnrefused/i.test(parent.message)
27
+ ? 'Connection refused'
28
+ : `Unable to connect to ${label}: ${parent.message}`;
29
+ return new errors_1.ConnectionError(message, { parent, database });
30
+ }
31
+ function wrapDatabaseError(err, action, label = 'Ignite') {
32
+ const parent = err instanceof Error ? err : new Error(String(err));
33
+ return errors_1.DatabaseError.from(parent, { message: `${label} ${action} failed: ${parent.message}` });
34
+ }
35
+ /**
36
+ * `IgniteStore` wraps an `apache-ignite-client` `IgniteClient` and exposes
37
+ * its distributed-cache operations as a typed, promise-based API.
38
+ */
39
+ class IgniteStore {
40
+ constructor(options = {}) {
41
+ this.name = 'ignite';
42
+ this.library = 'apache-ignite-client';
43
+ this.database = exports.IGNITE_DB;
44
+ this.label = 'Ignite';
45
+ this.client = null;
46
+ this.connected = false;
47
+ /** Resolved `CacheClient` handles, cached by name so `getMap` is idempotent. */
48
+ this.caches = new Map();
49
+ this.options = options;
50
+ }
51
+ // ---------------------------------------------------------------------
52
+ // Connection lifecycle
53
+ // ---------------------------------------------------------------------
54
+ async connect() {
55
+ if (this.connected && this.client) {
56
+ return;
57
+ }
58
+ try {
59
+ if (this.options.client) {
60
+ this.client = this.options.client;
61
+ }
62
+ else {
63
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
64
+ const mod = require('apache-ignite-client');
65
+ const IgniteClient = mod.IgniteClient ?? mod;
66
+ const IgniteClientConfiguration = mod.IgniteClientConfiguration;
67
+ const client = new IgniteClient();
68
+ const endpoints = this.options.endpoints ?? ['127.0.0.1:10800'];
69
+ const cfg = new IgniteClientConfiguration(...endpoints);
70
+ await client.connect(cfg);
71
+ this.client = client;
72
+ }
73
+ this.connected = true;
74
+ }
75
+ catch (err) {
76
+ this.client = null;
77
+ this.connected = false;
78
+ throw wrapConnectionError(err, this.database, this.label);
79
+ }
80
+ }
81
+ async disconnect() {
82
+ if (this.client) {
83
+ try {
84
+ await this.client.disconnect();
85
+ }
86
+ catch {
87
+ // best-effort disconnect
88
+ }
89
+ this.client = null;
90
+ }
91
+ this.caches.clear();
92
+ this.connected = false;
93
+ }
94
+ isConnected() {
95
+ return this.connected && this.client !== null;
96
+ }
97
+ /** Returns the underlying `apache-ignite-client` client for anything not wrapped here. */
98
+ getClient() {
99
+ return this.requireClient();
100
+ }
101
+ requireClient() {
102
+ if (!this.client) {
103
+ throw new errors_1.ConnectionError(`Not connected to ${this.label}`, { database: this.database });
104
+ }
105
+ return this.client;
106
+ }
107
+ // ---------------------------------------------------------------------
108
+ // Distributed cache operations
109
+ // ---------------------------------------------------------------------
110
+ /** Resolve (and cache) a distributed cache handle by name. */
111
+ async getMap(name) {
112
+ const cached = this.caches.get(name);
113
+ if (cached) {
114
+ return cached;
115
+ }
116
+ const client = this.requireClient();
117
+ try {
118
+ const cache = await client.getCache(name);
119
+ this.caches.set(name, cache);
120
+ return cache;
121
+ }
122
+ catch (err) {
123
+ throw wrapDatabaseError(err, 'getCache', this.label);
124
+ }
125
+ }
126
+ /** Put `value` under `key` in `map` (an Ignite cache handle). */
127
+ async mapPut(map, key, value) {
128
+ try {
129
+ return await map.put(key, value);
130
+ }
131
+ catch (err) {
132
+ throw wrapDatabaseError(err, 'cache put', this.label);
133
+ }
134
+ }
135
+ /** Get the value stored under `key` in `map` (or null if absent). */
136
+ async mapGet(map, key) {
137
+ try {
138
+ return await map.get(key);
139
+ }
140
+ catch (err) {
141
+ throw wrapDatabaseError(err, 'cache get', this.label);
142
+ }
143
+ }
144
+ /** Remove `key` from `map`. Returns Ignite's boolean success flag. */
145
+ async mapRemove(map, key) {
146
+ try {
147
+ return await map.removeKey(key);
148
+ }
149
+ catch (err) {
150
+ throw wrapDatabaseError(err, 'cache removeKey', this.label);
151
+ }
152
+ }
153
+ /** Return all keys currently in `map` as an array. */
154
+ async mapKeys(map) {
155
+ try {
156
+ return await map.getKeys();
157
+ }
158
+ catch (err) {
159
+ throw wrapDatabaseError(err, 'cache getKeys', this.label);
160
+ }
161
+ }
162
+ /** Return the number of entries in `map`. */
163
+ async mapSize(map) {
164
+ try {
165
+ return await map.getSize();
166
+ }
167
+ catch (err) {
168
+ throw wrapDatabaseError(err, 'cache getSize', this.label);
169
+ }
170
+ }
171
+ }
172
+ exports.IgniteStore = IgniteStore;
173
+ exports.default = IgniteStore;
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ /**
3
+ * immudb store implementation.
4
+ *
5
+ * immudb is an immutable, append-only key-value (and SQL) database with
6
+ * built-in cryptographic verification: every write is added to a tamper-
7
+ * evident Merkle-tree-backed log, and `verifiedSet`/`verifiedGet` return an
8
+ * inclusion/consistency proof the client checks locally, so a compromised
9
+ * server cannot lie about stored data without detection.
10
+ *
11
+ * immudb is a key-value ledger, not a SQL `Dialect`, so this class implements
12
+ * the minimal `NoSqlStore` marker interface plus the shared ledger surface
13
+ * (`append`/`get`/`history`/`verify`/`query`). Because immudb addresses
14
+ * records by key rather than by (table, row), `append`/`get`/`history`/
15
+ * `verify` treat their first argument as a key namespace and compose the
16
+ * immudb key as `<table>:<id>` (or just `<table>` when no id is given).
17
+ * `query` maps to immudb's embedded SQL engine (`sqlQuery`/`sqlExec`).
18
+ *
19
+ * ## Lazy driver loading
20
+ *
21
+ * The `immudb-node` package is loaded lazily inside `connect()`; importing
22
+ * this module never requires it. Tests inject a pre-built, already-logged-in
23
+ * client via `ImmudbStoreOptions.client`, bypassing the `require`.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ImmudbStore = void 0;
27
+ const errors_1 = require("../../errors");
28
+ /**
29
+ * `ImmudbStore` wraps an `immudb-node` client behind the shared ledger
30
+ * surface. `append` performs a `verifiedSet` (returning the write's
31
+ * transaction id), `get` a `verifiedGet`, `history` returns prior revisions
32
+ * of a key, `verify` returns the full verified-read response (value + proof),
33
+ * and `query` runs embedded SQL via `sqlQuery`.
34
+ */
35
+ class ImmudbStore {
36
+ constructor(options = {}) {
37
+ this.name = 'immudb';
38
+ this.library = 'immudb-node';
39
+ this.client = null;
40
+ this.connected = false;
41
+ this.options = options;
42
+ }
43
+ // ---------------------------------------------------------------------
44
+ // Connection lifecycle
45
+ // ---------------------------------------------------------------------
46
+ async connect() {
47
+ if (this.connected && this.client) {
48
+ return;
49
+ }
50
+ try {
51
+ if (this.options.client) {
52
+ this.client = this.options.client;
53
+ }
54
+ else {
55
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
56
+ const mod = require('immudb-node');
57
+ const ImmudbClient = mod.default ?? mod.ImmudbClient ?? mod;
58
+ this.client = new ImmudbClient({
59
+ host: this.options.host ?? '127.0.0.1',
60
+ port: this.options.port ?? 3322,
61
+ });
62
+ if (typeof this.client.login === 'function') {
63
+ await this.client.login({
64
+ user: this.options.user ?? 'immudb',
65
+ password: this.options.password ?? 'immudb',
66
+ });
67
+ }
68
+ if (this.options.database && typeof this.client.useDatabase === 'function') {
69
+ await this.client.useDatabase({ databasename: this.options.database });
70
+ }
71
+ }
72
+ this.connected = true;
73
+ }
74
+ catch (err) {
75
+ this.client = null;
76
+ this.connected = false;
77
+ const parent = err instanceof Error ? err : new Error(String(err));
78
+ throw new errors_1.ConnectionError(`Unable to connect to immudb: ${parent.message}`, {
79
+ parent,
80
+ database: 'immudb',
81
+ });
82
+ }
83
+ }
84
+ async disconnect() {
85
+ if (this.client) {
86
+ try {
87
+ if (typeof this.client.close === 'function')
88
+ await this.client.close();
89
+ else if (typeof this.client.shutdown === 'function')
90
+ await this.client.shutdown();
91
+ }
92
+ catch {
93
+ // best-effort close
94
+ }
95
+ }
96
+ this.client = null;
97
+ this.connected = false;
98
+ }
99
+ isConnected() {
100
+ return this.connected && this.client !== null;
101
+ }
102
+ /** Returns the underlying `immudb-node` client for anything not wrapped here. */
103
+ getClient() {
104
+ return this.requireClient();
105
+ }
106
+ requireClient() {
107
+ if (!this.client || !this.connected) {
108
+ throw new errors_1.ConnectionError('Not connected to immudb. Call connect() first.', {
109
+ database: 'immudb',
110
+ });
111
+ }
112
+ return this.client;
113
+ }
114
+ /** Compose the immudb key from a (table, id) address. */
115
+ keyFor(table, id) {
116
+ return id === undefined || id === null || id === '' ? table : `${table}:${id}`;
117
+ }
118
+ encode(data) {
119
+ return typeof data === 'string' ? data : JSON.stringify(data);
120
+ }
121
+ async run(action, fn) {
122
+ this.requireClient();
123
+ try {
124
+ return await fn();
125
+ }
126
+ catch (err) {
127
+ const parent = err instanceof Error ? err : new Error(String(err));
128
+ throw errors_1.DatabaseError.from(parent, { message: `immudb ${action} failed: ${parent.message}` });
129
+ }
130
+ }
131
+ // ---------------------------------------------------------------------
132
+ // Ledger surface
133
+ // ---------------------------------------------------------------------
134
+ /**
135
+ * Append `data` under the key `<table>:<data.id>` (or `<table>` if `data`
136
+ * has no `id`) via a verified, tamper-evident write. Returns the write's
137
+ * transaction id/hash from immudb's response.
138
+ */
139
+ async append(table, data) {
140
+ const id = data?.id;
141
+ const key = this.keyFor(table, id === undefined ? undefined : String(id));
142
+ const client = this.requireClient();
143
+ const res = await this.run('append', () => client.verifiedSet({ key, value: this.encode(data) }));
144
+ return String(res?.transactionId ?? res?.id ?? res?.txId ?? res?.tx ?? key);
145
+ }
146
+ /** Verified read of the current value at `<table>:<id>` (or `<table>`). */
147
+ async get(table, id) {
148
+ const client = this.requireClient();
149
+ return this.run('get', () => client.verifiedGet({ key: this.keyFor(table, id) }));
150
+ }
151
+ /** Return every prior revision of the key `<table>:<id>` (or `<table>`). */
152
+ async history(table, id) {
153
+ const client = this.requireClient();
154
+ return this.run('history', () => client.history({ key: this.keyFor(table, id) }));
155
+ }
156
+ /**
157
+ * Verified read returning the full response - value plus the cryptographic
158
+ * inclusion proof immudb generates for `verifiedGet`. The presence of a
159
+ * resolved response (rather than a thrown verification error) is the proof
160
+ * that the value is consistent with the tamper-evident log.
161
+ */
162
+ async verify(table, id) {
163
+ const client = this.requireClient();
164
+ return this.run('verify', () => client.verifiedGet({ key: this.keyFor(table, id) }));
165
+ }
166
+ /** Run a SQL `statement` against immudb's embedded SQL engine (`sqlQuery`). */
167
+ async query(statement, params) {
168
+ const client = this.requireClient();
169
+ if (typeof client.sqlQuery !== 'function') {
170
+ throw new errors_1.DatabaseError('immudb client does not support sqlQuery()', { code: 'QUERY_ERROR' });
171
+ }
172
+ return this.run('query', () => client.sqlQuery({ sql: statement, params }));
173
+ }
174
+ /** Execute a SQL DDL/DML `statement` via `sqlExec` (no rows returned). */
175
+ async exec(statement, params) {
176
+ const client = this.requireClient();
177
+ if (typeof client.sqlExec !== 'function') {
178
+ throw new errors_1.DatabaseError('immudb client does not support sqlExec()', { code: 'QUERY_ERROR' });
179
+ }
180
+ return this.run('exec', () => client.sqlExec({ sql: statement, params }));
181
+ }
182
+ }
183
+ exports.ImmudbStore = ImmudbStore;
184
+ exports.default = ImmudbStore;