@uql/core 3.1.0 → 3.1.2

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 (170) hide show
  1. package/CHANGELOG.md +134 -176
  2. package/README.md +413 -0
  3. package/package.json +31 -26
  4. package/dist/package.json +0 -131
  5. package/src/@types/index.d.ts +0 -1
  6. package/src/@types/jest.d.ts +0 -6
  7. package/src/browser/http/bus.spec.ts +0 -22
  8. package/src/browser/http/bus.ts +0 -17
  9. package/src/browser/http/http.spec.ts +0 -70
  10. package/src/browser/http/http.ts +0 -55
  11. package/src/browser/http/index.ts +0 -2
  12. package/src/browser/index.ts +0 -4
  13. package/src/browser/options.spec.ts +0 -37
  14. package/src/browser/options.ts +0 -18
  15. package/src/browser/querier/genericClientRepository.spec.ts +0 -105
  16. package/src/browser/querier/genericClientRepository.ts +0 -49
  17. package/src/browser/querier/httpQuerier.ts +0 -82
  18. package/src/browser/querier/index.ts +0 -3
  19. package/src/browser/querier/querier.util.spec.ts +0 -35
  20. package/src/browser/querier/querier.util.ts +0 -18
  21. package/src/browser/type/clientQuerier.ts +0 -45
  22. package/src/browser/type/clientQuerierPool.ts +0 -5
  23. package/src/browser/type/clientRepository.ts +0 -22
  24. package/src/browser/type/index.ts +0 -4
  25. package/src/browser/type/request.ts +0 -25
  26. package/src/dialect/abstractDialect.ts +0 -28
  27. package/src/dialect/abstractSqlDialect-spec.ts +0 -1309
  28. package/src/dialect/abstractSqlDialect.ts +0 -805
  29. package/src/dialect/index.ts +0 -3
  30. package/src/dialect/namingStrategy.spec.ts +0 -52
  31. package/src/dialect/queryContext.ts +0 -69
  32. package/src/entity/decorator/definition.spec.ts +0 -736
  33. package/src/entity/decorator/definition.ts +0 -265
  34. package/src/entity/decorator/entity.ts +0 -8
  35. package/src/entity/decorator/field.ts +0 -9
  36. package/src/entity/decorator/id.ts +0 -9
  37. package/src/entity/decorator/index.ts +0 -5
  38. package/src/entity/decorator/relation.spec.ts +0 -41
  39. package/src/entity/decorator/relation.ts +0 -34
  40. package/src/entity/index.ts +0 -1
  41. package/src/express/@types/express.d.ts +0 -8
  42. package/src/express/@types/index.d.ts +0 -1
  43. package/src/express/index.ts +0 -2
  44. package/src/express/querierMiddleware.ts +0 -217
  45. package/src/express/query.util.spec.ts +0 -40
  46. package/src/express/query.util.ts +0 -21
  47. package/src/index.ts +0 -9
  48. package/src/maria/index.ts +0 -3
  49. package/src/maria/mariaDialect.spec.ts +0 -207
  50. package/src/maria/mariaDialect.ts +0 -42
  51. package/src/maria/mariaQuerierPool.test.ts +0 -23
  52. package/src/maria/mariadbQuerier.test.ts +0 -23
  53. package/src/maria/mariadbQuerier.ts +0 -45
  54. package/src/maria/mariadbQuerierPool.ts +0 -21
  55. package/src/migrate/cli.ts +0 -301
  56. package/src/migrate/generator/index.ts +0 -4
  57. package/src/migrate/generator/mongoSchemaGenerator.spec.ts +0 -112
  58. package/src/migrate/generator/mongoSchemaGenerator.ts +0 -115
  59. package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +0 -34
  60. package/src/migrate/generator/mysqlSchemaGenerator.ts +0 -92
  61. package/src/migrate/generator/postgresSchemaGenerator.spec.ts +0 -44
  62. package/src/migrate/generator/postgresSchemaGenerator.ts +0 -127
  63. package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +0 -33
  64. package/src/migrate/generator/sqliteSchemaGenerator.ts +0 -81
  65. package/src/migrate/index.ts +0 -41
  66. package/src/migrate/introspection/index.ts +0 -4
  67. package/src/migrate/introspection/mongoIntrospector.spec.ts +0 -75
  68. package/src/migrate/introspection/mongoIntrospector.ts +0 -47
  69. package/src/migrate/introspection/mysqlIntrospector.spec.ts +0 -113
  70. package/src/migrate/introspection/mysqlIntrospector.ts +0 -278
  71. package/src/migrate/introspection/postgresIntrospector.spec.ts +0 -112
  72. package/src/migrate/introspection/postgresIntrospector.ts +0 -329
  73. package/src/migrate/introspection/sqliteIntrospector.spec.ts +0 -112
  74. package/src/migrate/introspection/sqliteIntrospector.ts +0 -296
  75. package/src/migrate/migrator-mongo.test.ts +0 -54
  76. package/src/migrate/migrator.spec.ts +0 -255
  77. package/src/migrate/migrator.test.ts +0 -94
  78. package/src/migrate/migrator.ts +0 -719
  79. package/src/migrate/namingStrategy.spec.ts +0 -22
  80. package/src/migrate/schemaGenerator-advanced.spec.ts +0 -138
  81. package/src/migrate/schemaGenerator.spec.ts +0 -190
  82. package/src/migrate/schemaGenerator.ts +0 -478
  83. package/src/migrate/storage/databaseStorage.spec.ts +0 -69
  84. package/src/migrate/storage/databaseStorage.ts +0 -100
  85. package/src/migrate/storage/index.ts +0 -2
  86. package/src/migrate/storage/jsonStorage.ts +0 -58
  87. package/src/migrate/type.ts +0 -1
  88. package/src/mongo/index.ts +0 -3
  89. package/src/mongo/mongoDialect.spec.ts +0 -251
  90. package/src/mongo/mongoDialect.ts +0 -238
  91. package/src/mongo/mongodbQuerier.test.ts +0 -45
  92. package/src/mongo/mongodbQuerier.ts +0 -256
  93. package/src/mongo/mongodbQuerierPool.test.ts +0 -25
  94. package/src/mongo/mongodbQuerierPool.ts +0 -24
  95. package/src/mysql/index.ts +0 -3
  96. package/src/mysql/mysql2Querier.test.ts +0 -20
  97. package/src/mysql/mysql2Querier.ts +0 -49
  98. package/src/mysql/mysql2QuerierPool.test.ts +0 -20
  99. package/src/mysql/mysql2QuerierPool.ts +0 -21
  100. package/src/mysql/mysqlDialect.spec.ts +0 -20
  101. package/src/mysql/mysqlDialect.ts +0 -16
  102. package/src/namingStrategy/defaultNamingStrategy.ts +0 -18
  103. package/src/namingStrategy/index.spec.ts +0 -36
  104. package/src/namingStrategy/index.ts +0 -2
  105. package/src/namingStrategy/snakeCaseNamingStrategy.ts +0 -15
  106. package/src/options.spec.ts +0 -41
  107. package/src/options.ts +0 -18
  108. package/src/postgres/index.ts +0 -3
  109. package/src/postgres/manual-types.d.ts +0 -4
  110. package/src/postgres/pgQuerier.test.ts +0 -25
  111. package/src/postgres/pgQuerier.ts +0 -45
  112. package/src/postgres/pgQuerierPool.test.ts +0 -28
  113. package/src/postgres/pgQuerierPool.ts +0 -21
  114. package/src/postgres/postgresDialect.spec.ts +0 -428
  115. package/src/postgres/postgresDialect.ts +0 -144
  116. package/src/querier/abstractQuerier-test.ts +0 -584
  117. package/src/querier/abstractQuerier.ts +0 -353
  118. package/src/querier/abstractQuerierPool-test.ts +0 -20
  119. package/src/querier/abstractQuerierPool.ts +0 -18
  120. package/src/querier/abstractSqlQuerier-spec.ts +0 -979
  121. package/src/querier/abstractSqlQuerier-test.ts +0 -21
  122. package/src/querier/abstractSqlQuerier.ts +0 -138
  123. package/src/querier/decorator/index.ts +0 -3
  124. package/src/querier/decorator/injectQuerier.spec.ts +0 -74
  125. package/src/querier/decorator/injectQuerier.ts +0 -45
  126. package/src/querier/decorator/serialized.spec.ts +0 -98
  127. package/src/querier/decorator/serialized.ts +0 -13
  128. package/src/querier/decorator/transactional.spec.ts +0 -240
  129. package/src/querier/decorator/transactional.ts +0 -56
  130. package/src/querier/index.ts +0 -4
  131. package/src/repository/genericRepository.spec.ts +0 -111
  132. package/src/repository/genericRepository.ts +0 -74
  133. package/src/repository/index.ts +0 -1
  134. package/src/sqlite/index.ts +0 -3
  135. package/src/sqlite/manual-types.d.ts +0 -4
  136. package/src/sqlite/sqliteDialect.spec.ts +0 -155
  137. package/src/sqlite/sqliteDialect.ts +0 -76
  138. package/src/sqlite/sqliteQuerier.spec.ts +0 -36
  139. package/src/sqlite/sqliteQuerier.test.ts +0 -21
  140. package/src/sqlite/sqliteQuerier.ts +0 -37
  141. package/src/sqlite/sqliteQuerierPool.test.ts +0 -12
  142. package/src/sqlite/sqliteQuerierPool.ts +0 -38
  143. package/src/test/entityMock.ts +0 -375
  144. package/src/test/index.ts +0 -3
  145. package/src/test/it.util.ts +0 -69
  146. package/src/test/spec.util.ts +0 -57
  147. package/src/type/entity.ts +0 -218
  148. package/src/type/index.ts +0 -9
  149. package/src/type/migration.ts +0 -241
  150. package/src/type/namingStrategy.ts +0 -17
  151. package/src/type/querier.ts +0 -143
  152. package/src/type/querierPool.ts +0 -26
  153. package/src/type/query.ts +0 -506
  154. package/src/type/repository.ts +0 -142
  155. package/src/type/universalQuerier.ts +0 -133
  156. package/src/type/utility.ts +0 -21
  157. package/src/util/dialect.util-extra.spec.ts +0 -96
  158. package/src/util/dialect.util.spec.ts +0 -23
  159. package/src/util/dialect.util.ts +0 -134
  160. package/src/util/index.ts +0 -5
  161. package/src/util/object.util.spec.ts +0 -29
  162. package/src/util/object.util.ts +0 -27
  163. package/src/util/raw.ts +0 -11
  164. package/src/util/sql.util-extra.spec.ts +0 -17
  165. package/src/util/sql.util.spec.ts +0 -208
  166. package/src/util/sql.util.ts +0 -104
  167. package/src/util/string.util.spec.ts +0 -46
  168. package/src/util/string.util.ts +0 -35
  169. package/tsconfig.build.json +0 -5
  170. package/tsconfig.json +0 -8
