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,411 @@
1
+ "use strict";
2
+ /**
3
+ * Migrator class - Manages the migration workflow
4
+ * Handles registering, running, and reverting migrations
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.Migrator = void 0;
41
+ exports.createMigrator = createMigrator;
42
+ exports.createMigration = createMigration;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const migration_1 = require("./migration");
46
+ const prormmigration_1 = require("./prormmigration");
47
+ /**
48
+ * Migrator class - Manages database migrations
49
+ */
50
+ class Migrator {
51
+ /**
52
+ * Create a new Migrator instance
53
+ * @param options - Configuration options
54
+ */
55
+ constructor(options) {
56
+ this.migrations = new Map();
57
+ /**
58
+ * Default filter for migration files
59
+ */
60
+ this.defaultFilter = (filename) => {
61
+ const ext = path.extname(filename);
62
+ return ext === this.extension || ext === '.ts';
63
+ };
64
+ this.prorm = options.prorm;
65
+ this.path = options.path || './migrations';
66
+ this.extension = options.extension || '.js';
67
+ this.filter = options.filter || this.defaultFilter;
68
+ const migrationOptions = {
69
+ prorm: options.prorm,
70
+ tableName: options.tableName || 'PrormMeta',
71
+ schema: options.schema,
72
+ };
73
+ this.PrormMigration = new prormmigration_1.PrormMigration(migrationOptions);
74
+ }
75
+ /**
76
+ * Get the PrormMigration instance
77
+ */
78
+ getPrormMigration() {
79
+ return this.PrormMigration;
80
+ }
81
+ /**
82
+ * Get the QueryInterface
83
+ */
84
+ getQueryInterface() {
85
+ return this.PrormMigration.getQueryInterface();
86
+ }
87
+ /**
88
+ * Register a migration file
89
+ * @param migrationPath - Path to the migration file
90
+ */
91
+ async migration(migrationPath) {
92
+ const migration = await this.loadMigrationFile(migrationPath);
93
+ const name = path.basename(migrationPath, path.extname(migrationPath));
94
+ this.migrations.set(name, migration);
95
+ }
96
+ /**
97
+ * Ensure TypeScript migration files can be loaded via require().
98
+ * Lazily registers ts-node/register the first time a .ts migration is loaded.
99
+ */
100
+ ensureTsNodeRegistered(filePath) {
101
+ if (Migrator.tsNodeRegistered) {
102
+ return;
103
+ }
104
+ try {
105
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
106
+ require('ts-node/register');
107
+ Migrator.tsNodeRegistered = true;
108
+ }
109
+ catch (error) {
110
+ throw new Error(`Cannot load TypeScript migration "${filePath}": ts-node is required to run ` +
111
+ `.ts migration files but could not be loaded. Install it with ` +
112
+ `"npm install --save-dev ts-node", or generate migrations with a .js extension ` +
113
+ `instead. Original error: ${error}`);
114
+ }
115
+ }
116
+ /**
117
+ * Load a migration file
118
+ * @param filePath - Path to the migration file
119
+ */
120
+ async loadMigrationFile(filePath) {
121
+ const name = path.basename(filePath, path.extname(filePath));
122
+ try {
123
+ const ext = path.extname(filePath);
124
+ const fullPath = path.resolve(filePath);
125
+ if (ext === '.ts') {
126
+ // Register ts-node so require() can transpile .ts migrations on the fly.
127
+ this.ensureTsNodeRegistered(filePath);
128
+ }
129
+ // Clear require cache to allow hot reloading
130
+ delete require.cache[require.resolve(fullPath)];
131
+ const migrationModule = require(fullPath);
132
+ const migration = new migration_1.Migration({ name });
133
+ // Support both CommonJS (module.exports = { up, down }) and
134
+ // ESM-interop (export const up/down) shapes, and default exports.
135
+ const up = migrationModule.up ?? migrationModule.default?.up;
136
+ const down = migrationModule.down ?? migrationModule.default?.down;
137
+ if (up && typeof up === 'function') {
138
+ migration.setUp(up);
139
+ }
140
+ if (down && typeof down === 'function') {
141
+ migration.setDown(down);
142
+ }
143
+ return migration;
144
+ }
145
+ catch (error) {
146
+ throw new Error(`Failed to load migration from ${filePath}: ${error}`);
147
+ }
148
+ }
149
+ /**
150
+ * Find and register all migration files in a directory
151
+ */
152
+ async findMigrations() {
153
+ if (!fs.existsSync(this.path)) {
154
+ console.log(`Migration directory not found: ${this.path}`);
155
+ return;
156
+ }
157
+ const files = fs.readdirSync(this.path);
158
+ for (const file of files) {
159
+ if (this.filter(file)) {
160
+ const filePath = path.join(this.path, file);
161
+ const stat = fs.statSync(filePath);
162
+ if (stat.isFile()) {
163
+ await this.migration(filePath);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ /**
169
+ * Get all registered migrations
170
+ */
171
+ getMigrations() {
172
+ return Array.from(this.migrations.values());
173
+ }
174
+ /**
175
+ * Get migration by name
176
+ */
177
+ getMigration(name) {
178
+ return this.migrations.get(name);
179
+ }
180
+ /**
181
+ * List pending (not yet executed) migrations
182
+ */
183
+ async pending() {
184
+ // Load all migrations if not already loaded. Without this, calling
185
+ // pending() before up()/down() (e.g. from the CLI's migration:run,
186
+ // which inspects pending() to decide whether there's anything to do)
187
+ // would see an empty `this.migrations` map and always report zero
188
+ // pending migrations, even when migration files exist on disk.
189
+ if (this.migrations.size === 0) {
190
+ await this.findMigrations();
191
+ }
192
+ const executed = await this.PrormMigration.getExecutedMigrations();
193
+ const executedNames = new Set(executed.map((m) => m.name));
194
+ const pending = [];
195
+ for (const [name, migration] of this.migrations) {
196
+ if (!executedNames.has(name)) {
197
+ pending.push(migration);
198
+ }
199
+ }
200
+ // Sort by name (which typically includes timestamp)
201
+ return pending.sort((a, b) => a.name.localeCompare(b.name));
202
+ }
203
+ /**
204
+ * List all executed migrations
205
+ */
206
+ async executed() {
207
+ // See pending() above: the migrations map must be populated from disk
208
+ // before we can match it up against the executed-migrations table.
209
+ if (this.migrations.size === 0) {
210
+ await this.findMigrations();
211
+ }
212
+ const executed = await this.PrormMigration.getExecutedMigrations();
213
+ const executedNames = new Set(executed.map((m) => m.name));
214
+ const executedMigrations = [];
215
+ for (const [name, migration] of this.migrations) {
216
+ if (executedNames.has(name)) {
217
+ executedMigrations.push(migration);
218
+ }
219
+ }
220
+ return executedMigrations.sort((a, b) => a.name.localeCompare(b.name));
221
+ }
222
+ /**
223
+ * Get migration status for all migrations
224
+ */
225
+ async status() {
226
+ // See pending() above: the migrations map must be populated from disk
227
+ // before status can be computed for each migration file.
228
+ if (this.migrations.size === 0) {
229
+ await this.findMigrations();
230
+ }
231
+ const executed = await this.PrormMigration.getExecutedMigrations();
232
+ const executedMap = new Map(executed.map((m) => [m.name, m]));
233
+ const allStatuses = [];
234
+ for (const [name, migration] of this.migrations) {
235
+ const meta = executedMap.get(name);
236
+ allStatuses.push({
237
+ name,
238
+ status: meta ? 'up' : 'pending',
239
+ batch: meta?.batch,
240
+ timestamp: meta?.timestamp,
241
+ });
242
+ }
243
+ return allStatuses.sort((a, b) => a.name.localeCompare(b.name));
244
+ }
245
+ /**
246
+ * Run all pending migrations
247
+ * @param options - Migration options
248
+ */
249
+ async up(options) {
250
+ // Load all migrations if not already loaded
251
+ if (this.migrations.size === 0) {
252
+ await this.findMigrations();
253
+ }
254
+ const result = {
255
+ executed: 0,
256
+ reverted: 0,
257
+ migrations: [],
258
+ };
259
+ if (options?.migration) {
260
+ // Run specific migration
261
+ const migration = this.migrations.get(options.migration);
262
+ if (!migration) {
263
+ throw new Error(`Migration ${options.migration} not found`);
264
+ }
265
+ const isExecuted = await this.PrormMigration.isMigrationExecuted(migration.name);
266
+ if (!isExecuted) {
267
+ await this.PrormMigration.runMigration(migration);
268
+ result.executed = 1;
269
+ result.migrations.push(migration.name);
270
+ }
271
+ }
272
+ else {
273
+ // Run all pending migrations
274
+ const pendingMigrations = await this.pending();
275
+ for (const migration of pendingMigrations) {
276
+ await this.PrormMigration.runMigration(migration);
277
+ result.executed++;
278
+ result.migrations.push(migration.name);
279
+ }
280
+ }
281
+ return result;
282
+ }
283
+ /**
284
+ * Revert migrations
285
+ * @param options - Revert options
286
+ */
287
+ async down(options) {
288
+ // Load all migrations if not already loaded
289
+ if (this.migrations.size === 0) {
290
+ await this.findMigrations();
291
+ }
292
+ const result = {
293
+ executed: 0,
294
+ reverted: 0,
295
+ migrations: [],
296
+ };
297
+ const executedMigrations = await this.executed();
298
+ if (options?.migration) {
299
+ // Revert specific migration
300
+ const migration = this.migrations.get(options.migration);
301
+ if (!migration) {
302
+ throw new Error(`Migration ${options.migration} not found`);
303
+ }
304
+ const isExecuted = await this.PrormMigration.isMigrationExecuted(migration.name);
305
+ if (isExecuted) {
306
+ await this.PrormMigration.revertMigration(migration);
307
+ result.reverted = 1;
308
+ result.migrations.push(migration.name);
309
+ }
310
+ }
311
+ else if (options?.steps !== undefined && options.steps > 0) {
312
+ // Revert N migrations
313
+ const toRevert = executedMigrations
314
+ .sort((a, b) => b.name.localeCompare(a.name))
315
+ .slice(0, options.steps);
316
+ for (const migration of toRevert) {
317
+ await this.PrormMigration.revertMigration(migration);
318
+ result.reverted++;
319
+ result.migrations.push(migration.name);
320
+ }
321
+ }
322
+ else {
323
+ // Revert last migration
324
+ const lastMigration = executedMigrations[executedMigrations.length - 1];
325
+ if (lastMigration) {
326
+ await this.PrormMigration.revertMigration(lastMigration);
327
+ result.reverted = 1;
328
+ result.migrations.push(lastMigration.name);
329
+ }
330
+ }
331
+ return result;
332
+ }
333
+ /**
334
+ * Revert all executed migrations with a batch number greater than
335
+ * `targetBatch`, actually running each migration's `down()` function
336
+ * (loaded the same way `up()` is) before removing its tracking row.
337
+ * @param targetBatch - Batch number to revert down to
338
+ */
339
+ async downToBatch(targetBatch) {
340
+ // Load all migrations if not already loaded
341
+ if (this.migrations.size === 0) {
342
+ await this.findMigrations();
343
+ }
344
+ const before = await this.PrormMigration.getExecutedMigrations();
345
+ await this.PrormMigration.revertToBatch(targetBatch, this.migrations);
346
+ const after = await this.PrormMigration.getExecutedMigrations();
347
+ const afterNames = new Set(after.map((m) => m.name));
348
+ const revertedNames = before.filter((m) => !afterNames.has(m.name)).map((m) => m.name);
349
+ return {
350
+ executed: 0,
351
+ reverted: revertedNames.length,
352
+ migrations: revertedNames,
353
+ };
354
+ }
355
+ /**
356
+ * Get database version
357
+ */
358
+ async getDatabaseVersion() {
359
+ return this.PrormMigration.getDatabaseVersion();
360
+ }
361
+ /**
362
+ * Sync the migrations table
363
+ */
364
+ async syncMigrationsTable() {
365
+ await this.PrormMigration.syncMigrationsTable();
366
+ }
367
+ /**
368
+ * Set the migration path
369
+ */
370
+ setPath(newPath) {
371
+ this.path = newPath;
372
+ this.migrations.clear();
373
+ }
374
+ /**
375
+ * Get the current migration path
376
+ */
377
+ getPath() {
378
+ return this.path;
379
+ }
380
+ }
381
+ exports.Migrator = Migrator;
382
+ /**
383
+ * Whether ts-node/register has already been registered in this process.
384
+ * Registering more than once is harmless but wasteful, so we only do it once.
385
+ */
386
+ Migrator.tsNodeRegistered = false;
387
+ /**
388
+ * Create a Migrator instance
389
+ */
390
+ function createMigrator(options) {
391
+ return new Migrator(options);
392
+ }
393
+ /**
394
+ * Create migration file template
395
+ * @param name - Migration name
396
+ * @param options - Template options
397
+ */
398
+ function createMigration(name, options) {
399
+ const timestamp = migration_1.Migration.getTimestamp();
400
+ const filename = `${timestamp}-${name}${options?.extension || '.js'}`;
401
+ const filepath = path.join(options?.path || './migrations', filename);
402
+ // Ensure directory exists
403
+ const dir = path.dirname(filepath);
404
+ if (!fs.existsSync(dir)) {
405
+ fs.mkdirSync(dir, { recursive: true });
406
+ }
407
+ const template = (0, migration_1.buildMigrationTemplate)(name);
408
+ fs.writeFileSync(filepath, template);
409
+ console.log(`Migration created: ${filepath}`);
410
+ return filepath;
411
+ }
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ /**
3
+ * PrormMigration class - Integration layer between migrations and Prorm
4
+ * Handles running migrations with the Prorm instance
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PrormMigration = void 0;
8
+ const query_interface_1 = require("./query-interface");
9
+ /**
10
+ * PrormMigration - Integrates with Prorm to manage migrations
11
+ */
12
+ class PrormMigration {
13
+ /**
14
+ * Create a new PrormMigration instance
15
+ * @param options - Configuration options
16
+ */
17
+ constructor(options) {
18
+ this.migrationMeta = new Map();
19
+ this.prorm = options.prorm;
20
+ this.tableName = options.tableName || 'PrormMeta';
21
+ this.schema = options.schema;
22
+ this.queryInterface = this.createQueryInterface();
23
+ }
24
+ /**
25
+ * Create a QueryInterface from the Prorm instance
26
+ */
27
+ createQueryInterface() {
28
+ const dialect = this.prorm.getDialectInstance();
29
+ if (!dialect) {
30
+ throw new Error('Prorm is not connected. Please call prorm.connect() first.');
31
+ }
32
+ return new query_interface_1.QueryInterface(dialect);
33
+ }
34
+ /**
35
+ * Get the QueryInterface
36
+ */
37
+ getQueryInterface() {
38
+ return this.queryInterface;
39
+ }
40
+ /**
41
+ * Get the Prorm instance
42
+ */
43
+ getProrm() {
44
+ return this.prorm;
45
+ }
46
+ /**
47
+ * Get the migrations table name
48
+ */
49
+ getTableName() {
50
+ return this.tableName;
51
+ }
52
+ /**
53
+ * Ensure the migrations table exists
54
+ */
55
+ async ensureMigrationsTable() {
56
+ const tableExists = await this.queryInterface.tableExists(this.tableName);
57
+ if (!tableExists) {
58
+ await this.queryInterface.createTable(this.tableName, {
59
+ name: {
60
+ type: 'STRING',
61
+ allowNull: false,
62
+ unique: true,
63
+ },
64
+ batch: {
65
+ type: 'INTEGER',
66
+ allowNull: false,
67
+ defaultValue: 0,
68
+ },
69
+ timestamp: {
70
+ type: 'INTEGER',
71
+ allowNull: false,
72
+ defaultValue: Math.floor(Date.now() / 1000),
73
+ },
74
+ });
75
+ }
76
+ }
77
+ /**
78
+ * Load migration metadata from the database
79
+ */
80
+ async loadMigrationMeta() {
81
+ await this.ensureMigrationsTable();
82
+ const result = await this.queryInterface.prormQuery(`SELECT * FROM ${this.queryInterface.getDialect().escapeId(this.tableName)} ORDER BY timestamp ASC`);
83
+ this.migrationMeta.clear();
84
+ for (const row of result.rows) {
85
+ const meta = {
86
+ id: row.id,
87
+ name: row.name,
88
+ batch: row.batch,
89
+ timestamp: row.timestamp,
90
+ };
91
+ this.migrationMeta.set(row.name, meta);
92
+ }
93
+ }
94
+ /**
95
+ * Record a migration as executed in the database
96
+ * @param migration - The migration to record
97
+ * @param batch - The batch number
98
+ */
99
+ async recordMigration(migration, batch) {
100
+ const dialect = this.queryInterface.getDialect();
101
+ const timestamp = Math.floor(Date.now() / 1000);
102
+ await this.queryInterface.prormQuery(`INSERT INTO ${dialect.escapeId(this.tableName)} (name, batch, timestamp) VALUES (${dialect.escape(migration.name)}, ${dialect.escape(batch)}, ${dialect.escape(timestamp)})`);
103
+ // Update local cache
104
+ const meta = {
105
+ name: migration.name,
106
+ batch,
107
+ timestamp,
108
+ };
109
+ this.migrationMeta.set(migration.name, meta);
110
+ }
111
+ /**
112
+ * Remove a migration record from the database
113
+ * @param migrationName - Name of the migration to remove
114
+ */
115
+ async removeMigration(migrationName) {
116
+ const dialect = this.queryInterface.getDialect();
117
+ await this.queryInterface.prormQuery(`DELETE FROM ${dialect.escapeId(this.tableName)} WHERE name = ${dialect.escape(migrationName)}`);
118
+ this.migrationMeta.delete(migrationName);
119
+ }
120
+ /**
121
+ * Get all executed migrations
122
+ */
123
+ async getExecutedMigrations() {
124
+ await this.loadMigrationMeta();
125
+ return Array.from(this.migrationMeta.values());
126
+ }
127
+ /**
128
+ * Check if a migration has been executed
129
+ * @param migrationName - Name of the migration
130
+ */
131
+ async isMigrationExecuted(migrationName) {
132
+ await this.loadMigrationMeta();
133
+ return this.migrationMeta.has(migrationName);
134
+ }
135
+ /**
136
+ * Compute the next batch number from the currently loaded migration meta.
137
+ * Callers are expected to have called `loadMigrationMeta()` beforehand.
138
+ */
139
+ computeNextBatch() {
140
+ const migrations = Array.from(this.migrationMeta.values());
141
+ const maxBatch = migrations.reduce((max, m) => Math.max(max, m.batch), 0);
142
+ return maxBatch + 1;
143
+ }
144
+ /**
145
+ * Run a migration
146
+ * @param migration - The migration to run
147
+ * @param batch - Optional batch number to record this migration under. When
148
+ * omitted, a fresh batch number is computed for this single migration.
149
+ * `runMigrations()` passes an explicit shared batch so that all migrations
150
+ * applied in one run land in the same batch.
151
+ */
152
+ async runMigration(migration, batch) {
153
+ // Load fresh meta before running
154
+ await this.loadMigrationMeta();
155
+ if (this.migrationMeta.has(migration.name)) {
156
+ console.log(`Migration ${migration.name} already executed`);
157
+ return;
158
+ }
159
+ // Use the caller-provided batch (shared across a run) or compute one.
160
+ const newBatch = batch ?? this.computeNextBatch();
161
+ try {
162
+ console.log(`Running migration: ${migration.name}`);
163
+ await migration.up(this.queryInterface, this.prorm);
164
+ await this.recordMigration(migration, newBatch);
165
+ console.log(`Migration ${migration.name} completed`);
166
+ }
167
+ catch (error) {
168
+ console.error(`Migration ${migration.name} failed:`, error);
169
+ throw error;
170
+ }
171
+ }
172
+ /**
173
+ * Revert a migration
174
+ * @param migration - The migration to revert
175
+ */
176
+ async revertMigration(migration) {
177
+ // Load fresh meta before reverting
178
+ await this.loadMigrationMeta();
179
+ if (!this.migrationMeta.has(migration.name)) {
180
+ console.log(`Migration ${migration.name} not executed`);
181
+ return;
182
+ }
183
+ if (!migration.down) {
184
+ console.warn(`Migration ${migration.name} has no down() function defined; removing its tracking ` +
185
+ `record without reverting any changes.`);
186
+ await this.removeMigration(migration.name);
187
+ return;
188
+ }
189
+ try {
190
+ console.log(`Reverting migration: ${migration.name}`);
191
+ await migration.down(this.queryInterface, this.prorm);
192
+ await this.removeMigration(migration.name);
193
+ console.log(`Migration ${migration.name} reverted`);
194
+ }
195
+ catch (error) {
196
+ console.error(`Failed to revert migration ${migration.name}:`, error);
197
+ throw error;
198
+ }
199
+ }
200
+ /**
201
+ * Execute all pending migrations
202
+ * @param migrations - Array of migrations to run
203
+ */
204
+ async runMigrations(migrations) {
205
+ // All migrations applied in a single run share one batch number so they
206
+ // can be reverted together as a unit. Compute it once up front rather than
207
+ // recomputing (maxBatch + 1) per migration, which would put each migration
208
+ // in its own batch.
209
+ await this.loadMigrationMeta();
210
+ const batch = this.computeNextBatch();
211
+ for (const migration of migrations) {
212
+ await this.runMigration(migration, batch);
213
+ }
214
+ }
215
+ /**
216
+ * Revert migrations to a specific batch
217
+ *
218
+ * For each executed migration with a batch number greater than
219
+ * `targetBatch`, this loads its `down()` function (via the supplied
220
+ * `migrations` lookup) and actually executes it before removing its
221
+ * tracking row. If `down()` throws, the error is logged and re-thrown, and
222
+ * the tracking row for that migration (and any migrations after it) is
223
+ * left in place so the revert can be retried.
224
+ *
225
+ * @param targetBatch - Target batch number to revert down to
226
+ * @param migrations - The loaded Migration definitions (with `down()`
227
+ * functions attached), keyed by migration name. Typically
228
+ * `Migrator.getMigrations()` / the Migrator's internal migrations map.
229
+ */
230
+ async revertToBatch(targetBatch, migrations) {
231
+ const migrationMap = migrations instanceof Map ? migrations : new Map(migrations.map((m) => [m.name, m]));
232
+ await this.loadMigrationMeta();
233
+ const migrationsToRevert = Array.from(this.migrationMeta.values())
234
+ .filter((m) => m.batch > targetBatch)
235
+ .sort((a, b) => b.batch - a.batch || b.timestamp - a.timestamp);
236
+ for (const meta of migrationsToRevert) {
237
+ const migration = migrationMap.get(meta.name);
238
+ if (!migration) {
239
+ throw new Error(`Cannot revert migration "${meta.name}" to batch ${targetBatch}: no loaded ` +
240
+ `migration definition was found for it, so its down() function is unavailable. ` +
241
+ `Ensure the migration file still exists and has been registered (e.g. via ` +
242
+ `Migrator.findMigrations()) before calling revertToBatch().`);
243
+ }
244
+ if (!migration.down) {
245
+ console.warn(`Migration ${meta.name} has no down() function defined; removing its tracking ` +
246
+ `record without reverting any changes.`);
247
+ await this.removeMigration(meta.name);
248
+ continue;
249
+ }
250
+ try {
251
+ console.log(`Reverting migration: ${meta.name}`);
252
+ await migration.down(this.queryInterface, this.prorm);
253
+ await this.removeMigration(meta.name);
254
+ console.log(`Migration ${meta.name} reverted`);
255
+ }
256
+ catch (error) {
257
+ console.error(`Failed to revert migration ${meta.name} while reverting to batch ${targetBatch}:`, error);
258
+ throw error;
259
+ }
260
+ }
261
+ }
262
+ /**
263
+ * Get the current database version
264
+ */
265
+ async getDatabaseVersion() {
266
+ return this.queryInterface.getDatabaseVersion();
267
+ }
268
+ /**
269
+ * Sync the migrations table
270
+ */
271
+ async syncMigrationsTable() {
272
+ await this.ensureMigrationsTable();
273
+ }
274
+ }
275
+ exports.PrormMigration = PrormMigration;