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,186 @@
1
+ "use strict";
2
+ /**
3
+ * OpenSearch store implementation.
4
+ *
5
+ * OpenSearch is a distributed document store forked from Elasticsearch 7.10.
6
+ * Like Elasticsearch it is built around an inverted index and a JSON-based
7
+ * Query DSL (`match`/`term`/`bool`/`range` queries, aggregations, sorting)
8
+ * rather than SQL: no `JOIN`, no transaction log, schema-flexible documents.
9
+ * It therefore does not fit the SQL-shaped `Dialect` interface used by the
10
+ * SQL dialects in this repo. Instead it implements the minimal `NoSqlStore`
11
+ * marker interface (`src/nosql/store.ts`) and exposes OpenSearch's real
12
+ * capabilities grouped by concern: connection lifecycle, index management,
13
+ * document CRUD (single + bulk), and search.
14
+ *
15
+ * Uses the official `@opensearch-project/opensearch` driver. The driver is
16
+ * loaded lazily via `require` so importing this module does not force the
17
+ * dependency to be resolved unless an OpenSearch store is actually
18
+ * constructed. For unit-testing without a live cluster, the constructor also
19
+ * accepts an already-built `client`, which `connect()` will use as-is instead
20
+ * of instantiating a new one.
21
+ *
22
+ * Note: the OpenSearch client wraps every response in an envelope and puts
23
+ * the actual payload under `.body` (`{ body, statusCode, headers, meta }`),
24
+ * so each wrapper here reads through `response.body`.
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.OpenSearchStore = void 0;
28
+ const errors_1 = require("../../errors");
29
+ function wrapConnectionError(err, node) {
30
+ const parent = err instanceof Error ? err : new Error(String(err));
31
+ const message = /econnrefused/i.test(parent.message)
32
+ ? 'Connection refused'
33
+ : `Unable to connect to OpenSearch: ${parent.message}`;
34
+ return new errors_1.ConnectionError(message, {
35
+ parent,
36
+ database: 'opensearch',
37
+ host: typeof node === 'string' ? node : undefined,
38
+ });
39
+ }
40
+ function wrapDatabaseError(err, message) {
41
+ const parent = err instanceof Error ? err : new Error(String(err));
42
+ const statusCode = err?.meta?.statusCode;
43
+ const detail = statusCode ? `${parent.message} (HTTP ${statusCode})` : parent.message;
44
+ const combined = message ? `${message}: ${detail}` : detail;
45
+ return errors_1.DatabaseError.from(parent, { message: combined });
46
+ }
47
+ /**
48
+ * `OpenSearchStore` wraps the official `@opensearch-project/opensearch`
49
+ * client and exposes index management, document CRUD (single + bulk), and
50
+ * Query-DSL search as a typed, promise-based API.
51
+ */
52
+ class OpenSearchStore {
53
+ constructor(options) {
54
+ this.name = 'opensearch';
55
+ this.library = '@opensearch-project/opensearch';
56
+ this.client = null;
57
+ this.connected = false;
58
+ this.options = options;
59
+ }
60
+ // ---------------------------------------------------------------------
61
+ // Connection lifecycle
62
+ // ---------------------------------------------------------------------
63
+ async connect() {
64
+ if (this.connected && this.client) {
65
+ return;
66
+ }
67
+ let client = this.options.client;
68
+ if (!client) {
69
+ // Lazy-load the driver so importing this module doesn't require the
70
+ // dependency to be present unless a store is actually constructed.
71
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
72
+ const { Client } = require('@opensearch-project/opensearch');
73
+ client = new Client({
74
+ node: this.options.node,
75
+ nodes: this.options.nodes,
76
+ auth: this.options.auth,
77
+ ssl: this.options.ssl,
78
+ });
79
+ }
80
+ try {
81
+ // The driver connects lazily on first request; `ping()` surfaces
82
+ // connection failures (bad host, refused connection, TLS errors)
83
+ // immediately instead of on the caller's first real operation.
84
+ await client.ping();
85
+ this.client = client;
86
+ this.connected = true;
87
+ }
88
+ catch (err) {
89
+ await client.close?.().catch?.(() => undefined);
90
+ this.client = null;
91
+ this.connected = false;
92
+ throw wrapConnectionError(err, this.options.node);
93
+ }
94
+ }
95
+ async disconnect() {
96
+ if (this.client) {
97
+ await this.client.close();
98
+ this.client = null;
99
+ }
100
+ this.connected = false;
101
+ }
102
+ isConnected() {
103
+ return this.connected && this.client !== null;
104
+ }
105
+ /** Returns the underlying `@opensearch-project/opensearch` client for anything not wrapped here. */
106
+ getClient() {
107
+ return this.requireClient();
108
+ }
109
+ requireClient() {
110
+ if (!this.client) {
111
+ throw new errors_1.ConnectionError('Not connected to OpenSearch', { database: 'opensearch' });
112
+ }
113
+ return this.client;
114
+ }
115
+ async exec(fn, action) {
116
+ const client = this.requireClient();
117
+ try {
118
+ return await fn(client);
119
+ }
120
+ catch (err) {
121
+ throw wrapDatabaseError(err, `OpenSearch ${action} failed`);
122
+ }
123
+ }
124
+ // ---------------------------------------------------------------------
125
+ // Index management
126
+ // ---------------------------------------------------------------------
127
+ /** Create an index, optionally with a body (mappings/settings/aliases). */
128
+ async createIndex(index, body) {
129
+ await this.exec((c) => c.indices.create({ index, body }), 'CREATE INDEX');
130
+ }
131
+ /** Delete an index. */
132
+ async deleteIndex(index) {
133
+ await this.exec((c) => c.indices.delete({ index }), 'DELETE INDEX');
134
+ }
135
+ /** Whether an index exists. */
136
+ async indexExists(index) {
137
+ const response = await this.exec((c) => c.indices.exists({ index }), 'INDICES EXISTS');
138
+ return response.body ?? false;
139
+ }
140
+ // ---------------------------------------------------------------------
141
+ // Document CRUD
142
+ // ---------------------------------------------------------------------
143
+ /** Index (create or overwrite) a document under an explicit `id`. */
144
+ async indexDocument(index, id, body) {
145
+ const response = await this.exec((c) => c.index({ index, id, body }), 'INDEX');
146
+ return response.body;
147
+ }
148
+ /** Get a document's `_source` by ID. */
149
+ async get(index, id) {
150
+ const response = await this.exec((c) => c.get({ index, id }), 'GET');
151
+ return response.body?._source;
152
+ }
153
+ /** Run a Query-DSL search and return the `hits` object from the response. */
154
+ async search(index, query) {
155
+ const response = await this.exec((c) => c.search({ index, body: query }), 'SEARCH');
156
+ return response.body?.hits;
157
+ }
158
+ /** Delete a document by ID. */
159
+ async deleteDocument(index, id) {
160
+ const response = await this.exec((c) => c.delete({ index, id }), 'DELETE');
161
+ return response.body;
162
+ }
163
+ // ---------------------------------------------------------------------
164
+ // Bulk operations
165
+ // ---------------------------------------------------------------------
166
+ /**
167
+ * Run a batch of operations (already in the driver's NDJSON action/source
168
+ * array form) in a single request. The real `_bulk` API rejects an empty
169
+ * request body outright, so short-circuit zero operations to a trivial
170
+ * no-op result rather than surfacing that as an error.
171
+ */
172
+ async bulk(operations) {
173
+ if (operations.length === 0) {
174
+ return { errors: false, items: [], took: 0 };
175
+ }
176
+ const response = await this.exec((c) => c.bulk({ body: operations }), 'BULK');
177
+ const bodyResult = response.body;
178
+ return {
179
+ errors: bodyResult.errors,
180
+ items: bodyResult.items ?? [],
181
+ took: bodyResult.took ?? 0,
182
+ };
183
+ }
184
+ }
185
+ exports.OpenSearchStore = OpenSearchStore;
186
+ exports.default = OpenSearchStore;
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ /**
3
+ * OrientDB store implementation for the Prorm NoSQL layer.
4
+ *
5
+ * OrientDB is a multi-model database combining document, graph, key/value and
6
+ * object models, queried with an extended SQL dialect over a session. While
7
+ * its query language is SQL-like, it does not fit Prorm's SQL-shaped
8
+ * `Dialect` interface (no shared identifier escaping / DDL builder), so this
9
+ * class implements the minimal `NoSqlStore` marker interface for connection
10
+ * lifecycle and exposes OrientDB's real session `command`/`query` API through
11
+ * a small document-CRUD convenience layer.
12
+ *
13
+ * Uses the official `orientjs` 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 session via
16
+ * `options.client`, which bypasses the lazy `require` entirely - no real
17
+ * driver and no network are needed.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.OrientDbStore = void 0;
21
+ const errors_1 = require("../../errors");
22
+ class OrientDbStore {
23
+ constructor(options = {}) {
24
+ this.name = 'orientdb';
25
+ this.library = 'orientjs';
26
+ this.orientClient = null;
27
+ this.session = null;
28
+ this.connected = false;
29
+ this.options = options;
30
+ }
31
+ // ---------------------------------------------------------------------
32
+ // Connection lifecycle
33
+ // ---------------------------------------------------------------------
34
+ async connect() {
35
+ if (this.connected && this.session) {
36
+ return;
37
+ }
38
+ try {
39
+ if (this.options.client) {
40
+ this.session = this.options.client;
41
+ }
42
+ else {
43
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
44
+ const orientjs = require('orientjs');
45
+ const OrientDBClient = orientjs.OrientDBClient ?? orientjs;
46
+ this.orientClient = await OrientDBClient.connect({
47
+ host: this.options.host,
48
+ port: this.options.port,
49
+ });
50
+ this.session = await this.orientClient.session({
51
+ name: this.options.database,
52
+ username: this.options.username,
53
+ password: this.options.password,
54
+ });
55
+ }
56
+ this.connected = true;
57
+ }
58
+ catch (err) {
59
+ this.session = null;
60
+ this.orientClient = 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 OrientDB: ${parent.message}`, {
64
+ parent,
65
+ database: 'orientdb',
66
+ });
67
+ }
68
+ }
69
+ async disconnect() {
70
+ try {
71
+ if (this.session && typeof this.session.close === 'function') {
72
+ await this.session.close();
73
+ }
74
+ if (this.orientClient && typeof this.orientClient.close === 'function') {
75
+ await this.orientClient.close();
76
+ }
77
+ }
78
+ catch (err) {
79
+ throw wrapDatabaseError(err, 'OrientDB disconnect failed');
80
+ }
81
+ finally {
82
+ this.session = null;
83
+ this.orientClient = null;
84
+ this.connected = false;
85
+ }
86
+ }
87
+ isConnected() {
88
+ return this.connected && this.session !== null;
89
+ }
90
+ getClient() {
91
+ return this.requireSession();
92
+ }
93
+ requireSession() {
94
+ if (!this.session || !this.connected) {
95
+ throw new errors_1.ConnectionError('Not connected to OrientDB. Call connect() first.', {
96
+ database: 'orientdb',
97
+ });
98
+ }
99
+ return this.session;
100
+ }
101
+ // ---------------------------------------------------------------------
102
+ // Document CRUD (extended SQL)
103
+ // ---------------------------------------------------------------------
104
+ /** Insert a document into `collection` (class); returns its `@rid`/id. */
105
+ async insert(collection, doc) {
106
+ const session = this.requireSession();
107
+ try {
108
+ const sql = `INSERT INTO ${collection} CONTENT ${JSON.stringify(doc)}`;
109
+ const rows = await session.command(sql).all();
110
+ const record = rows?.[0];
111
+ const rid = record?.['@rid'];
112
+ return rid !== undefined ? String(rid) : record?.id;
113
+ }
114
+ catch (err) {
115
+ throw wrapDatabaseError(err, 'OrientDB insert failed');
116
+ }
117
+ }
118
+ /** Fetch a document by `@rid`. */
119
+ async get(collection, id) {
120
+ const session = this.requireSession();
121
+ try {
122
+ const sql = `SELECT FROM ${collection} WHERE @rid = ${id}`;
123
+ const rows = await session.query(sql).all();
124
+ return rows?.[0];
125
+ }
126
+ catch (err) {
127
+ throw wrapDatabaseError(err, 'OrientDB get failed');
128
+ }
129
+ }
130
+ /** Merge `patch` into an existing document identified by `@rid`. */
131
+ async update(collection, id, patch) {
132
+ const session = this.requireSession();
133
+ try {
134
+ const sql = `UPDATE ${collection} MERGE ${JSON.stringify(patch)} WHERE @rid = ${id}`;
135
+ return await session.command(sql).all();
136
+ }
137
+ catch (err) {
138
+ throw wrapDatabaseError(err, 'OrientDB update failed');
139
+ }
140
+ }
141
+ /** Delete a document identified by `@rid`. */
142
+ async delete(collection, id) {
143
+ const session = this.requireSession();
144
+ try {
145
+ const sql = `DELETE FROM ${collection} WHERE @rid = ${id}`;
146
+ return await session.command(sql).all();
147
+ }
148
+ catch (err) {
149
+ throw wrapDatabaseError(err, 'OrientDB delete failed');
150
+ }
151
+ }
152
+ /**
153
+ * Run an OrientDB SQL `statement` and return the resulting rows.
154
+ * `options.params` binds parameters into the statement.
155
+ */
156
+ async query(collection, statement, options = {}) {
157
+ const session = this.requireSession();
158
+ try {
159
+ const rows = await session.query(statement, options).all();
160
+ return rows ?? [];
161
+ }
162
+ catch (err) {
163
+ throw wrapDatabaseError(err, 'OrientDB query failed');
164
+ }
165
+ }
166
+ }
167
+ exports.OrientDbStore = OrientDbStore;
168
+ function wrapDatabaseError(err, message) {
169
+ if (err instanceof errors_1.ConnectionError) {
170
+ return err;
171
+ }
172
+ const parent = err instanceof Error ? err : new Error(String(err));
173
+ return errors_1.DatabaseError.from(parent, { message: `${message}: ${parent.message}` });
174
+ }
175
+ exports.default = OrientDbStore;
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ /**
3
+ * Papertrail store implementation.
4
+ *
5
+ * Papertrail (by SolarWinds) is a hosted log-management service. Logs are
6
+ * ingested over syslog or an HTTP log destination, and searched via the REST
7
+ * events API. There is no SQL-shaped query surface, no row-level
8
+ * UPDATE/DELETE, and no identifier escaping, so Papertrail does not fit the
9
+ * SQL `Dialect` interface (`src/dialects/dialect.ts`). This class implements
10
+ * the minimal `NoSqlStore` marker interface (`src/nosql/store.ts`) and
11
+ * exposes Papertrail's ingest/search API.
12
+ *
13
+ * ## No canonical driver - HTTP over `fetch`
14
+ *
15
+ * Papertrail has no single canonical npm client; it is an HTTP/JSON API
16
+ * (`X-Papertrail-Token` auth). This store talks to it with the global
17
+ * `fetch` (so `library` is `'fetch'`). For tests (and custom transports) an
18
+ * alternative HTTP client can be injected via `PapertrailStoreOptions.client`.
19
+ *
20
+ * Search targets the REST API (`apiURL`); ingest targets the configured HTTP
21
+ * log destination (`ingestURL`). The internal client resolves absolute URLs
22
+ * verbatim, so `push()` posts to the full ingest URL while search/metadata
23
+ * methods use relative API paths.
24
+ *
25
+ * ## Endpoints wrapped
26
+ *
27
+ * - `push(lines)` -> `POST <ingestURL>` (HTTP/syslog ingest)
28
+ * - `query(q, opts?)` -> `GET /api/v1/events/search` (search events)
29
+ * - `labels()` -> `GET /api/v1/groups` (log groups)
30
+ * - `streams()` -> `GET /api/v1/systems` (systems/senders)
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.PapertrailStore = exports.DEFAULT_PAPERTRAIL_API_URL = void 0;
34
+ exports.createFetchClient = createFetchClient;
35
+ const errors_1 = require("../../errors");
36
+ /** Default Papertrail REST API base URL. */
37
+ exports.DEFAULT_PAPERTRAIL_API_URL = 'https://papertrailapp.com';
38
+ /** Build a `fetch`-backed client for the given base URL. */
39
+ function createFetchClient(baseURL, headers) {
40
+ const buildUrl = (path, params) => {
41
+ // Absolute URLs (the ingest URL) override the base entirely.
42
+ const url = new URL(path, baseURL.endsWith('/') ? baseURL : `${baseURL}/`);
43
+ for (const [key, value] of Object.entries(params ?? {})) {
44
+ if (value === undefined)
45
+ continue;
46
+ if (Array.isArray(value)) {
47
+ for (const item of value)
48
+ url.searchParams.append(key, item);
49
+ }
50
+ else {
51
+ url.searchParams.set(key, value);
52
+ }
53
+ }
54
+ return url.toString();
55
+ };
56
+ return {
57
+ async get(path, params) {
58
+ const res = await fetch(buildUrl(path, params), {
59
+ method: 'GET',
60
+ headers: { Accept: 'application/json', ...(headers ?? {}) },
61
+ });
62
+ if (!res.ok)
63
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
64
+ return res.json();
65
+ },
66
+ async post(path, body, contentType) {
67
+ const res = await fetch(buildUrl(path), {
68
+ method: 'POST',
69
+ body,
70
+ headers: { ...(headers ?? {}), ...(contentType ? { 'Content-Type': contentType } : {}) },
71
+ });
72
+ if (!res.ok)
73
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
74
+ const text = await res.text();
75
+ if (!text)
76
+ return undefined;
77
+ try {
78
+ return JSON.parse(text);
79
+ }
80
+ catch {
81
+ return text;
82
+ }
83
+ },
84
+ };
85
+ }
86
+ /**
87
+ * `PapertrailStore` wraps Papertrail's HTTP log-destination ingest and its
88
+ * REST events-search API (plus group/system metadata) behind the
89
+ * `NoSqlStore` lifecycle.
90
+ */
91
+ class PapertrailStore {
92
+ constructor(options = {}) {
93
+ this.name = 'papertrail';
94
+ this.library = 'fetch';
95
+ this.client = null;
96
+ this.connected = false;
97
+ this.apiURL = options.apiURL ?? exports.DEFAULT_PAPERTRAIL_API_URL;
98
+ this.ingestURL = options.ingestURL;
99
+ this.injectedClient = options.client;
100
+ this.headers = {
101
+ ...(options.headers ?? {}),
102
+ ...(options.token ? { 'X-Papertrail-Token': options.token } : {}),
103
+ };
104
+ }
105
+ // ---------------------------------------------------------------------
106
+ // Connection lifecycle
107
+ // ---------------------------------------------------------------------
108
+ async connect() {
109
+ if (this.connected && this.client)
110
+ return;
111
+ this.client = this.injectedClient ?? createFetchClient(this.apiURL, this.headers);
112
+ this.connected = true;
113
+ }
114
+ async disconnect() {
115
+ this.client = null;
116
+ this.connected = false;
117
+ }
118
+ isConnected() {
119
+ return this.connected && this.client !== null;
120
+ }
121
+ /** Returns the underlying (internal or injected) HTTP client. */
122
+ getClient() {
123
+ return this.requireClient();
124
+ }
125
+ requireClient() {
126
+ if (!this.client) {
127
+ throw new errors_1.ConnectionError('Not connected to Papertrail', {
128
+ database: 'papertrail',
129
+ host: this.apiURL,
130
+ });
131
+ }
132
+ return this.client;
133
+ }
134
+ async doGet(path, params, action) {
135
+ const client = this.requireClient();
136
+ try {
137
+ return await client.get(path, params);
138
+ }
139
+ catch (err) {
140
+ const parent = err instanceof Error ? err : new Error(String(err));
141
+ throw errors_1.DatabaseError.from(parent, {
142
+ message: `Papertrail ${action ?? 'request'} failed: ${parent.message}`,
143
+ });
144
+ }
145
+ }
146
+ // ---------------------------------------------------------------------
147
+ // Ingest (HTTP log destination)
148
+ // ---------------------------------------------------------------------
149
+ /**
150
+ * Ingests raw log lines by POSTing them (newline-delimited) to the
151
+ * configured HTTP log-destination `ingestURL`. Accepts a single string or
152
+ * an array of lines (joined with newlines).
153
+ */
154
+ async push(lines) {
155
+ if (!this.ingestURL) {
156
+ throw new errors_1.DatabaseError('Papertrail push requires an ingestURL to be configured');
157
+ }
158
+ const client = this.requireClient();
159
+ const body = Array.isArray(lines) ? lines.join('\n') : lines;
160
+ try {
161
+ return await client.post(this.ingestURL, body, 'text/plain');
162
+ }
163
+ catch (err) {
164
+ const parent = err instanceof Error ? err : new Error(String(err));
165
+ throw errors_1.DatabaseError.from(parent, { message: `Papertrail push failed: ${parent.message}` });
166
+ }
167
+ }
168
+ // ---------------------------------------------------------------------
169
+ // Search
170
+ // ---------------------------------------------------------------------
171
+ /**
172
+ * Searches log events via `GET /api/v1/events/search`. Returns the parsed
173
+ * response (`{ events, min_id, max_id, reached_beginning, ... }`).
174
+ */
175
+ async query(q, options = {}) {
176
+ return this.doGet('/api/v1/events/search.json', {
177
+ q,
178
+ system_id: options.systemId === undefined ? undefined : String(options.systemId),
179
+ group_id: options.groupId === undefined ? undefined : String(options.groupId),
180
+ min_id: options.minId,
181
+ max_id: options.maxId,
182
+ min_time: options.minTime === undefined ? undefined : String(options.minTime),
183
+ max_time: options.maxTime === undefined ? undefined : String(options.maxTime),
184
+ limit: options.limit === undefined ? undefined : String(options.limit),
185
+ }, 'query');
186
+ }
187
+ // ---------------------------------------------------------------------
188
+ // Metadata
189
+ // ---------------------------------------------------------------------
190
+ /** Lists the configured log groups via `GET /api/v1/groups`. */
191
+ async labels() {
192
+ return this.doGet('/api/v1/groups.json', undefined, 'labels');
193
+ }
194
+ /** Lists the configured systems (log senders) via `GET /api/v1/systems`. */
195
+ async streams() {
196
+ return this.doGet('/api/v1/systems.json', undefined, 'streams');
197
+ }
198
+ }
199
+ exports.PapertrailStore = PapertrailStore;
200
+ exports.default = PapertrailStore;
Binary file