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,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ForeignTableRegistry = void 0;
4
+ exports.setForeignTableRedisClient = setForeignTableRedisClient;
5
+ exports.getForeignTableRedisClient = getForeignTableRedisClient;
6
+ exports.ForeignTable = ForeignTable;
7
+ exports.getForeignTableOptions = getForeignTableOptions;
8
+ exports.isForeignTable = isForeignTable;
9
+ exports.cacheForeignTableOptions = cacheForeignTableOptions;
10
+ exports.getCachedForeignTableOptions = getCachedForeignTableOptions;
11
+ exports.invalidateForeignTableCache = invalidateForeignTableCache;
12
+ exports.warmupForeignTableCache = warmupForeignTableCache;
13
+ let globalRedisClient = null;
14
+ function setForeignTableRedisClient(client) {
15
+ globalRedisClient = client;
16
+ }
17
+ function getForeignTableRedisClient() {
18
+ return globalRedisClient;
19
+ }
20
+ const FOREIGN_TABLE_KEY = '__orm_foreign_table__';
21
+ function ForeignTable(options) {
22
+ return function (target) {
23
+ const resolved = {
24
+ server: options.server,
25
+ foreignSchema: options.foreignSchema,
26
+ options: options.options,
27
+ userMappings: options.userMappings,
28
+ columns: options.columns,
29
+ ifNotExists: options.ifNotExists ?? true,
30
+ schema: options.schema ?? 'public',
31
+ cache: {
32
+ redis: options.cache?.redis ?? true,
33
+ ttl: options.cache?.ttl ?? 3600,
34
+ keyPrefix: options.cache?.keyPrefix ?? 'orm:foreign-table',
35
+ },
36
+ };
37
+ target[FOREIGN_TABLE_KEY] = resolved;
38
+ };
39
+ }
40
+ function getForeignTableOptions(target) {
41
+ return target[FOREIGN_TABLE_KEY];
42
+ }
43
+ function isForeignTable(target) {
44
+ return !!target[FOREIGN_TABLE_KEY];
45
+ }
46
+ function getCacheKey(target, prefix = 'orm:foreign-table') {
47
+ return prefix + ':' + target.name;
48
+ }
49
+ function serializeOptions(opts) {
50
+ return JSON.stringify(opts);
51
+ }
52
+ function deserializeOptions(data) {
53
+ return JSON.parse(data);
54
+ }
55
+ async function cacheForeignTableOptions(target, options) {
56
+ const opts = options ?? getForeignTableOptions(target);
57
+ if (!opts)
58
+ throw new Error('[ORM] Class ' + target.name + ' does not have @ForeignTable decorator.');
59
+ const cacheConfig = opts.cache;
60
+ if (!cacheConfig?.redis)
61
+ return;
62
+ const redis = globalRedisClient;
63
+ if (!redis) {
64
+ console.warn('[ORM] Redis client not configured, skipping cache write.');
65
+ return;
66
+ }
67
+ const key = getCacheKey(target, cacheConfig.keyPrefix);
68
+ const ttl = cacheConfig.ttl ?? 3600;
69
+ await redis.set(key, serializeOptions(opts), 'EX', ttl);
70
+ }
71
+ async function getCachedForeignTableOptions(target) {
72
+ const opts = getForeignTableOptions(target);
73
+ if (!opts)
74
+ return null;
75
+ const cacheConfig = opts.cache;
76
+ if (!cacheConfig?.redis)
77
+ return null;
78
+ const redis = globalRedisClient;
79
+ if (!redis)
80
+ return null;
81
+ const data = await redis.get(getCacheKey(target, cacheConfig.keyPrefix));
82
+ if (!data)
83
+ return null;
84
+ return deserializeOptions(data);
85
+ }
86
+ async function invalidateForeignTableCache(target) {
87
+ const opts = getForeignTableOptions(target);
88
+ if (!opts)
89
+ return;
90
+ const cacheConfig = opts.cache;
91
+ if (!cacheConfig?.redis)
92
+ return;
93
+ const redis = globalRedisClient;
94
+ if (!redis)
95
+ return;
96
+ await redis.del(getCacheKey(target, cacheConfig.keyPrefix));
97
+ }
98
+ async function warmupForeignTableCache(target, prorm) {
99
+ await cacheForeignTableOptions(target);
100
+ }
101
+ exports.ForeignTableRegistry = {
102
+ getOptions(target) {
103
+ return getForeignTableOptions(target);
104
+ },
105
+ isForeignTable(target) {
106
+ return isForeignTable(target);
107
+ },
108
+ getSQL(target) {
109
+ const opts = getForeignTableOptions(target);
110
+ if (!opts)
111
+ throw new Error('[ORM] Class ' + target.name + ' does not have a @ForeignTable decorator.');
112
+ if (!opts.server)
113
+ throw new Error('[ORM] @ForeignTable requires a server option.');
114
+ const schema = opts.schema ?? 'public';
115
+ const tableName = target.name;
116
+ const columns = opts.columns ?? {};
117
+ const columnDefs = Object.entries(columns)
118
+ .map(([name, col]) => {
119
+ let def = name + ' ' + col.type;
120
+ if (col.options)
121
+ def += ' ' + col.options;
122
+ return def;
123
+ })
124
+ .join(',\n ');
125
+ if (!columnDefs)
126
+ throw new Error('[ORM] @ForeignTable requires columns option.');
127
+ let sql = `CREATE FOREIGN TABLE "${tableName}" (\n ${columnDefs}\n) SERVER "${opts.server}"`;
128
+ if (opts.foreignSchema) {
129
+ sql += `\n OPTIONS (schema '${opts.foreignSchema}')`;
130
+ }
131
+ if (opts.ifNotExists) {
132
+ sql = sql.replace('CREATE FOREIGN TABLE', 'CREATE FOREIGN TABLE IF NOT EXISTS');
133
+ }
134
+ return sql;
135
+ },
136
+ };
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ /**
3
+ * Generated Column decorators for the ORM.
4
+ *
5
+ * Supports database-level computed columns:
6
+ * - VIRTUAL: Computed on read, not stored in DB
7
+ * - STORED: Computed on write, physically stored in DB
8
+ * - IDENTITY: Auto-increment primary key configuration
9
+ *
10
+ * Usage:
11
+ *
12
+ * // Virtual computed column (default)
13
+ * @Generated()
14
+ * get fullName() {
15
+ * return `${this.firstName} ${this.lastName}`;
16
+ * }
17
+ *
18
+ * // Stored computed column
19
+ * @Generated('stored')
20
+ * get total() {
21
+ * return this.price * this.quantity;
22
+ * }
23
+ *
24
+ * // With custom expression
25
+ * @Generated({
26
+ * as: 'CONCAT(first_name, " ", last_name)',
27
+ * type: 'varchar(255)',
28
+ * stored: true
29
+ * })
30
+ * fullName: string;
31
+ *
32
+ * // Identity/Auto-increment configuration
33
+ * @Generated({
34
+ * identity: true,
35
+ * start: 1,
36
+ * increment: 1,
37
+ * cache: 1000
38
+ * })
39
+ * id: number;
40
+ */
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.Generated = Generated;
43
+ exports.Identity = Identity;
44
+ exports.getGeneratedMetadata = getGeneratedMetadata;
45
+ exports.getIdentityMetadata = getIdentityMetadata;
46
+ exports.getAllGeneratedMetadata = getAllGeneratedMetadata;
47
+ exports.getAllIdentityMetadata = getAllIdentityMetadata;
48
+ exports.isGeneratedColumn = isGeneratedColumn;
49
+ exports.isIdentityColumn = isIdentityColumn;
50
+ exports.buildGeneratedSQL = buildGeneratedSQL;
51
+ exports.isStored = isStored;
52
+ require("reflect-metadata");
53
+ // ==================== Metadata Key ====================
54
+ /**
55
+ * Symbol for storing generated column metadata
56
+ */
57
+ const GENERATED_METADATA_KEY = Symbol('prorm:generated');
58
+ /**
59
+ * Symbol for storing identity/auto-increment metadata
60
+ */
61
+ const IDENTITY_METADATA_KEY = Symbol('prorm:identity');
62
+ // ==================== Decorators ====================
63
+ /**
64
+ * Decorator for generated/computed columns.
65
+ *
66
+ * Usage with getter (for computed properties):
67
+ *
68
+ * class User extends Model {
69
+ * @Generated()
70
+ * get fullName() {
71
+ * return `${this.firstName} ${this.lastName}`;
72
+ * }
73
+ * }
74
+ *
75
+ * Usage with options:
76
+ *
77
+ * @Generated({
78
+ * as: 'CONCAT(first_name, " ", last_name)',
79
+ * type: 'varchar(255)',
80
+ * stored: true
81
+ * })
82
+ * fullName: string;
83
+ *
84
+ * @param options - Generated column options or just storage type
85
+ */
86
+ function Generated(options) {
87
+ return function (target, propertyKey) {
88
+ const opts = normalizeOptions(options);
89
+ // Store metadata
90
+ const metadata = {
91
+ propertyName: String(propertyKey),
92
+ options: opts,
93
+ };
94
+ Reflect.defineMetadata(GENERATED_METADATA_KEY, metadata, target, String(propertyKey));
95
+ // Also handle identity separately if enabled
96
+ if (opts.identity) {
97
+ Reflect.defineMetadata(IDENTITY_METADATA_KEY, { propertyName: String(propertyKey), options: opts }, target, String(propertyKey));
98
+ }
99
+ };
100
+ }
101
+ /**
102
+ * Decorator specifically for identity/auto-increment columns.
103
+ *
104
+ * Usage:
105
+ *
106
+ * @Generated({
107
+ * identity: true,
108
+ * start: 1,
109
+ * increment: 1,
110
+ * cache: 1000
111
+ * })
112
+ * id: number;
113
+ *
114
+ * @param options - Identity configuration options
115
+ */
116
+ function Identity(options) {
117
+ return function (target, propertyKey) {
118
+ const opts = {
119
+ ...options,
120
+ identity: true,
121
+ };
122
+ Reflect.defineMetadata(IDENTITY_METADATA_KEY, { propertyName: String(propertyKey), options: opts }, target, String(propertyKey));
123
+ };
124
+ }
125
+ // ==================== Helper Functions ====================
126
+ /**
127
+ * Normalize options from various input formats
128
+ */
129
+ function normalizeOptions(options) {
130
+ if (!options) {
131
+ // `stored` is left undefined here rather than defaulting to `false`,
132
+ // because the correct default depends on the target dialect (see
133
+ // `isStored`) and the dialect isn't known at decoration time.
134
+ return {};
135
+ }
136
+ if (typeof options === 'string') {
137
+ return { stored: options === 'stored' };
138
+ }
139
+ return options;
140
+ }
141
+ /**
142
+ * Get generated column metadata for a property.
143
+ *
144
+ * @param target - The target class or prototype
145
+ * @param propertyKey - The property name
146
+ * @returns The generated metadata or undefined
147
+ */
148
+ function getGeneratedMetadata(target, propertyKey) {
149
+ return Reflect.getMetadata(GENERATED_METADATA_KEY, target, propertyKey);
150
+ }
151
+ /**
152
+ * Get identity metadata for a property.
153
+ *
154
+ * @param target - The target class or prototype
155
+ * @param propertyKey - The property name
156
+ * @returns The identity metadata or undefined
157
+ */
158
+ function getIdentityMetadata(target, propertyKey) {
159
+ return Reflect.getMetadata(IDENTITY_METADATA_KEY, target, propertyKey);
160
+ }
161
+ /**
162
+ * Get all generated column metadata for a class.
163
+ *
164
+ * @param target - The target class or prototype
165
+ * @returns Map of property names to their generated metadata
166
+ */
167
+ function getAllGeneratedMetadata(target) {
168
+ const result = new Map();
169
+ // Get all own property keys
170
+ const keys = Object.getOwnPropertyNames(target);
171
+ for (const key of keys) {
172
+ const metadata = getGeneratedMetadata(target, key);
173
+ if (metadata) {
174
+ result.set(key, metadata);
175
+ }
176
+ }
177
+ // Also check prototype chain for inherited metadata
178
+ const proto = Object.getPrototypeOf(target);
179
+ if (proto && Object.getPrototypeOf(proto) !== null) {
180
+ const inherited = getAllGeneratedMetadata(proto);
181
+ for (const [key, value] of inherited) {
182
+ if (!result.has(key)) {
183
+ result.set(key, value);
184
+ }
185
+ }
186
+ }
187
+ return result;
188
+ }
189
+ /**
190
+ * Get all identity metadata for a class.
191
+ *
192
+ * @param target - The target class or prototype
193
+ * @returns Map of property names to their identity metadata
194
+ */
195
+ function getAllIdentityMetadata(target) {
196
+ const result = new Map();
197
+ const keys = Object.getOwnPropertyNames(target);
198
+ for (const key of keys) {
199
+ const metadata = getIdentityMetadata(target, key);
200
+ if (metadata) {
201
+ result.set(key, metadata);
202
+ }
203
+ }
204
+ const proto = Object.getPrototypeOf(target);
205
+ if (proto && Object.getPrototypeOf(proto) !== null) {
206
+ const inherited = getAllIdentityMetadata(proto);
207
+ for (const [key, value] of inherited) {
208
+ if (!result.has(key)) {
209
+ result.set(key, value);
210
+ }
211
+ }
212
+ }
213
+ return result;
214
+ }
215
+ /**
216
+ * Check if a property is a generated column.
217
+ *
218
+ * @param target - The target class or prototype
219
+ * @param propertyKey - The property name
220
+ * @returns True if the property is generated
221
+ */
222
+ function isGeneratedColumn(target, propertyKey) {
223
+ return !!getGeneratedMetadata(target, propertyKey);
224
+ }
225
+ /**
226
+ * Check if a property is an identity/auto-increment column.
227
+ *
228
+ * @param target - The target class or prototype
229
+ * @param propertyKey - The property name
230
+ * @returns True if the property is an identity column
231
+ */
232
+ function isIdentityColumn(target, propertyKey) {
233
+ const metadata = getIdentityMetadata(target, propertyKey);
234
+ return !!metadata?.options.identity;
235
+ }
236
+ /**
237
+ * Build the SQL expression for a generated column.
238
+ *
239
+ * @param options - The generated column options
240
+ * @returns The SQL expression string
241
+ */
242
+ function buildGeneratedSQL(options) {
243
+ if (options.as) {
244
+ return options.as;
245
+ }
246
+ // If no custom expression, return empty
247
+ return '';
248
+ }
249
+ /**
250
+ * Check if generated column is stored (persisted) or virtual.
251
+ *
252
+ * When `options.stored` is explicitly set, that value is used as-is.
253
+ * When it is left unspecified, the default depends on the target dialect:
254
+ * - PostgreSQL (before v18) only supports `STORED` generated columns —
255
+ * `VIRTUAL` is not a valid option, so it defaults to `true` (stored).
256
+ * - MySQL/MariaDB support both `VIRTUAL` and `STORED`, and default to
257
+ * `VIRTUAL` (the lighter-weight option), so this defaults to `false`.
258
+ * - Other dialects (sqlite, mssql, oracle) also default to `false`
259
+ * (virtual/computed, not persisted), matching their typical defaults.
260
+ *
261
+ * @param options - The generated column options
262
+ * @param dialect - The target SQL dialect (defaults to 'mysql' for backwards compatibility)
263
+ * @returns True if stored, false if virtual
264
+ */
265
+ function isStored(options, dialect = 'mysql') {
266
+ if (options.stored !== undefined) {
267
+ return options.stored;
268
+ }
269
+ // PostgreSQL doesn't support VIRTUAL generated columns before v18 —
270
+ // fall back to STORED, the only option it actually supports.
271
+ return dialect === 'postgres';
272
+ }
273
+ // ==================== Exports ====================
274
+ // Types are exported inline with the interfaces/classes above
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * HasMany decorator for the ORM.
4
+ *
5
+ * Defines a one-to-many relationship between models.
6
+ *
7
+ * Usage:
8
+ *
9
+ * @HasMany(() => Post)
10
+ * posts: Post[];
11
+ *
12
+ * @HasMany(() => Post, { as: 'articles' })
13
+ * articles: Post[];
14
+ *
15
+ * // With options
16
+ * @HasMany(() => Order, {
17
+ * foreignKey: { name: 'user_id', allowNull: false },
18
+ * onDelete: 'CASCADE',
19
+ * through: 'user_orders' // For belongsToMany
20
+ * })
21
+ * orders: Order[];
22
+ *
23
+ * // Self-referential
24
+ * @HasMany(() => Category, { as: 'children', foreignKey: 'parent_id' })
25
+ * children: Category[];
26
+ *
27
+ * // Nested hasMany with scope
28
+ * @HasMany(() => Comment, {
29
+ * as: 'replies',
30
+ * foreignKey: 'parent_id',
31
+ * scope: { deleted: false }
32
+ * })
33
+ * replies: Comment[];
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getHasMany = getHasMany;
37
+ exports.getAllHasMany = getAllHasMany;
38
+ exports.HasMany = HasMany;
39
+ exports.processHasManyDecorators = processHasManyDecorators;
40
+ // ==================== Metadata Storage ====================
41
+ const HAS_MANY_KEY = '__orm_has_many__';
42
+ /**
43
+ * Get all @HasMany annotations attached to a model constructor.
44
+ */
45
+ function getHasMany(target) {
46
+ return target[HAS_MANY_KEY] || [];
47
+ }
48
+ /**
49
+ * Get all hasMany associations including inherited ones.
50
+ */
51
+ function getAllHasMany(target) {
52
+ const associations = [];
53
+ let current = target;
54
+ while (current && current.prototype) {
55
+ const meta = getHasMany(current);
56
+ associations.push(...meta);
57
+ current = Object.getPrototypeOf(current);
58
+ if (current === Object.prototype)
59
+ break;
60
+ }
61
+ return associations;
62
+ }
63
+ // ==================== Decorator ====================
64
+ /**
65
+ * Define a one-to-many relationship.
66
+ *
67
+ * This decorator stores metadata on the model class that can be used
68
+ * by the ORM to establish the association at model initialization time.
69
+ *
70
+ * @param target - A function that returns the target model class
71
+ * @param options - Optional configuration for the association
72
+ */
73
+ function HasMany(target, options = {}) {
74
+ return function (prototype, propertyKey) {
75
+ const ModelClass = prototype.constructor;
76
+ if (!ModelClass[HAS_MANY_KEY]) {
77
+ ModelClass[HAS_MANY_KEY] = [];
78
+ }
79
+ ModelClass[HAS_MANY_KEY].push({
80
+ target,
81
+ options: {
82
+ as: options.as || propertyKey.toString(),
83
+ foreignKey: options.foreignKey,
84
+ constraints: options.constraints,
85
+ onDelete: options.onDelete,
86
+ onUpdate: options.onUpdate,
87
+ targetKey: options.targetKey,
88
+ sourceKey: options.sourceKey,
89
+ scope: options.scope,
90
+ through: options.through,
91
+ inverse: options.inverse,
92
+ },
93
+ });
94
+ };
95
+ }
96
+ /**
97
+ * Process @HasMany decorators and create association configuration.
98
+ *
99
+ * Call this to get the raw association definitions from decorators.
100
+ *
101
+ * @param ModelClass - The model class with @HasMany decorators
102
+ * @returns Array of association configurations
103
+ */
104
+ function processHasManyDecorators(ModelClass) {
105
+ const decorators = getAllHasMany(ModelClass);
106
+ return decorators.map(({ target, options }) => {
107
+ const targetModel = target();
108
+ const foreignKey = typeof options.foreignKey === 'string'
109
+ ? options.foreignKey
110
+ : options.foreignKey?.name
111
+ ? options.foreignKey.name
112
+ : `${ModelClass.name}Id`;
113
+ return {
114
+ source: ModelClass,
115
+ target: targetModel,
116
+ foreignKey,
117
+ as: options.as || '',
118
+ options,
119
+ };
120
+ });
121
+ }
122
+ exports.default = {
123
+ HasMany,
124
+ getHasMany,
125
+ getAllHasMany,
126
+ processHasManyDecorators,
127
+ };
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * HasOne decorator for the ORM.
4
+ *
5
+ * Defines a one-to-one relationship between models.
6
+ *
7
+ * Usage:
8
+ *
9
+ * @HasOne(() => Profile)
10
+ * profile: Profile;
11
+ *
12
+ * @HasOne(() => Profile, { as: 'userProfile' })
13
+ * userProfile: Profile;
14
+ *
15
+ * // With options
16
+ * @HasOne(() => Profile, {
17
+ * foreignKey: { name: 'user_id', allowNull: false },
18
+ * onDelete: 'CASCADE'
19
+ * })
20
+ * profile: Profile;
21
+ *
22
+ * // Self-referential
23
+ * @HasOne(() => User, { as: 'manager', foreignKey: 'manager_id' })
24
+ * manager: User;
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.getHasOne = getHasOne;
28
+ exports.getAllHasOne = getAllHasOne;
29
+ exports.HasOne = HasOne;
30
+ exports.processHasOneDecorators = processHasOneDecorators;
31
+ // ==================== Metadata Storage ====================
32
+ const HAS_ONE_KEY = '__orm_has_one__';
33
+ /**
34
+ * Get all @HasOne annotations attached to a model constructor.
35
+ */
36
+ function getHasOne(target) {
37
+ return target[HAS_ONE_KEY] || [];
38
+ }
39
+ /**
40
+ * Get all hasOne associations including inherited ones.
41
+ */
42
+ function getAllHasOne(target) {
43
+ const associations = [];
44
+ let current = target;
45
+ while (current && current.prototype) {
46
+ const meta = getHasOne(current);
47
+ associations.push(...meta);
48
+ current = Object.getPrototypeOf(current);
49
+ if (current === Object.prototype)
50
+ break;
51
+ }
52
+ return associations;
53
+ }
54
+ // ==================== Decorator ====================
55
+ /**
56
+ * Define a one-to-one relationship.
57
+ *
58
+ * This decorator stores metadata on the model class that can be used
59
+ * by the ORM to establish the association at model initialization time.
60
+ *
61
+ * @param target - A function that returns the target model class
62
+ * @param options - Optional configuration for the association
63
+ */
64
+ function HasOne(target, options = {}) {
65
+ return function (prototype, propertyKey) {
66
+ const ModelClass = prototype.constructor;
67
+ if (!ModelClass[HAS_ONE_KEY]) {
68
+ ModelClass[HAS_ONE_KEY] = [];
69
+ }
70
+ ModelClass[HAS_ONE_KEY].push({
71
+ target,
72
+ options: {
73
+ as: options.as || propertyKey.toString(),
74
+ foreignKey: options.foreignKey,
75
+ constraints: options.constraints,
76
+ onDelete: options.onDelete,
77
+ onUpdate: options.onUpdate,
78
+ targetKey: options.targetKey,
79
+ sourceKey: options.sourceKey,
80
+ inverse: options.inverse,
81
+ },
82
+ });
83
+ };
84
+ }
85
+ /**
86
+ * Process @HasOne decorators and create association configuration.
87
+ *
88
+ * Call this to get the raw association definitions from decorators.
89
+ *
90
+ * @param ModelClass - The model class with @HasOne decorators
91
+ * @returns Array of association configurations
92
+ */
93
+ function processHasOneDecorators(ModelClass) {
94
+ const decorators = getAllHasOne(ModelClass);
95
+ return decorators.map(({ target, options }) => {
96
+ const targetModel = target();
97
+ const foreignKey = typeof options.foreignKey === 'string'
98
+ ? options.foreignKey
99
+ : options.foreignKey?.name
100
+ ? options.foreignKey.name
101
+ : `${ModelClass.name}Id`;
102
+ return {
103
+ source: ModelClass,
104
+ target: targetModel,
105
+ foreignKey,
106
+ as: options.as || '',
107
+ options,
108
+ };
109
+ });
110
+ }
111
+ exports.default = {
112
+ HasOne,
113
+ getHasOne,
114
+ getAllHasOne,
115
+ processHasOneDecorators,
116
+ };