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,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MinioStore = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* MinIO object-storage store.
|
|
6
|
+
*
|
|
7
|
+
* MinIO is a self-hostable, S3-compatible object store. Like Amazon S3 it has
|
|
8
|
+
* no query language, no rows, and no SQL-shaped access pattern — data is
|
|
9
|
+
* opaque objects (byte bodies plus metadata) addressed by a `(bucket, key)`
|
|
10
|
+
* pair, where the "key" is a flat object name that only *looks* like a path
|
|
11
|
+
* (`foo/bar/baz.json`). None of that fits the SQL-shaped `Dialect` interface,
|
|
12
|
+
* so this store implements the minimal `NoSqlStore` marker interface
|
|
13
|
+
* (`src/nosql/store.ts`) and exposes MinIO's own object-level operations
|
|
14
|
+
* directly.
|
|
15
|
+
*
|
|
16
|
+
* Unlike `S3Store` (which uses the AWS SDK v3 command pattern), this store is
|
|
17
|
+
* built on the official `minio` JS client, whose `Minio.Client` exposes
|
|
18
|
+
* method-per-operation (`putObject`, `getObject`, `removeObject`, …). Two of
|
|
19
|
+
* those methods are *stream*-shaped rather than promise-of-value:
|
|
20
|
+
*
|
|
21
|
+
* - `getObject(bucket, key)` resolves to a readable byte stream. This store
|
|
22
|
+
* collects that stream to completion into a single `Buffer` so callers get
|
|
23
|
+
* the whole object body without wiring up stream plumbing themselves.
|
|
24
|
+
* - `listObjects(bucket, prefix, recursive)` returns an object stream that
|
|
25
|
+
* emits one item per object. This store collects that stream into an array
|
|
26
|
+
* of object *names* (`item.name`).
|
|
27
|
+
*
|
|
28
|
+
* The `minio` package is loaded lazily inside `connect()` (via `require`)
|
|
29
|
+
* rather than a top-level import so that importing this module doesn't
|
|
30
|
+
* hard-require `minio` unless a MinIO store is actually connected — and so
|
|
31
|
+
* tests can inject a pre-built mock `client` and never load the driver at all.
|
|
32
|
+
*/
|
|
33
|
+
const errors_1 = require("../../errors");
|
|
34
|
+
/**
|
|
35
|
+
* MinIO store, implementing the minimal `NoSqlStore` marker interface. Unlike
|
|
36
|
+
* the SQL dialects there is no `query(sql)` — MinIO's operations are
|
|
37
|
+
* object-shaped and that shape is preserved here rather than forced into a
|
|
38
|
+
* SQL string.
|
|
39
|
+
*/
|
|
40
|
+
class MinioStore {
|
|
41
|
+
constructor(options = {}) {
|
|
42
|
+
this.name = 'minio';
|
|
43
|
+
this.library = 'minio';
|
|
44
|
+
this.client = null;
|
|
45
|
+
this.connected = false;
|
|
46
|
+
this.options = options;
|
|
47
|
+
}
|
|
48
|
+
// ---------------------------------------------------------------------
|
|
49
|
+
// NoSqlStore lifecycle
|
|
50
|
+
// ---------------------------------------------------------------------
|
|
51
|
+
async connect() {
|
|
52
|
+
try {
|
|
53
|
+
if (this.options.client) {
|
|
54
|
+
// A pre-built client was injected (mock or custom). Use it directly
|
|
55
|
+
// and don't require the driver at all.
|
|
56
|
+
this.client = this.options.client;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const Minio = require('minio');
|
|
60
|
+
this.client = new Minio.Client({
|
|
61
|
+
endPoint: this.options.endPoint,
|
|
62
|
+
port: this.options.port,
|
|
63
|
+
useSSL: this.options.useSSL,
|
|
64
|
+
accessKey: this.options.accessKey,
|
|
65
|
+
secretKey: this.options.secretKey,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
this.connected = true;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
this.connected = false;
|
|
72
|
+
this.client = null;
|
|
73
|
+
throw new errors_1.ConnectionError(`Failed to connect to MinIO: ${err instanceof Error ? err.message : String(err)}`, { parent: err instanceof Error ? err : undefined });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async disconnect() {
|
|
77
|
+
// The MinIO client is stateless (no persistent socket to close), so
|
|
78
|
+
// disconnecting just drops the reference.
|
|
79
|
+
this.client = null;
|
|
80
|
+
this.connected = false;
|
|
81
|
+
}
|
|
82
|
+
isConnected() {
|
|
83
|
+
return this.connected && this.client !== null;
|
|
84
|
+
}
|
|
85
|
+
/** Returns the underlying `Minio.Client` (loosely typed) for anything not wrapped here. */
|
|
86
|
+
getClient() {
|
|
87
|
+
return this.requireClient();
|
|
88
|
+
}
|
|
89
|
+
requireClient() {
|
|
90
|
+
if (!this.client || !this.connected) {
|
|
91
|
+
throw new errors_1.ConnectionError('MinIO client is not connected. Call connect() first.');
|
|
92
|
+
}
|
|
93
|
+
return this.client;
|
|
94
|
+
}
|
|
95
|
+
/** Wraps a driver failure in a `DatabaseError`, preserving the original error. */
|
|
96
|
+
wrapError(action, err) {
|
|
97
|
+
const parent = err instanceof Error ? err : new Error(String(err));
|
|
98
|
+
const name = parent.name ? ` (${parent.name})` : '';
|
|
99
|
+
return new errors_1.DatabaseError(`MinIO ${action} failed${name}: ${parent.message}`, {
|
|
100
|
+
parent,
|
|
101
|
+
original: parent.message,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// ---------------------------------------------------------------------
|
|
105
|
+
// Object operations
|
|
106
|
+
// ---------------------------------------------------------------------
|
|
107
|
+
/** `putObject` — store an object's body (and optional metadata) under `bucket`/`key`. */
|
|
108
|
+
async putObject(bucket, key, data, options = {}) {
|
|
109
|
+
const client = this.requireClient();
|
|
110
|
+
try {
|
|
111
|
+
// The modern `minio` client resolves to an `UploadedObjectInfo`
|
|
112
|
+
// (`{ etag, versionId }`). `size`/`metadata` are optional trailing args.
|
|
113
|
+
const result = await client.putObject(bucket, key, data, options.size, options.metadata);
|
|
114
|
+
return { etag: result?.etag, versionId: result?.versionId };
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
throw this.wrapError(`putObject on '${bucket}/${key}'`, err);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* `getObject` — fetch an object. `Minio.Client.getObject` resolves to a
|
|
122
|
+
* readable *byte stream*; this method collects that stream to completion
|
|
123
|
+
* into a single `Buffer` so callers get the whole body without wiring up
|
|
124
|
+
* stream plumbing. Optionally attaches a companion `statObject` result.
|
|
125
|
+
*/
|
|
126
|
+
async getObject(bucket, key) {
|
|
127
|
+
const client = this.requireClient();
|
|
128
|
+
try {
|
|
129
|
+
const stream = await client.getObject(bucket, key);
|
|
130
|
+
const body = await this.collectStream(stream);
|
|
131
|
+
return { body };
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
throw this.wrapError(`getObject on '${bucket}/${key}'`, err);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** `removeObject` — delete an object. */
|
|
138
|
+
async removeObject(bucket, key) {
|
|
139
|
+
const client = this.requireClient();
|
|
140
|
+
try {
|
|
141
|
+
await client.removeObject(bucket, key);
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
throw this.wrapError(`removeObject on '${bucket}/${key}'`, err);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* `listObjects` — list objects in `bucket`, optionally restricted to those
|
|
149
|
+
* whose name starts with `prefix`. `Minio.Client.listObjects` returns an
|
|
150
|
+
* *object stream* that emits one item per object; this method collects that
|
|
151
|
+
* stream into an array of object *names* (`item.name`). Listing is recursive
|
|
152
|
+
* so nested "path"-style keys are all returned.
|
|
153
|
+
*/
|
|
154
|
+
async listObjects(bucket, prefix) {
|
|
155
|
+
const client = this.requireClient();
|
|
156
|
+
try {
|
|
157
|
+
const stream = client.listObjects(bucket, prefix ?? '', true);
|
|
158
|
+
const items = await this.collectObjectStream(stream);
|
|
159
|
+
return items
|
|
160
|
+
.map((item) => item?.name ?? item?.prefix)
|
|
161
|
+
.filter((name) => typeof name === 'string');
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
throw this.wrapError(`listObjects on '${bucket}'`, err);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** `statObject` — fetch an object's metadata without its body. */
|
|
168
|
+
async statObject(bucket, key) {
|
|
169
|
+
const client = this.requireClient();
|
|
170
|
+
try {
|
|
171
|
+
const stat = await client.statObject(bucket, key);
|
|
172
|
+
return {
|
|
173
|
+
size: stat?.size,
|
|
174
|
+
etag: stat?.etag,
|
|
175
|
+
lastModified: stat?.lastModified,
|
|
176
|
+
metaData: stat?.metaData,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
throw this.wrapError(`statObject on '${bucket}/${key}'`, err);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** `makeBucket` — create a bucket, optionally in a specific `region`. */
|
|
184
|
+
async makeBucket(bucket, region) {
|
|
185
|
+
const client = this.requireClient();
|
|
186
|
+
try {
|
|
187
|
+
if (region === undefined) {
|
|
188
|
+
await client.makeBucket(bucket);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
await client.makeBucket(bucket, region);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
throw this.wrapError(`makeBucket '${bucket}'`, err);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/** `bucketExists` — whether a bucket exists. */
|
|
199
|
+
async bucketExists(bucket) {
|
|
200
|
+
const client = this.requireClient();
|
|
201
|
+
try {
|
|
202
|
+
return Boolean(await client.bucketExists(bucket));
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
throw this.wrapError(`bucketExists '${bucket}'`, err);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// ---------------------------------------------------------------------
|
|
209
|
+
// Stream collection helpers
|
|
210
|
+
// ---------------------------------------------------------------------
|
|
211
|
+
/**
|
|
212
|
+
* Collect a readable byte stream into a single `Buffer`. Supports both
|
|
213
|
+
* Node.js event-emitter streams (`.on('data'|'end'|'error')`) and async
|
|
214
|
+
* iterables (`for await`), so a test can inject either shape.
|
|
215
|
+
*/
|
|
216
|
+
async collectStream(stream) {
|
|
217
|
+
if (stream && typeof stream.on === 'function') {
|
|
218
|
+
return new Promise((resolve, reject) => {
|
|
219
|
+
const chunks = [];
|
|
220
|
+
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
|
221
|
+
stream.on('end', () => resolve(Buffer.concat(chunks)));
|
|
222
|
+
stream.on('error', (err) => reject(err));
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (stream && typeof stream[Symbol.asyncIterator] === 'function') {
|
|
226
|
+
const chunks = [];
|
|
227
|
+
for await (const chunk of stream) {
|
|
228
|
+
chunks.push(Buffer.from(chunk));
|
|
229
|
+
}
|
|
230
|
+
return Buffer.concat(chunks);
|
|
231
|
+
}
|
|
232
|
+
// Nothing stream-like (e.g. already a Buffer/string) — coerce to Buffer.
|
|
233
|
+
if (Buffer.isBuffer(stream))
|
|
234
|
+
return stream;
|
|
235
|
+
if (stream == null)
|
|
236
|
+
return Buffer.alloc(0);
|
|
237
|
+
return Buffer.from(stream);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Collect an object stream into an array of emitted items. Supports both
|
|
241
|
+
* Node.js event-emitter streams and async iterables.
|
|
242
|
+
*/
|
|
243
|
+
async collectObjectStream(stream) {
|
|
244
|
+
if (stream && typeof stream.on === 'function') {
|
|
245
|
+
return new Promise((resolve, reject) => {
|
|
246
|
+
const items = [];
|
|
247
|
+
stream.on('data', (item) => items.push(item));
|
|
248
|
+
stream.on('end', () => resolve(items));
|
|
249
|
+
stream.on('error', (err) => reject(err));
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (stream && typeof stream[Symbol.asyncIterator] === 'function') {
|
|
253
|
+
const items = [];
|
|
254
|
+
for await (const item of stream) {
|
|
255
|
+
items.push(item);
|
|
256
|
+
}
|
|
257
|
+
return items;
|
|
258
|
+
}
|
|
259
|
+
if (Array.isArray(stream))
|
|
260
|
+
return stream;
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
exports.MinioStore = MinioStore;
|
|
265
|
+
exports.default = MinioStore;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Momento Cache store implementation.
|
|
4
|
+
*
|
|
5
|
+
* Momento is a serverless, globally-available cache accessed through the
|
|
6
|
+
* `@gomomento/sdk` `CacheClient`. Every operation is scoped to a named
|
|
7
|
+
* cache. Momento has no SQL surface and no arbitrary key enumeration, so
|
|
8
|
+
* this class implements the minimal `NoSqlStore` marker interface and
|
|
9
|
+
* exposes an edge-KV `get`/`set`/`del`/`list`/`incr` surface mapped onto the
|
|
10
|
+
* Momento client.
|
|
11
|
+
*
|
|
12
|
+
* ## Driver
|
|
13
|
+
*
|
|
14
|
+
* Uses `@gomomento/sdk` (`CacheClient`). The driver is loaded lazily inside
|
|
15
|
+
* `connect()` (or supplied pre-built via the `client` option) so importing
|
|
16
|
+
* this module never requires `@gomomento/sdk` to be installed unless a store
|
|
17
|
+
* is actually connected. Tests inject a mock `client`.
|
|
18
|
+
*
|
|
19
|
+
* ## Method mapping
|
|
20
|
+
*
|
|
21
|
+
* - `get(key)` -> `client.get(cacheName, key)`
|
|
22
|
+
* - `set(k,v,opts)` -> `client.set(cacheName, key, value, { ttl })`
|
|
23
|
+
* - `del(key)` -> `client.delete(cacheName, key)`
|
|
24
|
+
* - `list(name?)` -> `client.listFetch(cacheName, listName)`. Momento has
|
|
25
|
+
* no key-scan, so `list()` fetches the elements of a Momento *list*
|
|
26
|
+
* (`name` is the list name, defaulting to `defaultListName`) rather than
|
|
27
|
+
* enumerating cache keys.
|
|
28
|
+
* - `incr(k,by?)` -> `client.increment(cacheName, key, by)`
|
|
29
|
+
*
|
|
30
|
+
* ## Serialization
|
|
31
|
+
*
|
|
32
|
+
* String values are stored verbatim; every other value is `JSON.stringify`'d
|
|
33
|
+
* before being written.
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.MomentoStore = void 0;
|
|
37
|
+
const errors_1 = require("../../errors");
|
|
38
|
+
function serialize(value) {
|
|
39
|
+
return typeof value === 'string' ? value : JSON.stringify(value);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `MomentoStore` wraps a Momento `CacheClient` behind the `NoSqlStore`
|
|
43
|
+
* lifecycle and an edge-KV `get`/`set`/`del`/`list`/`incr` surface.
|
|
44
|
+
*/
|
|
45
|
+
class MomentoStore {
|
|
46
|
+
constructor(options = {}) {
|
|
47
|
+
this.name = 'momento';
|
|
48
|
+
this.library = '@gomomento/sdk';
|
|
49
|
+
this.client = null;
|
|
50
|
+
this.connected = false;
|
|
51
|
+
this.options = options;
|
|
52
|
+
}
|
|
53
|
+
get cacheName() {
|
|
54
|
+
return this.options.cacheName ?? '';
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------
|
|
57
|
+
// Connection lifecycle
|
|
58
|
+
// ---------------------------------------------------------------------
|
|
59
|
+
async connect() {
|
|
60
|
+
if (this.connected && this.client) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
if (this.options.client) {
|
|
65
|
+
this.client = this.options.client;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
69
|
+
const mod = require('@gomomento/sdk');
|
|
70
|
+
const CacheClient = mod.CacheClient ?? mod.default?.CacheClient ?? mod.default;
|
|
71
|
+
this.client = new CacheClient({
|
|
72
|
+
configuration: this.options.configuration,
|
|
73
|
+
credentialProvider: this.options.credentialProvider,
|
|
74
|
+
defaultTtlSeconds: this.options.defaultTtlSeconds,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
this.connected = true;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
this.client = null;
|
|
81
|
+
this.connected = false;
|
|
82
|
+
throw wrapConnectionError(err, this.cacheName);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async disconnect() {
|
|
86
|
+
this.client = null;
|
|
87
|
+
this.connected = false;
|
|
88
|
+
}
|
|
89
|
+
isConnected() {
|
|
90
|
+
return this.connected && this.client !== null;
|
|
91
|
+
}
|
|
92
|
+
/** Returns the underlying Momento `CacheClient` for anything not wrapped here. */
|
|
93
|
+
getClient() {
|
|
94
|
+
return this.requireClient();
|
|
95
|
+
}
|
|
96
|
+
requireClient() {
|
|
97
|
+
if (!this.client) {
|
|
98
|
+
throw new errors_1.ConnectionError('Not connected to Momento', {
|
|
99
|
+
database: 'momento',
|
|
100
|
+
host: this.cacheName,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return this.client;
|
|
104
|
+
}
|
|
105
|
+
// ---------------------------------------------------------------------
|
|
106
|
+
// Key-value operations
|
|
107
|
+
// ---------------------------------------------------------------------
|
|
108
|
+
/** Read a key from the configured cache. Returns the Momento response object. */
|
|
109
|
+
async get(key) {
|
|
110
|
+
const client = this.requireClient();
|
|
111
|
+
try {
|
|
112
|
+
return await client.get(this.cacheName, key);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
throw wrapDatabaseError(err, 'GET');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Write `value` under `key`. Strings are stored verbatim; other values are
|
|
120
|
+
* JSON-serialized. `options.ttl` sets a per-item TTL in seconds.
|
|
121
|
+
*/
|
|
122
|
+
async set(key, value, options = {}) {
|
|
123
|
+
const client = this.requireClient();
|
|
124
|
+
try {
|
|
125
|
+
return await client.set(this.cacheName, key, serialize(value), options.ttl !== undefined ? { ttl: options.ttl } : undefined);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
throw wrapDatabaseError(err, 'SET');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** Delete a key from the configured cache. */
|
|
132
|
+
async del(key) {
|
|
133
|
+
const client = this.requireClient();
|
|
134
|
+
try {
|
|
135
|
+
return await client.delete(this.cacheName, key);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
throw wrapDatabaseError(err, 'DEL');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Fetch the elements of a Momento list. Momento cannot enumerate cache
|
|
143
|
+
* keys, so `prefix`/`listName` names a list; defaults to
|
|
144
|
+
* `defaultListName`.
|
|
145
|
+
*/
|
|
146
|
+
async list(listName) {
|
|
147
|
+
const client = this.requireClient();
|
|
148
|
+
try {
|
|
149
|
+
return await client.listFetch(this.cacheName, listName ?? this.options.defaultListName ?? '');
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
throw wrapDatabaseError(err, 'LIST');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Atomically increment the numeric value at `key` by `by` (default `1`). */
|
|
156
|
+
async incr(key, by = 1) {
|
|
157
|
+
const client = this.requireClient();
|
|
158
|
+
try {
|
|
159
|
+
return await client.increment(this.cacheName, key, by);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
throw wrapDatabaseError(err, 'INCR');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
exports.MomentoStore = MomentoStore;
|
|
167
|
+
function wrapConnectionError(err, host) {
|
|
168
|
+
const parent = err instanceof Error ? err : new Error(String(err));
|
|
169
|
+
return new errors_1.ConnectionError(`Unable to connect to Momento: ${parent.message}`, {
|
|
170
|
+
parent,
|
|
171
|
+
database: 'momento',
|
|
172
|
+
host,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function wrapDatabaseError(err, action) {
|
|
176
|
+
const parent = err instanceof Error ? err : new Error(String(err));
|
|
177
|
+
return errors_1.DatabaseError.from(parent, { message: `Momento ${action} failed: ${parent.message}` });
|
|
178
|
+
}
|
|
179
|
+
exports.default = MomentoStore;
|