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,556 @@
1
+ "use strict";
2
+ /**
3
+ * Query options and performance hint decorators for the ORM.
4
+ *
5
+ * Provides decorators for controlling query execution:
6
+ * - Query hints (index hints, force index, ignore index)
7
+ * - Lock options (row locking, timeout, skip locked)
8
+ * - Statement timeout
9
+ * - Idle in transaction timeout
10
+ * - Cursor-based fetching
11
+ * - FETCH options (FIRST, OFFSET)
12
+ * - DISTINCT ON (PostgreSQL)
13
+ * - TABLESAMPLE
14
+ *
15
+ * Usage:
16
+ *
17
+ * // Index hints
18
+ * @UseIndex('idx_name')
19
+ * @ForceIndex('idx_name')
20
+ * @IgnoreIndex('idx_name')
21
+ * class User extends Model {}
22
+ *
23
+ * // Lock options (method decorator)
24
+ * @WithLock({ mode: 'UPDATE', timeout: 5000, skipLocked: true })
25
+ * async processOrder(id: number) { ... }
26
+ *
27
+ * // Statement timeout (method decorator)
28
+ * @StatementTimeout(30000)
29
+ * async runLongQuery() { ... }
30
+ *
31
+ * // Cursor-based fetch
32
+ * @Cursor({ holdable: true })
33
+ * async *getAllUsers() { ... }
34
+ *
35
+ * // FETCH options
36
+ * @Fetch(100)
37
+ * @Distinct
38
+ * async *getUsers() { ... }
39
+ *
40
+ * // TABLESAMPLE
41
+ * @Tablesample({ method: 'BERNOULLI', percentage: 50 })
42
+ * async *getSampleUsers() { ... }
43
+ */
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.DistinctOn = void 0;
46
+ exports.UseIndex = UseIndex;
47
+ exports.ForceIndex = ForceIndex;
48
+ exports.IgnoreIndex = IgnoreIndex;
49
+ exports.Tablesample = Tablesample;
50
+ exports.Distinct = Distinct;
51
+ exports.WithLock = WithLock;
52
+ exports.StatementTimeout = StatementTimeout;
53
+ exports.IdleInTransactionTimeout = IdleInTransactionTimeout;
54
+ exports.Cursor = Cursor;
55
+ exports.Fetch = Fetch;
56
+ exports.FetchWith = FetchWith;
57
+ exports.getQueryHints = getQueryHints;
58
+ exports.getLockOptions = getLockOptions;
59
+ exports.getStatementTimeout = getStatementTimeout;
60
+ exports.getIdleInTransactionTimeout = getIdleInTransactionTimeout;
61
+ exports.getCursorOptions = getCursorOptions;
62
+ exports.getFetchOptions = getFetchOptions;
63
+ exports.getDistinctOnColumns = getDistinctOnColumns;
64
+ exports.getTablesampleOptions = getTablesampleOptions;
65
+ exports.isDistinctEnabled = isDistinctEnabled;
66
+ exports.generateIndexHintSQL = generateIndexHintSQL;
67
+ exports.generateLockSQL = generateLockSQL;
68
+ exports.generateStatementTimeoutSQL = generateStatementTimeoutSQL;
69
+ exports.generateIdleInTransactionTimeoutSQL = generateIdleInTransactionTimeoutSQL;
70
+ exports.generateTablesampleSQL = generateTablesampleSQL;
71
+ exports.generateDistinctOnSQL = generateDistinctOnSQL;
72
+ exports.generateCursorSQL = generateCursorSQL;
73
+ require("reflect-metadata");
74
+ // ==================== Metadata Keys ====================
75
+ const QUERY_HINTS_KEY = Symbol('prorm:queryHints');
76
+ const LOCK_OPTIONS_KEY = Symbol('prorm:lockOptions');
77
+ const STATEMENT_TIMEOUT_KEY = Symbol('prorm:statementTimeout');
78
+ const IDLE_TRANSACTION_TIMEOUT_KEY = Symbol('prorm:idleInTransactionTimeout');
79
+ const CURSOR_OPTIONS_KEY = Symbol('prorm:cursorOptions');
80
+ const FETCH_OPTIONS_KEY = Symbol('prorm:fetchOptions');
81
+ const DISTINCT_ON_KEY = Symbol('prorm:distinctOn');
82
+ const TABLESAMPLE_KEY = Symbol('prorm:tablesample');
83
+ const DISTINCT_KEY = Symbol('prorm:distinct');
84
+ // ==================== Class Decorators ====================
85
+ /**
86
+ * Decorator to specify USE INDEX hint.
87
+ * Suggest the optimizer to use a specific index.
88
+ *
89
+ * Usage:
90
+ *
91
+ * @UseIndex('idx_user_email')
92
+ * @UseIndex(['idx_user_email', 'idx_user_status'])
93
+ * class User extends Model {}
94
+ *
95
+ * @param index - Index name or array of index names
96
+ */
97
+ function UseIndex(index) {
98
+ return function (target) {
99
+ const indexes = Array.isArray(index) ? index : [index];
100
+ const existing = Reflect.getMetadata(QUERY_HINTS_KEY, target) || {};
101
+ existing.useIndex = [...(existing.useIndex || []), ...indexes];
102
+ Reflect.defineMetadata(QUERY_HINTS_KEY, existing, target);
103
+ };
104
+ }
105
+ /**
106
+ * Decorator to specify FORCE INDEX hint.
107
+ * Force the optimizer to use a specific index.
108
+ *
109
+ * Usage:
110
+ *
111
+ * @ForceIndex('idx_user_email')
112
+ * class User extends Model {}
113
+ *
114
+ * @param index - Index name
115
+ */
116
+ function ForceIndex(index) {
117
+ return function (target) {
118
+ const indexes = Array.isArray(index) ? index : [index];
119
+ const existing = Reflect.getMetadata(QUERY_HINTS_KEY, target) || {};
120
+ existing.forceIndex = [...(existing.forceIndex || []), ...indexes];
121
+ Reflect.defineMetadata(QUERY_HINTS_KEY, existing, target);
122
+ };
123
+ }
124
+ /**
125
+ * Decorator to specify IGNORE INDEX hint.
126
+ * Tell the optimizer to ignore a specific index.
127
+ *
128
+ * Usage:
129
+ *
130
+ * @IgnoreIndex('idx_user_email')
131
+ * class User extends Model {}
132
+ *
133
+ * @param index - Index name
134
+ */
135
+ function IgnoreIndex(index) {
136
+ return function (target) {
137
+ const indexes = Array.isArray(index) ? index : [index];
138
+ const existing = Reflect.getMetadata(QUERY_HINTS_KEY, target) || {};
139
+ existing.ignoreIndex = [...(existing.ignoreIndex || []), ...indexes];
140
+ Reflect.defineMetadata(QUERY_HINTS_KEY, existing, target);
141
+ };
142
+ }
143
+ /**
144
+ * Decorator to set tablesample for query.
145
+ * Sample a subset of rows for query performance.
146
+ *
147
+ * Usage:
148
+ *
149
+ * @Tablesample({ method: 'BERNOULLI', percentage: 50 })
150
+ * class User extends Model {}
151
+ *
152
+ * @Tablesample({ method: 'SYSTEM', pages: 100 })
153
+ * class User extends Model {}
154
+ *
155
+ * @param options - Tablesample options
156
+ */
157
+ function Tablesample(options) {
158
+ return function (target) {
159
+ Reflect.defineMetadata(TABLESAMPLE_KEY, options, target);
160
+ };
161
+ }
162
+ /**
163
+ * Decorator to enable DISTINCT ON (PostgreSQL).
164
+ *
165
+ * Usage:
166
+ *
167
+ * @Distinct
168
+ * class User extends Model {}
169
+ *
170
+ * @DistinctOn(['email'])
171
+ * class User extends Model {}
172
+ *
173
+ * @param columns - Columns for DISTINCT ON (optional)
174
+ */
175
+ function Distinct(columns) {
176
+ return function (target) {
177
+ if (columns?.length) {
178
+ Reflect.defineMetadata(DISTINCT_ON_KEY, columns, target);
179
+ }
180
+ else {
181
+ Reflect.defineMetadata(DISTINCT_KEY, true, target);
182
+ }
183
+ };
184
+ }
185
+ /**
186
+ * Alias for @Distinct for DISTINCT ON
187
+ */
188
+ exports.DistinctOn = Distinct;
189
+ // ==================== Method Decorators ====================
190
+ /**
191
+ * Decorator to apply row lock to a method.
192
+ * Provides options for locking rows during query execution.
193
+ *
194
+ * Usage:
195
+ *
196
+ * @WithLock({ mode: 'UPDATE', timeout: 5000, skipLocked: true })
197
+ * async processOrder(id: number) {
198
+ * const order = await Order.findByPk(id, { lock: 'UPDATE' });
199
+ * // process order
200
+ * }
201
+ *
202
+ * @param options - Lock options
203
+ */
204
+ function WithLock(options = {}) {
205
+ return function (target, propertyKey, descriptor) {
206
+ const lockOptions = {
207
+ mode: options.mode || 'UPDATE',
208
+ timeout: options.timeout || 30000,
209
+ skipLocked: options.skipLocked || false,
210
+ tables: options.tables,
211
+ };
212
+ Reflect.defineMetadata(LOCK_OPTIONS_KEY, lockOptions, target, propertyKey);
213
+ // Wrap the method to apply lock context
214
+ const originalMethod = descriptor.value;
215
+ descriptor.value = async function (...args) {
216
+ // Note: In practice, this would acquire the lock via prorm.transaction
217
+ // The lock is applied when queries are executed within the method
218
+ return originalMethod.apply(this, args);
219
+ };
220
+ return descriptor;
221
+ };
222
+ }
223
+ /**
224
+ * Decorator to set statement timeout.
225
+ * Abort queries that take longer than the specified timeout.
226
+ *
227
+ * Usage:
228
+ *
229
+ * @StatementTimeout(30000) // 30 seconds
230
+ * async runLongQuery() {
231
+ * return await this.query('SELECT * FROM large_table');
232
+ * }
233
+ *
234
+ * @param timeout - Timeout in milliseconds
235
+ */
236
+ function StatementTimeout(timeout) {
237
+ return function (target, propertyKey, descriptor) {
238
+ Reflect.defineMetadata(STATEMENT_TIMEOUT_KEY, { timeout, scope: 'session' }, target, propertyKey);
239
+ // Wrap the method to set timeout
240
+ const originalMethod = descriptor.value;
241
+ descriptor.value = async function (...args) {
242
+ // Note: In practice, this would set the timeout before executing
243
+ // and reset it after the method completes
244
+ return originalMethod.apply(this, args);
245
+ };
246
+ return descriptor;
247
+ };
248
+ }
249
+ /**
250
+ * Decorator to set idle in transaction timeout.
251
+ * Abort transactions that are idle for longer than the specified timeout.
252
+ *
253
+ * Usage:
254
+ *
255
+ * @IdleInTransactionTimeout(60000) // 1 minute
256
+ * async runTransaction() {
257
+ * // long running transaction
258
+ * }
259
+ *
260
+ * @param timeout - Timeout in milliseconds
261
+ */
262
+ function IdleInTransactionTimeout(timeout) {
263
+ return function (target, propertyKey, descriptor) {
264
+ Reflect.defineMetadata(IDLE_TRANSACTION_TIMEOUT_KEY, { timeout, scope: 'session' }, target, propertyKey);
265
+ return descriptor;
266
+ };
267
+ }
268
+ /**
269
+ * Decorator to use cursor-based fetching.
270
+ * Useful for processing large result sets in batches.
271
+ *
272
+ * Usage:
273
+ *
274
+ * @Cursor({ holdable: true })
275
+ * async *getAllUsers() {
276
+ * for await (const user of this.findAll({ cursor: true })) {
277
+ * yield user;
278
+ * }
279
+ * }
280
+ *
281
+ * @param options - Cursor options
282
+ */
283
+ function Cursor(options = {}) {
284
+ return function (target, propertyKey, descriptor) {
285
+ const cursorOptions = {
286
+ holdable: options.holdable || 'WITHOUT HOLD',
287
+ name: options.name,
288
+ scroll: options.scroll ?? true,
289
+ };
290
+ Reflect.defineMetadata(CURSOR_OPTIONS_KEY, cursorOptions, target, propertyKey);
291
+ return descriptor;
292
+ };
293
+ }
294
+ /**
295
+ * Decorator to set FETCH FIRST limit.
296
+ * Limits the number of rows returned by a query.
297
+ *
298
+ * Usage:
299
+ *
300
+ * @Fetch(100)
301
+ * async *getTopUsers() {
302
+ * return await User.findAll({ limit: 100 });
303
+ * }
304
+ *
305
+ * @param limit - Number of rows to fetch
306
+ */
307
+ function Fetch(limit) {
308
+ return function (target, propertyKey, descriptor) {
309
+ Reflect.defineMetadata(FETCH_OPTIONS_KEY, { limit, offset: 0 }, target, propertyKey);
310
+ return descriptor;
311
+ };
312
+ }
313
+ /**
314
+ * Decorator to set FETCH with offset.
315
+ * Useful for pagination.
316
+ *
317
+ * Usage:
318
+ *
319
+ * @Fetch({ first: 100, offset: 50 })
320
+ * async *getPageUsers() {
321
+ * return await User.findAll({ offset: 50, limit: 100 });
322
+ * }
323
+ *
324
+ * @param options - Fetch options with limit and optional offset
325
+ */
326
+ function FetchWith(options) {
327
+ return function (target, propertyKey, descriptor) {
328
+ Reflect.defineMetadata(FETCH_OPTIONS_KEY, { limit: options.first, offset: options.offset || 0 }, target, propertyKey);
329
+ return descriptor;
330
+ };
331
+ }
332
+ // ==================== Helper Functions ====================
333
+ /**
334
+ * Get query hints for a model.
335
+ *
336
+ * @param target - The target class or prototype
337
+ * @returns Query hints or undefined
338
+ */
339
+ function getQueryHints(target) {
340
+ return Reflect.getMetadata(QUERY_HINTS_KEY, target);
341
+ }
342
+ /**
343
+ * Get lock options for a method.
344
+ *
345
+ * @param target - The target object
346
+ * @param propertyKey - The property key
347
+ * @returns Lock options or undefined
348
+ */
349
+ function getLockOptions(target, propertyKey) {
350
+ return Reflect.getMetadata(LOCK_OPTIONS_KEY, target, propertyKey);
351
+ }
352
+ /**
353
+ * Get statement timeout for a method.
354
+ *
355
+ * @param target - The target object
356
+ * @param propertyKey - The property key
357
+ * @returns Statement timeout options or undefined
358
+ */
359
+ function getStatementTimeout(target, propertyKey) {
360
+ return Reflect.getMetadata(STATEMENT_TIMEOUT_KEY, target, propertyKey);
361
+ }
362
+ /**
363
+ * Get idle transaction timeout for a method.
364
+ *
365
+ * @param target - The target object
366
+ * @param propertyKey - The property key
367
+ * @returns Idle transaction timeout options or undefined
368
+ */
369
+ function getIdleInTransactionTimeout(target, propertyKey) {
370
+ return Reflect.getMetadata(IDLE_TRANSACTION_TIMEOUT_KEY, target, propertyKey);
371
+ }
372
+ /**
373
+ * Get cursor options for a method.
374
+ *
375
+ * @param target - The target object
376
+ * @param propertyKey - The property key
377
+ * @returns Cursor options or undefined
378
+ */
379
+ function getCursorOptions(target, propertyKey) {
380
+ return Reflect.getMetadata(CURSOR_OPTIONS_KEY, target, propertyKey);
381
+ }
382
+ /**
383
+ * Get FETCH options for a method.
384
+ *
385
+ * @param target - The target object
386
+ * @param propertyKey - The property key
387
+ * @returns FETCH options or undefined
388
+ */
389
+ function getFetchOptions(target, propertyKey) {
390
+ return Reflect.getMetadata(FETCH_OPTIONS_KEY, target, propertyKey);
391
+ }
392
+ /**
393
+ * Get DISTINCT ON columns for a model.
394
+ *
395
+ * @param target - The target class or prototype
396
+ * @returns DISTINCT ON columns or undefined
397
+ */
398
+ function getDistinctOnColumns(target) {
399
+ return Reflect.getMetadata(DISTINCT_ON_KEY, target);
400
+ }
401
+ /**
402
+ * Get tablesample options for a model.
403
+ *
404
+ * @param target - The target class or prototype
405
+ * @returns Tablesample options or undefined
406
+ */
407
+ function getTablesampleOptions(target) {
408
+ return Reflect.getMetadata(TABLESAMPLE_KEY, target);
409
+ }
410
+ /**
411
+ * Check if DISTINCT is enabled for a model.
412
+ *
413
+ * @param target - The target class or prototype
414
+ * @returns True if DISTINCT is enabled
415
+ */
416
+ function isDistinctEnabled(target) {
417
+ return Reflect.getMetadata(DISTINCT_KEY, target) === true;
418
+ }
419
+ /**
420
+ * Generate index hint SQL.
421
+ *
422
+ * @param hints - Query hints
423
+ * @param dialect - Database dialect
424
+ * @returns SQL string or undefined
425
+ */
426
+ function generateIndexHintSQL(hints, dialect) {
427
+ const parts = [];
428
+ if (dialect === 'mysql' || dialect === 'mariadb') {
429
+ if (hints.useIndex?.length) {
430
+ parts.push(`USE INDEX (${hints.useIndex.join(', ')})`);
431
+ }
432
+ if (hints.forceIndex?.length) {
433
+ parts.push(`FORCE INDEX (${hints.forceIndex.join(', ')})`);
434
+ }
435
+ if (hints.ignoreIndex?.length) {
436
+ parts.push(`IGNORE INDEX (${hints.ignoreIndex.join(', ')})`);
437
+ }
438
+ }
439
+ if (dialect === 'sqlserver') {
440
+ if (hints.useIndex?.length) {
441
+ parts.push(`WITH (INDEX(${hints.useIndex.join(', ')}))`);
442
+ }
443
+ }
444
+ return parts.length > 0 ? parts.join(' ') : undefined;
445
+ }
446
+ /**
447
+ * Generate lock SQL.
448
+ *
449
+ * @param options - Lock options
450
+ * @returns SQL FOR clause or undefined
451
+ */
452
+ function generateLockSQL(options) {
453
+ if (options.mode === 'UPDATE') {
454
+ return 'FOR UPDATE' + (options.skipLocked ? ' SKIP LOCKED' : '');
455
+ }
456
+ if (options.mode === 'SHARE') {
457
+ return 'FOR SHARE' + (options.skipLocked ? ' SKIP LOCKED' : '');
458
+ }
459
+ if (options.mode === 'UPDATE NOWAIT') {
460
+ return 'FOR UPDATE NOWAIT';
461
+ }
462
+ if (options.mode === 'SHARE NOWAIT') {
463
+ return 'FOR SHARE NOWAIT';
464
+ }
465
+ if (options.mode === 'UPDATE SKIP LOCKED') {
466
+ return 'FOR UPDATE SKIP LOCKED';
467
+ }
468
+ return undefined;
469
+ }
470
+ /**
471
+ * Generate statement timeout SQL.
472
+ *
473
+ * @param timeout - Timeout in milliseconds
474
+ * @param scope - Session or global
475
+ * @returns SQL string
476
+ */
477
+ function generateStatementTimeoutSQL(timeout, scope = 'session') {
478
+ if (timeout <= 0) {
479
+ return `SET ${scope} statement_timeout = 0`;
480
+ }
481
+ return `SET ${scope} statement_timeout = '${timeout}ms'`;
482
+ }
483
+ /**
484
+ * Generate idle in transaction timeout SQL.
485
+ *
486
+ * @param timeout - Timeout in milliseconds
487
+ * @param scope - Session or global
488
+ * @returns SQL string
489
+ */
490
+ function generateIdleInTransactionTimeoutSQL(timeout, scope = 'session') {
491
+ return `SET ${scope} idle_in_transaction_session_timeout = '${timeout}ms'`;
492
+ }
493
+ /**
494
+ * Generate tablesample SQL.
495
+ *
496
+ * @param options - Tablesample options
497
+ * @returns SQL TABLESAMPLE clause
498
+ */
499
+ function generateTablesampleSQL(options) {
500
+ const { method, percentage, pages, seed, repeatable } = options;
501
+ if (method === 'BERNOULLI') {
502
+ let sql = `TABLESAMPLE BERNOULLI(${percentage || 10})`;
503
+ if (repeatable !== undefined) {
504
+ sql += ` REPEATABLE(${repeatable})`;
505
+ }
506
+ else if (seed !== undefined) {
507
+ sql += ` REPEATABLE(${seed})`;
508
+ }
509
+ return sql;
510
+ }
511
+ if (method === 'SYSTEM') {
512
+ if (pages) {
513
+ let sql = `TABLESAMPLE SYSTEM(${pages})`;
514
+ if (repeatable !== undefined) {
515
+ sql += ` REPEATABLE(${repeatable})`;
516
+ }
517
+ return sql;
518
+ }
519
+ let sql = `TABLESAMPLE SYSTEM(${percentage || 10})`;
520
+ if (repeatable !== undefined) {
521
+ sql += ` REPEATABLE(${repeatable})`;
522
+ }
523
+ return sql;
524
+ }
525
+ if (method === 'SYSTEM_TIME') {
526
+ const timestamp = options.timestamp
527
+ ? typeof options.timestamp === 'string'
528
+ ? `'${options.timestamp}'`
529
+ : `'${options.timestamp.toISOString()}'`
530
+ : "timestamp 'now'";
531
+ return `TABLESAMPLE SYSTEM_TIME(${timestamp})`;
532
+ }
533
+ return '';
534
+ }
535
+ /**
536
+ * Generate DISTINCT ON SQL (PostgreSQL).
537
+ *
538
+ * @param columns - DISTINCT ON columns
539
+ * @returns SQL DISTINCT ON clause
540
+ */
541
+ function generateDistinctOnSQL(columns) {
542
+ return `DISTINCT ON (${columns.join(', ')})`;
543
+ }
544
+ /**
545
+ * Generate cursor SQL.
546
+ *
547
+ * @param options - Cursor options
548
+ * @param name - Cursor name (optional)
549
+ * @returns SQL DECLARE CURSOR statement
550
+ */
551
+ function generateCursorSQL(options, name) {
552
+ const cursorName = name || options.name || 'cursor';
553
+ const hold = options.holdable === 'HOLD' ? 'WITH HOLD' : 'WITHOUT HOLD';
554
+ const scroll = options.scroll !== false ? 'SCROLL' : 'NO SCROLL';
555
+ return `DECLARE ${cursorName} CURSOR ${scroll} ${hold} FOR`;
556
+ }
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ * Range Decorator for the ORM
4
+ *
5
+ * Provides PostgreSQL Range Types support.
6
+ * Range types: int4range, int8range, numrange, tsrange, tstzrange, daterange
7
+ *
8
+ * Usage:
9
+ *
10
+ * // Timestamp range
11
+ * @Range('tsrange')
12
+ * duration: [Date, Date];
13
+ *
14
+ * // Integer range
15
+ * @Range('int4range')
16
+ * quantity: [number, number];
17
+ *
18
+ * // Date range
19
+ * @Range('daterange')
20
+ * dates: [string, string];
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.Range = Range;
24
+ exports.getRangeMetadata = getRangeMetadata;
25
+ exports.getAllRangeMetadata = getAllRangeMetadata;
26
+ exports.isRangeColumn = isRangeColumn;
27
+ exports.clearRangeMetadata = clearRangeMetadata;
28
+ exports.buildRangeLiteral = buildRangeLiteral;
29
+ exports.getRangeContainedBySQL = getRangeContainedBySQL;
30
+ exports.getRangeOverlapSQL = getRangeOverlapSQL;
31
+ // ==================== Registry ====================
32
+ const rangeMetadataMap = new Map();
33
+ /**
34
+ * Range decorator for PostgreSQL Range columns
35
+ *
36
+ * @param options - Required range options (subtype is required)
37
+ *
38
+ * @example
39
+ * // Timestamp range
40
+ * class Reservation extends Model {
41
+ * @Range({ subtype: 'tsrange' })
42
+ * during: [Date, Date];
43
+ * }
44
+ *
45
+ * // Date range
46
+ * class Event extends Model {
47
+ * @Range({ subtype: 'daterange' })
48
+ * dates: [string, string];
49
+ * }
50
+ *
51
+ * // Integer range
52
+ * class Inventory extends Model {
53
+ * @Range({ subtype: 'int4range', allowNull: false })
54
+ * quantity: [number, number];
55
+ * }
56
+ */
57
+ function Range(options) {
58
+ return function (target, propertyKey) {
59
+ const decoratorOptions = {
60
+ ...options,
61
+ subtype: 'int4range',
62
+ allowNull: true,
63
+ };
64
+ // Validate subtype
65
+ const validSubtypes = [
66
+ 'int4range',
67
+ 'int8range',
68
+ 'numrange',
69
+ 'tsrange',
70
+ 'tstzrange',
71
+ 'daterange',
72
+ ];
73
+ if (!validSubtypes.includes(decoratorOptions.subtype)) {
74
+ throw new Error(`Invalid range subtype: ${decoratorOptions.subtype}. Valid subtypes: ${validSubtypes.join(', ')}`);
75
+ }
76
+ // Get or create metadata map for this class
77
+ if (!rangeMetadataMap.has(target.constructor)) {
78
+ rangeMetadataMap.set(target.constructor, new Map());
79
+ }
80
+ const metadataMap = rangeMetadataMap.get(target.constructor);
81
+ // Store metadata
82
+ metadataMap.set(propertyKey, {
83
+ options: decoratorOptions,
84
+ });
85
+ };
86
+ }
87
+ /**
88
+ * Get Range metadata for a property
89
+ *
90
+ * @param target - The target class
91
+ * @param propertyKey - The property name
92
+ * @returns Range metadata or undefined if not found
93
+ */
94
+ function getRangeMetadata(target, propertyKey) {
95
+ const metadataMap = rangeMetadataMap.get(target.constructor);
96
+ if (!metadataMap) {
97
+ return undefined;
98
+ }
99
+ return metadataMap.get(propertyKey);
100
+ }
101
+ /**
102
+ * Get all Range metadata for a class
103
+ *
104
+ * @param target - The target class
105
+ * @returns Map of property names to Range metadata
106
+ */
107
+ function getAllRangeMetadata(target) {
108
+ return rangeMetadataMap.get(target.constructor) || new Map();
109
+ }
110
+ /**
111
+ * Check if a property is a Range column
112
+ *
113
+ * @param target - The target class
114
+ * @param propertyKey - The property name
115
+ * @returns True if the property is a Range column
116
+ */
117
+ function isRangeColumn(target, propertyKey) {
118
+ const metadata = getRangeMetadata(target, propertyKey);
119
+ return metadata !== undefined;
120
+ }
121
+ /**
122
+ * Clear Range metadata (useful for testing)
123
+ */
124
+ function clearRangeMetadata() {
125
+ rangeMetadataMap.clear();
126
+ }
127
+ /**
128
+ * Build the SQL for a range literal
129
+ *
130
+ * @param lower - Lower bound of the range
131
+ * @param upper - Upper bound of the range
132
+ * @param options - Options for the range
133
+ * @returns SQL for the range literal
134
+ */
135
+ function buildRangeLiteral(lower, upper, options) {
136
+ const lowerBracket = options?.inclusiveLower !== false ? '[' : '(';
137
+ const upperBracket = options?.inclusiveUpper !== false ? ']' : ')';
138
+ const formatBound = (bound) => {
139
+ if (bound === null || bound === undefined) {
140
+ return '';
141
+ }
142
+ if (typeof bound === 'string') {
143
+ return `'${bound}'`;
144
+ }
145
+ if (bound instanceof Date) {
146
+ return `'${bound.toISOString()}'`;
147
+ }
148
+ return String(bound);
149
+ };
150
+ return `${lowerBracket}${formatBound(lower)}, ${formatBound(upper)}${upperBracket}::${'tsrange'}`;
151
+ }
152
+ /**
153
+ * Get the SQL operator for range containment
154
+ *
155
+ * @returns SQL for the @> operator
156
+ */
157
+ function getRangeContainedBySQL() {
158
+ return '<@';
159
+ }
160
+ /**
161
+ * Get the SQL operator for range overlap
162
+ *
163
+ * @returns SQL for the && operator
164
+ */
165
+ function getRangeOverlapSQL() {
166
+ return '&&';
167
+ }