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.
- package/CHANGELOG.md +1111 -0
- package/LICENSE +21 -0
- package/README.md +573 -0
- package/dist/audit/history-query.js +180 -0
- package/dist/audit/index.js +23 -0
- package/dist/audit/logger.js +236 -0
- package/dist/cache/cache-manager.js +84 -0
- package/dist/cache/index.js +16 -0
- package/dist/cache/redis-cluster-cache.js +557 -0
- package/dist/cli.js +2200 -0
- package/dist/compliance/audit-trail.js +68 -0
- package/dist/compliance/backup-verification.js +685 -0
- package/dist/compliance/breach-detector.js +505 -0
- package/dist/compliance/consent-record.js +227 -0
- package/dist/compliance/consent-versioning.js +331 -0
- package/dist/compliance/cross-border-log.js +530 -0
- package/dist/compliance/data-classifier.js +258 -0
- package/dist/compliance/data-lineage.js +565 -0
- package/dist/compliance/data-masker.js +303 -0
- package/dist/compliance/data-portability.js +265 -0
- package/dist/compliance/data-retention.js +195 -0
- package/dist/compliance/dsar-workflow.js +342 -0
- package/dist/compliance/field-encryption.js +223 -0
- package/dist/compliance/immutable-record.js +148 -0
- package/dist/compliance/index.js +260 -0
- package/dist/compliance/privacy-impact-assessment.js +364 -0
- package/dist/compliance/pseudonymization.js +269 -0
- package/dist/compliance/query-firewall.js +1182 -0
- package/dist/compliance/rate-limiter.js +580 -0
- package/dist/compliance/right-to-erasure.js +117 -0
- package/dist/compliance/row-level-security.js +246 -0
- package/dist/compliance/security-decorator.js +574 -0
- package/dist/compliance/security-monitor.js +525 -0
- package/dist/compliance/sensitive-data-discovery.js +476 -0
- package/dist/compliance/session-isolation.js +472 -0
- package/dist/compliance/tls-enforcer.js +108 -0
- package/dist/compliance/worm-storage.js +712 -0
- package/dist/connection-manager.js +198 -0
- package/dist/connection-pool.js +519 -0
- package/dist/decorators/audit.js +136 -0
- package/dist/decorators/belongs-to-many.js +115 -0
- package/dist/decorators/belongs-to.js +115 -0
- package/dist/decorators/check.js +435 -0
- package/dist/decorators/collate.js +329 -0
- package/dist/decorators/comment.js +205 -0
- package/dist/decorators/database-settings.js +236 -0
- package/dist/decorators/default.js +244 -0
- package/dist/decorators/encryption.js +235 -0
- package/dist/decorators/engine.js +97 -0
- package/dist/decorators/fk-constraints.js +594 -0
- package/dist/decorators/foreign-table.js +136 -0
- package/dist/decorators/generated.js +274 -0
- package/dist/decorators/has-many.js +127 -0
- package/dist/decorators/has-one.js +116 -0
- package/dist/decorators/hstore.js +129 -0
- package/dist/decorators/index.js +355 -0
- package/dist/decorators/json-column.js +83 -0
- package/dist/decorators/jsonb.js +101 -0
- package/dist/decorators/orm-decorators.js +425 -0
- package/dist/decorators/permissions.js +294 -0
- package/dist/decorators/procedure.js +210 -0
- package/dist/decorators/query-options.js +556 -0
- package/dist/decorators/range.js +167 -0
- package/dist/decorators/set-column.js +83 -0
- package/dist/decorators/spatial.js +114 -0
- package/dist/decorators/storage.js +580 -0
- package/dist/decorators/timezone.js +512 -0
- package/dist/decorators/trigger.js +90 -0
- package/dist/decorators/uuid.js +135 -0
- package/dist/decorators/view.js +258 -0
- package/dist/diagrams/chen-diagram.js +354 -0
- package/dist/diagrams/class-diagram.js +384 -0
- package/dist/diagrams/dependency-diagram.js +432 -0
- package/dist/diagrams/er-diagram.js +605 -0
- package/dist/diagrams/flow-diagram.js +394 -0
- package/dist/diagrams/gantt-diagram.js +411 -0
- package/dist/diagrams/index-diagram.js +353 -0
- package/dist/diagrams/index.js +184 -0
- package/dist/diagrams/migration-diagram.js +316 -0
- package/dist/diagrams/model-diagram.js +616 -0
- package/dist/diagrams/package-diagram.js +376 -0
- package/dist/diagrams/palette.js +85 -0
- package/dist/diagrams/relational-diagram.js +455 -0
- package/dist/diagrams/schemadoc-diagram.js +309 -0
- package/dist/diagrams/sequence-diagram.js +307 -0
- package/dist/diagrams/state-diagram.js +344 -0
- package/dist/diagrams/svg-dom.js +111 -0
- package/dist/diagrams/tree-diagram.js +250 -0
- package/dist/dialects/clickhouse/index.js +1742 -0
- package/dist/dialects/cockroachdb/index.js +4677 -0
- package/dist/dialects/cratedb/index.js +441 -0
- package/dist/dialects/databricks/index.js +517 -0
- package/dist/dialects/db2/index.js +2225 -0
- package/dist/dialects/dialect.js +720 -0
- package/dist/dialects/duckdb/index.js +2014 -0
- package/dist/dialects/exasol/index.js +357 -0
- package/dist/dialects/firebird/index.js +495 -0
- package/dist/dialects/greenplum/index.js +457 -0
- package/dist/dialects/hana/index.js +1741 -0
- package/dist/dialects/mariadb/index.js +3590 -0
- package/dist/dialects/mssql/index.js +2296 -0
- package/dist/dialects/mysql/index.js +4058 -0
- package/dist/dialects/oracle/index.js +2999 -0
- package/dist/dialects/postgres/index.js +5319 -0
- package/dist/dialects/query-stream-helper.js +152 -0
- package/dist/dialects/questdb/index.js +433 -0
- package/dist/dialects/redshift/index.js +2277 -0
- package/dist/dialects/singlestore/index.js +354 -0
- package/dist/dialects/snowflake/index.js +2082 -0
- package/dist/dialects/spanner/index.js +1768 -0
- package/dist/dialects/sqlite/index.js +3382 -0
- package/dist/dialects/tidb/index.js +377 -0
- package/dist/dialects/timescaledb/index.js +164 -0
- package/dist/dialects/trino/index.js +420 -0
- package/dist/dialects/turso/index.js +227 -0
- package/dist/dialects/vertica/index.js +317 -0
- package/dist/dialects/yugabytedb/index.js +424 -0
- package/dist/errors/index.js +472 -0
- package/dist/errors/utils.js +340 -0
- package/dist/errors.js +21 -0
- package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
- package/dist/extensions/catalog/mssql-features.js +147 -0
- package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
- package/dist/extensions/catalog/oracle-db2-features.js +196 -0
- package/dist/extensions/catalog/postgres-extensions.js +516 -0
- package/dist/extensions/index.js +71 -0
- package/dist/extensions/types.js +13 -0
- package/dist/foreign-data.js +173 -0
- package/dist/hooks/hooks-manager.js +350 -0
- package/dist/hooks/index.js +37 -0
- package/dist/index.js +463 -0
- package/dist/logging.js +335 -0
- package/dist/migrations/index.js +40 -0
- package/dist/migrations/migration.js +196 -0
- package/dist/migrations/migrator.js +411 -0
- package/dist/migrations/prormmigration.js +275 -0
- package/dist/migrations/query-interface.js +435 -0
- package/dist/migrations/seeder.js +353 -0
- package/dist/models/associations.js +852 -0
- package/dist/models/constraints.js +288 -0
- package/dist/models/data-types.js +2518 -0
- package/dist/models/decorators.js +445 -0
- package/dist/models/index.js +33 -0
- package/dist/models/indexes.js +531 -0
- package/dist/models/methods.js +382 -0
- package/dist/models/model-manager.js +103 -0
- package/dist/models/model.js +5349 -0
- package/dist/models/operators.js +67 -0
- package/dist/models/scopes.js +189 -0
- package/dist/models/typescript-types.js +26 -0
- package/dist/nosql/aerospike/index.js +205 -0
- package/dist/nosql/allegrograph/index.js +169 -0
- package/dist/nosql/arangodb/index.js +364 -0
- package/dist/nosql/azure-blob/index.js +206 -0
- package/dist/nosql/beanstalkd/index.js +231 -0
- package/dist/nosql/beequeue/index.js +210 -0
- package/dist/nosql/bigchaindb/index.js +195 -0
- package/dist/nosql/bigtable/index.js +224 -0
- package/dist/nosql/blazegraph/index.js +173 -0
- package/dist/nosql/bullmq/index.js +191 -0
- package/dist/nosql/cassandra/index.js +174 -0
- package/dist/nosql/chroma/index.js +190 -0
- package/dist/nosql/cloudflare-kv/index.js +220 -0
- package/dist/nosql/coherence/index.js +200 -0
- package/dist/nosql/cosmosdb/index.js +157 -0
- package/dist/nosql/couchbase/index.js +213 -0
- package/dist/nosql/dax/index.js +212 -0
- package/dist/nosql/deno-kv/index.js +206 -0
- package/dist/nosql/dgraph/index.js +171 -0
- package/dist/nosql/doris/index.js +169 -0
- package/dist/nosql/druid/index.js +162 -0
- package/dist/nosql/dynamodb/index.js +937 -0
- package/dist/nosql/elasticsearch/index.js +377 -0
- package/dist/nosql/etcd/index.js +502 -0
- package/dist/nosql/eventhubs/index.js +213 -0
- package/dist/nosql/eventstore/index.js +254 -0
- package/dist/nosql/faunadb/index.js +188 -0
- package/dist/nosql/firestore/index.js +177 -0
- package/dist/nosql/fluree/index.js +148 -0
- package/dist/nosql/fuseki/index.js +170 -0
- package/dist/nosql/gcs/index.js +172 -0
- package/dist/nosql/gearman/index.js +160 -0
- package/dist/nosql/geode/index.js +196 -0
- package/dist/nosql/graphdb/index.js +169 -0
- package/dist/nosql/graylog/index.js +188 -0
- package/dist/nosql/gridgain/index.js +171 -0
- package/dist/nosql/hazelcast/index.js +162 -0
- package/dist/nosql/hbase/index.js +230 -0
- package/dist/nosql/ignite/index.js +173 -0
- package/dist/nosql/immudb/index.js +184 -0
- package/dist/nosql/index.js +232 -0
- package/dist/nosql/infinispan/index.js +200 -0
- package/dist/nosql/influxdb/index.js +0 -0
- package/dist/nosql/kafka/index.js +234 -0
- package/dist/nosql/keyspaces/index.js +189 -0
- package/dist/nosql/kinesis/index.js +253 -0
- package/dist/nosql/leveldb/index.js +153 -0
- package/dist/nosql/lmdb/index.js +160 -0
- package/dist/nosql/loki/index.js +201 -0
- package/dist/nosql/marklogic/index.js +204 -0
- package/dist/nosql/materialize/index.js +145 -0
- package/dist/nosql/meilisearch/index.js +154 -0
- package/dist/nosql/memcached/index.js +223 -0
- package/dist/nosql/milvus/index.js +410 -0
- package/dist/nosql/minio/index.js +265 -0
- package/dist/nosql/momento/index.js +179 -0
- package/dist/nosql/mongodb/index.js +461 -0
- package/dist/nosql/nats/index.js +247 -0
- package/dist/nosql/nedb/index.js +164 -0
- package/dist/nosql/neo4j/index.js +450 -0
- package/dist/nosql/neptune/index.js +470 -0
- package/dist/nosql/nsq/index.js +200 -0
- package/dist/nosql/opensearch/index.js +186 -0
- package/dist/nosql/orientdb/index.js +175 -0
- package/dist/nosql/papertrail/index.js +200 -0
- package/dist/nosql/pinecone/index.js +0 -0
- package/dist/nosql/pinot/index.js +133 -0
- package/dist/nosql/pouchdb/index.js +172 -0
- package/dist/nosql/prometheus/index.js +174 -0
- package/dist/nosql/provendb/index.js +147 -0
- package/dist/nosql/pubsub/index.js +187 -0
- package/dist/nosql/pulsar/index.js +232 -0
- package/dist/nosql/qdrant/index.js +295 -0
- package/dist/nosql/qldb/index.js +192 -0
- package/dist/nosql/r2/index.js +281 -0
- package/dist/nosql/rabbitmq/index.js +237 -0
- package/dist/nosql/ravendb/index.js +175 -0
- package/dist/nosql/redis/index.js +607 -0
- package/dist/nosql/redpanda/index.js +237 -0
- package/dist/nosql/resque/index.js +203 -0
- package/dist/nosql/rethinkdb/index.js +232 -0
- package/dist/nosql/rocksdb/index.js +152 -0
- package/dist/nosql/rockset/index.js +126 -0
- package/dist/nosql/s3/index.js +298 -0
- package/dist/nosql/scylladb/index.js +178 -0
- package/dist/nosql/signoz/index.js +227 -0
- package/dist/nosql/sns/index.js +201 -0
- package/dist/nosql/solr/index.js +231 -0
- package/dist/nosql/splunk/index.js +227 -0
- package/dist/nosql/sqs/index.js +246 -0
- package/dist/nosql/stardog/index.js +169 -0
- package/dist/nosql/starrocks/index.js +170 -0
- package/dist/nosql/store.js +2 -0
- package/dist/nosql/sumologic/index.js +213 -0
- package/dist/nosql/surrealdb/index.js +179 -0
- package/dist/nosql/terminusdb/index.js +151 -0
- package/dist/nosql/tigergraph/index.js +469 -0
- package/dist/nosql/typesense/index.js +148 -0
- package/dist/nosql/unqlite/index.js +157 -0
- package/dist/nosql/upstash/index.js +167 -0
- package/dist/nosql/vercel-kv/index.js +166 -0
- package/dist/nosql/victoriametrics/index.js +213 -0
- package/dist/nosql/virtuoso/index.js +169 -0
- package/dist/nosql/weaviate/index.js +276 -0
- package/dist/operators/index.js +108 -0
- package/dist/operators.js +2690 -0
- package/dist/prisma-migrate/index.js +38 -0
- package/dist/prisma-migrate/migration-generator.js +125 -0
- package/dist/prisma-migrate/model-generator.js +172 -0
- package/dist/prisma-migrate/relations.js +100 -0
- package/dist/prisma-migrate/schema-parser.js +167 -0
- package/dist/prisma-migrate/type-mapper.js +40 -0
- package/dist/prorm.js +6832 -0
- package/dist/query-builders/cte-builder.js +80 -0
- package/dist/query-builders/functions/aggregate.js +390 -0
- package/dist/query-builders/functions/conditional.js +503 -0
- package/dist/query-builders/functions/datetime.js +695 -0
- package/dist/query-builders/functions/fulltext.js +439 -0
- package/dist/query-builders/functions/index.js +93 -0
- package/dist/query-builders/functions/json.js +427 -0
- package/dist/query-builders/functions/math.js +399 -0
- package/dist/query-builders/functions/string.js +518 -0
- package/dist/query-builders/functions/window.js +328 -0
- package/dist/query-builders/include-builder.js +323 -0
- package/dist/query-builders/index-expression-builder.js +242 -0
- package/dist/query-builders/index.js +161 -0
- package/dist/query-builders/insert-builder.js +164 -0
- package/dist/query-builders/model-helpers.js +38 -0
- package/dist/query-builders/order-limit-builder.js +239 -0
- package/dist/query-builders/sql-compiler.js +2040 -0
- package/dist/query-builders/subquery-builder.js +152 -0
- package/dist/query-builders/update-builder.js +182 -0
- package/dist/query-builders/view-builder.js +218 -0
- package/dist/query-builders/where-builder.js +1532 -0
- package/dist/query-interface.js +622 -0
- package/dist/query-optimizers/batch-optimizer.js +426 -0
- package/dist/query-optimizers/explain-plans.js +415 -0
- package/dist/query-optimizers/index.js +51 -0
- package/dist/query-optimizers/prepared-statement-cache.js +423 -0
- package/dist/query-optimizers/query-hints.js +438 -0
- package/dist/query-optimizers/query-optimizer.js +278 -0
- package/dist/query-optimizers/slow-query-logger.js +271 -0
- package/dist/replica-manager.js +507 -0
- package/dist/schema/index.js +15 -0
- package/dist/schema/migration-generator.js +374 -0
- package/dist/schema/schema-differ.js +549 -0
- package/dist/schema/types.js +6 -0
- package/dist/sql-constants.js +300 -0
- package/dist/sqlite-advanced.js +1047 -0
- package/dist/streams/index.js +12 -0
- package/dist/streams/transforms.js +178 -0
- package/dist/transaction.js +456 -0
- package/dist/types/index.js +180 -0
- package/dist/user-management.js +127 -0
- package/dist/utils/date.js +300 -0
- package/dist/utils/index.js +1079 -0
- package/dist/utils/string.js +161 -0
- package/dist/validators/index.js +19 -0
- package/dist/validators/validator.js +911 -0
- package/package.json +190 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Foreign Key Constraints and Column Options Decorators for the ORM.
|
|
4
|
+
*
|
|
5
|
+
* Provides decorators for:
|
|
6
|
+
* - FK cascade options (ON DELETE, ON UPDATE)
|
|
7
|
+
* - FK references definition
|
|
8
|
+
* - Deferrable constraints
|
|
9
|
+
* - Unique constraints
|
|
10
|
+
* - Auto-increment / Identity configuration
|
|
11
|
+
* - Generated columns (PostgreSQL 12+)
|
|
12
|
+
* - Exclusion constraints
|
|
13
|
+
*
|
|
14
|
+
* Usage Examples:
|
|
15
|
+
*
|
|
16
|
+
* // Foreign Key cascade options
|
|
17
|
+
* @OnDelete('CASCADE')
|
|
18
|
+
* @OnUpdate('CASCADE')
|
|
19
|
+
* @References({ model: Role, key: 'id' })
|
|
20
|
+
* roleId: number;
|
|
21
|
+
*
|
|
22
|
+
* // Multiple FK options with deferrable
|
|
23
|
+
* @OnDelete('RESTRICT')
|
|
24
|
+
* @OnUpdate('SET NULL')
|
|
25
|
+
* @References({
|
|
26
|
+
* model: User,
|
|
27
|
+
* key: 'id',
|
|
28
|
+
* deferrable: 'INITIALLY DEFERRED'
|
|
29
|
+
* })
|
|
30
|
+
* assignedTo: number;
|
|
31
|
+
*
|
|
32
|
+
* // Deferrable constraint
|
|
33
|
+
* @Deferrable('INITIALLY DEFERRED')
|
|
34
|
+
* @Unique('user_email')
|
|
35
|
+
* email: string;
|
|
36
|
+
*
|
|
37
|
+
* // AutoIncrement with custom settings
|
|
38
|
+
* @AutoIncrement({
|
|
39
|
+
* start: 1000,
|
|
40
|
+
* increment: 1,
|
|
41
|
+
* cache: 1000,
|
|
42
|
+
* minValue: 1,
|
|
43
|
+
* maxValue: 999999,
|
|
44
|
+
* cycle: false,
|
|
45
|
+
* sequence: 'user_id_seq'
|
|
46
|
+
* })
|
|
47
|
+
* id: number;
|
|
48
|
+
*
|
|
49
|
+
* // Sequence-based identity (PostgreSQL)
|
|
50
|
+
* @Identity({
|
|
51
|
+
* type: 'ALWAYS',
|
|
52
|
+
* start: 1,
|
|
53
|
+
* increment: 1
|
|
54
|
+
* })
|
|
55
|
+
* id: number;
|
|
56
|
+
*
|
|
57
|
+
* // Generated column (PostgreSQL 12+)
|
|
58
|
+
* @GeneratedAlways({
|
|
59
|
+
* as: 'id + 1',
|
|
60
|
+
* stored: true
|
|
61
|
+
* })
|
|
62
|
+
* sequenceNumber: number;
|
|
63
|
+
*
|
|
64
|
+
* // Exclusion constraint (PostgreSQL)
|
|
65
|
+
* @Exclusion({
|
|
66
|
+
* using: 'daterange',
|
|
67
|
+
* elements: ['daterange WITH &&']
|
|
68
|
+
* })
|
|
69
|
+
* bookingRange: [Date, Date];
|
|
70
|
+
*/
|
|
71
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
72
|
+
exports.OnDelete = OnDelete;
|
|
73
|
+
exports.OnUpdate = OnUpdate;
|
|
74
|
+
exports.References = References;
|
|
75
|
+
exports.Deferrable = Deferrable;
|
|
76
|
+
exports.Unique = Unique;
|
|
77
|
+
exports.AutoIncrement = AutoIncrement;
|
|
78
|
+
exports.Identity = Identity;
|
|
79
|
+
exports.GeneratedAlways = GeneratedAlways;
|
|
80
|
+
exports.Exclusion = Exclusion;
|
|
81
|
+
exports.getForeignKeyMetadata = getForeignKeyMetadata;
|
|
82
|
+
exports.getAllForeignKeyMetadata = getAllForeignKeyMetadata;
|
|
83
|
+
exports.getUniqueMetadata = getUniqueMetadata;
|
|
84
|
+
exports.getAllUniqueMetadata = getAllUniqueMetadata;
|
|
85
|
+
exports.getAutoIncrementMetadata = getAutoIncrementMetadata;
|
|
86
|
+
exports.getAllAutoIncrementMetadata = getAllAutoIncrementMetadata;
|
|
87
|
+
exports.getIdentityMetadata = getIdentityMetadata;
|
|
88
|
+
exports.getAllIdentityMetadata = getAllIdentityMetadata;
|
|
89
|
+
exports.getGeneratedAlwaysMetadata = getGeneratedAlwaysMetadata;
|
|
90
|
+
exports.getAllGeneratedAlwaysMetadata = getAllGeneratedAlwaysMetadata;
|
|
91
|
+
exports.getExclusionMetadata = getExclusionMetadata;
|
|
92
|
+
exports.getAllExclusionMetadata = getAllExclusionMetadata;
|
|
93
|
+
exports.buildOnDeleteSQL = buildOnDeleteSQL;
|
|
94
|
+
exports.buildOnUpdateSQL = buildOnUpdateSQL;
|
|
95
|
+
exports.buildReferencesSQL = buildReferencesSQL;
|
|
96
|
+
exports.buildDeferrableSQL = buildDeferrableSQL;
|
|
97
|
+
exports.buildAutoIncrementSQL = buildAutoIncrementSQL;
|
|
98
|
+
exports.buildIdentitySQL = buildIdentitySQL;
|
|
99
|
+
exports.buildGeneratedAlwaysSQL = buildGeneratedAlwaysSQL;
|
|
100
|
+
exports.buildExclusionSQL = buildExclusionSQL;
|
|
101
|
+
require("reflect-metadata");
|
|
102
|
+
// ==================== Metadata Keys ====================
|
|
103
|
+
const FOREIGN_KEY_META_KEY = Symbol('orm:foreignKey');
|
|
104
|
+
const UNIQUE_META_KEY = Symbol('orm:unique');
|
|
105
|
+
const AUTO_INCREMENT_META_KEY = Symbol('orm:autoIncrement');
|
|
106
|
+
const IDENTITY_META_KEY = Symbol('orm:identity');
|
|
107
|
+
const GENERATED_ALWAYS_META_KEY = Symbol('orm:generatedAlways');
|
|
108
|
+
const EXCLUSION_META_KEY = Symbol('orm:exclusion');
|
|
109
|
+
// ==================== OnDelete Decorator ====================
|
|
110
|
+
/**
|
|
111
|
+
* @OnDelete - Specify foreign key ON DELETE action
|
|
112
|
+
*
|
|
113
|
+
* @OnDelete('CASCADE')
|
|
114
|
+
* roleId: number;
|
|
115
|
+
*
|
|
116
|
+
* @param action - The delete action (CASCADE, RESTRICT, SET NULL, SET DEFAULT, NO ACTION)
|
|
117
|
+
*/
|
|
118
|
+
function OnDelete(action) {
|
|
119
|
+
return function (target, propertyKey) {
|
|
120
|
+
const key = String(propertyKey);
|
|
121
|
+
const existing = Reflect.getMetadata(FOREIGN_KEY_META_KEY, target, key) || {
|
|
122
|
+
propertyName: key,
|
|
123
|
+
};
|
|
124
|
+
Reflect.defineMetadata(FOREIGN_KEY_META_KEY, { ...existing, onDelete: action }, target, key);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
// ==================== OnUpdate Decorator ====================
|
|
128
|
+
/**
|
|
129
|
+
* @OnUpdate - Specify foreign key ON UPDATE action
|
|
130
|
+
*
|
|
131
|
+
* @OnUpdate('CASCADE')
|
|
132
|
+
* roleId: number;
|
|
133
|
+
*
|
|
134
|
+
* @param action - The update action (CASCADE, RESTRICT, SET NULL, SET DEFAULT, NO ACTION)
|
|
135
|
+
*/
|
|
136
|
+
function OnUpdate(action) {
|
|
137
|
+
return function (target, propertyKey) {
|
|
138
|
+
const key = String(propertyKey);
|
|
139
|
+
const existing = Reflect.getMetadata(FOREIGN_KEY_META_KEY, target, key) || {
|
|
140
|
+
propertyName: key,
|
|
141
|
+
};
|
|
142
|
+
Reflect.defineMetadata(FOREIGN_KEY_META_KEY, { ...existing, onUpdate: action }, target, key);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// ==================== References Decorator ====================
|
|
146
|
+
/**
|
|
147
|
+
* @References - Define foreign key references
|
|
148
|
+
*
|
|
149
|
+
* @References({ model: Role, key: 'id' })
|
|
150
|
+
* roleId: number;
|
|
151
|
+
*
|
|
152
|
+
* @References({
|
|
153
|
+
* model: User,
|
|
154
|
+
* key: 'id',
|
|
155
|
+
* deferrable: 'INITIALLY DEFERRED'
|
|
156
|
+
* })
|
|
157
|
+
* assignedTo: number;
|
|
158
|
+
*
|
|
159
|
+
* @param options - Reference configuration
|
|
160
|
+
*/
|
|
161
|
+
function References(options) {
|
|
162
|
+
return function (target, propertyKey) {
|
|
163
|
+
const key = String(propertyKey);
|
|
164
|
+
const existing = Reflect.getMetadata(FOREIGN_KEY_META_KEY, target, key) || {
|
|
165
|
+
propertyName: key,
|
|
166
|
+
};
|
|
167
|
+
Reflect.defineMetadata(FOREIGN_KEY_META_KEY, { ...existing, references: options }, target, key);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
// ==================== Deferrable Decorator ====================
|
|
171
|
+
/**
|
|
172
|
+
* @Deferrable - Make constraint deferrable
|
|
173
|
+
*
|
|
174
|
+
* @Deferrable('INITIALLY DEFERRED')
|
|
175
|
+
* email: string;
|
|
176
|
+
*
|
|
177
|
+
* // With operation override
|
|
178
|
+
* @Deferrable({
|
|
179
|
+
* deferrable: 'INITIALLY IMMEDIATE',
|
|
180
|
+
* deferFor: 'NOT DEFERRABLE'
|
|
181
|
+
* })
|
|
182
|
+
* departmentId: number;
|
|
183
|
+
*
|
|
184
|
+
* @param options - Deferrable configuration (string or object)
|
|
185
|
+
*/
|
|
186
|
+
function Deferrable(options) {
|
|
187
|
+
return function (target, propertyKey) {
|
|
188
|
+
const key = String(propertyKey);
|
|
189
|
+
const existing = Reflect.getMetadata(FOREIGN_KEY_META_KEY, target, key) || {
|
|
190
|
+
propertyName: key,
|
|
191
|
+
};
|
|
192
|
+
const deferOpts = typeof options === 'string' ? { deferrable: options } : options;
|
|
193
|
+
Reflect.defineMetadata(FOREIGN_KEY_META_KEY, { ...existing, deferrable: deferOpts }, target, key);
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// ==================== Unique Decorator ====================
|
|
197
|
+
/**
|
|
198
|
+
* @Unique - Add unique constraint to a column
|
|
199
|
+
*
|
|
200
|
+
* @Unique('user_email')
|
|
201
|
+
* email: string;
|
|
202
|
+
*
|
|
203
|
+
* @param name - Optional constraint name
|
|
204
|
+
*/
|
|
205
|
+
function Unique(name) {
|
|
206
|
+
return function (target, propertyKey) {
|
|
207
|
+
const key = String(propertyKey);
|
|
208
|
+
const metadata = {
|
|
209
|
+
propertyName: key,
|
|
210
|
+
constraintName: name,
|
|
211
|
+
};
|
|
212
|
+
Reflect.defineMetadata(UNIQUE_META_KEY, metadata, target, key);
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// ==================== AutoIncrement Decorator ====================
|
|
216
|
+
/**
|
|
217
|
+
* @AutoIncrement - Configure auto-increment with custom settings
|
|
218
|
+
*
|
|
219
|
+
* @AutoIncrement({
|
|
220
|
+
* start: 1000,
|
|
221
|
+
* increment: 1,
|
|
222
|
+
* cache: 1000,
|
|
223
|
+
* minValue: 1,
|
|
224
|
+
* maxValue: 999999,
|
|
225
|
+
* cycle: false,
|
|
226
|
+
* sequence: 'user_id_seq'
|
|
227
|
+
* })
|
|
228
|
+
* id: number;
|
|
229
|
+
*
|
|
230
|
+
* @param options - Auto-increment configuration
|
|
231
|
+
*/
|
|
232
|
+
function AutoIncrement(options) {
|
|
233
|
+
return function (target, propertyKey) {
|
|
234
|
+
const key = String(propertyKey);
|
|
235
|
+
const metadata = {
|
|
236
|
+
propertyName: key,
|
|
237
|
+
options,
|
|
238
|
+
};
|
|
239
|
+
Reflect.defineMetadata(AUTO_INCREMENT_META_KEY, metadata, target, key);
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// ==================== Identity Decorator ====================
|
|
243
|
+
/**
|
|
244
|
+
* @Identity - Configure sequence-based identity (PostgreSQL)
|
|
245
|
+
*
|
|
246
|
+
* @Identity({
|
|
247
|
+
* type: 'ALWAYS',
|
|
248
|
+
* start: 1,
|
|
249
|
+
* increment: 1
|
|
250
|
+
* })
|
|
251
|
+
* id: number;
|
|
252
|
+
*
|
|
253
|
+
* @param options - Identity configuration
|
|
254
|
+
*/
|
|
255
|
+
function Identity(options) {
|
|
256
|
+
return function (target, propertyKey) {
|
|
257
|
+
const key = String(propertyKey);
|
|
258
|
+
const metadata = {
|
|
259
|
+
propertyName: key,
|
|
260
|
+
options,
|
|
261
|
+
};
|
|
262
|
+
Reflect.defineMetadata(IDENTITY_META_KEY, metadata, target, key);
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// ==================== GeneratedAlways Decorator ====================
|
|
266
|
+
/**
|
|
267
|
+
* @GeneratedAlways - Define a generated column (PostgreSQL 12+)
|
|
268
|
+
*
|
|
269
|
+
* @GeneratedAlways({
|
|
270
|
+
* as: 'id + 1',
|
|
271
|
+
* stored: true
|
|
272
|
+
* })
|
|
273
|
+
* sequenceNumber: number;
|
|
274
|
+
*
|
|
275
|
+
* @param options - Generated column configuration
|
|
276
|
+
*/
|
|
277
|
+
function GeneratedAlways(options) {
|
|
278
|
+
return function (target, propertyKey) {
|
|
279
|
+
const key = String(propertyKey);
|
|
280
|
+
const metadata = {
|
|
281
|
+
propertyName: key,
|
|
282
|
+
options,
|
|
283
|
+
};
|
|
284
|
+
Reflect.defineMetadata(GENERATED_ALWAYS_META_KEY, metadata, target, key);
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
// ==================== Exclusion Decorator ====================
|
|
288
|
+
/**
|
|
289
|
+
* @Exclusion - Define exclusion constraint (PostgreSQL)
|
|
290
|
+
*
|
|
291
|
+
* @Exclusion({
|
|
292
|
+
* using: 'daterange',
|
|
293
|
+
* elements: ['daterange WITH &&']
|
|
294
|
+
* })
|
|
295
|
+
* bookingRange: [Date, Date];
|
|
296
|
+
*
|
|
297
|
+
* @param options - Exclusion constraint configuration
|
|
298
|
+
*/
|
|
299
|
+
function Exclusion(options) {
|
|
300
|
+
return function (target, propertyKey) {
|
|
301
|
+
const key = String(propertyKey);
|
|
302
|
+
const metadata = {
|
|
303
|
+
propertyName: key,
|
|
304
|
+
options,
|
|
305
|
+
};
|
|
306
|
+
Reflect.defineMetadata(EXCLUSION_META_KEY, metadata, target, key);
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
// ==================== Helper Functions ====================
|
|
310
|
+
/**
|
|
311
|
+
* Get foreign key metadata for a property.
|
|
312
|
+
*/
|
|
313
|
+
function getForeignKeyMetadata(target, propertyKey) {
|
|
314
|
+
return Reflect.getMetadata(FOREIGN_KEY_META_KEY, target, propertyKey);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Get all foreign key metadata for a class.
|
|
318
|
+
*/
|
|
319
|
+
function getAllForeignKeyMetadata(target) {
|
|
320
|
+
const result = new Map();
|
|
321
|
+
const keys = Object.getOwnPropertyNames(target);
|
|
322
|
+
for (const key of keys) {
|
|
323
|
+
const metadata = getForeignKeyMetadata(target, key);
|
|
324
|
+
if (metadata) {
|
|
325
|
+
result.set(key, metadata);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Check prototype chain
|
|
329
|
+
const proto = Object.getPrototypeOf(target);
|
|
330
|
+
if (proto && Object.getPrototypeOf(proto) !== null) {
|
|
331
|
+
const inherited = getAllForeignKeyMetadata(proto);
|
|
332
|
+
for (const [key, value] of inherited) {
|
|
333
|
+
if (!result.has(key)) {
|
|
334
|
+
result.set(key, value);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return result;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Get unique metadata for a property.
|
|
342
|
+
*/
|
|
343
|
+
function getUniqueMetadata(target, propertyKey) {
|
|
344
|
+
return Reflect.getMetadata(UNIQUE_META_KEY, target, propertyKey);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get all unique metadata for a class.
|
|
348
|
+
*/
|
|
349
|
+
function getAllUniqueMetadata(target) {
|
|
350
|
+
const result = new Map();
|
|
351
|
+
const keys = Object.getOwnPropertyNames(target);
|
|
352
|
+
for (const key of keys) {
|
|
353
|
+
const metadata = getUniqueMetadata(target, key);
|
|
354
|
+
if (metadata) {
|
|
355
|
+
result.set(key, metadata);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const proto = Object.getPrototypeOf(target);
|
|
359
|
+
if (proto && Object.getPrototypeOf(proto) !== null) {
|
|
360
|
+
const inherited = getAllUniqueMetadata(proto);
|
|
361
|
+
for (const [key, value] of inherited) {
|
|
362
|
+
if (!result.has(key)) {
|
|
363
|
+
result.set(key, value);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return result;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Get auto-increment metadata for a property.
|
|
371
|
+
*/
|
|
372
|
+
function getAutoIncrementMetadata(target, propertyKey) {
|
|
373
|
+
return Reflect.getMetadata(AUTO_INCREMENT_META_KEY, target, propertyKey);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Get all auto-increment metadata for a class.
|
|
377
|
+
*/
|
|
378
|
+
function getAllAutoIncrementMetadata(target) {
|
|
379
|
+
const result = new Map();
|
|
380
|
+
const keys = Object.getOwnPropertyNames(target);
|
|
381
|
+
for (const key of keys) {
|
|
382
|
+
const metadata = getAutoIncrementMetadata(target, key);
|
|
383
|
+
if (metadata) {
|
|
384
|
+
result.set(key, metadata);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const proto = Object.getPrototypeOf(target);
|
|
388
|
+
if (proto && Object.getPrototypeOf(proto) !== null) {
|
|
389
|
+
const inherited = getAllAutoIncrementMetadata(proto);
|
|
390
|
+
for (const [key, value] of inherited) {
|
|
391
|
+
if (!result.has(key)) {
|
|
392
|
+
result.set(key, value);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return result;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Get identity metadata for a property.
|
|
400
|
+
*/
|
|
401
|
+
function getIdentityMetadata(target, propertyKey) {
|
|
402
|
+
return Reflect.getMetadata(IDENTITY_META_KEY, target, propertyKey);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Get all identity metadata for a class.
|
|
406
|
+
*/
|
|
407
|
+
function getAllIdentityMetadata(target) {
|
|
408
|
+
const result = new Map();
|
|
409
|
+
const keys = Object.getOwnPropertyNames(target);
|
|
410
|
+
for (const key of keys) {
|
|
411
|
+
const metadata = getIdentityMetadata(target, key);
|
|
412
|
+
if (metadata) {
|
|
413
|
+
result.set(key, metadata);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const proto = Object.getPrototypeOf(target);
|
|
417
|
+
if (proto && Object.getPrototypeOf(proto) !== null) {
|
|
418
|
+
const inherited = getAllIdentityMetadata(proto);
|
|
419
|
+
for (const [key, value] of inherited) {
|
|
420
|
+
if (!result.has(key)) {
|
|
421
|
+
result.set(key, value);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return result;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Get generated always metadata for a property.
|
|
429
|
+
*/
|
|
430
|
+
function getGeneratedAlwaysMetadata(target, propertyKey) {
|
|
431
|
+
return Reflect.getMetadata(GENERATED_ALWAYS_META_KEY, target, propertyKey);
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Get all generated always metadata for a class.
|
|
435
|
+
*/
|
|
436
|
+
function getAllGeneratedAlwaysMetadata(target) {
|
|
437
|
+
const result = new Map();
|
|
438
|
+
const keys = Object.getOwnPropertyNames(target);
|
|
439
|
+
for (const key of keys) {
|
|
440
|
+
const metadata = getGeneratedAlwaysMetadata(target, key);
|
|
441
|
+
if (metadata) {
|
|
442
|
+
result.set(key, metadata);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const proto = Object.getPrototypeOf(target);
|
|
446
|
+
if (proto && Object.getPrototypeOf(proto) !== null) {
|
|
447
|
+
const inherited = getAllGeneratedAlwaysMetadata(proto);
|
|
448
|
+
for (const [key, value] of inherited) {
|
|
449
|
+
if (!result.has(key)) {
|
|
450
|
+
result.set(key, value);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return result;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Get exclusion metadata for a property.
|
|
458
|
+
*/
|
|
459
|
+
function getExclusionMetadata(target, propertyKey) {
|
|
460
|
+
return Reflect.getMetadata(EXCLUSION_META_KEY, target, propertyKey);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Get all exclusion metadata for a class.
|
|
464
|
+
*/
|
|
465
|
+
function getAllExclusionMetadata(target) {
|
|
466
|
+
const result = new Map();
|
|
467
|
+
const keys = Object.getOwnPropertyNames(target);
|
|
468
|
+
for (const key of keys) {
|
|
469
|
+
const metadata = getExclusionMetadata(target, key);
|
|
470
|
+
if (metadata) {
|
|
471
|
+
result.set(key, metadata);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const proto = Object.getPrototypeOf(target);
|
|
475
|
+
if (proto && Object.getPrototypeOf(proto) !== null) {
|
|
476
|
+
const inherited = getAllExclusionMetadata(proto);
|
|
477
|
+
for (const [key, value] of inherited) {
|
|
478
|
+
if (!result.has(key)) {
|
|
479
|
+
result.set(key, value);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return result;
|
|
484
|
+
}
|
|
485
|
+
// ==================== SQL Builders ====================
|
|
486
|
+
/**
|
|
487
|
+
* Build ON DELETE SQL clause.
|
|
488
|
+
*/
|
|
489
|
+
function buildOnDeleteSQL(action) {
|
|
490
|
+
return `ON DELETE ${action}`;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Build ON UPDATE SQL clause.
|
|
494
|
+
*/
|
|
495
|
+
function buildOnUpdateSQL(action) {
|
|
496
|
+
return `ON UPDATE ${action}`;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Build REFERENCES SQL clause.
|
|
500
|
+
*/
|
|
501
|
+
function buildReferencesSQL(options) {
|
|
502
|
+
const modelName = typeof options.model === 'string' ? options.model : options.model.name;
|
|
503
|
+
const key = options.key || 'id';
|
|
504
|
+
let sql = `REFERENCES "${modelName}"("${key}")`;
|
|
505
|
+
if (options.deferrable) {
|
|
506
|
+
sql += ` DEFERRABLE ${options.deferrable}`;
|
|
507
|
+
}
|
|
508
|
+
return sql;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Build DEFERRABLE SQL clause.
|
|
512
|
+
*/
|
|
513
|
+
function buildDeferrableSQL(options) {
|
|
514
|
+
let sql = `DEFERRABLE ${options.deferrable}`;
|
|
515
|
+
if (options.deferFor) {
|
|
516
|
+
sql += ` INITIALLY ${options.deferFor === 'NOT DEFERRABLE' ? 'NOT DEFERRED' : options.deferFor.replace('INITIALLY ', '')}`;
|
|
517
|
+
}
|
|
518
|
+
return sql;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Build AUTO_INCREMENT / IDENTITY SQL.
|
|
522
|
+
*/
|
|
523
|
+
function buildAutoIncrementSQL(options) {
|
|
524
|
+
const parts = [];
|
|
525
|
+
if (options.start !== undefined) {
|
|
526
|
+
parts.push(`START WITH ${options.start}`);
|
|
527
|
+
}
|
|
528
|
+
if (options.increment !== undefined) {
|
|
529
|
+
parts.push(`INCREMENT BY ${options.increment}`);
|
|
530
|
+
}
|
|
531
|
+
if (options.minValue !== undefined) {
|
|
532
|
+
parts.push(`MINVALUE ${options.minValue}`);
|
|
533
|
+
}
|
|
534
|
+
if (options.maxValue !== undefined) {
|
|
535
|
+
parts.push(`MAXVALUE ${options.maxValue}`);
|
|
536
|
+
}
|
|
537
|
+
if (options.cache !== undefined) {
|
|
538
|
+
parts.push(`CACHE ${options.cache}`);
|
|
539
|
+
}
|
|
540
|
+
if (options.cycle) {
|
|
541
|
+
parts.push('CYCLE');
|
|
542
|
+
}
|
|
543
|
+
if (options.sequence) {
|
|
544
|
+
parts.push(`SEQUENCE ${options.sequence}`);
|
|
545
|
+
}
|
|
546
|
+
return parts.length > 0 ? parts.join(' ') : '';
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Build IDENTITY SQL (PostgreSQL).
|
|
550
|
+
*/
|
|
551
|
+
function buildIdentitySQL(options) {
|
|
552
|
+
const type = options.type || 'ALWAYS';
|
|
553
|
+
const parts = [`GENERATED ${type} AS IDENTITY`];
|
|
554
|
+
if (options.start !== undefined || options.increment !== undefined) {
|
|
555
|
+
const seqParts = ['('];
|
|
556
|
+
if (options.start !== undefined) {
|
|
557
|
+
seqParts.push(`START WITH ${options.start}`);
|
|
558
|
+
}
|
|
559
|
+
if (options.increment !== undefined) {
|
|
560
|
+
seqParts.push(`INCREMENT BY ${options.increment}`);
|
|
561
|
+
}
|
|
562
|
+
if (options.min !== undefined) {
|
|
563
|
+
seqParts.push(`MINVALUE ${options.min}`);
|
|
564
|
+
}
|
|
565
|
+
if (options.max !== undefined) {
|
|
566
|
+
seqParts.push(`MAXVALUE ${options.max}`);
|
|
567
|
+
}
|
|
568
|
+
if (options.cache !== undefined) {
|
|
569
|
+
seqParts.push(`CACHE ${options.cache}`);
|
|
570
|
+
}
|
|
571
|
+
if (options.cycle) {
|
|
572
|
+
seqParts.push('CYCLE');
|
|
573
|
+
}
|
|
574
|
+
seqParts.push(')');
|
|
575
|
+
parts.push(seqParts.join(' '));
|
|
576
|
+
}
|
|
577
|
+
return parts.join(' ');
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Build GENERATED ALWAYS SQL (PostgreSQL 12+).
|
|
581
|
+
*/
|
|
582
|
+
function buildGeneratedAlwaysSQL(options) {
|
|
583
|
+
const stored = options.stored ? 'STORED' : 'VIRTUAL';
|
|
584
|
+
return `GENERATED ALWAYS AS (${options.as}) ${stored}`;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Build EXCLUSION constraint SQL (PostgreSQL).
|
|
588
|
+
*/
|
|
589
|
+
function buildExclusionSQL(tableName, options) {
|
|
590
|
+
const name = options.name || `excl_${tableName}_${Date.now().toString(36)}`;
|
|
591
|
+
const using = options.using || 'gist';
|
|
592
|
+
const elements = options.elements.join(', ');
|
|
593
|
+
return `CONSTRAINT "${name}" EXCLUDE USING ${using} (${elements})`;
|
|
594
|
+
}
|