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.
- package/CHANGELOG.md +1111 -0
- package/LICENSE +21 -0
- package/README.md +573 -0
- package/dist/audit/history-query.js +180 -0
- package/dist/audit/index.js +23 -0
- package/dist/audit/logger.js +236 -0
- package/dist/cache/cache-manager.js +84 -0
- package/dist/cache/index.js +16 -0
- package/dist/cache/redis-cluster-cache.js +557 -0
- package/dist/cli.js +2200 -0
- package/dist/compliance/audit-trail.js +68 -0
- package/dist/compliance/backup-verification.js +685 -0
- package/dist/compliance/breach-detector.js +505 -0
- package/dist/compliance/consent-record.js +227 -0
- package/dist/compliance/consent-versioning.js +331 -0
- package/dist/compliance/cross-border-log.js +530 -0
- package/dist/compliance/data-classifier.js +258 -0
- package/dist/compliance/data-lineage.js +565 -0
- package/dist/compliance/data-masker.js +303 -0
- package/dist/compliance/data-portability.js +265 -0
- package/dist/compliance/data-retention.js +195 -0
- package/dist/compliance/dsar-workflow.js +342 -0
- package/dist/compliance/field-encryption.js +223 -0
- package/dist/compliance/immutable-record.js +148 -0
- package/dist/compliance/index.js +260 -0
- package/dist/compliance/privacy-impact-assessment.js +364 -0
- package/dist/compliance/pseudonymization.js +269 -0
- package/dist/compliance/query-firewall.js +1182 -0
- package/dist/compliance/rate-limiter.js +580 -0
- package/dist/compliance/right-to-erasure.js +117 -0
- package/dist/compliance/row-level-security.js +246 -0
- package/dist/compliance/security-decorator.js +574 -0
- package/dist/compliance/security-monitor.js +525 -0
- package/dist/compliance/sensitive-data-discovery.js +476 -0
- package/dist/compliance/session-isolation.js +472 -0
- package/dist/compliance/tls-enforcer.js +108 -0
- package/dist/compliance/worm-storage.js +712 -0
- package/dist/connection-manager.js +198 -0
- package/dist/connection-pool.js +519 -0
- package/dist/decorators/audit.js +136 -0
- package/dist/decorators/belongs-to-many.js +115 -0
- package/dist/decorators/belongs-to.js +115 -0
- package/dist/decorators/check.js +435 -0
- package/dist/decorators/collate.js +329 -0
- package/dist/decorators/comment.js +205 -0
- package/dist/decorators/database-settings.js +236 -0
- package/dist/decorators/default.js +244 -0
- package/dist/decorators/encryption.js +235 -0
- package/dist/decorators/engine.js +97 -0
- package/dist/decorators/fk-constraints.js +594 -0
- package/dist/decorators/foreign-table.js +136 -0
- package/dist/decorators/generated.js +274 -0
- package/dist/decorators/has-many.js +127 -0
- package/dist/decorators/has-one.js +116 -0
- package/dist/decorators/hstore.js +129 -0
- package/dist/decorators/index.js +355 -0
- package/dist/decorators/json-column.js +83 -0
- package/dist/decorators/jsonb.js +101 -0
- package/dist/decorators/orm-decorators.js +425 -0
- package/dist/decorators/permissions.js +294 -0
- package/dist/decorators/procedure.js +210 -0
- package/dist/decorators/query-options.js +556 -0
- package/dist/decorators/range.js +167 -0
- package/dist/decorators/set-column.js +83 -0
- package/dist/decorators/spatial.js +114 -0
- package/dist/decorators/storage.js +580 -0
- package/dist/decorators/timezone.js +512 -0
- package/dist/decorators/trigger.js +90 -0
- package/dist/decorators/uuid.js +135 -0
- package/dist/decorators/view.js +258 -0
- package/dist/diagrams/chen-diagram.js +354 -0
- package/dist/diagrams/class-diagram.js +384 -0
- package/dist/diagrams/dependency-diagram.js +432 -0
- package/dist/diagrams/er-diagram.js +605 -0
- package/dist/diagrams/flow-diagram.js +394 -0
- package/dist/diagrams/gantt-diagram.js +411 -0
- package/dist/diagrams/index-diagram.js +353 -0
- package/dist/diagrams/index.js +184 -0
- package/dist/diagrams/migration-diagram.js +316 -0
- package/dist/diagrams/model-diagram.js +616 -0
- package/dist/diagrams/package-diagram.js +376 -0
- package/dist/diagrams/palette.js +85 -0
- package/dist/diagrams/relational-diagram.js +455 -0
- package/dist/diagrams/schemadoc-diagram.js +309 -0
- package/dist/diagrams/sequence-diagram.js +307 -0
- package/dist/diagrams/state-diagram.js +344 -0
- package/dist/diagrams/svg-dom.js +111 -0
- package/dist/diagrams/tree-diagram.js +250 -0
- package/dist/dialects/clickhouse/index.js +1742 -0
- package/dist/dialects/cockroachdb/index.js +4677 -0
- package/dist/dialects/cratedb/index.js +441 -0
- package/dist/dialects/databricks/index.js +517 -0
- package/dist/dialects/db2/index.js +2225 -0
- package/dist/dialects/dialect.js +720 -0
- package/dist/dialects/duckdb/index.js +2014 -0
- package/dist/dialects/exasol/index.js +357 -0
- package/dist/dialects/firebird/index.js +495 -0
- package/dist/dialects/greenplum/index.js +457 -0
- package/dist/dialects/hana/index.js +1741 -0
- package/dist/dialects/mariadb/index.js +3590 -0
- package/dist/dialects/mssql/index.js +2296 -0
- package/dist/dialects/mysql/index.js +4058 -0
- package/dist/dialects/oracle/index.js +2999 -0
- package/dist/dialects/postgres/index.js +5319 -0
- package/dist/dialects/query-stream-helper.js +152 -0
- package/dist/dialects/questdb/index.js +433 -0
- package/dist/dialects/redshift/index.js +2277 -0
- package/dist/dialects/singlestore/index.js +354 -0
- package/dist/dialects/snowflake/index.js +2082 -0
- package/dist/dialects/spanner/index.js +1768 -0
- package/dist/dialects/sqlite/index.js +3382 -0
- package/dist/dialects/tidb/index.js +377 -0
- package/dist/dialects/timescaledb/index.js +164 -0
- package/dist/dialects/trino/index.js +420 -0
- package/dist/dialects/turso/index.js +227 -0
- package/dist/dialects/vertica/index.js +317 -0
- package/dist/dialects/yugabytedb/index.js +424 -0
- package/dist/errors/index.js +472 -0
- package/dist/errors/utils.js +340 -0
- package/dist/errors.js +21 -0
- package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
- package/dist/extensions/catalog/mssql-features.js +147 -0
- package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
- package/dist/extensions/catalog/oracle-db2-features.js +196 -0
- package/dist/extensions/catalog/postgres-extensions.js +516 -0
- package/dist/extensions/index.js +71 -0
- package/dist/extensions/types.js +13 -0
- package/dist/foreign-data.js +173 -0
- package/dist/hooks/hooks-manager.js +350 -0
- package/dist/hooks/index.js +37 -0
- package/dist/index.js +463 -0
- package/dist/logging.js +335 -0
- package/dist/migrations/index.js +40 -0
- package/dist/migrations/migration.js +196 -0
- package/dist/migrations/migrator.js +411 -0
- package/dist/migrations/prormmigration.js +275 -0
- package/dist/migrations/query-interface.js +435 -0
- package/dist/migrations/seeder.js +353 -0
- package/dist/models/associations.js +852 -0
- package/dist/models/constraints.js +288 -0
- package/dist/models/data-types.js +2518 -0
- package/dist/models/decorators.js +445 -0
- package/dist/models/index.js +33 -0
- package/dist/models/indexes.js +531 -0
- package/dist/models/methods.js +382 -0
- package/dist/models/model-manager.js +103 -0
- package/dist/models/model.js +5349 -0
- package/dist/models/operators.js +67 -0
- package/dist/models/scopes.js +189 -0
- package/dist/models/typescript-types.js +26 -0
- package/dist/nosql/aerospike/index.js +205 -0
- package/dist/nosql/allegrograph/index.js +169 -0
- package/dist/nosql/arangodb/index.js +364 -0
- package/dist/nosql/azure-blob/index.js +206 -0
- package/dist/nosql/beanstalkd/index.js +231 -0
- package/dist/nosql/beequeue/index.js +210 -0
- package/dist/nosql/bigchaindb/index.js +195 -0
- package/dist/nosql/bigtable/index.js +224 -0
- package/dist/nosql/blazegraph/index.js +173 -0
- package/dist/nosql/bullmq/index.js +191 -0
- package/dist/nosql/cassandra/index.js +174 -0
- package/dist/nosql/chroma/index.js +190 -0
- package/dist/nosql/cloudflare-kv/index.js +220 -0
- package/dist/nosql/coherence/index.js +200 -0
- package/dist/nosql/cosmosdb/index.js +157 -0
- package/dist/nosql/couchbase/index.js +213 -0
- package/dist/nosql/dax/index.js +212 -0
- package/dist/nosql/deno-kv/index.js +206 -0
- package/dist/nosql/dgraph/index.js +171 -0
- package/dist/nosql/doris/index.js +169 -0
- package/dist/nosql/druid/index.js +162 -0
- package/dist/nosql/dynamodb/index.js +937 -0
- package/dist/nosql/elasticsearch/index.js +377 -0
- package/dist/nosql/etcd/index.js +502 -0
- package/dist/nosql/eventhubs/index.js +213 -0
- package/dist/nosql/eventstore/index.js +254 -0
- package/dist/nosql/faunadb/index.js +188 -0
- package/dist/nosql/firestore/index.js +177 -0
- package/dist/nosql/fluree/index.js +148 -0
- package/dist/nosql/fuseki/index.js +170 -0
- package/dist/nosql/gcs/index.js +172 -0
- package/dist/nosql/gearman/index.js +160 -0
- package/dist/nosql/geode/index.js +196 -0
- package/dist/nosql/graphdb/index.js +169 -0
- package/dist/nosql/graylog/index.js +188 -0
- package/dist/nosql/gridgain/index.js +171 -0
- package/dist/nosql/hazelcast/index.js +162 -0
- package/dist/nosql/hbase/index.js +230 -0
- package/dist/nosql/ignite/index.js +173 -0
- package/dist/nosql/immudb/index.js +184 -0
- package/dist/nosql/index.js +232 -0
- package/dist/nosql/infinispan/index.js +200 -0
- package/dist/nosql/influxdb/index.js +0 -0
- package/dist/nosql/kafka/index.js +234 -0
- package/dist/nosql/keyspaces/index.js +189 -0
- package/dist/nosql/kinesis/index.js +253 -0
- package/dist/nosql/leveldb/index.js +153 -0
- package/dist/nosql/lmdb/index.js +160 -0
- package/dist/nosql/loki/index.js +201 -0
- package/dist/nosql/marklogic/index.js +204 -0
- package/dist/nosql/materialize/index.js +145 -0
- package/dist/nosql/meilisearch/index.js +154 -0
- package/dist/nosql/memcached/index.js +223 -0
- package/dist/nosql/milvus/index.js +410 -0
- package/dist/nosql/minio/index.js +265 -0
- package/dist/nosql/momento/index.js +179 -0
- package/dist/nosql/mongodb/index.js +461 -0
- package/dist/nosql/nats/index.js +247 -0
- package/dist/nosql/nedb/index.js +164 -0
- package/dist/nosql/neo4j/index.js +450 -0
- package/dist/nosql/neptune/index.js +470 -0
- package/dist/nosql/nsq/index.js +200 -0
- package/dist/nosql/opensearch/index.js +186 -0
- package/dist/nosql/orientdb/index.js +175 -0
- package/dist/nosql/papertrail/index.js +200 -0
- package/dist/nosql/pinecone/index.js +0 -0
- package/dist/nosql/pinot/index.js +133 -0
- package/dist/nosql/pouchdb/index.js +172 -0
- package/dist/nosql/prometheus/index.js +174 -0
- package/dist/nosql/provendb/index.js +147 -0
- package/dist/nosql/pubsub/index.js +187 -0
- package/dist/nosql/pulsar/index.js +232 -0
- package/dist/nosql/qdrant/index.js +295 -0
- package/dist/nosql/qldb/index.js +192 -0
- package/dist/nosql/r2/index.js +281 -0
- package/dist/nosql/rabbitmq/index.js +237 -0
- package/dist/nosql/ravendb/index.js +175 -0
- package/dist/nosql/redis/index.js +607 -0
- package/dist/nosql/redpanda/index.js +237 -0
- package/dist/nosql/resque/index.js +203 -0
- package/dist/nosql/rethinkdb/index.js +232 -0
- package/dist/nosql/rocksdb/index.js +152 -0
- package/dist/nosql/rockset/index.js +126 -0
- package/dist/nosql/s3/index.js +298 -0
- package/dist/nosql/scylladb/index.js +178 -0
- package/dist/nosql/signoz/index.js +227 -0
- package/dist/nosql/sns/index.js +201 -0
- package/dist/nosql/solr/index.js +231 -0
- package/dist/nosql/splunk/index.js +227 -0
- package/dist/nosql/sqs/index.js +246 -0
- package/dist/nosql/stardog/index.js +169 -0
- package/dist/nosql/starrocks/index.js +170 -0
- package/dist/nosql/store.js +2 -0
- package/dist/nosql/sumologic/index.js +213 -0
- package/dist/nosql/surrealdb/index.js +179 -0
- package/dist/nosql/terminusdb/index.js +151 -0
- package/dist/nosql/tigergraph/index.js +469 -0
- package/dist/nosql/typesense/index.js +148 -0
- package/dist/nosql/unqlite/index.js +157 -0
- package/dist/nosql/upstash/index.js +167 -0
- package/dist/nosql/vercel-kv/index.js +166 -0
- package/dist/nosql/victoriametrics/index.js +213 -0
- package/dist/nosql/virtuoso/index.js +169 -0
- package/dist/nosql/weaviate/index.js +276 -0
- package/dist/operators/index.js +108 -0
- package/dist/operators.js +2690 -0
- package/dist/prisma-migrate/index.js +38 -0
- package/dist/prisma-migrate/migration-generator.js +125 -0
- package/dist/prisma-migrate/model-generator.js +172 -0
- package/dist/prisma-migrate/relations.js +100 -0
- package/dist/prisma-migrate/schema-parser.js +167 -0
- package/dist/prisma-migrate/type-mapper.js +40 -0
- package/dist/prorm.js +6832 -0
- package/dist/query-builders/cte-builder.js +80 -0
- package/dist/query-builders/functions/aggregate.js +390 -0
- package/dist/query-builders/functions/conditional.js +503 -0
- package/dist/query-builders/functions/datetime.js +695 -0
- package/dist/query-builders/functions/fulltext.js +439 -0
- package/dist/query-builders/functions/index.js +93 -0
- package/dist/query-builders/functions/json.js +427 -0
- package/dist/query-builders/functions/math.js +399 -0
- package/dist/query-builders/functions/string.js +518 -0
- package/dist/query-builders/functions/window.js +328 -0
- package/dist/query-builders/include-builder.js +323 -0
- package/dist/query-builders/index-expression-builder.js +242 -0
- package/dist/query-builders/index.js +161 -0
- package/dist/query-builders/insert-builder.js +164 -0
- package/dist/query-builders/model-helpers.js +38 -0
- package/dist/query-builders/order-limit-builder.js +239 -0
- package/dist/query-builders/sql-compiler.js +2040 -0
- package/dist/query-builders/subquery-builder.js +152 -0
- package/dist/query-builders/update-builder.js +182 -0
- package/dist/query-builders/view-builder.js +218 -0
- package/dist/query-builders/where-builder.js +1532 -0
- package/dist/query-interface.js +622 -0
- package/dist/query-optimizers/batch-optimizer.js +426 -0
- package/dist/query-optimizers/explain-plans.js +415 -0
- package/dist/query-optimizers/index.js +51 -0
- package/dist/query-optimizers/prepared-statement-cache.js +423 -0
- package/dist/query-optimizers/query-hints.js +438 -0
- package/dist/query-optimizers/query-optimizer.js +278 -0
- package/dist/query-optimizers/slow-query-logger.js +271 -0
- package/dist/replica-manager.js +507 -0
- package/dist/schema/index.js +15 -0
- package/dist/schema/migration-generator.js +374 -0
- package/dist/schema/schema-differ.js +549 -0
- package/dist/schema/types.js +6 -0
- package/dist/sql-constants.js +300 -0
- package/dist/sqlite-advanced.js +1047 -0
- package/dist/streams/index.js +12 -0
- package/dist/streams/transforms.js +178 -0
- package/dist/transaction.js +456 -0
- package/dist/types/index.js +180 -0
- package/dist/user-management.js +127 -0
- package/dist/utils/date.js +300 -0
- package/dist/utils/index.js +1079 -0
- package/dist/utils/string.js +161 -0
- package/dist/validators/index.js +19 -0
- package/dist/validators/validator.js +911 -0
- 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;
|