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,204 @@
1
+ "use strict";
2
+ /**
3
+ * MarkLogic store implementation for the Prorm NoSQL layer.
4
+ *
5
+ * MarkLogic is a multi-model database (document, graph/RDF triples, search,
6
+ * relational views) where documents are addressed by an opaque URI. It does
7
+ * not fit the SQL-shaped `Dialect` interface, so this class implements the
8
+ * minimal `NoSqlStore` marker interface for connection lifecycle and exposes
9
+ * MarkLogic's real `documents.write/read/remove` plus `documents.query` API
10
+ * through a small document-CRUD convenience layer. Collection + id are mapped
11
+ * to a URI of the form `/<collection>/<id>.json`.
12
+ *
13
+ * Uses the official `marklogic` driver. That driver is an optional peer
14
+ * dependency and is loaded lazily inside `connect()` so importing this module
15
+ * never requires it to be installed. Tests inject a pre-built mock `client`
16
+ * (and `queryBuilder`) via options, which bypasses the lazy `require`
17
+ * entirely - no real driver and no network are needed.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.MarkLogicStore = void 0;
21
+ const errors_1 = require("../../errors");
22
+ class MarkLogicStore {
23
+ constructor(options = {}) {
24
+ this.name = 'marklogic';
25
+ this.library = 'marklogic';
26
+ this.client = null;
27
+ this.qb = null;
28
+ this.connected = false;
29
+ this.options = options;
30
+ }
31
+ // ---------------------------------------------------------------------
32
+ // Connection lifecycle
33
+ // ---------------------------------------------------------------------
34
+ async connect() {
35
+ if (this.connected && this.client) {
36
+ return;
37
+ }
38
+ try {
39
+ if (this.options.client) {
40
+ this.client = this.options.client;
41
+ this.qb = this.options.queryBuilder ?? this.tryRequireQueryBuilder();
42
+ }
43
+ else {
44
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
45
+ const marklogic = require('marklogic');
46
+ this.client = marklogic.createDatabaseClient({
47
+ host: this.options.host,
48
+ port: this.options.port,
49
+ user: this.options.user,
50
+ password: this.options.password,
51
+ authType: this.options.authType,
52
+ database: this.options.database,
53
+ });
54
+ this.qb = this.options.queryBuilder ?? marklogic.queryBuilder;
55
+ }
56
+ this.connected = true;
57
+ }
58
+ catch (err) {
59
+ this.client = null;
60
+ this.qb = null;
61
+ this.connected = false;
62
+ const parent = err instanceof Error ? err : new Error(String(err));
63
+ throw new errors_1.ConnectionError(`Unable to connect to MarkLogic: ${parent.message}`, {
64
+ parent,
65
+ database: 'marklogic',
66
+ });
67
+ }
68
+ }
69
+ tryRequireQueryBuilder() {
70
+ try {
71
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
72
+ return require('marklogic').queryBuilder;
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }
78
+ async disconnect() {
79
+ // The MarkLogic client is stateless over HTTP; drop the reference so a
80
+ // subsequent call must connect() again.
81
+ this.client = null;
82
+ this.qb = null;
83
+ this.connected = false;
84
+ }
85
+ isConnected() {
86
+ return this.connected && this.client !== null;
87
+ }
88
+ getClient() {
89
+ return this.requireClient();
90
+ }
91
+ requireClient() {
92
+ if (!this.client || !this.connected) {
93
+ throw new errors_1.ConnectionError('Not connected to MarkLogic. Call connect() first.', {
94
+ database: 'marklogic',
95
+ });
96
+ }
97
+ return this.client;
98
+ }
99
+ uri(collection, id) {
100
+ return `/${collection}/${id}.json`;
101
+ }
102
+ // ---------------------------------------------------------------------
103
+ // Document CRUD
104
+ // ---------------------------------------------------------------------
105
+ /** Write a document into `collection`; returns the id used. */
106
+ async insert(collection, doc) {
107
+ const client = this.requireClient();
108
+ try {
109
+ const id = (doc.id ?? genId());
110
+ await client.documents
111
+ .write({
112
+ uri: this.uri(collection, id),
113
+ contentType: 'application/json',
114
+ collections: [collection],
115
+ content: doc,
116
+ })
117
+ .result();
118
+ return id;
119
+ }
120
+ catch (err) {
121
+ throw wrapDatabaseError(err, 'MarkLogic insert failed');
122
+ }
123
+ }
124
+ /** Read a document by id, returning its stored `content`. */
125
+ async get(collection, id) {
126
+ const client = this.requireClient();
127
+ try {
128
+ const docs = await client.documents.read(this.uri(collection, id)).result();
129
+ return docs?.[0]?.content;
130
+ }
131
+ catch (err) {
132
+ throw wrapDatabaseError(err, 'MarkLogic get failed');
133
+ }
134
+ }
135
+ /** Merge `patch` into an existing document and re-write it. */
136
+ async update(collection, id, patch) {
137
+ const client = this.requireClient();
138
+ try {
139
+ const docs = await client.documents.read(this.uri(collection, id)).result();
140
+ const current = docs?.[0]?.content ?? {};
141
+ const merged = { ...current, ...patch };
142
+ await client.documents
143
+ .write({
144
+ uri: this.uri(collection, id),
145
+ contentType: 'application/json',
146
+ collections: [collection],
147
+ content: merged,
148
+ })
149
+ .result();
150
+ return merged;
151
+ }
152
+ catch (err) {
153
+ throw wrapDatabaseError(err, 'MarkLogic update failed');
154
+ }
155
+ }
156
+ /** Remove a document by id. */
157
+ async delete(collection, id) {
158
+ const client = this.requireClient();
159
+ try {
160
+ return await client.documents.remove(this.uri(collection, id)).result();
161
+ }
162
+ catch (err) {
163
+ throw wrapDatabaseError(err, 'MarkLogic delete failed');
164
+ }
165
+ }
166
+ /**
167
+ * Query documents. When `builtQuery` is provided it is passed straight to
168
+ * `documents.query`; otherwise all documents in `collection` are matched via
169
+ * `queryBuilder.where(queryBuilder.collection(collection))`. Returns the
170
+ * result documents.
171
+ */
172
+ async query(collection, builtQuery) {
173
+ const client = this.requireClient();
174
+ try {
175
+ const query = builtQuery !== undefined ? builtQuery : this.buildCollectionQuery(collection);
176
+ const result = await client.documents.query(query).result();
177
+ return result ?? [];
178
+ }
179
+ catch (err) {
180
+ throw wrapDatabaseError(err, 'MarkLogic query failed');
181
+ }
182
+ }
183
+ buildCollectionQuery(collection) {
184
+ const qb = this.qb;
185
+ if (!qb) {
186
+ throw new errors_1.ConnectionError('MarkLogic queryBuilder unavailable. Call connect() first.', {
187
+ database: 'marklogic',
188
+ });
189
+ }
190
+ return qb.where(qb.collection(collection));
191
+ }
192
+ }
193
+ exports.MarkLogicStore = MarkLogicStore;
194
+ function genId() {
195
+ return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
196
+ }
197
+ function wrapDatabaseError(err, message) {
198
+ if (err instanceof errors_1.ConnectionError) {
199
+ return err;
200
+ }
201
+ const parent = err instanceof Error ? err : new Error(String(err));
202
+ return errors_1.DatabaseError.from(parent, { message: `${message}: ${parent.message}` });
203
+ }
204
+ exports.default = MarkLogicStore;
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ /**
3
+ * Materialize store.
4
+ *
5
+ * Materialize is a streaming (incrementally-updated) analytics database: you
6
+ * define SOURCEs over event streams and MATERIALIZED VIEWs whose results are
7
+ * kept continuously up to date as new data arrives, then read them with
8
+ * low-latency SQL. Materialize speaks the **PostgreSQL wire protocol**, so it
9
+ * is driven with the `pg` client over a normal Postgres-style connection.
10
+ * Although the wire is Postgres, Materialize's compute model (streaming
11
+ * dataflows, `SUBSCRIBE`, `CREATE SOURCE`) is not a general OLTP relational
12
+ * store and does not fit this ORM's SQL `Dialect` abstraction, so it is
13
+ * modelled as a `NoSqlStore` (`src/nosql/store.ts`) exposing a direct `query`
14
+ * surface plus source/view helpers.
15
+ *
16
+ * ## Driver: `pg` (PostgreSQL-wire)
17
+ *
18
+ * The `pg` package is an optional peer dependency, lazily `require`d inside
19
+ * `connect()` so importing this module never forces it to be installed. Tests
20
+ * inject a pre-built mock client via `MaterializeStoreOptions.client`, which
21
+ * skips the `require` entirely.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.MaterializeStore = void 0;
25
+ const errors_1 = require("../../errors");
26
+ /**
27
+ * `MaterializeStore` wraps a `pg` client connected to Materialize and exposes
28
+ * `query(sql, params)` for reads/DDL, plus `createSource()` and
29
+ * `createMaterializedView()` convenience helpers for the streaming-specific
30
+ * DDL that defines what Materialize keeps incrementally up to date.
31
+ */
32
+ class MaterializeStore {
33
+ constructor(options = {}) {
34
+ this.name = 'materialize';
35
+ this.library = 'pg';
36
+ this.client = null;
37
+ this.connected = false;
38
+ this.options = options;
39
+ }
40
+ // ---------------------------------------------------------------------
41
+ // NoSqlStore lifecycle
42
+ // ---------------------------------------------------------------------
43
+ async connect() {
44
+ if (this.connected && this.client) {
45
+ return;
46
+ }
47
+ try {
48
+ let client = this.options.client;
49
+ if (!client) {
50
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
51
+ const pg = require('pg');
52
+ client = new pg.Client({
53
+ host: this.options.host,
54
+ port: this.options.port,
55
+ user: this.options.user,
56
+ password: this.options.password,
57
+ database: this.options.database,
58
+ connectionString: this.options.connectionString,
59
+ ...this.options.connectionOptions,
60
+ });
61
+ }
62
+ await client.connect();
63
+ this.client = client;
64
+ this.connected = true;
65
+ }
66
+ catch (err) {
67
+ this.client = null;
68
+ this.connected = false;
69
+ const parent = err instanceof Error ? err : new Error(String(err));
70
+ throw new errors_1.ConnectionError(`Unable to connect to Materialize: ${parent.message}`, {
71
+ parent,
72
+ database: 'materialize',
73
+ host: this.options.host,
74
+ });
75
+ }
76
+ }
77
+ async disconnect() {
78
+ if (this.client) {
79
+ try {
80
+ await this.client.end();
81
+ }
82
+ finally {
83
+ this.client = null;
84
+ this.connected = false;
85
+ }
86
+ }
87
+ else {
88
+ this.connected = false;
89
+ }
90
+ }
91
+ isConnected() {
92
+ return this.connected && this.client !== null;
93
+ }
94
+ /** Returns the underlying `pg` client for anything not wrapped here. */
95
+ getClient() {
96
+ return this.requireClient();
97
+ }
98
+ requireClient() {
99
+ if (!this.client || !this.connected) {
100
+ throw new errors_1.ConnectionError('Materialize client is not connected. Call connect() first.', {
101
+ database: 'materialize',
102
+ });
103
+ }
104
+ return this.client;
105
+ }
106
+ // ---------------------------------------------------------------------
107
+ // Query + streaming DDL
108
+ // ---------------------------------------------------------------------
109
+ /**
110
+ * Execute a SQL statement over the Postgres wire with optional positional
111
+ * `params` and return the result rows (`pg`'s `result.rows`).
112
+ */
113
+ async query(sql, params) {
114
+ const client = this.requireClient();
115
+ try {
116
+ const result = await client.query(sql, params);
117
+ return (result?.rows ?? []);
118
+ }
119
+ catch (err) {
120
+ const parent = err instanceof Error ? err : new Error(String(err));
121
+ throw errors_1.DatabaseError.from(parent, {
122
+ message: `Materialize query failed: ${parent.message}`,
123
+ sql,
124
+ });
125
+ }
126
+ }
127
+ /**
128
+ * Create a streaming SOURCE via `CREATE SOURCE <name> <definition>`, e.g.
129
+ * `createSource('kafka_src', "FROM KAFKA CONNECTION ... (TOPIC 'events')")`.
130
+ * Returns the driver result rows.
131
+ */
132
+ async createSource(name, definition) {
133
+ return this.query(`CREATE SOURCE ${name} ${definition}`);
134
+ }
135
+ /**
136
+ * Create a MATERIALIZED VIEW (kept incrementally up to date) via
137
+ * `CREATE MATERIALIZED VIEW <name> AS <selectSql>`. Returns the driver
138
+ * result rows.
139
+ */
140
+ async createMaterializedView(name, selectSql) {
141
+ return this.query(`CREATE MATERIALIZED VIEW ${name} AS ${selectSql}`);
142
+ }
143
+ }
144
+ exports.MaterializeStore = MaterializeStore;
145
+ exports.default = MaterializeStore;
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ /**
3
+ * Meilisearch store implementation.
4
+ *
5
+ * Meilisearch is a search engine built around an inverted index with
6
+ * typo-tolerant, prefix, full-text search and faceting rather than SQL: no
7
+ * `JOIN`, no transaction log, schema-flexible documents grouped into indexes
8
+ * (each identified by a `uid` and a primary key). It therefore does not fit
9
+ * the SQL-shaped `Dialect` interface used by the SQL dialects in this repo.
10
+ * Instead it implements the minimal `NoSqlStore` marker interface
11
+ * (`src/nosql/store.ts`) and exposes Meilisearch's real capabilities grouped
12
+ * by concern: connection lifecycle, index management and document CRUD/search.
13
+ *
14
+ * Uses the official `meilisearch` JS driver. The driver is loaded lazily via
15
+ * `require` so importing this module does not force the dependency to be
16
+ * resolved unless a Meilisearch store is actually constructed. For
17
+ * unit-testing without a live server, the constructor also accepts an
18
+ * already-built `client`, which `connect()` will use as-is instead of
19
+ * instantiating a new one.
20
+ *
21
+ * Most operations are scoped to an index and reached through
22
+ * `client.index(uid).<op>(...)`; index lifecycle (`createIndex`/`deleteIndex`)
23
+ * and cluster stats live directly on the top-level client.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.MeilisearchStore = void 0;
27
+ const errors_1 = require("../../errors");
28
+ function wrapConnectionError(err, host) {
29
+ const parent = err instanceof Error ? err : new Error(String(err));
30
+ const message = /econnrefused/i.test(parent.message)
31
+ ? 'Connection refused'
32
+ : `Unable to connect to Meilisearch: ${parent.message}`;
33
+ return new errors_1.ConnectionError(message, {
34
+ parent,
35
+ database: 'meilisearch',
36
+ host: typeof host === 'string' ? host : undefined,
37
+ });
38
+ }
39
+ function wrapDatabaseError(err, message) {
40
+ const parent = err instanceof Error ? err : new Error(String(err));
41
+ const statusCode = err?.httpStatus;
42
+ const detail = statusCode ? `${parent.message} (HTTP ${statusCode})` : parent.message;
43
+ const combined = message ? `${message}: ${detail}` : detail;
44
+ return errors_1.DatabaseError.from(parent, { message: combined });
45
+ }
46
+ /**
47
+ * `MeilisearchStore` wraps the official `meilisearch` client and exposes
48
+ * index management, document CRUD, and search as a typed, promise-based API.
49
+ */
50
+ class MeilisearchStore {
51
+ constructor(options) {
52
+ this.name = 'meilisearch';
53
+ this.library = 'meilisearch';
54
+ this.client = null;
55
+ this.connected = false;
56
+ this.options = options;
57
+ }
58
+ // ---------------------------------------------------------------------
59
+ // Connection lifecycle
60
+ // ---------------------------------------------------------------------
61
+ async connect() {
62
+ if (this.connected && this.client) {
63
+ return;
64
+ }
65
+ let client = this.options.client;
66
+ if (!client) {
67
+ // Lazy-load the driver so importing this module doesn't require the
68
+ // dependency to be present unless a store is actually constructed.
69
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
70
+ const { MeiliSearch } = require('meilisearch');
71
+ client = new MeiliSearch({ host: this.options.host, apiKey: this.options.apiKey });
72
+ }
73
+ try {
74
+ // `health()` surfaces connection failures (bad host, refused
75
+ // connection) immediately instead of on the caller's first real
76
+ // operation.
77
+ await client.health();
78
+ this.client = client;
79
+ this.connected = true;
80
+ }
81
+ catch (err) {
82
+ this.client = null;
83
+ this.connected = false;
84
+ throw wrapConnectionError(err, this.options.host);
85
+ }
86
+ }
87
+ async disconnect() {
88
+ // The Meilisearch client is stateless HTTP; there's no socket to close.
89
+ this.client = null;
90
+ this.connected = false;
91
+ }
92
+ isConnected() {
93
+ return this.connected && this.client !== null;
94
+ }
95
+ /** Returns the underlying `meilisearch` client for anything not wrapped here. */
96
+ getClient() {
97
+ return this.requireClient();
98
+ }
99
+ requireClient() {
100
+ if (!this.client) {
101
+ throw new errors_1.ConnectionError('Not connected to Meilisearch', { database: 'meilisearch' });
102
+ }
103
+ return this.client;
104
+ }
105
+ async exec(fn, action) {
106
+ const client = this.requireClient();
107
+ try {
108
+ return await fn(client);
109
+ }
110
+ catch (err) {
111
+ throw wrapDatabaseError(err, `Meilisearch ${action} failed`);
112
+ }
113
+ }
114
+ // ---------------------------------------------------------------------
115
+ // Index management
116
+ // ---------------------------------------------------------------------
117
+ /** Create an index by `uid`, optionally specifying its primary key via `options`. */
118
+ async createIndex(uid, options) {
119
+ return this.exec((c) => c.createIndex(uid, options), 'CREATE INDEX');
120
+ }
121
+ /** Delete an index by `uid`. */
122
+ async deleteIndex(uid) {
123
+ return this.exec((c) => c.deleteIndex(uid), 'DELETE INDEX');
124
+ }
125
+ // ---------------------------------------------------------------------
126
+ // Document CRUD + search
127
+ // ---------------------------------------------------------------------
128
+ /** Add (or replace) documents in an index. Returns the enqueued task. */
129
+ async addDocuments(index, documents, options) {
130
+ return this.exec((c) => c.index(index).addDocuments(documents, options), 'ADD DOCUMENTS');
131
+ }
132
+ /** Run a search against an index and return the `hits` array from the response. */
133
+ async search(index, query, options) {
134
+ const result = await this.exec((c) => c.index(index).search(query, options), 'SEARCH');
135
+ return result?.hits ?? [];
136
+ }
137
+ /** Get a single document by its primary-key value. */
138
+ async getDocument(index, id) {
139
+ return this.exec((c) => c.index(index).getDocument(id), 'GET DOCUMENT');
140
+ }
141
+ /** Delete a single document by its primary-key value. Returns the enqueued task. */
142
+ async deleteDocument(index, id) {
143
+ return this.exec((c) => c.index(index).deleteDocument(id), 'DELETE DOCUMENT');
144
+ }
145
+ // ---------------------------------------------------------------------
146
+ // Stats
147
+ // ---------------------------------------------------------------------
148
+ /** Get server-wide stats (database size, per-index document counts, etc.). */
149
+ async getStats() {
150
+ return this.exec((c) => c.getStats(), 'GET STATS');
151
+ }
152
+ }
153
+ exports.MeilisearchStore = MeilisearchStore;
154
+ exports.default = MeilisearchStore;