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,212 @@
1
+ "use strict";
2
+ /**
3
+ * DAX (Amazon DynamoDB Accelerator) store implementation.
4
+ *
5
+ * DAX is a fully managed, in-memory, write-through cache for Amazon
6
+ * DynamoDB. It is not a standalone database - it is a DynamoDB *cache* that
7
+ * speaks the DynamoDB wire API, so the `amazon-dax-client` driver is a
8
+ * drop-in replacement for the low-level `AWS.DynamoDB` client
9
+ * (`getItem`/`putItem`/`deleteItem`/`scan`, each returning a request with a
10
+ * `.promise()`).
11
+ *
12
+ * This class implements the minimal `NoSqlStore` marker interface and maps a
13
+ * simple edge-KV surface onto a single DynamoDB table used as a key-value
14
+ * bucket:
15
+ *
16
+ * - `get(key)` -> `getItem` (Key = { <keyAttr>: key })
17
+ * - `set(k,v)` -> `putItem` (Item = { <keyAttr>: key, <valueAttr>: value })
18
+ * - `del(key)` -> `deleteItem`
19
+ * - `list(pref?)` -> `scan` (returns the `<keyAttr>` of each item)
20
+ * - `incr(k,by?)` -> read-modify-write over `getItem`/`putItem`
21
+ * (non-atomic; documented).
22
+ *
23
+ * ## Driver
24
+ *
25
+ * Uses `amazon-dax-client`. The driver is loaded lazily inside `connect()`
26
+ * (or supplied pre-built via the `client` option) so importing this module
27
+ * never requires `amazon-dax-client` to be installed unless a store is
28
+ * actually connected. Tests inject a mock `client`.
29
+ *
30
+ * ## Serialization
31
+ *
32
+ * Values are stored as DynamoDB string (`S`) attributes: strings verbatim,
33
+ * every other value `JSON.stringify`'d first.
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DaxStore = void 0;
37
+ const errors_1 = require("../../errors");
38
+ function serialize(value) {
39
+ return typeof value === 'string' ? value : JSON.stringify(value);
40
+ }
41
+ /**
42
+ * `DaxStore` wraps an `amazon-dax-client` (DynamoDB-compatible) client behind
43
+ * the `NoSqlStore` lifecycle and an edge-KV `get`/`set`/`del`/`list`/`incr`
44
+ * surface over a single DynamoDB table.
45
+ */
46
+ class DaxStore {
47
+ constructor(options = {}) {
48
+ this.name = 'dax';
49
+ this.library = 'amazon-dax-client';
50
+ this.client = null;
51
+ this.connected = false;
52
+ this.options = options;
53
+ }
54
+ get tableName() {
55
+ return this.options.tableName ?? '';
56
+ }
57
+ get keyAttr() {
58
+ return this.options.keyAttr ?? 'key';
59
+ }
60
+ get valueAttr() {
61
+ return this.options.valueAttr ?? 'value';
62
+ }
63
+ get ttlAttr() {
64
+ return this.options.ttlAttr ?? 'ttl';
65
+ }
66
+ // ---------------------------------------------------------------------
67
+ // Connection lifecycle
68
+ // ---------------------------------------------------------------------
69
+ async connect() {
70
+ if (this.connected && this.client) {
71
+ return;
72
+ }
73
+ try {
74
+ if (this.options.client) {
75
+ this.client = this.options.client;
76
+ }
77
+ else {
78
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
79
+ const mod = require('amazon-dax-client');
80
+ const AmazonDaxClient = mod.default ?? mod;
81
+ this.client = new AmazonDaxClient({
82
+ endpoints: this.options.endpoints,
83
+ region: this.options.region,
84
+ });
85
+ }
86
+ this.connected = true;
87
+ }
88
+ catch (err) {
89
+ this.client = null;
90
+ this.connected = false;
91
+ throw wrapConnectionError(err, this.options.endpoints?.[0]);
92
+ }
93
+ }
94
+ async disconnect() {
95
+ this.client = null;
96
+ this.connected = false;
97
+ }
98
+ isConnected() {
99
+ return this.connected && this.client !== null;
100
+ }
101
+ /** Returns the underlying DAX (DynamoDB-compatible) client for anything not wrapped here. */
102
+ getClient() {
103
+ return this.requireClient();
104
+ }
105
+ requireClient() {
106
+ if (!this.client) {
107
+ throw new errors_1.ConnectionError('Not connected to DAX', {
108
+ database: 'dax',
109
+ host: this.options.endpoints?.[0],
110
+ });
111
+ }
112
+ return this.client;
113
+ }
114
+ // ---------------------------------------------------------------------
115
+ // Key-value operations
116
+ // ---------------------------------------------------------------------
117
+ /** Read a key via `getItem`. Returns the stored string, or `null` if missing. */
118
+ async get(key) {
119
+ const client = this.requireClient();
120
+ try {
121
+ const res = await client
122
+ .getItem({ TableName: this.tableName, Key: { [this.keyAttr]: { S: key } } })
123
+ .promise();
124
+ const attr = res.Item?.[this.valueAttr];
125
+ return attr?.S ?? null;
126
+ }
127
+ catch (err) {
128
+ throw wrapDatabaseError(err, 'GET');
129
+ }
130
+ }
131
+ /**
132
+ * Write `value` under `key` via `putItem`. Strings are stored verbatim;
133
+ * other values are JSON-serialized. `options.ttl`/`options.expiration`
134
+ * populate the table's TTL attribute (`ttlAttr`).
135
+ */
136
+ async set(key, value, options = {}) {
137
+ const client = this.requireClient();
138
+ const item = {
139
+ [this.keyAttr]: { S: key },
140
+ [this.valueAttr]: { S: serialize(value) },
141
+ };
142
+ if (options.expiration !== undefined) {
143
+ item[this.ttlAttr] = { N: String(options.expiration) };
144
+ }
145
+ else if (options.ttl !== undefined) {
146
+ item[this.ttlAttr] = { N: String(Math.floor(Date.now() / 1000) + options.ttl) };
147
+ }
148
+ try {
149
+ await client.putItem({ TableName: this.tableName, Item: item }).promise();
150
+ }
151
+ catch (err) {
152
+ throw wrapDatabaseError(err, 'SET');
153
+ }
154
+ }
155
+ /** Delete a key via `deleteItem`. */
156
+ async del(key) {
157
+ const client = this.requireClient();
158
+ try {
159
+ await client
160
+ .deleteItem({ TableName: this.tableName, Key: { [this.keyAttr]: { S: key } } })
161
+ .promise();
162
+ }
163
+ catch (err) {
164
+ throw wrapDatabaseError(err, 'DEL');
165
+ }
166
+ }
167
+ /** List key names via `scan`, optionally filtered to those beginning with `prefix`. */
168
+ async list(prefix) {
169
+ const client = this.requireClient();
170
+ const params = {
171
+ TableName: this.tableName,
172
+ ProjectionExpression: '#k',
173
+ ExpressionAttributeNames: { '#k': this.keyAttr },
174
+ };
175
+ if (prefix !== undefined) {
176
+ params.FilterExpression = 'begins_with(#k, :p)';
177
+ params.ExpressionAttributeValues = { ':p': { S: prefix } };
178
+ }
179
+ try {
180
+ const res = await client.scan(params).promise();
181
+ const items = res.Items ?? [];
182
+ return items.map((item) => item[this.keyAttr]?.S).filter((k) => k !== undefined);
183
+ }
184
+ catch (err) {
185
+ throw wrapDatabaseError(err, 'LIST');
186
+ }
187
+ }
188
+ /**
189
+ * Increment the numeric value at `key` by `by` (default `1`). Implemented
190
+ * as a non-atomic read-modify-write over `getItem`/`putItem`.
191
+ */
192
+ async incr(key, by = 1) {
193
+ const current = await this.get(key);
194
+ const next = (current === null ? 0 : Number(current)) + by;
195
+ await this.set(key, String(next));
196
+ return next;
197
+ }
198
+ }
199
+ exports.DaxStore = DaxStore;
200
+ function wrapConnectionError(err, host) {
201
+ const parent = err instanceof Error ? err : new Error(String(err));
202
+ return new errors_1.ConnectionError(`Unable to connect to DAX: ${parent.message}`, {
203
+ parent,
204
+ database: 'dax',
205
+ host,
206
+ });
207
+ }
208
+ function wrapDatabaseError(err, action) {
209
+ const parent = err instanceof Error ? err : new Error(String(err));
210
+ return errors_1.DatabaseError.from(parent, { message: `DAX ${action} failed: ${parent.message}` });
211
+ }
212
+ exports.default = DaxStore;
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ /**
3
+ * Deno KV store implementation.
4
+ *
5
+ * Deno KV is a globally-distributed, serverless key-value database. Outside
6
+ * a Deno runtime it is reached over the network with the KV Connect
7
+ * protocol, which is an HTTP/JSON transport. This class implements the
8
+ * minimal `NoSqlStore` marker interface and exposes an edge-KV
9
+ * `get`/`set`/`del`/`list`/`incr` surface.
10
+ *
11
+ * ## No canonical Node driver - HTTP over `fetch` (KV Connect assumption)
12
+ *
13
+ * There is no first-party Node client for Deno KV, so `library` is
14
+ * `'fetch'`. This store assumes a **KV Connect-style HTTP gateway** that
15
+ * exposes a small REST surface for the underlying database:
16
+ *
17
+ * - `get(key)` -> `GET /kv/values/<key>` (404 => `null`)
18
+ * - `set(k,v)` -> `PUT /kv/values/<key>` (body + optional `expireIn`)
19
+ * - `del(key)` -> `DELETE /kv/values/<key>`
20
+ * - `list(pref?)` -> `GET /kv/keys?prefix=` (returns the key names)
21
+ * - `incr(k,by?)` -> read-modify-write over `get`/`set` (documented as
22
+ * non-atomic; the native `atomic().sum()` op is not modeled here).
23
+ *
24
+ * Keys are treated as opaque strings (Deno KV's array key parts are joined
25
+ * by the caller). For tests (and callers with their own transport) an
26
+ * alternative HTTP client can be injected via `client`; when omitted a tiny
27
+ * internal `fetch`-based client is built at `connect()` time.
28
+ *
29
+ * ## Serialization
30
+ *
31
+ * String values are stored verbatim; every other value is `JSON.stringify`'d
32
+ * before being written.
33
+ */
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.DenoKvStore = void 0;
36
+ exports.createFetchClient = createFetchClient;
37
+ const errors_1 = require("../../errors");
38
+ function serialize(value) {
39
+ return typeof value === 'string' ? value : JSON.stringify(value);
40
+ }
41
+ /** Build a `fetch`-backed HTTP client for the KV Connect gateway. */
42
+ function createFetchClient(baseURL, accessToken) {
43
+ const root = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;
44
+ return {
45
+ async request(method, path, init) {
46
+ const url = new URL(root + path);
47
+ for (const [key, value] of Object.entries(init?.query ?? {})) {
48
+ if (value !== undefined)
49
+ url.searchParams.set(key, value);
50
+ }
51
+ const headers = {};
52
+ if (accessToken)
53
+ headers.Authorization = `Bearer ${accessToken}`;
54
+ if (init?.body !== undefined)
55
+ headers['Content-Type'] = 'application/json';
56
+ return fetch(url.toString(), { method, headers, body: init?.body });
57
+ },
58
+ };
59
+ }
60
+ /**
61
+ * `DenoKvStore` wraps a KV Connect HTTP gateway behind the `NoSqlStore`
62
+ * lifecycle and an edge-KV `get`/`set`/`del`/`list`/`incr` surface.
63
+ */
64
+ class DenoKvStore {
65
+ constructor(options = {}) {
66
+ this.name = 'deno-kv';
67
+ this.library = 'fetch';
68
+ this.client = null;
69
+ this.connected = false;
70
+ this.options = options;
71
+ }
72
+ // ---------------------------------------------------------------------
73
+ // Connection lifecycle
74
+ // ---------------------------------------------------------------------
75
+ async connect() {
76
+ if (this.connected && this.client) {
77
+ return;
78
+ }
79
+ try {
80
+ this.client =
81
+ this.options.client ?? createFetchClient(this.options.url ?? '', this.options.accessToken);
82
+ this.connected = true;
83
+ }
84
+ catch (err) {
85
+ this.client = null;
86
+ this.connected = false;
87
+ throw wrapConnectionError(err, this.options.url);
88
+ }
89
+ }
90
+ async disconnect() {
91
+ this.client = null;
92
+ this.connected = false;
93
+ }
94
+ isConnected() {
95
+ return this.connected && this.client !== null;
96
+ }
97
+ /** Returns the underlying (internal or injected) HTTP client. */
98
+ getClient() {
99
+ return this.requireClient();
100
+ }
101
+ requireClient() {
102
+ if (!this.client) {
103
+ throw new errors_1.ConnectionError('Not connected to Deno KV', {
104
+ database: 'deno-kv',
105
+ host: this.options.url,
106
+ });
107
+ }
108
+ return this.client;
109
+ }
110
+ valuePath(key) {
111
+ return `/kv/values/${encodeURIComponent(key)}`;
112
+ }
113
+ // ---------------------------------------------------------------------
114
+ // Key-value operations
115
+ // ---------------------------------------------------------------------
116
+ /** Read a key. Returns `null` on a 404 (missing key). */
117
+ async get(key) {
118
+ const client = this.requireClient();
119
+ try {
120
+ const res = await client.request('GET', this.valuePath(key));
121
+ if (res.status === 404)
122
+ return null;
123
+ if (!res.ok)
124
+ throw new Error(`HTTP ${res.status}`);
125
+ return await res.text();
126
+ }
127
+ catch (err) {
128
+ throw wrapDatabaseError(err, 'GET');
129
+ }
130
+ }
131
+ /**
132
+ * Write `value` under `key`. Strings are stored verbatim; other values are
133
+ * JSON-serialized. `options.ttl` maps to `expireIn` (ms), `options.expiration`
134
+ * to `expireAt` (absolute Unix ms).
135
+ */
136
+ async set(key, value, options = {}) {
137
+ const client = this.requireClient();
138
+ const query = {};
139
+ if (options.ttl !== undefined)
140
+ query.expireIn = String(options.ttl);
141
+ if (options.expiration !== undefined)
142
+ query.expireAt = String(options.expiration);
143
+ try {
144
+ const res = await client.request('PUT', this.valuePath(key), {
145
+ body: serialize(value),
146
+ query,
147
+ });
148
+ if (!res.ok)
149
+ throw new Error(`HTTP ${res.status}`);
150
+ }
151
+ catch (err) {
152
+ throw wrapDatabaseError(err, 'SET');
153
+ }
154
+ }
155
+ /** Delete a key. */
156
+ async del(key) {
157
+ const client = this.requireClient();
158
+ try {
159
+ const res = await client.request('DELETE', this.valuePath(key));
160
+ if (!res.ok && res.status !== 404)
161
+ throw new Error(`HTTP ${res.status}`);
162
+ }
163
+ catch (err) {
164
+ throw wrapDatabaseError(err, 'DEL');
165
+ }
166
+ }
167
+ /** List key names, optionally filtered by `prefix`. */
168
+ async list(prefix) {
169
+ const client = this.requireClient();
170
+ try {
171
+ const res = await client.request('GET', '/kv/keys', { query: { prefix } });
172
+ if (!res.ok)
173
+ throw new Error(`HTTP ${res.status}`);
174
+ const body = await res.json();
175
+ const keys = body?.keys ?? [];
176
+ return keys;
177
+ }
178
+ catch (err) {
179
+ throw wrapDatabaseError(err, 'LIST');
180
+ }
181
+ }
182
+ /**
183
+ * Increment the numeric value at `key` by `by` (default `1`). Implemented
184
+ * as a non-atomic read-modify-write over `get`/`set`.
185
+ */
186
+ async incr(key, by = 1) {
187
+ const current = await this.get(key);
188
+ const next = (current === null ? 0 : Number(current)) + by;
189
+ await this.set(key, String(next));
190
+ return next;
191
+ }
192
+ }
193
+ exports.DenoKvStore = DenoKvStore;
194
+ function wrapConnectionError(err, host) {
195
+ const parent = err instanceof Error ? err : new Error(String(err));
196
+ return new errors_1.ConnectionError(`Unable to connect to Deno KV: ${parent.message}`, {
197
+ parent,
198
+ database: 'deno-kv',
199
+ host,
200
+ });
201
+ }
202
+ function wrapDatabaseError(err, action) {
203
+ const parent = err instanceof Error ? err : new Error(String(err));
204
+ return errors_1.DatabaseError.from(parent, { message: `Deno KV ${action} failed: ${parent.message}` });
205
+ }
206
+ exports.default = DenoKvStore;
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DgraphStore = void 0;
4
+ /**
5
+ * Dgraph store.
6
+ *
7
+ * Dgraph is a distributed, native graph database queried with DQL (its
8
+ * GraphQL-derived query language) rather than SQL. Data is modeled as nodes
9
+ * (identified by UIDs) and typed predicates/edges between them, with an
10
+ * optional schema defined via `alter`. It has no `Dialect`-shaped
11
+ * `query(sql)`/identifier-escaping surface, so this class implements the
12
+ * minimal `NoSqlStore` marker interface (`src/nosql/store.ts`) and exposes
13
+ * Dgraph's real primitives — parameterized DQL queries, JSON mutations, and
14
+ * schema `alter`/`dropAll` operations — directly.
15
+ *
16
+ * Built on the official `dgraph-js` gRPC driver. That driver is an optional
17
+ * peer dependency loaded lazily inside `connect()` (via `require`) so importing
18
+ * this module never forces the driver to be installed; tests inject a pre-built
19
+ * mock `client` instead and never reach the `require`.
20
+ */
21
+ const errors_1 = require("../../errors");
22
+ /**
23
+ * `DgraphStore` wraps a `dgraph-js` `DgraphClient` and exposes Dgraph's real
24
+ * surface: `query()` for parameterized DQL reads, `mutate()` for JSON
25
+ * mutations (auto-committed), and `alter()`/`dropAll()` for schema/data
26
+ * management.
27
+ */
28
+ class DgraphStore {
29
+ constructor(options = {}) {
30
+ this.name = 'dgraph';
31
+ this.library = 'dgraph-js';
32
+ this.client = null;
33
+ /** The client stub, kept so `disconnect()` can close its gRPC channel. Null when a client is injected. */
34
+ this.stub = null;
35
+ this.connected = false;
36
+ this.options = options;
37
+ }
38
+ // ---------------------------------------------------------------------
39
+ // NoSqlStore lifecycle
40
+ // ---------------------------------------------------------------------
41
+ async connect() {
42
+ if (this.connected && this.client) {
43
+ return;
44
+ }
45
+ try {
46
+ if (this.options.client) {
47
+ // Injected mock: use it directly and never touch the real driver.
48
+ this.client = this.options.client;
49
+ }
50
+ else {
51
+ // Lazy-load the optional driver so importing this module never
52
+ // requires `dgraph-js` to be installed.
53
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
54
+ const dgraph = require('dgraph-js');
55
+ const stub = new dgraph.DgraphClientStub(this.options.address);
56
+ this.stub = stub;
57
+ this.client = new dgraph.DgraphClient(stub);
58
+ }
59
+ this.connected = true;
60
+ }
61
+ catch (err) {
62
+ this.client = null;
63
+ this.stub = null;
64
+ this.connected = false;
65
+ const parent = err instanceof Error ? err : new Error(String(err));
66
+ throw new errors_1.ConnectionError(`Unable to connect to Dgraph: ${parent.message}`, {
67
+ parent,
68
+ database: 'dgraph',
69
+ host: this.options.address,
70
+ });
71
+ }
72
+ }
73
+ async disconnect() {
74
+ if (this.stub) {
75
+ this.stub.close();
76
+ this.stub = null;
77
+ }
78
+ this.client = null;
79
+ this.connected = false;
80
+ }
81
+ isConnected() {
82
+ return this.connected && this.client !== null;
83
+ }
84
+ /** Returns the underlying `dgraph-js` `DgraphClient` for anything not wrapped here. */
85
+ getClient() {
86
+ return this.requireClient();
87
+ }
88
+ requireClient() {
89
+ if (!this.client || !this.connected) {
90
+ throw new errors_1.ConnectionError('Dgraph client is not connected. Call connect() first.', {
91
+ database: 'dgraph',
92
+ });
93
+ }
94
+ return this.client;
95
+ }
96
+ wrapError(action, err) {
97
+ const parent = err instanceof Error ? err : new Error(String(err));
98
+ return errors_1.DatabaseError.from(parent, { message: `Dgraph ${action} failed: ${parent.message}` });
99
+ }
100
+ // ---------------------------------------------------------------------
101
+ // Query / mutate
102
+ // ---------------------------------------------------------------------
103
+ /**
104
+ * Runs a parameterized DQL query in a fresh transaction and returns the
105
+ * parsed JSON result. `vars` binds DQL query variables (e.g.
106
+ * `{ $name: 'alice' }`) sent separately from the query text. The
107
+ * transaction is always discarded in a `finally` — a read-only query never
108
+ * needs committing, and discarding releases its server-side resources.
109
+ */
110
+ async query(dql, vars = {}) {
111
+ const client = this.requireClient();
112
+ const txn = client.newTxn();
113
+ try {
114
+ const res = await txn.queryWithVars(dql, vars);
115
+ return JSON.parse(res.getJson());
116
+ }
117
+ catch (err) {
118
+ throw this.wrapError('query', err);
119
+ }
120
+ finally {
121
+ await txn.discard();
122
+ }
123
+ }
124
+ /**
125
+ * Applies a JSON mutation (`setJson`) and commits it immediately
126
+ * (`commitNow: true`), so no separate commit round trip is needed. The
127
+ * transaction is discarded in a `finally` as a safety net (committed
128
+ * transactions treat discard as a no-op).
129
+ */
130
+ async mutate(setJson) {
131
+ const client = this.requireClient();
132
+ const txn = client.newTxn();
133
+ try {
134
+ return await txn.mutate({ setJson, commitNow: true });
135
+ }
136
+ catch (err) {
137
+ throw this.wrapError('mutate', err);
138
+ }
139
+ finally {
140
+ await txn.discard();
141
+ }
142
+ }
143
+ // ---------------------------------------------------------------------
144
+ // Schema / data management
145
+ // ---------------------------------------------------------------------
146
+ /**
147
+ * Alters the schema by forwarding a DQL schema definition (DDL) to
148
+ * `client.alter({ schema })`, e.g. `'name: string @index(exact) .'`.
149
+ */
150
+ async alter(schema) {
151
+ const client = this.requireClient();
152
+ try {
153
+ return await client.alter({ schema });
154
+ }
155
+ catch (err) {
156
+ throw this.wrapError('alter', err);
157
+ }
158
+ }
159
+ /** Drops all data and schema in the cluster via `client.alter({ dropAll: true })`. */
160
+ async dropAll() {
161
+ const client = this.requireClient();
162
+ try {
163
+ return await client.alter({ dropAll: true });
164
+ }
165
+ catch (err) {
166
+ throw this.wrapError('dropAll', err);
167
+ }
168
+ }
169
+ }
170
+ exports.DgraphStore = DgraphStore;
171
+ exports.default = DgraphStore;