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,178 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScyllaStore = void 0;
4
+ /**
5
+ * ScyllaDB (CQL) store.
6
+ *
7
+ * ScyllaDB is a wide-column, partition-key-based distributed store that is
8
+ * wire- and query-compatible with Apache Cassandra: it speaks the same CQL
9
+ * (Cassandra Query Language) and native protocol, so the same `cassandra-driver`
10
+ * (DataStax Node.js driver) connects to it unchanged. Its distinguishing trait
11
+ * is a C++, shard-per-core (seastar) architecture aimed at much higher
12
+ * throughput and lower, more predictable latency than the JVM-based Cassandra.
13
+ *
14
+ * Like Cassandra, ScyllaDB deliberately omits joins, arbitrary WHERE-clause
15
+ * filtering, and subqueries: every query must be answerable from a single
16
+ * partition (or an explicitly designed secondary index / materialized view),
17
+ * and data is modelled query-first around partition and clustering keys. That
18
+ * model does not fit the SQL-shaped `Dialect` interface
19
+ * (`src/dialects/dialect.ts`), so this store implements the minimal
20
+ * `NoSqlStore` marker interface (`src/nosql/store.ts`) and exposes CQL
21
+ * execution directly rather than pretending to be a relational dialect.
22
+ *
23
+ * Built on the `cassandra-driver`. The driver is an optional peer dependency
24
+ * and is loaded lazily inside `connect()` (via `require`) so importing this
25
+ * module never forces the driver to be installed; tests inject a pre-built
26
+ * mock `Client` instead.
27
+ */
28
+ const errors_1 = require("../../errors");
29
+ /**
30
+ * `ScyllaStore` wraps a `cassandra-driver` `Client` and exposes CQL execution
31
+ * (`execute`), atomic multi-statement batches (`batch`), and a few
32
+ * parameterized convenience helpers (`insert`, `selectAll`).
33
+ *
34
+ * Statements are prepared by default (`prepare: true`) so the driver can cache
35
+ * query metadata, infer parameter types, and route requests to the shard/replica
36
+ * that owns the partition — the recommended default for anything run more than
37
+ * once, and especially valuable on ScyllaDB's shard-aware driver path.
38
+ */
39
+ class ScyllaStore {
40
+ constructor(options = {}) {
41
+ this.name = 'scylladb';
42
+ this.library = 'cassandra-driver';
43
+ this.client = null;
44
+ this.connected = false;
45
+ this.options = options;
46
+ }
47
+ // ---------------------------------------------------------------------
48
+ // NoSqlStore lifecycle
49
+ // ---------------------------------------------------------------------
50
+ async connect() {
51
+ if (this.connected && this.client) {
52
+ return;
53
+ }
54
+ try {
55
+ let client = this.options.client;
56
+ if (!client) {
57
+ // Lazy-load the optional driver so importing this module never
58
+ // requires `cassandra-driver` to be installed. Tests inject a mock
59
+ // `client` above and never reach this branch.
60
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
61
+ const cql = require('cassandra-driver');
62
+ client = new cql.Client({
63
+ contactPoints: this.options.contactPoints,
64
+ localDataCenter: this.options.localDataCenter,
65
+ keyspace: this.options.keyspace,
66
+ credentials: this.options.credentials,
67
+ ...this.options.clientOptions,
68
+ });
69
+ }
70
+ await client.connect();
71
+ this.client = client;
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 ScyllaDB: ${parent.message}`, {
79
+ parent,
80
+ database: 'scylladb',
81
+ host: this.options.contactPoints?.[0],
82
+ });
83
+ }
84
+ }
85
+ async disconnect() {
86
+ if (this.client) {
87
+ try {
88
+ await this.client.shutdown();
89
+ }
90
+ finally {
91
+ this.client = null;
92
+ this.connected = false;
93
+ }
94
+ }
95
+ else {
96
+ this.connected = false;
97
+ }
98
+ }
99
+ isConnected() {
100
+ return this.connected && this.client !== null;
101
+ }
102
+ /** Returns the underlying `cassandra-driver` `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('ScyllaDB client is not connected. Call connect() first.', {
109
+ database: 'scylladb',
110
+ });
111
+ }
112
+ return this.client;
113
+ }
114
+ wrapError(action, err) {
115
+ const parent = err instanceof Error ? err : new Error(String(err));
116
+ return errors_1.DatabaseError.from(parent, { message: `ScyllaDB ${action} failed: ${parent.message}` });
117
+ }
118
+ // ---------------------------------------------------------------------
119
+ // CQL execution
120
+ // ---------------------------------------------------------------------
121
+ /**
122
+ * Execute a single CQL statement with optional bound `params`. Statements
123
+ * are prepared by default (`prepare: true`); pass `opts.prepare = false` to
124
+ * run a one-off unprepared. Any other driver query options are forwarded via
125
+ * `opts`. Returns the full driver result (with `.rows`).
126
+ */
127
+ async execute(query, params = [], opts = {}) {
128
+ const client = this.requireClient();
129
+ try {
130
+ return (await client.execute(query, params, { prepare: true, ...opts }));
131
+ }
132
+ catch (err) {
133
+ throw this.wrapError(`execute (${query})`, err);
134
+ }
135
+ }
136
+ /**
137
+ * Execute multiple statements as a single logged batch (atomic across the
138
+ * statements, though not isolated — CQL batches are not SQL transactions).
139
+ * Each entry is a `{ query, params }` pair. Prepared by default; forward
140
+ * other driver batch options via `opts`.
141
+ */
142
+ async batch(queries, opts = {}) {
143
+ const client = this.requireClient();
144
+ try {
145
+ return await client.batch(queries, { prepare: true, ...opts });
146
+ }
147
+ catch (err) {
148
+ throw this.wrapError('batch', err);
149
+ }
150
+ }
151
+ // ---------------------------------------------------------------------
152
+ // Convenience helpers
153
+ // ---------------------------------------------------------------------
154
+ /**
155
+ * Convenience `INSERT`: builds a parameterized
156
+ * `INSERT INTO table (cols...) VALUES (?, ?, ...)` from `obj`'s keys and
157
+ * executes it (prepared). For upserts with TTL, IF NOT EXISTS, or other
158
+ * clauses, write the CQL yourself and call `execute()`.
159
+ */
160
+ async insert(table, obj, opts = {}) {
161
+ const columns = Object.keys(obj);
162
+ if (columns.length === 0) {
163
+ throw new errors_1.DatabaseError('insert() requires at least one column', {
164
+ original: 'empty insert object',
165
+ });
166
+ }
167
+ const placeholders = columns.map(() => '?').join(', ');
168
+ const query = `INSERT INTO ${table} (${columns.join(', ')}) VALUES (${placeholders})`;
169
+ const params = columns.map((c) => obj[c]);
170
+ return this.execute(query, params, opts);
171
+ }
172
+ /** Convenience `SELECT * FROM table`. Returns the full driver result (with `.rows`). */
173
+ async selectAll(table, opts = {}) {
174
+ return this.execute(`SELECT * FROM ${table}`, [], opts);
175
+ }
176
+ }
177
+ exports.ScyllaStore = ScyllaStore;
178
+ exports.default = ScyllaStore;
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ /**
3
+ * SigNoz store implementation.
4
+ *
5
+ * SigNoz is an open-source, ClickHouse-backed observability platform for
6
+ * logs, traces, and metrics. Logs are ingested over OTLP/HTTP (the
7
+ * OpenTelemetry logs protocol) and queried through SigNoz's query-range API
8
+ * (a builder-style JSON body over its ClickHouse store). There is no
9
+ * SQL-shaped query surface exposed to clients, no row-level UPDATE/DELETE,
10
+ * and no identifier escaping, so SigNoz does not fit the SQL `Dialect`
11
+ * interface (`src/dialects/dialect.ts`). This class implements the minimal
12
+ * `NoSqlStore` marker interface (`src/nosql/store.ts`) and exposes SigNoz's
13
+ * OTLP ingest + query API.
14
+ *
15
+ * ## No canonical driver - HTTP over `fetch`
16
+ *
17
+ * SigNoz has no single canonical npm client; ingest is OTLP/HTTP JSON and
18
+ * query is a REST/JSON API. This store talks to both with the global `fetch`
19
+ * (so `library` is `'fetch'`). For tests (and custom transports) an
20
+ * alternative HTTP client can be injected via `SigNozStoreOptions.client`.
21
+ *
22
+ * ## Endpoints wrapped
23
+ *
24
+ * - `push(resource, entries)` -> `POST /v1/logs` (OTLP/HTTP ingest)
25
+ * - `query(builder, opts?)` -> `POST /api/v4/query_range` (query-range)
26
+ * - `labels()` -> `GET /api/v1/logs/fields` (log field keys)
27
+ * - `streams()` -> `GET /api/v1/services` (services)
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.SigNozStore = exports.DEFAULT_SIGNOZ_BASE_URL = void 0;
31
+ exports.createFetchClient = createFetchClient;
32
+ const errors_1 = require("../../errors");
33
+ /** Default SigNoz base URL (query service). */
34
+ exports.DEFAULT_SIGNOZ_BASE_URL = 'http://localhost:8080';
35
+ /** Build a `fetch`-backed client for the given base URL. */
36
+ function createFetchClient(baseURL, headers) {
37
+ const buildUrl = (path, params) => {
38
+ const url = new URL(path, baseURL.endsWith('/') ? baseURL : `${baseURL}/`);
39
+ for (const [key, value] of Object.entries(params ?? {})) {
40
+ if (value === undefined)
41
+ continue;
42
+ if (Array.isArray(value)) {
43
+ for (const item of value)
44
+ url.searchParams.append(key, item);
45
+ }
46
+ else {
47
+ url.searchParams.set(key, value);
48
+ }
49
+ }
50
+ return url.toString();
51
+ };
52
+ return {
53
+ async get(path, params) {
54
+ const res = await fetch(buildUrl(path, params), {
55
+ method: 'GET',
56
+ headers: { Accept: 'application/json', ...(headers ?? {}) },
57
+ });
58
+ if (!res.ok)
59
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
60
+ return res.json();
61
+ },
62
+ async post(path, body, contentType) {
63
+ const res = await fetch(buildUrl(path), {
64
+ method: 'POST',
65
+ body,
66
+ headers: { ...(headers ?? {}), ...(contentType ? { 'Content-Type': contentType } : {}) },
67
+ });
68
+ if (!res.ok)
69
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
70
+ const text = await res.text();
71
+ if (!text)
72
+ return undefined;
73
+ try {
74
+ return JSON.parse(text);
75
+ }
76
+ catch {
77
+ return text;
78
+ }
79
+ },
80
+ };
81
+ }
82
+ /** Map a simplified attribute value into an OTLP AnyValue. */
83
+ function toAnyValue(value) {
84
+ if (typeof value === 'number') {
85
+ return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };
86
+ }
87
+ if (typeof value === 'boolean')
88
+ return { boolValue: value };
89
+ return { stringValue: value };
90
+ }
91
+ /**
92
+ * `SigNozStore` wraps SigNoz's OTLP/HTTP log ingest and its query-range API
93
+ * (plus log-field and service metadata) behind the `NoSqlStore` lifecycle.
94
+ */
95
+ class SigNozStore {
96
+ constructor(options = {}) {
97
+ this.name = 'signoz';
98
+ this.library = 'fetch';
99
+ this.client = null;
100
+ this.connected = false;
101
+ this.baseURL = options.baseURL ?? exports.DEFAULT_SIGNOZ_BASE_URL;
102
+ this.injectedClient = options.client;
103
+ this.headers = options.headers;
104
+ }
105
+ // ---------------------------------------------------------------------
106
+ // Connection lifecycle
107
+ // ---------------------------------------------------------------------
108
+ async connect() {
109
+ if (this.connected && this.client)
110
+ return;
111
+ this.client = this.injectedClient ?? createFetchClient(this.baseURL, this.headers);
112
+ this.connected = true;
113
+ }
114
+ async disconnect() {
115
+ this.client = null;
116
+ this.connected = false;
117
+ }
118
+ isConnected() {
119
+ return this.connected && this.client !== null;
120
+ }
121
+ /** Returns the underlying (internal or injected) HTTP client. */
122
+ getClient() {
123
+ return this.requireClient();
124
+ }
125
+ requireClient() {
126
+ if (!this.client) {
127
+ throw new errors_1.ConnectionError('Not connected to SigNoz', {
128
+ database: 'signoz',
129
+ host: this.baseURL,
130
+ });
131
+ }
132
+ return this.client;
133
+ }
134
+ async doGet(path, params, action) {
135
+ const client = this.requireClient();
136
+ try {
137
+ return await client.get(path, params);
138
+ }
139
+ catch (err) {
140
+ const parent = err instanceof Error ? err : new Error(String(err));
141
+ throw errors_1.DatabaseError.from(parent, {
142
+ message: `SigNoz ${action ?? 'request'} failed: ${parent.message}`,
143
+ });
144
+ }
145
+ }
146
+ // ---------------------------------------------------------------------
147
+ // Ingest (OTLP/HTTP)
148
+ // ---------------------------------------------------------------------
149
+ /**
150
+ * Ingests log records over OTLP/HTTP via `POST /v1/logs`. The simplified
151
+ * `entries` are assembled into the OTLP `resourceLogs -> scopeLogs ->
152
+ * logRecords` envelope, tagged with the shared `resource` attributes.
153
+ */
154
+ async push(resource, entries) {
155
+ const client = this.requireClient();
156
+ const payload = {
157
+ resourceLogs: [
158
+ {
159
+ resource: {
160
+ attributes: Object.entries(resource).map(([key, value]) => ({
161
+ key,
162
+ value: toAnyValue(value),
163
+ })),
164
+ },
165
+ scopeLogs: [
166
+ {
167
+ logRecords: entries.map((e) => ({
168
+ timeUnixNano: e.timeUnixNano === undefined ? undefined : String(e.timeUnixNano),
169
+ severityText: e.severity,
170
+ body: { stringValue: e.body },
171
+ attributes: Object.entries(e.attributes ?? {}).map(([key, value]) => ({
172
+ key,
173
+ value: toAnyValue(value),
174
+ })),
175
+ })),
176
+ },
177
+ ],
178
+ },
179
+ ],
180
+ };
181
+ try {
182
+ return await client.post('/v1/logs', JSON.stringify(payload), 'application/json');
183
+ }
184
+ catch (err) {
185
+ const parent = err instanceof Error ? err : new Error(String(err));
186
+ throw errors_1.DatabaseError.from(parent, { message: `SigNoz push failed: ${parent.message}` });
187
+ }
188
+ }
189
+ // ---------------------------------------------------------------------
190
+ // Query
191
+ // ---------------------------------------------------------------------
192
+ /**
193
+ * Runs a query-range request via `POST /api/v4/query_range`. The
194
+ * `builder` is SigNoz's composite query payload (`compositeQuery` /
195
+ * builder queries); `start`/`end`/`step` fill the time window. Returns the
196
+ * parsed response.
197
+ */
198
+ async query(builder, options = {}) {
199
+ const client = this.requireClient();
200
+ const payload = {
201
+ start: options.start,
202
+ end: options.end,
203
+ step: options.step,
204
+ ...builder,
205
+ };
206
+ try {
207
+ return await client.post('/api/v4/query_range', JSON.stringify(payload), 'application/json');
208
+ }
209
+ catch (err) {
210
+ const parent = err instanceof Error ? err : new Error(String(err));
211
+ throw errors_1.DatabaseError.from(parent, { message: `SigNoz query failed: ${parent.message}` });
212
+ }
213
+ }
214
+ // ---------------------------------------------------------------------
215
+ // Metadata
216
+ // ---------------------------------------------------------------------
217
+ /** Lists the known log field/attribute keys via `GET /api/v1/logs/fields`. */
218
+ async labels() {
219
+ return this.doGet('/api/v1/logs/fields', undefined, 'labels');
220
+ }
221
+ /** Lists the observed services via `GET /api/v1/services`. */
222
+ async streams() {
223
+ return this.doGet('/api/v1/services', undefined, 'streams');
224
+ }
225
+ }
226
+ exports.SigNozStore = SigNozStore;
227
+ exports.default = SigNozStore;
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnsStore = void 0;
4
+ /**
5
+ * Amazon SNS (Simple Notification Service) store.
6
+ *
7
+ * SNS is a managed, push-based publish/subscribe fan-out service: publishers
8
+ * send to a topic and SNS pushes to every subscribed endpoint (SQS queue,
9
+ * Lambda, HTTP(S), email, SMS, ...). It has no query language and no SQL-shaped
10
+ * access pattern, so this store implements the minimal `NoSqlStore` marker
11
+ * interface (`src/nosql/store.ts`) and exposes SNS's real operations:
12
+ * publishing to a topic (`publish`), registering a subscription endpoint
13
+ * (`subscribe`), and topic administration (`createTopic`).
14
+ *
15
+ * Built on AWS SDK v3 (`@aws-sdk/client-sns`): an `SNSClient` speaks the wire
16
+ * protocol via the command pattern — you build a command object
17
+ * (`new PublishCommand(input)`) and hand it to `client.send(command)`. The SDK
18
+ * is loaded lazily inside `connect()` (via `require`) so importing this module
19
+ * never hard-requires the driver, and tests inject a mock `client` (with a
20
+ * `send(command)` method) so no real SDK or network is used.
21
+ *
22
+ * IMPORTANT: SNS delivery is *push*-based — there is no client-side receive
23
+ * loop. `subscribe()` therefore does NOT take a message handler; it registers
24
+ * an endpoint (an SQS queue ARN, Lambda ARN, HTTPS URL, email address, ...)
25
+ * that SNS will push messages to. Consuming those messages happens at that
26
+ * endpoint (e.g. via `SqsStore.subscribe` on a subscribed queue).
27
+ *
28
+ * Message encoding: `publish()` accepts a `string` (sent as-is), a `Buffer`
29
+ * (decoded to UTF-8), or any other JSON-serializable value (`JSON.stringify`d).
30
+ * The result becomes the notification `Message`.
31
+ */
32
+ const errors_1 = require("../../errors");
33
+ /** Encode a message into the string SNS carries as the notification `Message`. */
34
+ function toMessage(message) {
35
+ if (typeof message === 'string')
36
+ return message;
37
+ if (Buffer.isBuffer(message))
38
+ return message.toString('utf8');
39
+ return JSON.stringify(message);
40
+ }
41
+ /**
42
+ * `SnsStore` wraps an AWS v3 `SNSClient` and exposes topic publishing,
43
+ * endpoint subscription registration, and topic administration.
44
+ */
45
+ class SnsStore {
46
+ constructor(options = {}) {
47
+ this.name = 'sns';
48
+ this.library = '@aws-sdk/client-sns';
49
+ this.client = null;
50
+ this.aws = null;
51
+ this.connected = false;
52
+ this.options = options;
53
+ }
54
+ // ---------------------------------------------------------------------
55
+ // Lifecycle
56
+ // ---------------------------------------------------------------------
57
+ async connect() {
58
+ try {
59
+ if (this.options.client) {
60
+ this.client = this.options.client;
61
+ this.tryLoadSdk();
62
+ }
63
+ else {
64
+ const aws = require('@aws-sdk/client-sns');
65
+ this.aws = aws;
66
+ this.client = new aws.SNSClient({
67
+ region: this.options.region,
68
+ credentials: this.options.credentials,
69
+ endpoint: this.options.endpoint,
70
+ });
71
+ }
72
+ this.connected = true;
73
+ }
74
+ catch (err) {
75
+ this.connected = false;
76
+ this.client = null;
77
+ this.aws = null;
78
+ throw new errors_1.ConnectionError(`Failed to connect to SNS: ${err instanceof Error ? err.message : String(err)}`, { parent: err instanceof Error ? err : undefined, database: 'sns' });
79
+ }
80
+ }
81
+ tryLoadSdk() {
82
+ if (this.aws)
83
+ return;
84
+ try {
85
+ this.aws = require('@aws-sdk/client-sns');
86
+ }
87
+ catch {
88
+ this.aws = null;
89
+ }
90
+ }
91
+ async disconnect() {
92
+ try {
93
+ this.client?.destroy?.();
94
+ }
95
+ finally {
96
+ this.client = null;
97
+ this.aws = null;
98
+ this.connected = false;
99
+ }
100
+ }
101
+ isConnected() {
102
+ return this.connected && this.client !== null;
103
+ }
104
+ /** Returns the underlying `SNSClient` (loosely typed) for anything not wrapped here. */
105
+ getClient() {
106
+ return this.requireClient();
107
+ }
108
+ requireClient() {
109
+ if (!this.client || !this.connected) {
110
+ throw new errors_1.ConnectionError('SNS client is not connected. Call connect() first.', {
111
+ database: 'sns',
112
+ });
113
+ }
114
+ return this.client;
115
+ }
116
+ command(name, input) {
117
+ if (!this.aws)
118
+ this.tryLoadSdk();
119
+ const Ctor = this.aws?.[name];
120
+ if (typeof Ctor !== 'function') {
121
+ throw new errors_1.ConnectionError(`SNS command '${name}' is unavailable: '@aws-sdk/client-sns' could not be loaded.`, { database: 'sns' });
122
+ }
123
+ return new Ctor(input);
124
+ }
125
+ wrapError(action, err) {
126
+ const parent = err instanceof Error ? err : new Error(String(err));
127
+ const name = parent.name ? ` (${parent.name})` : '';
128
+ return new errors_1.DatabaseError(`SNS ${action} failed${name}: ${parent.message}`, {
129
+ parent,
130
+ original: parent.message,
131
+ });
132
+ }
133
+ // ---------------------------------------------------------------------
134
+ // Producing
135
+ // ---------------------------------------------------------------------
136
+ /**
137
+ * `Publish` — publish one `message` to the topic at `topicArn`. The message
138
+ * is encoded to a string (string as-is, Buffer → UTF-8, else JSON). Returns
139
+ * the message id (and FIFO sequence number, if any).
140
+ */
141
+ async publish(topicArn, message, options = {}) {
142
+ const client = this.requireClient();
143
+ try {
144
+ const result = await client.send(this.command('PublishCommand', {
145
+ TopicArn: topicArn,
146
+ Message: toMessage(message),
147
+ Subject: options.subject,
148
+ MessageGroupId: options.messageGroupId,
149
+ MessageDeduplicationId: options.messageDeduplicationId,
150
+ MessageAttributes: options.messageAttributes,
151
+ MessageStructure: options.messageStructureJson ? 'json' : undefined,
152
+ }));
153
+ return { messageId: result?.MessageId, sequenceNumber: result?.SequenceNumber };
154
+ }
155
+ catch (err) {
156
+ throw this.wrapError(`Publish to '${topicArn}'`, err);
157
+ }
158
+ }
159
+ // ---------------------------------------------------------------------
160
+ // Topic administration
161
+ // ---------------------------------------------------------------------
162
+ /** `CreateTopic` — create a topic by name. Returns its ARN. */
163
+ async createTopic(name, attributes) {
164
+ const client = this.requireClient();
165
+ try {
166
+ const result = await client.send(this.command('CreateTopicCommand', { Name: name, Attributes: attributes }));
167
+ return result?.TopicArn;
168
+ }
169
+ catch (err) {
170
+ throw this.wrapError(`CreateTopic '${name}'`, err);
171
+ }
172
+ }
173
+ // ---------------------------------------------------------------------
174
+ // Subscribing (push-based)
175
+ // ---------------------------------------------------------------------
176
+ /**
177
+ * `Subscribe` — register a push `endpoint` on the topic at `topicArn`. Unlike
178
+ * poll-based engines, SNS pushes notifications to the endpoint, so this takes
179
+ * an endpoint (SQS/Lambda ARN, HTTPS URL, email, ...) and a protocol rather
180
+ * than a message handler. Returns the subscription ARN (or 'pending
181
+ * confirmation' for endpoints that require confirmation).
182
+ */
183
+ async subscribe(topicArn, endpoint, options = {}) {
184
+ const client = this.requireClient();
185
+ try {
186
+ const result = await client.send(this.command('SubscribeCommand', {
187
+ TopicArn: topicArn,
188
+ Protocol: options.protocol ?? 'https',
189
+ Endpoint: endpoint,
190
+ ReturnSubscriptionArn: options.returnSubscriptionArn,
191
+ Attributes: options.attributes,
192
+ }));
193
+ return result?.SubscriptionArn;
194
+ }
195
+ catch (err) {
196
+ throw this.wrapError(`Subscribe to '${topicArn}'`, err);
197
+ }
198
+ }
199
+ }
200
+ exports.SnsStore = SnsStore;
201
+ exports.default = SnsStore;