@@ -1,207 +0,0 @@
1
- import { expect } from 'bun:test';
2
- import { AbstractSqlDialectSpec } from '../dialect/abstractSqlDialect-spec.js';
3
- import { InventoryAdjustment, ItemTag, TaxCategory, User } from '../test/index.js';
4
- import { createSpec } from '../test/spec.util.js';
5
- import type { FieldKey } from '../type/index.js';
6
- import { MariaDialect } from './mariaDialect.js';
7
-
8
- export class MariaDialectSpec extends AbstractSqlDialectSpec {
9
- constructor() {
10
- super(new MariaDialect());
11
- }
12
-
13
- shouldHandleDate() {
14
- const dialect = new MariaDialect();
15
- const values: unknown[] = [];
16
- expect(dialect.addValue(values, new Date())).toBe('?');
17
- expect(values).toHaveLength(1);
18
- expect(values[0]).toBeInstanceOf(Date);
19
- }
20
-
21
- shouldUpsertWithNoUpdateFields() {
22
- const { sql } = this.exec((ctx) => this.dialect.upsert(ctx, ItemTag, { id: true }, { id: 123 }));
23
- expect(sql).toContain('INSERT IGNORE');
24
- }
25
-
26
- override shouldInsertMany() {
27
- const { sql, values } = this.exec((ctx) =>
28
- this.dialect.insert(ctx, User, [
29
- {
30
- name: 'Some name 1',
31
- email: 'someemail1@example.com',
32
- createdAt: 123,
33
- },
34
- {
35
- name: 'Some name 2',
36
- email: 'someemail2@example.com',
37
- createdAt: 456,
38
- },
39
- {
40
- name: 'Some name 3',
41
- email: 'someemail3@example.com',
42
- createdAt: 789,
43
- },
44
- ]),
45
- );
46
- expect(sql).toBe(
47
- 'INSERT INTO `User` (`name`, `email`, `createdAt`) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?) RETURNING `id` `id`',
48
- );
49
- expect(values).toEqual([
50
- 'Some name 1',
51
- 'someemail1@example.com',
52
- 123,
53
- 'Some name 2',
54
- 'someemail2@example.com',
55
- 456,
56
- 'Some name 3',
57
- 'someemail3@example.com',
58
- 789,
59
- ]);
60
- }
61
-
62
- override shouldBeSecure() {
63
- let res = this.exec((ctx) =>
64
- this.dialect.find(ctx, User, {
65
- $select: ['id', 'something' as FieldKey<User>],
66
- $where: {
67
- id: 1,
68
- something: 1,
69
- } as any,
70
- $sort: {
71
- id: 1,
72
- something: 1,
73
- } as any,
74
- }),
75
- );
76
- expect(res.sql).toBe('SELECT `id` FROM `User` WHERE `id` = ? AND `something` = ? ORDER BY `id`, `something`');
77
- expect(res.values).toEqual([1, 1]);
78
-
79
- res = this.exec((ctx) =>
80
- this.dialect.insert(ctx, User, {
81
- name: 'Some Name',
82
- something: 'anything',
83
- createdAt: 1,
84
- } as any),
85
- );
86
- expect(res.sql).toBe('INSERT INTO `User` (`name`, `createdAt`) VALUES (?, ?) RETURNING `id` `id`');
87
- expect(res.values).toEqual(['Some Name', 1]);
88
-
89
- res = this.exec((ctx) =>
90
- this.dialect.update(
91
- ctx,
92
- User,
93
- {
94
- $where: { something: 'anything' },
95
- },
96
- {
97
- name: 'Some Name',
98
- something: 'anything',
99
- updatedAt: 1,
100
- } as any,
101
- ),
102
- );
103
- expect(res.sql).toBe('UPDATE `User` SET `name` = ?, `updatedAt` = ? WHERE `something` = ?');
104
- expect(res.values).toEqual(['Some Name', 1, 'anything']);
105
-
106
- res = this.exec((ctx) =>
107
- this.dialect.delete(ctx, User, {
108
- $where: { something: 'anything' } as any,
109
- }),
110
- );
111
- expect(res.sql).toBe('DELETE FROM `User` WHERE `something` = ?');
112
- expect(res.values).toEqual(['anything']);
113
- }
114
-
115
- override shouldUpsert() {
116
- const { sql, values } = this.exec((ctx) =>
117
- this.dialect.upsert(
118
- ctx,
119
- User,
120
- { email: true },
121
- {
122
- name: 'Some Name',
123
- email: 'someemail@example.com',
124
- createdAt: 123,
125
- },
126
- ),
127
- );
128
- expect(sql).toBe(
129
- 'INSERT INTO `User` (`name`, `email`, `createdAt`, `updatedAt`) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `createdAt` = VALUES(`createdAt`), `updatedAt` = VALUES(`updatedAt`) RETURNING `id` `id`',
130
- );
131
- expect(values).toEqual(['Some Name', 'someemail@example.com', 123, expect.any(Number)]);
132
- }
133
-
134
- override shouldInsertManyWithSpecifiedIdsAndOnInsertIdAsDefault() {
135
- const { sql, values } = this.exec((ctx) =>
136
- this.dialect.insert(ctx, TaxCategory, [
137
- {
138
- name: 'Some Name A',
139
- },
140
- {
141
- pk: '50',
142
- name: 'Some Name B',
143
- },
144
- {
145
- name: 'Some Name C',
146
- },
147
- {
148
- pk: '70',
149
- name: 'Some Name D',
150
- },
151
- ]),
152
- );
153
- expect(sql).toMatch(
154
- /^INSERT INTO `TaxCategory` \(`name`, `createdAt`, `pk`\) VALUES \(\?, \?, \?\), \(\?, \?, \?\), \(\?, \?, \?\), \(\?, \?, \?\) RETURNING `pk` `id`$/,
155
- );
156
- expect(values).toEqual([
157
- 'Some Name A',
158
- expect.any(Number),
159
- expect.any(String),
160
- 'Some Name B',
161
- expect.any(Number),
162
- '50',
163
- 'Some Name C',
164
- expect.any(Number),
165
- expect.any(String),
166
- 'Some Name D',
167
- expect.any(Number),
168
- '70',
169
- ]);
170
- }
171
-
172
- override shouldInsertOne() {
173
- let res = this.exec((ctx) =>
174
- this.dialect.insert(ctx, User, {
175
- name: 'Some Name',
176
- email: 'someemail@example.com',
177
- createdAt: 123,
178
- }),
179
- );
180
- expect(res.sql).toBe('INSERT INTO `User` (`name`, `email`, `createdAt`) VALUES (?, ?, ?) RETURNING `id` `id`');
181
- expect(res.values).toEqual(['Some Name', 'someemail@example.com', 123]);
182
-
183
- res = this.exec((ctx) =>
184
- this.dialect.insert(ctx, InventoryAdjustment, {
185
- date: new Date(2021, 11, 31, 23, 59, 59, 999),
186
- createdAt: 123,
187
- }),
188
- );
189
- expect(res.sql).toBe('INSERT INTO `InventoryAdjustment` (`date`, `createdAt`) VALUES (?, ?) RETURNING `id` `id`');
190
- expect(res.values).toEqual([new Date(2021, 11, 31, 23, 59, 59, 999), 123]);
191
- }
192
-
193
- override shouldInsertWithOnInsertId() {
194
- const { sql, values } = this.exec((ctx) =>
195
- this.dialect.insert(ctx, TaxCategory, {
196
- name: 'Some Name',
197
- createdAt: 123,
198
- }),
199
- );
200
- expect(sql).toMatch(
201
- /^INSERT INTO `TaxCategory` \(`name`, `createdAt`, `pk`\) VALUES \(\?, \?, \?\) RETURNING `pk` `id`$/,
202
- );
203
- expect(values).toEqual(['Some Name', 123, expect.any(String)]);
204
- }
205
- }
206
-
207
- createSpec(new MariaDialectSpec());
@@ -1,42 +0,0 @@
1
- import SqlString from 'sqlstring';
2
- import { AbstractSqlDialect } from '../dialect/index.js';
3
- import { getMeta } from '../entity/index.js';
4
- import type { QueryConflictPaths, QueryContext, QueryOptions, Type } from '../type/index.js';
5
-
6
- export class MariaDialect extends AbstractSqlDialect {
7
- override addValue(values: unknown[], value: unknown): string {
8
- if (value instanceof Date) {
9
- values.push(value);
10
- return '?';
11
- }
12
- return super.addValue(values, value);
13
- }
14
-
15
- override insert<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[], opts?: QueryOptions): void {
16
- super.insert(ctx, entity, payload, opts);
17
- ctx.append(' ' + this.returningId(entity));
18
- }
19
-
20
- override upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): void {
21
- const meta = getMeta(entity);
22
- const update = this.getUpsertUpdateAssignments(ctx, meta, conflictPaths, payload, (name) => `VALUES(${name})`);
23
- const returning = this.returningId(entity);
24
-
25
- if (update) {
26
- super.insert(ctx, entity, payload);
27
- ctx.append(` ON DUPLICATE KEY UPDATE ${update} ${returning}`);
28
- } else {
29
- const insertCtx = this.createContext();
30
- super.insert(insertCtx, entity, payload);
31
- ctx.append(insertCtx.sql.replace(/^INSERT/, 'INSERT IGNORE'));
32
- ctx.append(' ' + returning);
33
- insertCtx.values.forEach((val) => {
34
- ctx.pushValue(val);
35
- });
36
- }
37
- }
38
-
39
- override escape(value: unknown): string {
40
- return SqlString.escape(value);
41
- }
42
- }
@@ -1,23 +0,0 @@
1
- import { AbstractQuerierPoolIt } from '../querier/abstractQuerierPool-test.js';
2
- import { createSpec } from '../test/index.js';
3
- import type { MariadbQuerier } from './mariadbQuerier.js';
4
- import { MariadbQuerierPool } from './mariadbQuerierPool.js';
5
-
6
- export class MariadbQuerierPoolIt extends AbstractQuerierPoolIt<MariadbQuerier> {
7
- constructor() {
8
- super(
9
- new MariadbQuerierPool({
10
- host: '0.0.0.0',
11
- port: 3326,
12
- user: 'test',
13
- password: 'test',
14
- database: 'test',
15
- connectionLimit: 5,
16
- trace: true,
17
- bigIntAsNumber: true,
18
- }),
19
- );
20
- }
21
- }
22
-
23
- createSpec(new MariadbQuerierPoolIt());
@@ -1,23 +0,0 @@
1
- import { AbstractSqlQuerierIt } from '../querier/abstractSqlQuerier-test.js';
2
- import { createSpec } from '../test/index.js';
3
- import { MariadbQuerierPool } from './mariadbQuerierPool.js';
4
-
5
- export class MariadbQuerierIt extends AbstractSqlQuerierIt {
6
- constructor() {
7
- super(
8
- new MariadbQuerierPool({
9
- host: '0.0.0.0',
10
- port: 3326,
11
- user: 'test',
12
- password: 'test',
13
- database: 'test',
14
- connectionLimit: 5,
15
- trace: true,
16
- bigIntAsNumber: true,
17
- }),
18
- 'INT AUTO_INCREMENT PRIMARY KEY',
19
- );
20
- }
21
- }
22
-
23
- createSpec(new MariadbQuerierIt());
@@ -1,45 +0,0 @@
1
- import type { PoolConnection } from 'mariadb';
2
- import { AbstractSqlQuerier } from '../querier/index.js';
3
- import type { ExtraOptions, QueryUpdateResult } from '../type/index.js';
4
- import { MariaDialect } from './mariaDialect.js';
5
-
6
- export class MariadbQuerier extends AbstractSqlQuerier {
7
- conn: PoolConnection;
8
-
9
- constructor(
10
- readonly connect: () => Promise<PoolConnection>,
11
- readonly extra?: ExtraOptions,
12
- ) {
13
- super(new MariaDialect(extra?.namingStrategy));
14
- }
15
-
16
- override async internalAll<T>(query: string, values?: unknown[]) {
17
- this.extra?.logger?.(query, values);
18
- await this.lazyConnect();
19
- const res: T[] = await this.conn.query(query, values);
20
- return res.slice(0, res.length);
21
- }
22
-
23
- override async internalRun(query: string, values?: unknown[]) {
24
- this.extra?.logger?.(query, values);
25
- await this.lazyConnect();
26
- const res = await this.conn.query(query, values);
27
- const ids = res.length ? res.map((r: any) => r.id) : [];
28
- return { changes: res.affectedRows, ids, firstId: ids[0] } satisfies QueryUpdateResult;
29
- }
30
-
31
- async lazyConnect() {
32
- this.conn ??= await this.connect();
33
- }
34
-
35
- override async internalRelease() {
36
- if (this.hasOpenTransaction) {
37
- throw TypeError('pending transaction');
38
- }
39
- if (!this.conn) {
40
- return;
41
- }
42
- await this.conn.release();
43
- this.conn = undefined;
44
- }
45
- }
@@ -1,21 +0,0 @@
1
- import { createPool, type Pool, type PoolConfig } from 'mariadb';
2
- import { AbstractQuerierPool } from '../querier/index.js';
3
- import type { ExtraOptions } from '../type/index.js';
4
- import { MariadbQuerier } from './mariadbQuerier.js';
5
-
6
- export class MariadbQuerierPool extends AbstractQuerierPool<MariadbQuerier> {
7
- readonly pool: Pool;
8
-
9
- constructor(opts: PoolConfig, extra?: ExtraOptions) {
10
- super('mariadb', extra);
11
- this.pool = createPool(opts);
12
- }
13
-
14
- async getQuerier() {
15
- return new MariadbQuerier(() => this.pool.getConnection(), this.extra);
16
- }
17
-
18
- async end() {
19
- await this.pool.end();
20
- }
21
- }
@@ -1,301 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { resolve } from 'node:path';
4
- import { pathToFileURL } from 'node:url';
5
- import type { Dialect, MigratorOptions, NamingStrategy, QuerierPool } from '../type/index.js';
6
- import { MongoSchemaGenerator } from './generator/mongoSchemaGenerator.js';
7
- import { MysqlSchemaGenerator } from './generator/mysqlSchemaGenerator.js';
8
- import { PostgresSchemaGenerator } from './generator/postgresSchemaGenerator.js';
9
- import { SqliteSchemaGenerator } from './generator/sqliteSchemaGenerator.js';
10
- import { Migrator } from './migrator.js';
11
-
12
- interface CliConfig {
13
- querierPool?: QuerierPool;
14
- migrationsPath?: string;
15
- tableName?: string;
16
- dialect?: Dialect;
17
- entities?: unknown[];
18
- namingStrategy?: NamingStrategy;
19
- }
20
-
21
- async function loadConfig(): Promise<CliConfig> {
22
- const configPaths = ['uql.config.ts', 'uql.config.js', 'uql.config.mjs', '.uqlrc.ts', '.uqlrc.js'];
23
-
24
- for (const configPath of configPaths) {
25
- try {
26
- const fullPath = resolve(process.cwd(), configPath);
27
- const fileUrl = pathToFileURL(fullPath).href;
28
- const module = await import(fileUrl);
29
- return module.default ?? module;
30
- } catch {
31
- // Config file not found, try next one
32
- }
33
- }
34
-
35
- throw new Error(
36
- 'Could not find uql configuration file. ' + 'Create a uql.config.ts or uql.config.js file in your project root.',
37
- );
38
- }
39
-
40
- function getSchemaGenerator(dialect: Dialect, namingStrategy?: NamingStrategy) {
41
- switch (dialect) {
42
- case 'postgres':
43
- return new PostgresSchemaGenerator(namingStrategy);
44
- case 'mysql':
45
- case 'mariadb':
46
- return new MysqlSchemaGenerator(namingStrategy);
47
- case 'sqlite':
48
- return new SqliteSchemaGenerator(namingStrategy);
49
- case 'mongodb':
50
- return new MongoSchemaGenerator(namingStrategy);
51
- default:
52
- throw new TypeError(`Unknown dialect: ${dialect}`);
53
- }
54
- }
55
-
56
- async function main() {
57
- const args = process.argv.slice(2);
58
- const command = args[0];
59
-
60
- if (!command || command === '--help' || command === '-h') {
61
- printHelp();
62
- return;
63
- }
64
-
65
- try {
66
- const config = await loadConfig();
67
-
68
- if (!config.querierPool) {
69
- throw new Error('querierPool is required in configuration');
70
- }
71
-
72
- const dialect = config.dialect ?? 'postgres';
73
-
74
- const options: MigratorOptions & { dialect: Dialect } = {
75
- migrationsPath: config.migrationsPath ?? './migrations',
76
- tableName: config.tableName,
77
- logger: console.log,
78
- entities: config.entities as MigratorOptions['entities'],
79
- dialect,
80
- namingStrategy: config.namingStrategy,
81
- };
82
-
83
- const migrator = new Migrator(config.querierPool, options);
84
- migrator.setSchemaGenerator(getSchemaGenerator(dialect, config.namingStrategy));
85
-
86
- switch (command) {
87
- case 'up':
88
- await runUp(migrator, args.slice(1));
89
- break;
90
- case 'down':
91
- await runDown(migrator, args.slice(1));
92
- break;
93
- case 'status':
94
- await runStatus(migrator);
95
- break;
96
- case 'generate':
97
- case 'create':
98
- await runGenerate(migrator, args.slice(1));
99
- break;
100
- case 'generate:entities':
101
- case 'generate-entities':
102
- await runGenerateFromEntities(migrator, args.slice(1));
103
- break;
104
- case 'sync':
105
- await runSync(migrator, args.slice(1));
106
- break;
107
- case 'pending':
108
- await runPending(migrator);
109
- break;
110
- default:
111
- console.error(`Unknown command: ${command}`);
112
- printHelp();
113
- process.exit(1);
114
- }
115
-
116
- // Close the connection pool
117
- const pool = config.querierPool as { end?: () => Promise<void> };
118
- if (pool.end) {
119
- await pool.end();
120
- }
121
- } catch (error) {
122
- console.error('Error:', (error as Error).message);
123
- process.exit(1);
124
- }
125
- }
126
-
127
- async function runUp(migrator: Migrator, args: string[]) {
128
- const options: { to?: string; step?: number } = {};
129
-
130
- for (let i = 0; i < args.length; i++) {
131
- if (args[i] === '--to' && args[i + 1]) {
132
- options.to = args[++i];
133
- } else if (args[i] === '--step' && args[i + 1]) {
134
- options.step = Number.parseInt(args[++i], 10);
135
- }
136
- }
137
-
138
- const results = await migrator.up(options);
139
-
140
- if (results.length === 0) {
141
- console.log('No pending migrations.');
142
- return;
143
- }
144
-
145
- const successful = results.filter((r: any) => r.success).length;
146
- const failed = results.filter((r: any) => !r.success).length;
147
-
148
- console.log(`\nMigrations complete: ${successful} successful, ${failed} failed`);
149
-
150
- if (failed > 0) {
151
- process.exit(1);
152
- }
153
- }
154
-
155
- async function runDown(migrator: Migrator, args: string[]) {
156
- const options: { to?: string; step?: number } = { step: 1 }; // Default to 1 step
157
-
158
- for (let i = 0; i < args.length; i++) {
159
- if (args[i] === '--to' && args[i + 1]) {
160
- options.to = args[++i];
161
- delete options.step;
162
- } else if (args[i] === '--step' && args[i + 1]) {
163
- options.step = Number.parseInt(args[++i], 10);
164
- } else if (args[i] === '--all') {
165
- delete options.step;
166
- }
167
- }
168
-
169
- const results = await migrator.down(options);
170
-
171
- if (results.length === 0) {
172
- console.log('No migrations to rollback.');
173
- return;
174
- }
175
-
176
- const successful = results.filter((r: any) => r.success).length;
177
- const failed = results.filter((r: any) => !r.success).length;
178
-
179
- console.log(`\nRollback complete: ${successful} successful, ${failed} failed`);
180
-
181
- if (failed > 0) {
182
- process.exit(1);
183
- }
184
- }
185
-
186
- async function runStatus(migrator: Migrator) {
187
- const status = await migrator.status();
188
-
189
- console.log('\n=== Migration Status ===\n');
190
-
191
- console.log('Executed migrations:');
192
- if (status.executed.length === 0) {
193
- console.log(' (none)');
194
- } else {
195
- for (const name of status.executed) {
196
- console.log(` ✓ ${name}`);
197
- }
198
- }
199
-
200
- console.log('\nPending migrations:');
201
- if (status.pending.length === 0) {
202
- console.log(' (none)');
203
- } else {
204
- for (const name of status.pending) {
205
- console.log(` ○ ${name}`);
206
- }
207
- }
208
-
209
- console.log('');
210
- }
211
-
212
- async function runPending(migrator: Migrator) {
213
- const pending = await migrator.pending();
214
-
215
- if (pending.length === 0) {
216
- console.log('No pending migrations.');
217
- return;
218
- }
219
-
220
- console.log('Pending migrations:');
221
- for (const migration of pending) {
222
- console.log(` ○ ${migration.name}`);
223
- }
224
- }
225
-
226
- async function runGenerate(migrator: Migrator, args: string[]) {
227
- const name = args.join('_') || 'migration';
228
- const filePath = await migrator.generate(name);
229
- console.log(`\nCreated migration: ${filePath}`);
230
- }
231
-
232
- async function runGenerateFromEntities(migrator: Migrator, args: string[]) {
233
- const name = args.join('_') || 'schema';
234
- const filePath = await migrator.generateFromEntities(name);
235
- console.log(`\nCreated migration from entities: ${filePath}`);
236
- }
237
-
238
- async function runSync(migrator: Migrator, args: string[]) {
239
- const force = args.includes('--force');
240
-
241
- if (force) {
242
- console.log('\n⚠️ WARNING: This will drop and recreate all tables!');
243
- console.log(' All data will be lost. This should only be used in development.\n');
244
- }
245
-
246
- await migrator.sync({ force });
247
- console.log('\nSchema sync completed.');
248
- }
249
-
250
- function printHelp() {
251
- console.log(`
252
- @uql/migrate - Database migration tool for uql ORM
253
-
254
- Usage: @uql/migrate <command> [options]
255
-
256
- Commands:
257
- up Run all pending migrations
258
- --to <name> Run migrations up to and including <name>
259
- --step <n> Run only <n> migrations
260
-
261
- down Rollback the last migration
262
- --to <name> Rollback to (and including) migration <name>
263
- --step <n> Rollback <n> migrations (default: 1)
264
- --all Rollback all migrations
265
-
266
- status Show migration status
267
-
268
- pending Show pending migrations
269
-
270
- generate <name> Create a new empty migration file
271
- create <name> Alias for generate
272
-
273
- generate:entities Generate migration from entity definitions
274
- <name> Optional name for the migration
275
-
276
- sync Sync schema directly (development only!)
277
- --force Drop and recreate all tables
278
-
279
- Configuration:
280
- Create a uql.config.ts or uql.config.js file in your project root:
281
-
282
- export default {
283
- querierPool: new PgQuerierPool({ ... }),
284
- migrationsPath: './migrations',
285
- tableName: 'uql_migrations',
286
- dialect: 'postgres', // 'postgres' | 'mysql' | 'mariadb' | 'sqlite'
287
- entities: [User, Post, ...],
288
- };
289
-
290
- Examples:
291
- @uql/migrate up
292
- @uql/migrate up --step 1
293
- @uql/migrate down
294
- @uql/migrate down --step 3
295
- @uql/migrate status
296
- @uql/migrate generate add_users_table
297
- @uql/migrate generate:entities initial_schema
298
- `);
299
- }
300
-
301
- main().catch(console.error);
@@ -1,4 +0,0 @@
1
- export * from './mongoSchemaGenerator.js';
2
- export { MysqlSchemaGenerator, MysqlSchemaGenerator as MariadbSchemaGenerator } from './mysqlSchemaGenerator.js';
3
- export * from './postgresSchemaGenerator.js';
4
- export * from './sqliteSchemaGenerator.js';