uql-orm 0.21.0 → 0.23.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 (214) hide show
  1. package/README.md +5 -4
  2. package/dist/browser/uql-browser.min.js.map +3 -3
  3. package/dist/bunSql/bunSqlCockroachDialect.d.ts +2 -2
  4. package/dist/bunSql/bunSqlCockroachDialect.js +4 -10
  5. package/dist/bunSql/bunSqlPostgresDialect.d.ts +2 -2
  6. package/dist/bunSql/bunSqlPostgresDialect.js +4 -10
  7. package/dist/cockroachdb/cockroachDialect.d.ts +20 -4
  8. package/dist/cockroachdb/cockroachDialect.js +33 -18
  9. package/dist/d1/d1Querier.d.ts +4 -3
  10. package/dist/d1/d1Querier.js +0 -3
  11. package/dist/d1/d1SqliteDialect.d.ts +7 -0
  12. package/dist/d1/d1SqliteDialect.js +9 -0
  13. package/dist/dialect/abstractDialect.d.ts +8 -3
  14. package/dist/dialect/abstractDialect.js +9 -4
  15. package/dist/dialect/abstractSqlDialect.d.ts +49 -8
  16. package/dist/dialect/abstractSqlDialect.js +95 -47
  17. package/dist/dialect/index.d.ts +1 -0
  18. package/dist/dialect/index.js +1 -0
  19. package/dist/dialect/indexSqlDialect.d.ts +57 -0
  20. package/dist/dialect/indexSqlDialect.js +101 -0
  21. package/dist/dialect/mysqlLikeSqlDialect.d.ts +26 -1
  22. package/dist/dialect/mysqlLikeSqlDialect.js +57 -1
  23. package/dist/dialect/pgLikeSqlDialect.d.ts +37 -22
  24. package/dist/dialect/pgLikeSqlDialect.js +97 -68
  25. package/dist/dialect/vectorCast.d.ts +21 -0
  26. package/dist/dialect/vectorCast.js +28 -0
  27. package/dist/dialect/vectorSqlDialect.d.ts +10 -3
  28. package/dist/dialect/vectorSqlDialect.js +19 -8
  29. package/dist/entity/decorator/bag.d.ts +35 -0
  30. package/dist/entity/decorator/bag.js +54 -0
  31. package/dist/entity/decorator/entity.d.ts +28 -2
  32. package/dist/entity/decorator/entity.js +40 -2
  33. package/dist/entity/decorator/members.d.ts +51 -0
  34. package/dist/entity/decorator/members.js +51 -0
  35. package/dist/entity/index.d.ts +3 -1
  36. package/dist/entity/index.js +3 -1
  37. package/dist/entity/metadata/definition.d.ts +23 -8
  38. package/dist/entity/metadata/definition.js +56 -100
  39. package/dist/http/contract.js +1 -2
  40. package/dist/http/handler.js +5 -26
  41. package/dist/http/query.js +1 -1
  42. package/dist/libsql/libsqlDialect.d.ts +12 -2
  43. package/dist/libsql/libsqlDialect.js +14 -2
  44. package/dist/libsql/libsqlQuerier.d.ts +9 -22
  45. package/dist/libsql/libsqlQuerier.js +9 -85
  46. package/dist/libsql/libsqlQuerierPool.d.ts +10 -8
  47. package/dist/libsql/libsqlQuerierPool.js +17 -15
  48. package/dist/maria/mariaDialect.d.ts +26 -4
  49. package/dist/maria/mariaDialect.js +54 -15
  50. package/dist/migrate/acquireQuerierForMigrations.d.ts +13 -1
  51. package/dist/migrate/acquireQuerierForMigrations.js +28 -0
  52. package/dist/migrate/builder/migrationBuilder.d.ts +9 -29
  53. package/dist/migrate/builder/migrationBuilder.js +58 -76
  54. package/dist/migrate/builder/splitSqlStatements.d.ts +0 -2
  55. package/dist/migrate/builder/splitSqlStatements.js +0 -2
  56. package/dist/migrate/builder/tableBuilder.d.ts +12 -2
  57. package/dist/migrate/builder/tableBuilder.js +71 -119
  58. package/dist/migrate/builder/types.d.ts +30 -41
  59. package/dist/migrate/cli-config.js +24 -8
  60. package/dist/migrate/cli.d.ts +3 -2
  61. package/dist/migrate/cli.js +26 -49
  62. package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -4
  63. package/dist/migrate/codegen/entityCodeGenerator.js +8 -67
  64. package/dist/migrate/codegen/fieldOptionsSource.d.ts +10 -0
  65. package/dist/migrate/codegen/fieldOptionsSource.js +55 -0
  66. package/dist/migrate/codegen/index.d.ts +0 -3
  67. package/dist/migrate/codegen/index.js +0 -6
  68. package/dist/migrate/drift/driftDetector.d.ts +10 -1
  69. package/dist/migrate/drift/driftDetector.js +22 -5
  70. package/dist/migrate/generator/indexNodeToSchema.d.ts +9 -0
  71. package/dist/migrate/generator/indexNodeToSchema.js +14 -0
  72. package/dist/migrate/generator/mongoCommand.d.ts +57 -0
  73. package/dist/migrate/generator/mongoCommand.js +26 -0
  74. package/dist/migrate/generator/mongoSchemaGenerator.d.ts +9 -20
  75. package/dist/migrate/generator/mongoSchemaGenerator.js +40 -82
  76. package/dist/migrate/index.d.ts +0 -1
  77. package/dist/migrate/index.js +0 -1
  78. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +30 -11
  79. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +61 -57
  80. package/dist/migrate/introspection/baseSqlIntrospector.d.ts +0 -1
  81. package/dist/migrate/introspection/baseSqlIntrospector.js +3 -12
  82. package/dist/migrate/introspection/mongoIntrospector.js +9 -15
  83. package/dist/migrate/introspection/mysqlIntrospector.d.ts +5 -8
  84. package/dist/migrate/introspection/mysqlIntrospector.js +4 -10
  85. package/dist/migrate/introspection/postgresIntrospector.d.ts +5 -8
  86. package/dist/migrate/introspection/postgresIntrospector.js +4 -10
  87. package/dist/migrate/introspection/sqliteIntrospector.d.ts +6 -5
  88. package/dist/migrate/introspection/sqliteIntrospector.js +26 -18
  89. package/dist/migrate/migrator.d.ts +23 -3
  90. package/dist/migrate/migrator.js +101 -150
  91. package/dist/migrate/schemaGenerator.d.ts +26 -37
  92. package/dist/migrate/schemaGenerator.js +69 -174
  93. package/dist/migrate/schemaGeneratorAsync.d.ts +2 -2
  94. package/dist/migrate/schemaGeneratorAsync.js +3 -3
  95. package/dist/migrate/storage/databaseStorage.d.ts +2 -0
  96. package/dist/migrate/storage/databaseStorage.js +12 -27
  97. package/dist/mongo/mongoDialect.d.ts +2 -0
  98. package/dist/mongo/mongoDialect.js +14 -3
  99. package/dist/mongo/mongodbQuerier.js +171 -229
  100. package/dist/mysql/mysqlDialect.d.ts +8 -0
  101. package/dist/mysql/mysqlDialect.js +13 -0
  102. package/dist/nestjs/uqlContextInterceptor.js +58 -22
  103. package/dist/nestjs/uqlModule.d.ts +2 -11
  104. package/dist/nestjs/uqlModule.js +93 -44
  105. package/dist/postgres/postgresDialect.js +2 -2
  106. package/dist/querier/abstractQuerier.d.ts +28 -0
  107. package/dist/querier/abstractQuerier.js +47 -22
  108. package/dist/querier/abstractQuerierPool.d.ts +3 -0
  109. package/dist/querier/abstractQuerierPool.js +5 -3
  110. package/dist/querier/abstractSqlQuerier.d.ts +1 -3
  111. package/dist/querier/abstractSqlQuerier.js +48 -96
  112. package/dist/querier/index.d.ts +3 -1
  113. package/dist/querier/index.js +3 -1
  114. package/dist/querier/querierContext.browser.d.ts +12 -0
  115. package/dist/querier/querierContext.browser.js +18 -0
  116. package/dist/querier/querierContext.d.ts +22 -0
  117. package/dist/querier/querierContext.js +42 -0
  118. package/dist/querier/queryError.d.ts +22 -0
  119. package/dist/querier/queryError.js +20 -0
  120. package/dist/querier/transactional.d.ts +26 -0
  121. package/dist/querier/transactional.js +43 -0
  122. package/dist/schema/canonicalType.d.ts +14 -2
  123. package/dist/schema/canonicalType.js +41 -31
  124. package/dist/schema/index.d.ts +1 -1
  125. package/dist/schema/schemaASTBuilder.d.ts +9 -2
  126. package/dist/schema/schemaASTBuilder.js +58 -49
  127. package/dist/schema/types.d.ts +10 -58
  128. package/dist/sqlite/abstractSqliteQuerier.d.ts +46 -0
  129. package/dist/sqlite/abstractSqliteQuerier.js +44 -0
  130. package/dist/sqlite/bunSqliteAdapter.bun.d.ts +26 -0
  131. package/dist/sqlite/bunSqliteAdapter.bun.js +25 -0
  132. package/dist/sqlite/hranaQuerier.d.ts +54 -0
  133. package/dist/sqlite/hranaQuerier.js +68 -0
  134. package/dist/sqlite/hranaQuerierPool.d.ts +21 -0
  135. package/dist/sqlite/hranaQuerierPool.js +25 -0
  136. package/dist/sqlite/index.d.ts +3 -1
  137. package/dist/sqlite/index.js +3 -1
  138. package/dist/sqlite/localSqliteQuerierPool.d.ts +31 -0
  139. package/dist/sqlite/localSqliteQuerierPool.js +34 -0
  140. package/dist/sqlite/nodeSqliteAdapter.d.ts +35 -0
  141. package/dist/sqlite/nodeSqliteAdapter.js +28 -0
  142. package/dist/sqlite/nodeSqliteQuerierPool.d.ts +28 -0
  143. package/dist/sqlite/nodeSqliteQuerierPool.js +29 -0
  144. package/dist/sqlite/sqliteDialect.d.ts +18 -5
  145. package/dist/sqlite/sqliteDialect.js +23 -36
  146. package/dist/sqlite/sqliteQuerier.d.ts +16 -9
  147. package/dist/sqlite/sqliteQuerier.js +4 -27
  148. package/dist/sqlite/sqliteQuerierPool.d.ts +11 -14
  149. package/dist/sqlite/sqliteQuerierPool.js +16 -24
  150. package/dist/turso/index.d.ts +3 -0
  151. package/dist/turso/index.js +3 -0
  152. package/dist/turso/local.d.ts +3 -0
  153. package/dist/turso/local.js +3 -0
  154. package/dist/turso/tursoDialect.d.ts +15 -0
  155. package/dist/turso/tursoDialect.js +18 -0
  156. package/dist/turso/tursoLocalQuerier.d.ts +25 -0
  157. package/dist/turso/tursoLocalQuerier.js +20 -0
  158. package/dist/turso/tursoLocalQuerierPool.d.ts +32 -0
  159. package/dist/turso/tursoLocalQuerierPool.js +39 -0
  160. package/dist/turso/tursoQuerier.d.ts +10 -0
  161. package/dist/turso/tursoQuerier.js +10 -0
  162. package/dist/turso/tursoQuerierPool.d.ts +39 -0
  163. package/dist/turso/tursoQuerierPool.js +38 -0
  164. package/dist/type/config.d.ts +0 -6
  165. package/dist/type/dialect.d.ts +12 -4
  166. package/dist/type/dialect.js +7 -1
  167. package/dist/type/entity.d.ts +154 -26
  168. package/dist/type/migration.d.ts +32 -23
  169. package/dist/type/querier.d.ts +6 -0
  170. package/dist/type/vector.d.ts +5 -2
  171. package/dist/util/hook.util.js +1 -1
  172. package/dist/util/index.d.ts +1 -0
  173. package/dist/util/index.js +1 -0
  174. package/dist/util/indexColumn.util.d.ts +6 -0
  175. package/dist/util/indexColumn.util.js +26 -0
  176. package/package.json +21 -16
  177. package/dist/entity/decorator/field.d.ts +0 -2
  178. package/dist/entity/decorator/field.js +0 -7
  179. package/dist/entity/decorator/filter.d.ts +0 -7
  180. package/dist/entity/decorator/filter.js +0 -11
  181. package/dist/entity/decorator/hook.d.ts +0 -7
  182. package/dist/entity/decorator/hook.js +0 -14
  183. package/dist/entity/decorator/id.d.ts +0 -2
  184. package/dist/entity/decorator/id.js +0 -7
  185. package/dist/entity/decorator/index-decorator.d.ts +0 -29
  186. package/dist/entity/decorator/index-decorator.js +0 -26
  187. package/dist/entity/decorator/index.d.ts +0 -8
  188. package/dist/entity/decorator/index.js +0 -8
  189. package/dist/entity/decorator/relation.d.ts +0 -8
  190. package/dist/entity/decorator/relation.js +0 -19
  191. package/dist/migrate/codegen/entityMerger.d.ts +0 -114
  192. package/dist/migrate/codegen/entityMerger.js +0 -293
  193. package/dist/migrate/codegen/migrationCodeGenerator.d.ts +0 -61
  194. package/dist/migrate/codegen/migrationCodeGenerator.js +0 -355
  195. package/dist/migrate/codegen/smartRelationDetector.d.ts +0 -47
  196. package/dist/migrate/codegen/smartRelationDetector.js +0 -134
  197. package/dist/migrate/generator/index.d.ts +0 -2
  198. package/dist/migrate/generator/index.js +0 -2
  199. package/dist/migrate/sync/index.d.ts +0 -6
  200. package/dist/migrate/sync/index.js +0 -6
  201. package/dist/migrate/sync/schemaSync.d.ts +0 -131
  202. package/dist/migrate/sync/schemaSync.js +0 -259
  203. package/dist/querier/decorator/index.d.ts +0 -4
  204. package/dist/querier/decorator/index.js +0 -4
  205. package/dist/querier/decorator/injectQuerier.d.ts +0 -3
  206. package/dist/querier/decorator/injectQuerier.js +0 -33
  207. package/dist/querier/decorator/log.d.ts +0 -32
  208. package/dist/querier/decorator/log.js +0 -52
  209. package/dist/querier/decorator/serialized.d.ts +0 -6
  210. package/dist/querier/decorator/serialized.js +0 -13
  211. package/dist/querier/decorator/transactional.d.ts +0 -6
  212. package/dist/querier/decorator/transactional.js +0 -48
  213. package/dist/sqlite/betterSqlite3Dialect.d.ts +0 -9
  214. package/dist/sqlite/betterSqlite3Dialect.js +0 -9
