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,720 @@
1
+ "use strict";
2
+ /**
3
+ * Base dialect interface for the ORM
4
+ * Each database dialect implements this interface
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.DialectRegistry = exports.BaseDialect = void 0;
8
+ const index_1 = require("../errors/index");
9
+ /**
10
+ * Abstract base class for database dialects
11
+ * Provides common functionality for all dialect implementations
12
+ */
13
+ class BaseDialect {
14
+ constructor() {
15
+ this._connection = null;
16
+ this._connected = false;
17
+ this.dialectName = 'unknown';
18
+ }
19
+ /**
20
+ * Create a stored procedure (alias for createStoredProcedure)
21
+ * @param options - Stored procedure options
22
+ */
23
+ async createProcedure(options) {
24
+ return this.createStoredProcedure(options);
25
+ }
26
+ /**
27
+ * Drop a stored procedure (alias for dropStoredProcedure)
28
+ * @param procedureName - Name of the stored procedure
29
+ * @param options - Drop options
30
+ */
31
+ async dropProcedure(procedureName, options) {
32
+ return this.dropStoredProcedure(procedureName, options);
33
+ }
34
+ /**
35
+ * Rename a column (default throws error)
36
+ */
37
+ async renameColumn(_tableName, _oldColumnName, _newColumnName) {
38
+ throw new Error(`renameColumn not supported for ${this.dialectName} dialect`);
39
+ }
40
+ /**
41
+ * Add a foreign key (default throws error)
42
+ */
43
+ async addForeignKey(_tableName, _columnName, _referencedTableName, _referencedColumnName, _options) {
44
+ throw new Error(`addForeignKey not supported for ${this.dialectName} dialect`);
45
+ }
46
+ /**
47
+ * Bulk insert records (default implementation)
48
+ */
49
+ async bulkInsert(tableName, records, _options) {
50
+ if (records.length === 0) {
51
+ return { rows: [], rowCount: 0, fields: [] };
52
+ }
53
+ const values = [];
54
+ const placeholders = [];
55
+ const columns = Object.keys(records[0]);
56
+ for (const record of records) {
57
+ const rowPlaceholders = [];
58
+ for (let i = 0; i < columns.length; i++) {
59
+ rowPlaceholders.push(`$${values.length + i + 1}`);
60
+ values.push(record[columns[i]]);
61
+ }
62
+ placeholders.push(`(${rowPlaceholders.join(', ')})`);
63
+ }
64
+ const sql = `INSERT INTO ${this.quoteTable(tableName)} (${columns.map((c) => this.escapeId(c)).join(', ')}) VALUES ${placeholders.join(', ')}`;
65
+ return this.query(sql);
66
+ }
67
+ /**
68
+ * Create a fulltext index (default throws error)
69
+ */
70
+ async createFulltextIndex(_tableName, _indexName, _fields, _options) {
71
+ throw new Error(`createFulltextIndex not supported for ${this.dialectName} dialect`);
72
+ }
73
+ /**
74
+ * Create a spatial index (default throws error)
75
+ */
76
+ async createSpatialIndex(_tableName, _indexName, _fields, _options) {
77
+ throw new Error(`createSpatialIndex not supported for ${this.dialectName} dialect`);
78
+ }
79
+ /**
80
+ * List all schemas in the database
81
+ */
82
+ async listSchemas() {
83
+ return this.showAllSchemas();
84
+ }
85
+ /**
86
+ * Generate SQL for creating a database (default implementation)
87
+ * @param options - Database creation options
88
+ */
89
+ createDatabaseSQL(options) {
90
+ const parts = [];
91
+ parts.push(`CREATE DATABASE ${this.quoteIdentifier(options.name)}`);
92
+ if (options.encoding) {
93
+ parts.push(`ENCODING = '${options.encoding}'`);
94
+ }
95
+ if (options.lcCollate) {
96
+ parts.push(`LC_COLLATE = '${options.lcCollate}'`);
97
+ }
98
+ if (options.lcCtype) {
99
+ parts.push(`LC_CTYPE = '${options.lcCtype}'`);
100
+ }
101
+ if (options.template) {
102
+ parts.push(`TEMPLATE = ${options.template}`);
103
+ }
104
+ if (options.tablespace) {
105
+ parts.push(`TABLESPACE = ${options.tablespace}`);
106
+ }
107
+ if (options.isTemplate !== undefined) {
108
+ parts.push(options.isTemplate ? 'IS_TEMPLATE = true' : 'IS_TEMPLATE = false');
109
+ }
110
+ if (options.collate) {
111
+ parts.push(`COLLATE = '${options.collate}'`);
112
+ }
113
+ return parts.join(' ');
114
+ }
115
+ /**
116
+ * Generate SQL for dropping a database
117
+ * @param name - Database name to drop
118
+ */
119
+ dropDatabaseSQL(name) {
120
+ return `DROP DATABASE IF EXISTS ${this.quoteIdentifier(name)}`;
121
+ }
122
+ /**
123
+ * Generate SQL for creating a savepoint
124
+ * @param name - Savepoint name (optional, will be generated if not provided)
125
+ */
126
+ createSavepointSQL(name) {
127
+ const savepointName = name || `sp_${Date.now()}`;
128
+ return `SAVEPOINT ${savepointName}`;
129
+ }
130
+ /**
131
+ * Generate SQL for releasing a savepoint
132
+ * @param name - Savepoint name to release
133
+ */
134
+ releaseSavepointSQL(name) {
135
+ return `RELEASE SAVEPOINT ${name}`;
136
+ }
137
+ /**
138
+ * Generate SQL for rolling back to a savepoint
139
+ * @param name - Savepoint name to rollback to
140
+ */
141
+ rollbackToSavepointSQL(name) {
142
+ return `ROLLBACK TO SAVEPOINT ${name}`;
143
+ }
144
+ /**
145
+ * Create a PostgreSQL extension (only supported in PostgreSQL)
146
+ * @param extensionName - Name of the extension to create
147
+ * @param options - Extension options
148
+ */
149
+ createExtension(_extensionName, _options) {
150
+ throw new Error('Extensions are only supported in PostgreSQL');
151
+ }
152
+ /**
153
+ * Drop a PostgreSQL extension (only supported in PostgreSQL)
154
+ * @param extensionName - Name of the extension to drop
155
+ * @param options - Drop options
156
+ */
157
+ dropExtension(_extensionName, _options) {
158
+ throw new Error('Extensions are only supported in PostgreSQL');
159
+ }
160
+ /**
161
+ * Get all installed PostgreSQL extensions (only supported in PostgreSQL)
162
+ * @returns Array of extension information
163
+ */
164
+ getExtensions() {
165
+ throw new Error('Extensions are only supported in PostgreSQL');
166
+ }
167
+ /**
168
+ * Check if a PostgreSQL extension is installed (only supported in PostgreSQL)
169
+ * @param extensionName - Name of the extension
170
+ * @returns True if the extension is installed
171
+ */
172
+ hasExtension(_extensionName) {
173
+ throw new Error('Extensions are only supported in PostgreSQL');
174
+ }
175
+ /**
176
+ * Create a PostgreSQL enum type (only supported in PostgreSQL)
177
+ */
178
+ createEnumType(_name, _values, _options) {
179
+ throw new Error('CREATE TYPE ... AS ENUM is only supported in PostgreSQL');
180
+ }
181
+ /**
182
+ * Drop a PostgreSQL type (only supported in PostgreSQL)
183
+ */
184
+ dropType(_name, _options) {
185
+ throw new Error('DROP TYPE is only supported in PostgreSQL');
186
+ }
187
+ /**
188
+ * Create a PostgreSQL domain (only supported in PostgreSQL)
189
+ */
190
+ createDomain(_name, _baseType, _options) {
191
+ throw new Error('CREATE DOMAIN is only supported in PostgreSQL');
192
+ }
193
+ /**
194
+ * Drop a PostgreSQL domain (only supported in PostgreSQL)
195
+ */
196
+ dropDomain(_name, _options) {
197
+ throw new Error('DROP DOMAIN is only supported in PostgreSQL');
198
+ }
199
+ // ---------------------------------------------------------------------------
200
+ // Foreign Data Wrapper stubs – overridden by PostgresDialect
201
+ // All other dialects throw a DatabaseError.
202
+ // ---------------------------------------------------------------------------
203
+ buildCreateServerQuery(_name, _opts) {
204
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
205
+ }
206
+ buildAlterServerQuery(_name, _opts) {
207
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
208
+ }
209
+ buildDropServerQuery(_name, _opts) {
210
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
211
+ }
212
+ buildCreateUserMappingQuery(_opts) {
213
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
214
+ }
215
+ buildAlterUserMappingQuery(_opts) {
216
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
217
+ }
218
+ buildDropUserMappingQuery(_serverName, _user, _opts) {
219
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
220
+ }
221
+ /**
222
+ * Create a user mapping (default throws error)
223
+ */
224
+ async createUserMapping(_userName, _serverName, _options) {
225
+ throw new Error(`createUserMapping not supported for ${this.dialectName} dialect`);
226
+ }
227
+ /**
228
+ * Drop a user mapping (default throws error)
229
+ */
230
+ async dropUserMapping(_userName, _serverName, _options) {
231
+ throw new Error(`dropUserMapping not supported for ${this.dialectName} dialect`);
232
+ }
233
+ buildCreateForeignTableQuery(_tableName, _opts) {
234
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
235
+ }
236
+ buildDropForeignTableQuery(_tableName, _opts) {
237
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
238
+ }
239
+ buildImportForeignSchemaQuery(_remoteSchema, _serverName, _opts) {
240
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
241
+ }
242
+ getServersQuery() {
243
+ throw new Error('Foreign Data Wrappers are not supported by this dialect');
244
+ }
245
+ // ---------------------------------------------------------------------------
246
+ // User / privilege management stubs – overridden by MySQL and MariaDB dialects.
247
+ // All other dialects (SQLite, etc.) throw a DatabaseError.
248
+ // ---------------------------------------------------------------------------
249
+ buildCreateUserQuery(_username, _options) {
250
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
251
+ }
252
+ buildAlterUserQuery(_username, _options) {
253
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
254
+ }
255
+ buildDropUserQuery(_username, _options) {
256
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
257
+ }
258
+ getUsersQuery() {
259
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
260
+ }
261
+ buildGrantQuery(_options) {
262
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
263
+ }
264
+ buildRevokeQuery(_options) {
265
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
266
+ }
267
+ buildShowGrantsQuery(_username, _host) {
268
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
269
+ }
270
+ buildFlushPrivilegesQuery() {
271
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
272
+ }
273
+ buildCreateRoleQuery(_roleName, _options) {
274
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
275
+ }
276
+ buildDropRoleQuery(_roleName, _options) {
277
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
278
+ }
279
+ buildGrantRoleQuery(_role, _to, _options) {
280
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
281
+ }
282
+ buildRevokeRoleQuery(_role, _from, _options) {
283
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
284
+ }
285
+ getRolesQuery() {
286
+ throw new index_1.DatabaseError('User management is not supported by this dialect');
287
+ }
288
+ /**
289
+ * Build a JSON/JSONB path query
290
+ * Default implementation using common JSON extraction syntax
291
+ *
292
+ * @param column - The JSON/JSONB column name
293
+ * @param path - The JSON path to access (e.g., 'key' or 'key.subkey')
294
+ * @param value - The value to compare against (optional)
295
+ * @param operator - The comparison operator to use (defaults to =)
296
+ * @returns SQL fragment and values for the JSON query
297
+ */
298
+ buildJsonQuery(column, path, value, operator = '=') {
299
+ const values = [];
300
+ const columnRef = this.quoteIdentifier(column);
301
+ // Convert dot notation path to JSON path
302
+ const jsonPath = path
303
+ .split('.')
304
+ .map((p) => `$.${p}`)
305
+ .join('');
306
+ // Build JSON extraction SQL
307
+ // Using JSON_EXTRACT for compatibility (works with MySQL, SQLite)
308
+ // For PostgreSQL, dialects should override this method
309
+ const jsonExtract = `JSON_EXTRACT(${columnRef}, '${jsonPath}')`;
310
+ if (value !== undefined) {
311
+ values.push(value);
312
+ // Use = comparison with the extracted value
313
+ return { sql: `${jsonExtract} ${operator} ?`, values };
314
+ }
315
+ // Just return the JSON extraction without value comparison
316
+ return { sql: jsonExtract, values };
317
+ }
318
+ /**
319
+ * Format a value for SQL based on its type
320
+ */
321
+ formatValue(value) {
322
+ if (value === null || value === undefined) {
323
+ return 'NULL';
324
+ }
325
+ if (typeof value === 'boolean') {
326
+ return value ? '1' : '0';
327
+ }
328
+ if (typeof value === 'number') {
329
+ return String(value);
330
+ }
331
+ // Handle Date objects or date-like objects
332
+ if (value instanceof Date || (value && typeof value === 'object' && typeof value.getFullYear === 'function')) {
333
+ return this.formatDate(new Date(value.getFullYear(), value.getMonth(), value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds()));
334
+ }
335
+ // Handle date strings
336
+ if (typeof value === 'string') {
337
+ const dateStr = value.trim();
338
+ // Check if it looks like an ISO date string
339
+ if (/^\d{4}-\d{2}-\d{2}/.test(dateStr) || /^\d{4}-\d{2}-\d{2}T/.test(dateStr)) {
340
+ const parsedDate = new Date(dateStr);
341
+ if (!isNaN(parsedDate.getTime())) {
342
+ return this.formatDate(parsedDate);
343
+ }
344
+ }
345
+ }
346
+ if (Buffer.isBuffer(value)) {
347
+ return `X'${value.toString('hex')}'`;
348
+ }
349
+ if (Array.isArray(value) || typeof value === 'object') {
350
+ return this.escape(JSON.stringify(value));
351
+ }
352
+ return this.escape(String(value));
353
+ }
354
+ /**
355
+ * Format a date for SQL
356
+ */
357
+ formatDate(date) {
358
+ const year = date.getFullYear();
359
+ const month = String(date.getMonth() + 1).padStart(2, '0');
360
+ const day = String(date.getDate()).padStart(2, '0');
361
+ const hours = String(date.getHours()).padStart(2, '0');
362
+ const minutes = String(date.getMinutes()).padStart(2, '0');
363
+ const seconds = String(date.getSeconds()).padStart(2, '0');
364
+ const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
365
+ return `'${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}'`;
366
+ }
367
+ /**
368
+ * Replace placeholders in SQL with actual values
369
+ * Supports both named (:param) and positional (?) placeholders
370
+ * Properly escapes values to prevent SQL injection
371
+ */
372
+ replaceReplacements(sql, replacements) {
373
+ if (!replacements) {
374
+ return sql;
375
+ }
376
+ // Handle array replacements (positional ?)
377
+ if (Array.isArray(replacements)) {
378
+ return this.replacePositionalReplacements(sql, replacements);
379
+ }
380
+ // Handle object replacements (named :param)
381
+ return this.replaceNamedReplacements(sql, replacements);
382
+ }
383
+ /**
384
+ * Replace positional (?) placeholders with escaped values
385
+ */
386
+ replacePositionalReplacements(sql, replacements) {
387
+ let result = sql;
388
+ let paramIndex = 0;
389
+ // Use a placeholder to avoid infinite loops with ?
390
+ const placeholder = '__POS_PLACEHOLDER__';
391
+ // First, escape the ? to avoid issues with the replacement loop
392
+ // We'll track positions of ?
393
+ const matches = [];
394
+ // Find all ? that are not inside quotes
395
+ let inSingleQuote = false;
396
+ let inDoubleQuote = false;
397
+ let escaped = false;
398
+ let i = 0;
399
+ while (i < result.length) {
400
+ const char = result[i];
401
+ if (escaped) {
402
+ escaped = false;
403
+ i++;
404
+ continue;
405
+ }
406
+ if (char === '\\') {
407
+ escaped = true;
408
+ i++;
409
+ continue;
410
+ }
411
+ if (char === "'" && !inDoubleQuote) {
412
+ inSingleQuote = !inSingleQuote;
413
+ }
414
+ else if (char === '"' && !inSingleQuote) {
415
+ inDoubleQuote = !inDoubleQuote;
416
+ }
417
+ if (!inSingleQuote && !inDoubleQuote && char === '?') {
418
+ const value = replacements[paramIndex];
419
+ const escapedValue = this.escapeReplacement(value);
420
+ matches.push({ index: i, value: escapedValue });
421
+ paramIndex++;
422
+ }
423
+ i++;
424
+ }
425
+ // Replace from end to beginning to maintain correct indices
426
+ for (let i = matches.length - 1; i >= 0; i--) {
427
+ const match = matches[i];
428
+ result = result.slice(0, match.index) + match.value + result.slice(match.index + 1);
429
+ }
430
+ return result;
431
+ }
432
+ /**
433
+ * Replace named (:param) placeholders with escaped values
434
+ */
435
+ replaceNamedReplacements(sql, replacements) {
436
+ let result = sql;
437
+ // Find all :param placeholders
438
+ // Match :param where param is alphanumeric (and possibly with underscores)
439
+ const namedParamRegex = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
440
+ // We need to handle this carefully to avoid replacing inside strings
441
+ // For simplicity, we'll use a two-pass approach
442
+ // First pass: identify placeholders not in quotes
443
+ const matches = [];
444
+ let inSingleQuote = false;
445
+ let inDoubleQuote = false;
446
+ const escaped = false;
447
+ const i = 0;
448
+ // Make a fresh regex for each call
449
+ const regex = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
450
+ let match;
451
+ // Reset regex state
452
+ regex.lastIndex = 0;
453
+ while ((match = regex.exec(result)) !== null) {
454
+ // Check if we're inside quotes
455
+ const beforeMatch = result.slice(0, match.index);
456
+ const inQuote = false;
457
+ for (const char of beforeMatch) {
458
+ if (char === "'" && !inDoubleQuote) {
459
+ inSingleQuote = !inSingleQuote;
460
+ }
461
+ else if (char === '"' && !inSingleQuote) {
462
+ inDoubleQuote = !inDoubleQuote;
463
+ }
464
+ }
465
+ if (!inSingleQuote && !inDoubleQuote) {
466
+ matches.push({
467
+ match: match[0],
468
+ param: match[1],
469
+ index: match.index,
470
+ });
471
+ }
472
+ // Reset quote state tracking for next iteration
473
+ inSingleQuote = false;
474
+ inDoubleQuote = false;
475
+ }
476
+ // Replace from end to beginning to maintain correct indices
477
+ for (let i = matches.length - 1; i >= 0; i--) {
478
+ const m = matches[i];
479
+ const value = replacements[m.param];
480
+ if (value === undefined) {
481
+ throw new Error(`Replacement parameter :${m.param} is not defined`);
482
+ }
483
+ const escapedValue = this.escapeReplacement(value);
484
+ result = result.slice(0, m.index) + escapedValue + result.slice(m.index + m.match.length);
485
+ }
486
+ return result;
487
+ }
488
+ /**
489
+ * Escape a replacement value for safe inclusion in SQL
490
+ */
491
+ escapeReplacement(value) {
492
+ if (value === null || value === undefined) {
493
+ return 'NULL';
494
+ }
495
+ // Handle arrays - convert to (val1, val2, ...) for IN clauses
496
+ if (Array.isArray(value)) {
497
+ const escapedValues = value.map((v) => this.escapeReplacement(v));
498
+ return `(${escapedValues.join(', ')})`;
499
+ }
500
+ // Handle boolean
501
+ if (typeof value === 'boolean') {
502
+ return value ? '1' : '0';
503
+ }
504
+ // Handle numbers
505
+ if (typeof value === 'number') {
506
+ return String(value);
507
+ }
508
+ // Handle Date
509
+ if (value instanceof Date) {
510
+ return this.formatDate(value);
511
+ }
512
+ // Handle Buffer
513
+ if (Buffer.isBuffer(value)) {
514
+ return `X'${value.toString('hex')}'`;
515
+ }
516
+ // Handle objects/arrays as JSON strings
517
+ if (typeof value === 'object') {
518
+ return this.escape(JSON.stringify(value));
519
+ }
520
+ // Handle strings and other types
521
+ return this.escape(String(value));
522
+ }
523
+ /**
524
+ * Parse a value from the database
525
+ */
526
+ parseValue(value, type) {
527
+ if (value === null || value === undefined) {
528
+ return value;
529
+ }
530
+ // Handle based on data type
531
+ const typeObj = type;
532
+ const typeKey = typeObj?.key || '';
533
+ switch (typeKey) {
534
+ case 'BOOLEAN':
535
+ if (typeof value === 'number') {
536
+ return value === 1;
537
+ }
538
+ if (typeof value === 'string') {
539
+ return value.toLowerCase() === 'true' || value === '1';
540
+ }
541
+ return Boolean(value);
542
+ case 'INTEGER':
543
+ case 'BIGINT':
544
+ case 'FLOAT':
545
+ case 'DOUBLE':
546
+ case 'DECIMAL':
547
+ return Number(value);
548
+ case 'DATE':
549
+ case 'DATEONLY':
550
+ case 'TIME':
551
+ if (typeof value === 'string' || typeof value === 'number') {
552
+ return new Date(value);
553
+ }
554
+ return value;
555
+ case 'JSON':
556
+ case 'JSONB':
557
+ if (typeof value === 'string') {
558
+ try {
559
+ return JSON.parse(value);
560
+ }
561
+ catch {
562
+ return value;
563
+ }
564
+ }
565
+ return value;
566
+ case 'BLOB':
567
+ if (typeof value === 'string') {
568
+ return Buffer.from(value, 'hex');
569
+ }
570
+ return value;
571
+ default:
572
+ return value;
573
+ }
574
+ }
575
+ /**
576
+ * Get the isolation level SQL
577
+ */
578
+ getIsolationLevelSql(isolationLevel) {
579
+ if (!isolationLevel) {
580
+ return '';
581
+ }
582
+ const levels = {
583
+ 'READ UNCOMMITTED': 'READ UNCOMMITTED',
584
+ 'READ COMMITTED': 'READ COMMITTED',
585
+ 'REPEATABLE READ': 'REPEATABLE READ',
586
+ SERIALIZABLE: 'SERIALIZABLE',
587
+ };
588
+ const level = levels[isolationLevel];
589
+ return level ? `ISOLATION LEVEL ${level}` : '';
590
+ }
591
+ /**
592
+ * Resolve the 'all' include option to actual include configurations
593
+ */
594
+ resolveAllInclude(include, parentAlias, depth) {
595
+ const result = [];
596
+ const model = include.model;
597
+ const associations = model?.associations || {};
598
+ for (const [assocName, association] of Object.entries(associations)) {
599
+ // If 'all' is a string, only include that specific association
600
+ if (typeof include.all === 'string' && include.all !== assocName) {
601
+ continue;
602
+ }
603
+ const assocModel = association.target;
604
+ // Build the include config for this association
605
+ const assocInclude = {
606
+ model: assocModel,
607
+ as: assocName,
608
+ where: include.where,
609
+ required: include.required,
610
+ attributes: include.attributes,
611
+ order: include.order,
612
+ limit: include.limit,
613
+ offset: include.offset,
614
+ duplicating: include.duplicating,
615
+ };
616
+ // Handle nested includes within 'all' - recursively process them
617
+ if (include.include && include.include.length > 0) {
618
+ assocInclude.include = this.resolveAllInclude({ all: true, include: include.include }, assocName, depth + 1);
619
+ }
620
+ result.push(assocInclude);
621
+ }
622
+ return result;
623
+ }
624
+ /**
625
+ * Generate column list with proper aliasing to avoid duplicates
626
+ */
627
+ generateSelectColumns(mainTableName, mainTableAlias, attributes, includes) {
628
+ // If explicit attributes are provided, use those
629
+ if (attributes) {
630
+ if (Array.isArray(attributes)) {
631
+ // Add table alias prefix to avoid duplicates
632
+ return attributes
633
+ .map((a) => `${this.escapeId(mainTableAlias)}.${this.escapeId(a)}`)
634
+ .join(', ');
635
+ }
636
+ else if (attributes.include) {
637
+ return attributes.include
638
+ .map((a) => `${this.escapeId(mainTableAlias)}.${this.escapeId(a)}`)
639
+ .join(', ');
640
+ }
641
+ else if (attributes.exclude) {
642
+ // For exclude, we need to get all columns and exclude specific ones
643
+ // This is database-specific; for now, return * with EXCEPT
644
+ return `* EXCEPT (${attributes.exclude.map((a) => this.escapeId(a)).join(', ')})`;
645
+ }
646
+ }
647
+ // Default: select all columns from main table with alias prefix
648
+ // and all columns from included tables with their aliases
649
+ const mainColumns = [`${this.escapeId(mainTableAlias)}.*`];
650
+ // Add columns from included tables to avoid duplicates
651
+ if (includes && includes.length > 0) {
652
+ for (const inc of includes) {
653
+ mainColumns.push(`${this.escapeId(inc.alias)}.*`);
654
+ }
655
+ }
656
+ return mainColumns.join(', ');
657
+ }
658
+ /**
659
+ * Flatten nested includes to handle 'all' option
660
+ */
661
+ flattenIncludesWithAll(includes, parentAlias = 'main', depth = 0) {
662
+ const flattened = [];
663
+ for (const include of includes) {
664
+ // Handle 'all' option
665
+ if (include.all) {
666
+ const resolved = this.resolveAllInclude(include, parentAlias, depth);
667
+ for (const res of resolved) {
668
+ const nested = this.flattenIncludesWithAll([res], res.as || '', depth + 1);
669
+ flattened.push(...nested);
670
+ }
671
+ continue;
672
+ }
673
+ flattened.push(include);
674
+ // Recursively process nested includes
675
+ if (include.include && include.include.length > 0) {
676
+ const nested = this.flattenIncludesWithAll(include.include, include.as || include.model?.tableName || '', depth + 1);
677
+ // Replace nested includes with flattened versions
678
+ include.include = nested;
679
+ }
680
+ }
681
+ return flattened;
682
+ }
683
+ }
684
+ exports.BaseDialect = BaseDialect;
685
+ /**
686
+ * Dialect registry for managing available dialects
687
+ */
688
+ class DialectRegistry {
689
+ /**
690
+ * Register a new dialect
691
+ */
692
+ static register(name, factory) {
693
+ this.dialects.set(name.toLowerCase(), factory);
694
+ }
695
+ /**
696
+ * Get a dialect by name
697
+ */
698
+ static get(name) {
699
+ const factory = this.dialects.get(name.toLowerCase());
700
+ if (!factory) {
701
+ const available = Array.from(this.dialects.keys()).join(', ');
702
+ throw new Error(`Dialect "${name}" is not registered. Available dialects: ${available}`);
703
+ }
704
+ return factory;
705
+ }
706
+ /**
707
+ * Check if a dialect is registered
708
+ */
709
+ static has(name) {
710
+ return this.dialects.has(name.toLowerCase());
711
+ }
712
+ /**
713
+ * Get all registered dialect names
714
+ */
715
+ static getAvailable() {
716
+ return Array.from(this.dialects.keys());
717
+ }
718
+ }
719
+ exports.DialectRegistry = DialectRegistry;
720
+ DialectRegistry.dialects = new Map();