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,133 @@
1
+ "use strict";
2
+ /**
3
+ * Apache Pinot store.
4
+ *
5
+ * Pinot is a real-time distributed OLAP datastore built for low-latency
6
+ * analytics on both streaming and batch data. Queries are issued against a
7
+ * *broker* over an HTTP/JSON API using Pinot SQL; results come back in a
8
+ * columnar `resultTable` envelope (a `dataSchema` plus positional `rows`).
9
+ * Pinot has no client-side row `INSERT` path (real-time ingestion is driven
10
+ * by Kafka/stream connectors configured server-side), so it does not fit the
11
+ * SQL-shaped `Dialect` interface (`src/dialects/dialect.ts`). This class
12
+ * implements the minimal `NoSqlStore` marker interface (`src/nosql/store.ts`)
13
+ * and exposes Pinot's read-only broker query API directly.
14
+ *
15
+ * ## No canonical driver - HTTP over `fetch`
16
+ *
17
+ * Pinot has no single canonical npm client; the broker is just an HTTP/JSON
18
+ * API. This store uses the global `fetch`. Tests (and callers wanting their
19
+ * own transport) inject an alternative client via `PinotStoreOptions.client`;
20
+ * when omitted a tiny `fetch`-based client is built against `endpoint` on
21
+ * `connect()`.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.PinotStore = exports.DEFAULT_PINOT_ENDPOINT = void 0;
25
+ exports.createFetchClient = createFetchClient;
26
+ const errors_1 = require("../../errors");
27
+ /** Default Pinot broker HTTP endpoint. */
28
+ exports.DEFAULT_PINOT_ENDPOINT = 'http://localhost:8000';
29
+ /** Build a `fetch`-backed client for the given endpoint. */
30
+ function createFetchClient(endpoint, headers) {
31
+ const base = endpoint.endsWith('/') ? endpoint.slice(0, -1) : endpoint;
32
+ return {
33
+ async post(path, body) {
34
+ const res = await fetch(`${base}${path}`, {
35
+ method: 'POST',
36
+ headers: { 'Content-Type': 'application/json', ...(headers ?? {}) },
37
+ body: JSON.stringify(body),
38
+ });
39
+ if (!res.ok) {
40
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
41
+ }
42
+ const text = await res.text();
43
+ return text ? JSON.parse(text) : undefined;
44
+ },
45
+ };
46
+ }
47
+ /**
48
+ * `PinotStore` wraps Pinot's broker query API (`POST /query/sql`) behind the
49
+ * `NoSqlStore` lifecycle. `query()` maps the columnar `resultTable` into an
50
+ * array of row objects; `queryTable()` returns the raw `resultTable` envelope
51
+ * for callers who need the schema or the positional rows.
52
+ */
53
+ class PinotStore {
54
+ constructor(options = {}) {
55
+ this.name = 'pinot';
56
+ this.library = 'fetch';
57
+ this.client = null;
58
+ this.connected = false;
59
+ this.endpoint = options.endpoint ?? exports.DEFAULT_PINOT_ENDPOINT;
60
+ this.injectedClient = options.client;
61
+ this.headers = options.headers;
62
+ }
63
+ // ---------------------------------------------------------------------
64
+ // Connection lifecycle
65
+ // ---------------------------------------------------------------------
66
+ async connect() {
67
+ if (this.connected && this.client) {
68
+ return;
69
+ }
70
+ this.client = this.injectedClient ?? createFetchClient(this.endpoint, this.headers);
71
+ this.connected = true;
72
+ }
73
+ async disconnect() {
74
+ this.client = null;
75
+ this.connected = false;
76
+ }
77
+ isConnected() {
78
+ return this.connected && this.client !== null;
79
+ }
80
+ /** Returns the underlying (internal or injected) HTTP client. */
81
+ getClient() {
82
+ return this.requireClient();
83
+ }
84
+ requireClient() {
85
+ if (!this.client || !this.connected) {
86
+ throw new errors_1.ConnectionError('Not connected to Pinot. Call connect() first.', {
87
+ database: 'pinot',
88
+ host: this.endpoint,
89
+ });
90
+ }
91
+ return this.client;
92
+ }
93
+ async runSql(sql) {
94
+ const client = this.requireClient();
95
+ try {
96
+ return await client.post('/query/sql', { sql });
97
+ }
98
+ catch (err) {
99
+ const parent = err instanceof Error ? err : new Error(String(err));
100
+ throw errors_1.DatabaseError.from(parent, { message: `Pinot query failed: ${parent.message}` });
101
+ }
102
+ }
103
+ // ---------------------------------------------------------------------
104
+ // Query API (read-only)
105
+ // ---------------------------------------------------------------------
106
+ /**
107
+ * Run a Pinot SQL query via `POST /query/sql` and return the rows as an
108
+ * array of objects keyed by the result column names. For the raw columnar
109
+ * envelope (schema + positional rows), use `queryTable()`.
110
+ */
111
+ async query(sql) {
112
+ const table = await this.queryTable(sql);
113
+ const columns = table.dataSchema?.columnNames ?? [];
114
+ const rows = table.rows ?? [];
115
+ return rows.map((row) => {
116
+ const obj = {};
117
+ columns.forEach((col, i) => {
118
+ obj[col] = row[i];
119
+ });
120
+ return obj;
121
+ });
122
+ }
123
+ /**
124
+ * Run a Pinot SQL query and return the raw `resultTable` envelope
125
+ * (`dataSchema` + positional `rows`), exactly as the broker returns it.
126
+ */
127
+ async queryTable(sql) {
128
+ const body = await this.runSql(sql);
129
+ return (body?.resultTable ?? { rows: [] });
130
+ }
131
+ }
132
+ exports.PinotStore = PinotStore;
133
+ exports.default = PinotStore;
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PouchdbStore = void 0;
4
+ /**
5
+ * PouchDB store.
6
+ *
7
+ * PouchDB is an embedded, in-process document database (it can run purely in
8
+ * Node against a filesystem-backed adapter, with no server). Documents are
9
+ * addressed by an `_id` and versioned by a `_rev`, and the API is
10
+ * promise-based: `put`/`get`/`remove`/`allDocs`/`bulkDocs`. It has no
11
+ * SQL-shaped surface, so it does not fit the `Dialect` interface used by the
12
+ * SQL dialects in this repo. Instead it implements the minimal `NoSqlStore`
13
+ * marker interface (`src/nosql/store.ts`) and maps a common KV surface
14
+ * (`put`/`get`/`del` on `_id`) onto PouchDB's document API.
15
+ *
16
+ * Built on the `pouchdb` npm driver, loaded lazily inside `connect()` (via
17
+ * `require`) so importing this module never forces the driver to be installed;
18
+ * tests inject a pre-built mock `client` instead and never reach the `require`.
19
+ */
20
+ const errors_1 = require("../../errors");
21
+ /**
22
+ * `PouchdbStore` wraps a `pouchdb` database and exposes both a common KV
23
+ * surface — `put`/`get`/`del` keyed on `_id`, `batch`, `list` — and PouchDB's
24
+ * native `insert`/`allDocs` operations.
25
+ */
26
+ class PouchdbStore {
27
+ constructor(options = {}) {
28
+ this.name = 'pouchdb';
29
+ this.library = 'pouchdb';
30
+ this.client = null;
31
+ this.connected = false;
32
+ this.options = options;
33
+ this.dbName = options.name ?? './data/pouchdb';
34
+ }
35
+ async connect() {
36
+ if (this.connected && this.client) {
37
+ return;
38
+ }
39
+ try {
40
+ if (this.options.client) {
41
+ this.client = this.options.client;
42
+ }
43
+ else {
44
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
45
+ const PouchDB = require('pouchdb');
46
+ this.client = new PouchDB(this.dbName, this.options.config);
47
+ }
48
+ this.connected = true;
49
+ }
50
+ catch (err) {
51
+ this.client = null;
52
+ this.connected = false;
53
+ const parent = err instanceof Error ? err : new Error(String(err));
54
+ throw new errors_1.ConnectionError(`Unable to open PouchDB: ${parent.message}`, {
55
+ parent,
56
+ database: 'pouchdb',
57
+ });
58
+ }
59
+ }
60
+ async disconnect() {
61
+ if (this.client) {
62
+ try {
63
+ await this.client.close();
64
+ }
65
+ catch {
66
+ // best-effort close
67
+ }
68
+ this.client = null;
69
+ }
70
+ this.connected = false;
71
+ }
72
+ isConnected() {
73
+ return this.connected && this.client !== null;
74
+ }
75
+ /** Returns the underlying `pouchdb` database for anything not wrapped here. */
76
+ getClient() {
77
+ return this.requireClient();
78
+ }
79
+ requireClient() {
80
+ if (!this.client || !this.connected) {
81
+ throw new errors_1.ConnectionError('PouchDB database is not connected. Call connect() first.', {
82
+ database: 'pouchdb',
83
+ });
84
+ }
85
+ return this.client;
86
+ }
87
+ wrapError(action, err) {
88
+ const parent = err instanceof Error ? err : new Error(String(err));
89
+ return errors_1.DatabaseError.from(parent, { message: `PouchDB ${action} failed: ${parent.message}` });
90
+ }
91
+ /** Writes a document keyed by `_id = key` (PouchDB `put`), merging `key` in as its `_id`. */
92
+ async put(key, value) {
93
+ const client = this.requireClient();
94
+ try {
95
+ return await client.put({ _id: key, ...value });
96
+ }
97
+ catch (err) {
98
+ throw this.wrapError('put', err);
99
+ }
100
+ }
101
+ /** Native `insert`: stores a document as-is (must carry its own `_id`). */
102
+ async insert(doc) {
103
+ const client = this.requireClient();
104
+ try {
105
+ return await client.put(doc);
106
+ }
107
+ catch (err) {
108
+ throw this.wrapError('insert', err);
109
+ }
110
+ }
111
+ /** Reads a document by `_id` (PouchDB `get`). */
112
+ async get(key) {
113
+ const client = this.requireClient();
114
+ try {
115
+ return await client.get(key);
116
+ }
117
+ catch (err) {
118
+ throw this.wrapError('get', err);
119
+ }
120
+ }
121
+ /**
122
+ * Deletes a document by `_id`. PouchDB needs the current `_rev` to delete, so
123
+ * this first `get`s the document, then `remove`s it.
124
+ */
125
+ async del(key) {
126
+ const client = this.requireClient();
127
+ try {
128
+ const doc = await client.get(key);
129
+ return await client.remove(doc);
130
+ }
131
+ catch (err) {
132
+ throw this.wrapError('del', err);
133
+ }
134
+ }
135
+ /** Applies a list of `put`/`del` operations. Puts go through `bulkDocs`; deletes are resolved individually. */
136
+ async batch(ops) {
137
+ const client = this.requireClient();
138
+ try {
139
+ const puts = ops
140
+ .filter((op) => op.type === 'put')
141
+ .map((op) => ({ _id: op.key, ...op.value }));
142
+ if (puts.length > 0) {
143
+ await client.bulkDocs(puts);
144
+ }
145
+ for (const op of ops) {
146
+ if (op.type === 'del') {
147
+ await this.del(op.key);
148
+ }
149
+ }
150
+ }
151
+ catch (err) {
152
+ throw this.wrapError('batch', err);
153
+ }
154
+ }
155
+ /**
156
+ * Lists document ids via `allDocs`. With `prefix`, restricts to ids
157
+ * `>= prefix` and `<= prefix + '￿'` (PouchDB's startkey/endkey range).
158
+ */
159
+ async list(prefix) {
160
+ const client = this.requireClient();
161
+ try {
162
+ const options = prefix !== undefined ? { startkey: prefix, endkey: `${prefix}￿` } : {};
163
+ const result = await client.allDocs(options);
164
+ return result.rows.map((row) => row.id);
165
+ }
166
+ catch (err) {
167
+ throw this.wrapError('list', err);
168
+ }
169
+ }
170
+ }
171
+ exports.PouchdbStore = PouchdbStore;
172
+ exports.default = PouchdbStore;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ /**
3
+ * Prometheus store implementation.
4
+ *
5
+ * Prometheus is a pull-based time-series monitoring system. It is queried
6
+ * over its HTTP API using PromQL (Prometheus Query Language). There is no
7
+ * SQL-shaped query surface, no row-level UPDATE/DELETE, and no client-side
8
+ * ingestion path (Prometheus scrapes targets itself), so it does not fit
9
+ * the SQL `Dialect` interface (`src/dialects/dialect.ts`). This class
10
+ * implements the minimal `NoSqlStore` marker interface (`src/nosql/store.ts`)
11
+ * and exposes Prometheus's read-only HTTP query API directly.
12
+ *
13
+ * ## No canonical driver - HTTP over `fetch`
14
+ *
15
+ * Prometheus has no single canonical npm client library; it is just an
16
+ * HTTP/JSON API. Rather than depend on any package, this store talks to
17
+ * the server with the global `fetch`. For tests (and for callers who want
18
+ * to route requests through their own transport), an alternative HTTP
19
+ * client can be injected via `PrometheusStoreOptions.client`; when omitted,
20
+ * a tiny internal client over `fetch` + `baseURL` is built at connect time.
21
+ *
22
+ * ## Endpoints wrapped (all read-only, all under `/api/v1`)
23
+ *
24
+ * - `instantQuery(promql, time?)` -> `GET /api/v1/query`
25
+ * - `rangeQuery(promql, {start,end,step})` -> `GET /api/v1/query_range`
26
+ * - `series(match)` -> `GET /api/v1/series`
27
+ * - `labelValues(label)` -> `GET /api/v1/label/<label>/values`
28
+ *
29
+ * Each method returns the parsed `data` field of the Prometheus response
30
+ * envelope (`{ status: 'success', data: ... }`).
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.PrometheusStore = exports.DEFAULT_PROMETHEUS_BASE_URL = void 0;
34
+ exports.createFetchClient = createFetchClient;
35
+ const errors_1 = require("../../errors");
36
+ /** Default Prometheus HTTP API base URL. */
37
+ exports.DEFAULT_PROMETHEUS_BASE_URL = 'http://localhost:9090';
38
+ /** Build a `fetch`-backed client for the given base URL. */
39
+ function createFetchClient(baseURL, headers) {
40
+ const buildUrl = (path, params) => {
41
+ const url = new URL(path, baseURL.endsWith('/') ? baseURL : `${baseURL}/`);
42
+ for (const [key, value] of Object.entries(params ?? {})) {
43
+ if (value === undefined)
44
+ continue;
45
+ if (Array.isArray(value)) {
46
+ for (const item of value)
47
+ url.searchParams.append(key, item);
48
+ }
49
+ else {
50
+ url.searchParams.set(key, value);
51
+ }
52
+ }
53
+ return url.toString();
54
+ };
55
+ return {
56
+ async get(path, params) {
57
+ const res = await fetch(buildUrl(path, params), { method: 'GET', headers });
58
+ if (!res.ok) {
59
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
60
+ }
61
+ return res.json();
62
+ },
63
+ async post(path, body, contentType) {
64
+ const res = await fetch(buildUrl(path), {
65
+ method: 'POST',
66
+ body,
67
+ headers: { ...(headers ?? {}), ...(contentType ? { 'Content-Type': contentType } : {}) },
68
+ });
69
+ if (!res.ok) {
70
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
71
+ }
72
+ const text = await res.text();
73
+ return text || undefined;
74
+ },
75
+ };
76
+ }
77
+ /**
78
+ * `PrometheusStore` wraps Prometheus's read-only HTTP query API (PromQL
79
+ * instant/range queries plus series/label metadata lookups) behind the
80
+ * `NoSqlStore` lifecycle. It performs no writes - Prometheus ingests data
81
+ * by scraping targets, not by client-side pushes.
82
+ */
83
+ class PrometheusStore {
84
+ constructor(options = {}) {
85
+ this.name = 'prometheus';
86
+ this.library = 'fetch';
87
+ this.client = null;
88
+ this.connected = false;
89
+ this.baseURL = options.baseURL ?? exports.DEFAULT_PROMETHEUS_BASE_URL;
90
+ this.injectedClient = options.client;
91
+ this.headers = options.headers;
92
+ }
93
+ // ---------------------------------------------------------------------
94
+ // Connection lifecycle
95
+ // ---------------------------------------------------------------------
96
+ async connect() {
97
+ if (this.connected && this.client) {
98
+ return;
99
+ }
100
+ this.client = this.injectedClient ?? createFetchClient(this.baseURL, this.headers);
101
+ this.connected = true;
102
+ }
103
+ async disconnect() {
104
+ this.client = null;
105
+ this.connected = false;
106
+ }
107
+ isConnected() {
108
+ return this.connected && this.client !== null;
109
+ }
110
+ /** Returns the underlying (internal or injected) HTTP client. */
111
+ getClient() {
112
+ return this.requireClient();
113
+ }
114
+ requireClient() {
115
+ if (!this.client) {
116
+ throw new errors_1.ConnectionError('Not connected to Prometheus', {
117
+ database: 'prometheus',
118
+ host: this.baseURL,
119
+ });
120
+ }
121
+ return this.client;
122
+ }
123
+ async get(path, params, action) {
124
+ const client = this.requireClient();
125
+ try {
126
+ const body = await client.get(path, params);
127
+ return body?.data;
128
+ }
129
+ catch (err) {
130
+ const parent = err instanceof Error ? err : new Error(String(err));
131
+ throw errors_1.DatabaseError.from(parent, {
132
+ message: `Prometheus ${action ?? 'request'} failed: ${parent.message}`,
133
+ });
134
+ }
135
+ }
136
+ // ---------------------------------------------------------------------
137
+ // PromQL query API (read-only)
138
+ // ---------------------------------------------------------------------
139
+ /**
140
+ * Runs a PromQL instant query at a single point in time via
141
+ * `GET /api/v1/query`. Returns the `data` payload (result type + result).
142
+ */
143
+ async instantQuery(promql, time) {
144
+ return this.get('/api/v1/query', { query: promql, time: time === undefined ? undefined : String(time) }, 'instantQuery');
145
+ }
146
+ /**
147
+ * Runs a PromQL range query over `[start, end]` at `step` resolution via
148
+ * `GET /api/v1/query_range`. Returns the `data` payload (matrix result).
149
+ */
150
+ async rangeQuery(promql, options) {
151
+ return this.get('/api/v1/query_range', {
152
+ query: promql,
153
+ start: String(options.start),
154
+ end: String(options.end),
155
+ step: String(options.step),
156
+ }, 'rangeQuery');
157
+ }
158
+ /**
159
+ * Finds series matching one or more PromQL series selectors via
160
+ * `GET /api/v1/series`. Returns the array of matching label sets.
161
+ */
162
+ async series(match) {
163
+ const matches = Array.isArray(match) ? match : [match];
164
+ return this.get('/api/v1/series', { 'match[]': matches }, 'series');
165
+ }
166
+ /**
167
+ * Lists the distinct values of a label via
168
+ * `GET /api/v1/label/<label>/values`. Returns the array of values.
169
+ */
170
+ async labelValues(label) {
171
+ return this.get(`/api/v1/label/${encodeURIComponent(label)}/values`, undefined, 'labelValues');
172
+ }
173
+ }
174
+ exports.PrometheusStore = PrometheusStore;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ /**
3
+ * ProvenDB store implementation.
4
+ *
5
+ * ProvenDB is a MongoDB-compatible database that adds immutable, versioned
6
+ * documents plus cryptographic proofs: every write is captured at a
7
+ * monotonically increasing **version**, and ProvenDB can produce a Merkle
8
+ * proof that a document (or a whole query result) existed at a given version,
9
+ * anchored into a public blockchain. That makes it append-only/auditable on
10
+ * top of a familiar document API.
11
+ *
12
+ * ## HTTP proof API over `fetch`
13
+ *
14
+ * While ProvenDB exposes a Mongo wire protocol, its distinguishing feature -
15
+ * versioned documents and proofs - is surfaced here over its REST/HTTP proof
16
+ * API using the global `fetch` (so `library === 'fetch'`), matching the
17
+ * Prometheus store's injectable-client pattern. This class implements the
18
+ * minimal `NoSqlStore` marker interface plus the shared ledger surface:
19
+ * - `append(collection, data)` -> `POST /collections/<c>/documents`.
20
+ * - `get(collection, id)` -> `GET /collections/<c>/documents/<id>`.
21
+ * - `history(collection, id)` -> `GET .../documents/<id>/versions`.
22
+ * - `verify(collection, id)` -> `POST .../documents/<id>/proof` (returns
23
+ * the Merkle proof + blockchain anchor).
24
+ * - `query(filter)` -> `POST /collections/<c>/query`.
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.ProvendbStore = exports.DEFAULT_PROVENDB_BASE_URL = void 0;
28
+ exports.createProvendbFetchClient = createProvendbFetchClient;
29
+ const errors_1 = require("../../errors");
30
+ /** Default ProvenDB HTTP API base URL. */
31
+ exports.DEFAULT_PROVENDB_BASE_URL = 'http://localhost:8080';
32
+ /** Build a `fetch`-backed JSON client for the given base URL. */
33
+ function createProvendbFetchClient(baseURL, headers) {
34
+ const root = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;
35
+ const json = async (res) => {
36
+ if (!res.ok) {
37
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
38
+ }
39
+ return res.json();
40
+ };
41
+ return {
42
+ async get(path) {
43
+ return json(await fetch(`${root}${path}`, { method: 'GET', headers }));
44
+ },
45
+ async post(path, body) {
46
+ return json(await fetch(`${root}${path}`, {
47
+ method: 'POST',
48
+ headers: { 'Content-Type': 'application/json', ...(headers ?? {}) },
49
+ body: body === undefined ? undefined : JSON.stringify(body),
50
+ }));
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * `ProvendbStore` wraps ProvenDB's HTTP proof/document API behind the shared
56
+ * ledger surface.
57
+ */
58
+ class ProvendbStore {
59
+ constructor(options = {}) {
60
+ this.name = 'provendb';
61
+ this.library = 'fetch';
62
+ this.client = null;
63
+ this.connected = false;
64
+ this.baseURL = options.baseURL ?? exports.DEFAULT_PROVENDB_BASE_URL;
65
+ this.injectedClient = options.client;
66
+ this.headers = options.headers;
67
+ }
68
+ // ---------------------------------------------------------------------
69
+ // Connection lifecycle
70
+ // ---------------------------------------------------------------------
71
+ async connect() {
72
+ if (this.connected && this.client) {
73
+ return;
74
+ }
75
+ this.client = this.injectedClient ?? createProvendbFetchClient(this.baseURL, this.headers);
76
+ this.connected = true;
77
+ }
78
+ async disconnect() {
79
+ this.client = null;
80
+ this.connected = false;
81
+ }
82
+ isConnected() {
83
+ return this.connected && this.client !== null;
84
+ }
85
+ /** Returns the underlying (internal or injected) HTTP client. */
86
+ getClient() {
87
+ return this.requireClient();
88
+ }
89
+ requireClient() {
90
+ if (!this.client) {
91
+ throw new errors_1.ConnectionError('Not connected to ProvenDB', {
92
+ database: 'provendb',
93
+ host: this.baseURL,
94
+ });
95
+ }
96
+ return this.client;
97
+ }
98
+ async call(action, fn) {
99
+ const client = this.requireClient();
100
+ try {
101
+ return await fn(client);
102
+ }
103
+ catch (err) {
104
+ const parent = err instanceof Error ? err : new Error(String(err));
105
+ throw errors_1.DatabaseError.from(parent, { message: `ProvenDB ${action} failed: ${parent.message}` });
106
+ }
107
+ }
108
+ // ---------------------------------------------------------------------
109
+ // Ledger surface
110
+ // ---------------------------------------------------------------------
111
+ /**
112
+ * Insert `data` into `collection` at a new version
113
+ * (`POST /collections/<c>/documents`). Returns the inserted document
114
+ * (including its `_id` and `_version`).
115
+ */
116
+ async append(collection, data) {
117
+ return this.call('append', (client) => client.post(`/collections/${encodeURIComponent(collection)}/documents`, data));
118
+ }
119
+ /** Read the current version of document `id` from `collection`. */
120
+ async get(collection, id) {
121
+ return this.call('get', (client) => client.get(`/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}`));
122
+ }
123
+ /** Return every version of document `id` (`GET .../documents/<id>/versions`). */
124
+ async history(collection, id) {
125
+ return this.call('history', (client) => client.get(`/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}/versions`));
126
+ }
127
+ /**
128
+ * Request a cryptographic proof for document `id`
129
+ * (`POST .../documents/<id>/proof`). The returned object contains the
130
+ * Merkle proof and the public-blockchain anchor that tamper-proofs the
131
+ * document's state at its version.
132
+ */
133
+ async verify(collection, id) {
134
+ return this.call('verify', (client) => client.post(`/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}/proof`));
135
+ }
136
+ /**
137
+ * Run a Mongo-style filter query against `collection`
138
+ * (`POST /collections/<c>/query`). `query` is the Mongo filter document;
139
+ * `options` carries projection/sort/limit and an optional historical
140
+ * `version`.
141
+ */
142
+ async query(collection, query = {}, options) {
143
+ return this.call('query', (client) => client.post(`/collections/${encodeURIComponent(collection)}/query`, { query, options }));
144
+ }
145
+ }
146
+ exports.ProvendbStore = ProvendbStore;
147
+ exports.default = ProvendbStore;