@@ -1,26 +0,0 @@
1
- import { defineIndex } from '../metadata/definition.js';
2
- /**
3
- * Define a composite index on an entity class.
4
- *
5
- * @example
6
- * ```ts
7
- * @Index(['lastName', 'firstName'], { name: 'idx_users_fullname' })
8
- * @Entity()
9
- * export class User {
10
- * @Id() id?: number;
11
- * @Field() firstName?: string;
12
- * @Field() lastName?: string;
13
- * }
14
- *
15
- * // With unique and partial index
16
- * @Index(['email'], { unique: true })
17
- * @Index(['status'], { where: "status = 'active'" })
18
- * @Entity()
19
- * export class User { ... }
20
- * ```
21
- */
22
- export function Index(columns, options = {}) {
23
- return (target) => {
24
- defineIndex(target, { ...options, columns });
25
- };
26
- }
@@ -1,8 +0,0 @@
1
- export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, } from '../metadata/definition.js';
2
- export * from './entity.js';
3
- export * from './field.js';
4
- export * from './filter.js';
5
- export * from './hook.js';
6
- export * from './id.js';
7
- export * from './index-decorator.js';
8
- export * from './relation.js';
@@ -1,8 +0,0 @@
1
- export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, } from '../metadata/definition.js';
2
- export * from './entity.js';
3
- export * from './field.js';
4
- export * from './filter.js';
5
- export * from './hook.js';
6
- export * from './id.js';
7
- export * from './index-decorator.js';
8
- export * from './relation.js';
@@ -1,8 +0,0 @@
1
- import type { RelationManyToManyOptions, RelationManyToOneOptions, RelationOneToManyOptions, RelationOneToOneOptions, RelationOptions } from '../../type/index.js';
2
- declare function Relation<E>(opts: RelationOptions<E>): (target: object, key: string) => void;
3
- type RelationReturn = ReturnType<typeof Relation>;
4
- export declare function OneToOne<E>(opts?: RelationOneToOneOptions<E>): RelationReturn;
5
- export declare function ManyToOne<E>(opts?: RelationManyToOneOptions<E>): RelationReturn;
6
- export declare function OneToMany<E>(opts: RelationOneToManyOptions<E>): RelationReturn;
7
- export declare function ManyToMany<E>(opts: RelationManyToManyOptions<E>): RelationReturn;
8
- export {};
@@ -1,19 +0,0 @@
1
- import { defineRelation } from '../metadata/definition.js';
2
- function Relation(opts) {
3
- return (target, key) => {
4
- const entity = target.constructor;
5
- defineRelation(entity, key, opts);
6
- };
7
- }
8
- export function OneToOne(opts) {
9
- return Relation({ cardinality: '11', ...opts });
10
- }
11
- export function ManyToOne(opts) {
12
- return Relation({ cardinality: 'm1', ...opts });
13
- }
14
- export function OneToMany(opts) {
15
- return Relation({ cardinality: '1m', ...opts });
16
- }
17
- export function ManyToMany(opts) {
18
- return Relation({ cardinality: 'mm', ...opts });
19
- }
@@ -1,114 +0,0 @@
1
- /**
2
- * Entity Merger
3
- *
4
- * Merges generated entity code with existing TypeScript entity files.
5
- * Uses string-based parsing to add new fields with JSDoc comments.
6
- */
7
- import type { ColumnNode, RelationshipNode } from '../../schema/types.js';
8
- /**
9
- * Options for entity merging.
10
- */
11
- export interface EntityMergerOptions {
12
- /** Add JSDoc @sync-added comments to new fields */
13
- addSyncComments?: boolean;
14
- /** Mark removed fields with @deprecated instead of deleting */
15
- markRemovedAsDeprecated?: boolean;
16
- /** Custom property name transformer */
17
- propertyNameTransformer?: (columnName: string) => string;
18
- }
19
- /**
20
- * Represents a field to add to an entity.
21
- */
22
- export interface FieldToAdd {
23
- column: ColumnNode;
24
- propertyName: string;
25
- isRelation?: boolean;
26
- relation?: RelationshipNode;
27
- }
28
- /**
29
- * Represents a field to mark as deprecated.
30
- */
31
- export interface FieldToDeprecate {
32
- propertyName: string;
33
- reason: string;
34
- }
35
- /**
36
- * Result of entity merge operation.
37
- */
38
- export interface MergeResult {
39
- /** The merged source code */
40
- code: string;
41
- /** Number of fields added */
42
- fieldsAdded: number;
43
- /** Number of fields marked deprecated */
44
- fieldsDeprecated: number;
45
- /** Whether the file was modified */
46
- modified: boolean;
47
- }
48
- /**
49
- * Merges new fields from database schema into existing entity files.
50
- */
51
- export declare class EntityMerger {
52
- private readonly options;
53
- constructor(options?: EntityMergerOptions);
54
- /**
55
- * Merge new fields into existing entity source code.
56
- */
57
- merge(existingCode: string, fieldsToAdd: FieldToAdd[], fieldsToDeprecate?: FieldToDeprecate[]): MergeResult;
58
- /**
59
- * Extract existing property names from entity code.
60
- */
61
- private extractPropertyNames;
62
- /**
63
- * Find the position to insert new fields (before the last closing brace).
64
- */
65
- private findInsertPosition;
66
- /**
67
- * Count net brace depth change in a line.
68
- */
69
- private countBraces;
70
- /**
71
- * Generate code for new fields.
72
- */
73
- private generateFieldsCode;
74
- /**
75
- * Generate code for a column field.
76
- */
77
- private generateColumnField;
78
- /**
79
- * Generate code for a relation field.
80
- */
81
- private generateRelationField;
82
- /**
83
- * Mark a field as deprecated in the source code.
84
- */
85
- private markFieldAsDeprecated;
86
- /**
87
- * Build Field decorator options string.
88
- */
89
- private buildFieldOptions;
90
- /**
91
- * Format type for description.
92
- */
93
- private formatTypeDescription;
94
- /**
95
- * Get relation decorator name.
96
- */
97
- private getRelationDecoratorName;
98
- /**
99
- * Default property name transformer (delegates to shared utility).
100
- */
101
- private defaultPropertyNameTransformer;
102
- /**
103
- * Convert to PascalCase (delegates to shared utility).
104
- */
105
- private toPascalCase;
106
- /**
107
- * Singularize (delegates to shared utility).
108
- */
109
- private singularize;
110
- }
111
- /**
112
- * Create an EntityMerger instance.
113
- */
114
- export declare function createEntityMerger(options?: EntityMergerOptions): EntityMerger;
@@ -1,293 +0,0 @@
1
- /**
2
- * Entity Merger
3
- *
4
- * Merges generated entity code with existing TypeScript entity files.
5
- * Uses string-based parsing to add new fields with JSDoc comments.
6
- */
7
- import { canonicalToColumnType, canonicalToTypeScript } from '../../schema/canonicalType.js';
8
- import { camelCase, pascalCase, singularize } from '../../util/string.util.js';
9
- /**
10
- * Merges new fields from database schema into existing entity files.
11
- */
12
- export class EntityMerger {
13
- options;
14
- constructor(options = {}) {
15
- this.options = {
16
- addSyncComments: options.addSyncComments ?? true,
17
- markRemovedAsDeprecated: options.markRemovedAsDeprecated ?? true,
18
- propertyNameTransformer: options.propertyNameTransformer ?? this.defaultPropertyNameTransformer.bind(this),
19
- };
20
- }
21
- /**
22
- * Merge new fields into existing entity source code.
23
- */
24
- merge(existingCode, fieldsToAdd, fieldsToDeprecate = []) {
25
- let code = existingCode;
26
- let fieldsAdded = 0;
27
- let fieldsDeprecated = 0;
28
- // Find the existing property names to avoid duplicates
29
- const existingProps = this.extractPropertyNames(code);
30
- // Filter out fields that already exist
31
- const newFields = fieldsToAdd.filter((f) => !existingProps.has(f.propertyName));
32
- // Find the position to insert new fields (before closing brace)
33
- const insertPosition = this.findInsertPosition(code);
34
- if (insertPosition === -1) {
35
- return { code, fieldsAdded: 0, fieldsDeprecated: 0, modified: false };
36
- }
37
- // Generate code for new fields
38
- const newFieldsCode = this.generateFieldsCode(newFields);
39
- if (newFieldsCode) {
40
- // Insert the new fields
41
- code = code.slice(0, insertPosition) + newFieldsCode + code.slice(insertPosition);
42
- fieldsAdded = newFields.length;
43
- }
44
- // Mark fields as deprecated
45
- if (this.options.markRemovedAsDeprecated) {
46
- for (const field of fieldsToDeprecate) {
47
- const deprecatedCode = this.markFieldAsDeprecated(code, field);
48
- if (deprecatedCode !== code) {
49
- code = deprecatedCode;
50
- fieldsDeprecated++;
51
- }
52
- }
53
- }
54
- return {
55
- code,
56
- fieldsAdded,
57
- fieldsDeprecated,
58
- modified: fieldsAdded > 0 || fieldsDeprecated > 0,
59
- };
60
- }
61
- /**
62
- * Extract existing property names from entity code.
63
- */
64
- extractPropertyNames(code) {
65
- const props = new Set();
66
- // Match property declarations: propertyName?: Type;
67
- const regex = /^\s*(?:readonly\s+)?(\w+)\s*[?!]?\s*:/gm;
68
- let match = regex.exec(code);
69
- while (match !== null) {
70
- props.add(match[1]);
71
- match = regex.exec(code);
72
- }
73
- return props;
74
- }
75
- /**
76
- * Find the position to insert new fields (before the last closing brace).
77
- */
78
- findInsertPosition(code) {
79
- const lines = code.split('\n');
80
- let braceCount = 0;
81
- let inClass = false;
82
- let lastPropertyLine = -1;
83
- for (let i = 0; i < lines.length; i++) {
84
- const line = lines[i];
85
- if (line.includes('class ')) {
86
- inClass = true;
87
- }
88
- if (!inClass)
89
- continue;
90
- braceCount += this.countBraces(line);
91
- if (/^\s*(?:@\w+|readonly\s+|\w+\s*[?!]?:)/.test(line)) {
92
- lastPropertyLine = i;
93
- }
94
- if (braceCount !== 0)
95
- continue;
96
- // Found the closing brace - calculate insertion position
97
- const insertLineIndex = lastPropertyLine >= 0 ? lastPropertyLine + 1 : i;
98
- let pos = 0;
99
- for (let j = 0; j < insertLineIndex; j++) {
100
- pos += lines[j].length + 1;
101
- }
102
- return pos;
103
- }
104
- return -1;
105
- }
106
- /**
107
- * Count net brace depth change in a line.
108
- */
109
- countBraces(line) {
110
- let count = 0;
111
- for (const char of line) {
112
- if (char === '{')
113
- count++;
114
- if (char === '}')
115
- count--;
116
- }
117
- return count;
118
- }
119
- /**
120
- * Generate code for new fields.
121
- */
122
- generateFieldsCode(fields) {
123
- if (fields.length === 0)
124
- return '';
125
- const lines = [''];
126
- for (const field of fields) {
127
- if (field.isRelation && field.relation) {
128
- lines.push(...this.generateRelationField(field));
129
- }
130
- else {
131
- lines.push(...this.generateColumnField(field));
132
- }
133
- lines.push('');
134
- }
135
- return lines.join('\n');
136
- }
137
- /**
138
- * Generate code for a column field.
139
- */
140
- generateColumnField(field) {
141
- const lines = [];
142
- const col = field.column;
143
- const tsType = canonicalToTypeScript(col.type);
144
- // JSDoc comment
145
- if (this.options.addSyncComments) {
146
- lines.push(' /**');
147
- lines.push(` * @sync-added ${new Date().toISOString().split('T')[0]}`);
148
- lines.push(` * Column discovered in database but not in entity.`);
149
- lines.push(` * Type: ${this.formatTypeDescription(col.type)}, Nullable: ${col.nullable}`);
150
- lines.push(' */');
151
- }
152
- // Decorator
153
- if (col.isPrimaryKey) {
154
- lines.push(` @Id()`);
155
- }
156
- else {
157
- const fieldOptions = this.buildFieldOptions(col);
158
- lines.push(` @Field(${fieldOptions})`);
159
- }
160
- // Property
161
- const nullable = col.nullable ? '?' : '';
162
- lines.push(` ${field.propertyName}${nullable}: ${tsType};`);
163
- return lines;
164
- }
165
- /**
166
- * Generate code for a relation field.
167
- */
168
- generateRelationField(field) {
169
- const lines = [];
170
- const rel = field.relation;
171
- if (!rel)
172
- return lines;
173
- // Determine related table and decorator
174
- const isOutgoing = rel.from.columns.some((c) => c.name === field.column.name);
175
- const relatedTable = isOutgoing ? rel.to.table : rel.from.table;
176
- const decoratorName = this.getRelationDecoratorName(rel.type, !isOutgoing);
177
- const relatedClassName = this.toPascalCase(this.singularize(relatedTable.name));
178
- // JSDoc comment
179
- if (this.options.addSyncComments) {
180
- lines.push(' /**');
181
- lines.push(` * @sync-added ${new Date().toISOString().split('T')[0]}`);
182
- lines.push(` * Foreign key relation detected: references "${relatedTable.name}"`);
183
- lines.push(' */');
184
- }
185
- // Decorator
186
- lines.push(` @${decoratorName}({ entity: () => ${relatedClassName} })`);
187
- // Property
188
- const isArray = decoratorName === 'OneToMany' || decoratorName === 'ManyToMany';
189
- const typeStr = isArray ? `Relation<${relatedClassName}[]>` : `Relation<${relatedClassName}>`;
190
- lines.push(` ${field.propertyName}?: ${typeStr};`);
191
- return lines;
192
- }
193
- /**
194
- * Mark a field as deprecated in the source code.
195
- */
196
- markFieldAsDeprecated(code, field) {
197
- // Find the property declaration
198
- const propRegex = new RegExp(`(^\\s*)(@\\w+.*?\\n\\s*)*?(${field.propertyName}\\s*[?!]?\\s*:)`, 'm');
199
- const match = propRegex.exec(code);
200
- if (!match)
201
- return code;
202
- // Check if already has @deprecated
203
- const beforeMatch = code.slice(Math.max(0, match.index - 100), match.index);
204
- if (beforeMatch.includes('@deprecated'))
205
- return code;
206
- // Add @deprecated JSDoc
207
- const indent = match[1] || ' ';
208
- const deprecationComment = [
209
- `${indent}/**`,
210
- `${indent} * @deprecated ${field.reason}`,
211
- `${indent} * @sync-removed ${new Date().toISOString().split('T')[0]}`,
212
- `${indent} */`,
213
- '',
214
- ].join('\n');
215
- return code.slice(0, match.index) + deprecationComment + code.slice(match.index);
216
- }
217
- /**
218
- * Build Field decorator options string.
219
- */
220
- buildFieldOptions(col) {
221
- const options = [];
222
- const columnType = canonicalToColumnType(col.type);
223
- if (columnType) {
224
- options.push(`columnType: '${columnType}'`);
225
- }
226
- if (col.type.length && col.type.category === 'string') {
227
- options.push(`length: ${col.type.length}`);
228
- }
229
- if (col.type.precision !== undefined) {
230
- options.push(`precision: ${col.type.precision}`);
231
- }
232
- if (col.type.scale !== undefined) {
233
- options.push(`scale: ${col.type.scale}`);
234
- }
235
- if (col.nullable) {
236
- options.push('nullable: true');
237
- }
238
- return options.length > 0 ? `{ ${options.join(', ')} }` : '';
239
- }
240
- /**
241
- * Format type for description.
242
- */
243
- formatTypeDescription(type) {
244
- let desc = type.category.toUpperCase();
245
- if (type.size)
246
- desc = `${type.size.toUpperCase()}${desc}`;
247
- if (type.length)
248
- desc += `(${type.length})`;
249
- if (type.precision) {
250
- desc += `(${type.precision}`;
251
- if (type.scale)
252
- desc += `,${type.scale}`;
253
- desc += ')';
254
- }
255
- return desc;
256
- }
257
- /**
258
- * Get relation decorator name.
259
- */
260
- getRelationDecoratorName(type, inverse) {
261
- if (inverse) {
262
- if (type === 'ManyToOne')
263
- return 'OneToMany';
264
- if (type === 'OneToMany')
265
- return 'ManyToOne';
266
- }
267
- return type;
268
- }
269
- /**
270
- * Default property name transformer (delegates to shared utility).
271
- */
272
- defaultPropertyNameTransformer(columnName) {
273
- return camelCase(columnName);
274
- }
275
- /**
276
- * Convert to PascalCase (delegates to shared utility).
277
- */
278
- toPascalCase(str) {
279
- return pascalCase(str);
280
- }
281
- /**
282
- * Singularize (delegates to shared utility).
283
- */
284
- singularize(name) {
285
- return singularize(name);
286
- }
287
- }
288
- /**
289
- * Create an EntityMerger instance.
290
- */
291
- export function createEntityMerger(options) {
292
- return new EntityMerger(options);
293
- }
@@ -1,61 +0,0 @@
1
- /**
2
- * Migration Code Generator
3
- *
4
- * Generates TypeScript migration code from SchemaDiff.
5
- * This enables auto-generating migrations from entity changes.
6
- */
7
- import type { SchemaDiff } from '../../type/index.js';
8
- export interface MigrationCodeOptions {
9
- /** Indentation string (default: 2 spaces) */
10
- indent?: string;
11
- /** Whether to include comments explaining changes */
12
- includeComments?: boolean;
13
- }
14
- export interface GeneratedMigration {
15
- /** The up migration code */
16
- up: string;
17
- /** The down migration code */
18
- down: string;
19
- /** Human-readable description of changes */
20
- description: string;
21
- }
22
- /**
23
- * Generates TypeScript migration code from schema diffs.
24
- */
25
- export declare class MigrationCodeGenerator {
26
- private readonly indent;
27
- private readonly includeComments;
28
- constructor(options?: MigrationCodeOptions);
29
- /**
30
- * Generate migration code from a single SchemaDiff.
31
- */
32
- generate(diff: SchemaDiff): GeneratedMigration;
33
- /**
34
- * Generate migration code from multiple diffs.
35
- */
36
- generateAll(diffs: SchemaDiff[]): GeneratedMigration;
37
- /**
38
- * Generate a complete migration file template.
39
- */
40
- generateFile(diffs: SchemaDiff[], name?: string): string;
41
- private generateCreateTable;
42
- private generateDropTable;
43
- private generateAlterUp;
44
- private generateAlterDown;
45
- private generateAddColumn;
46
- private generateAlterColumn;
47
- private generateCreateIndex;
48
- private generateAddForeignKey;
49
- private generateColumnCall;
50
- private generateIndexCall;
51
- private getColumnMethod;
52
- private generateColumnOptionsObject;
53
- private generateColumnOptions;
54
- private formatValue;
55
- private generateDescription;
56
- private indentBlock;
57
- }
58
- /**
59
- * Factory function to create a MigrationCodeGenerator.
60
- */
61
- export declare function createMigrationCodeGenerator(options?: MigrationCodeOptions): MigrationCodeGenerator;