orchid-orm 1.5.29 → 1.5.31

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 (59) hide show
  1. package/dist/index.d.ts +6 -14
  2. package/dist/index.js +26 -21
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +26 -21
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +12 -22
  7. package/.env.example +0 -1
  8. package/.turbo/turbo-check.log +0 -26
  9. package/.turbo/turbo-test.log +0 -26
  10. package/.turbo/turbo-test:ci.log +0 -26
  11. package/CHANGELOG.md +0 -382
  12. package/coverage/coverage-summary.json +0 -28
  13. package/jest-setup.ts +0 -11
  14. package/rollup.config.js +0 -18
  15. package/src/bin/bin.ts +0 -3
  16. package/src/bin/init.test.ts +0 -810
  17. package/src/bin/init.ts +0 -529
  18. package/src/codegen/appCodeUpdater.test.ts +0 -75
  19. package/src/codegen/appCodeUpdater.ts +0 -53
  20. package/src/codegen/createBaseTableFile.test.ts +0 -53
  21. package/src/codegen/createBaseTableFile.ts +0 -31
  22. package/src/codegen/fileChanges.ts +0 -41
  23. package/src/codegen/testUtils.ts +0 -56
  24. package/src/codegen/tsUtils.ts +0 -180
  25. package/src/codegen/updateMainFile.test.ts +0 -253
  26. package/src/codegen/updateMainFile.ts +0 -210
  27. package/src/codegen/updateTableFile/changeTable.test.ts +0 -804
  28. package/src/codegen/updateTableFile/changeTable.ts +0 -536
  29. package/src/codegen/updateTableFile/createTable.test.ts +0 -139
  30. package/src/codegen/updateTableFile/createTable.ts +0 -51
  31. package/src/codegen/updateTableFile/renameTable.test.ts +0 -124
  32. package/src/codegen/updateTableFile/renameTable.ts +0 -67
  33. package/src/codegen/updateTableFile/updateTableFile.ts +0 -22
  34. package/src/codegen/utils.ts +0 -13
  35. package/src/index.ts +0 -5
  36. package/src/orm.test.ts +0 -92
  37. package/src/orm.ts +0 -98
  38. package/src/relations/belongsTo.test.ts +0 -1122
  39. package/src/relations/belongsTo.ts +0 -352
  40. package/src/relations/hasAndBelongsToMany.test.ts +0 -1335
  41. package/src/relations/hasAndBelongsToMany.ts +0 -472
  42. package/src/relations/hasMany.test.ts +0 -2616
  43. package/src/relations/hasMany.ts +0 -401
  44. package/src/relations/hasOne.test.ts +0 -1701
  45. package/src/relations/hasOne.ts +0 -351
  46. package/src/relations/relations.test.ts +0 -37
  47. package/src/relations/relations.ts +0 -363
  48. package/src/relations/utils.ts +0 -162
  49. package/src/repo.test.ts +0 -200
  50. package/src/repo.ts +0 -119
  51. package/src/table.test.ts +0 -121
  52. package/src/table.ts +0 -184
  53. package/src/test-utils/test-db.ts +0 -32
  54. package/src/test-utils/test-tables.ts +0 -194
  55. package/src/test-utils/test-utils.ts +0 -119
  56. package/src/transaction.test.ts +0 -47
  57. package/src/transaction.ts +0 -27
  58. package/src/utils.ts +0 -9
  59. package/tsconfig.json +0 -14
@@ -1,472 +0,0 @@
1
- import { RelationData, RelationThunkBase } from './relations';
2
- import { Table } from '../table';
3
- import {
4
- CreateCtx,
5
- getQueryAs,
6
- HasAndBelongsToManyRelation,
7
- MaybeArray,
8
- NotFoundError,
9
- pushQueryValue,
10
- Query,
11
- QueryBase,
12
- toSqlCacheKey,
13
- UpdateCtx,
14
- VirtualColumn,
15
- WhereArg,
16
- WhereResult,
17
- } from 'pqb';
18
- import { hasRelationHandleCreate, hasRelationHandleUpdate } from './utils';
19
- import { HasManyNestedInsert, HasManyNestedUpdate } from './hasMany';
20
-
21
- export interface HasAndBelongsToMany extends RelationThunkBase {
22
- type: 'hasAndBelongsToMany';
23
- returns: 'many';
24
- options: HasAndBelongsToManyRelation['options'];
25
- }
26
-
27
- export type HasAndBelongsToManyInfo<
28
- T extends Table,
29
- Relation extends HasAndBelongsToMany,
30
- > = {
31
- params: Record<
32
- Relation['options']['primaryKey'],
33
- T['columns']['shape'][Relation['options']['primaryKey']]['type']
34
- >;
35
- populate: never;
36
- chainedCreate: true;
37
- chainedDelete: true;
38
- };
39
-
40
- type State = {
41
- relatedTableQuery: Query;
42
- joinTableQuery: Query;
43
- primaryKey: string;
44
- foreignKey: string;
45
- associationPrimaryKey: string;
46
- associationForeignKey: string;
47
- foreignKeyFull: string;
48
- associationPrimaryKeyFull: string;
49
- associationForeignKeyFull: string;
50
- };
51
-
52
- class HasAndBelongsToManyVirtualColumn extends VirtualColumn {
53
- private readonly nestedInsert: HasManyNestedInsert;
54
- private readonly nestedUpdate: HasManyNestedUpdate;
55
-
56
- constructor(private key: string, private state: State) {
57
- super();
58
- this.nestedInsert = nestedInsert(state);
59
- this.nestedUpdate = nestedUpdate(state);
60
- }
61
-
62
- create(
63
- q: Query,
64
- ctx: CreateCtx,
65
- item: Record<string, unknown>,
66
- rowIndex: number,
67
- ) {
68
- hasRelationHandleCreate(
69
- q,
70
- ctx,
71
- item,
72
- rowIndex,
73
- this.key,
74
- this.state.primaryKey,
75
- this.nestedInsert,
76
- );
77
- }
78
-
79
- update(q: Query, ctx: UpdateCtx, set: Record<string, unknown>) {
80
- hasRelationHandleUpdate(
81
- q,
82
- ctx,
83
- set,
84
- this.key,
85
- this.state.primaryKey,
86
- this.nestedUpdate,
87
- );
88
- }
89
- }
90
-
91
- export const makeHasAndBelongsToManyMethod = (
92
- table: Query,
93
- qb: Query,
94
- relation: HasAndBelongsToMany,
95
- relationName: string,
96
- query: Query,
97
- ): RelationData => {
98
- const {
99
- primaryKey: pk,
100
- foreignKey: fk,
101
- associationPrimaryKey: apk,
102
- associationForeignKey: afk,
103
- joinTable,
104
- } = relation.options;
105
-
106
- const foreignKeyFull = `${joinTable}.${fk}`;
107
- const associationForeignKeyFull = `${joinTable}.${afk}`;
108
- const associationPrimaryKeyFull = `${getQueryAs(query)}.${apk}`;
109
-
110
- const __table = Object.create(qb.__table);
111
- __table.__table = __table;
112
- __table.table = joinTable;
113
- __table.shape = {
114
- [fk]: table.shape[pk],
115
- [afk]: query.shape[apk],
116
- };
117
- const subQuery = Object.create(__table);
118
- subQuery.query = { ...subQuery.query };
119
-
120
- const state: State = {
121
- relatedTableQuery: query,
122
- joinTableQuery: subQuery,
123
- primaryKey: pk,
124
- foreignKey: fk,
125
- associationPrimaryKey: apk,
126
- associationForeignKey: afk,
127
- foreignKeyFull,
128
- associationForeignKeyFull,
129
- associationPrimaryKeyFull,
130
- };
131
-
132
- return {
133
- returns: 'many',
134
- method(params: Record<string, unknown>) {
135
- return query.whereExists(subQuery, (q) =>
136
- q.on(associationForeignKeyFull, associationPrimaryKeyFull).where({
137
- [foreignKeyFull]: params[pk],
138
- }),
139
- );
140
- },
141
- virtualColumn: new HasAndBelongsToManyVirtualColumn(relationName, state),
142
- // joinQuery can be a property of RelationQuery and be used by whereExists and other stuff which needs it
143
- // and the chained query itself may be a query around this joinQuery
144
- joinQuery(fromQuery, toQuery) {
145
- return toQuery.whereExists(subQuery, (q) =>
146
- q
147
- ._on(associationForeignKeyFull, `${getQueryAs(toQuery)}.${pk}`)
148
- ._on(foreignKeyFull, `${getQueryAs(fromQuery)}.${pk}`),
149
- );
150
- },
151
- reverseJoin(fromQuery, toQuery) {
152
- return fromQuery.whereExists(subQuery, (q) =>
153
- q
154
- ._on(associationForeignKeyFull, `${getQueryAs(toQuery)}.${pk}`)
155
- ._on(foreignKeyFull, `${getQueryAs(fromQuery)}.${pk}`),
156
- );
157
- },
158
- primaryKey: pk,
159
- modifyRelatedQuery(relationQuery) {
160
- const ref = {} as { query: Query };
161
-
162
- pushQueryValue(
163
- relationQuery,
164
- 'afterCreate',
165
- async (q: Query, result: Record<string, unknown>) => {
166
- const fromQuery = ref.query.clone();
167
- fromQuery.query.select = [{ selectAs: { [fk]: pk } }];
168
-
169
- const createdCount = await subQuery
170
- .transacting(q)
171
- .count()
172
- ._createFrom(
173
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
174
- fromQuery as any,
175
- {
176
- [afk]: result[apk],
177
- } as never,
178
- );
179
-
180
- if (createdCount === 0) {
181
- throw new NotFoundError();
182
- }
183
- },
184
- );
185
-
186
- return (q) => {
187
- ref.query = q;
188
- };
189
- },
190
- };
191
- };
192
-
193
- const queryJoinTable = (
194
- state: State,
195
- q: Query,
196
- data: Record<string, unknown>[],
197
- conditions?: MaybeArray<WhereArg<Query>>,
198
- ) => {
199
- const t = state.joinTableQuery.transacting(q);
200
- const where: WhereArg<Query> = {
201
- [state.foreignKey]: { in: data.map((item) => item[state.primaryKey]) },
202
- };
203
-
204
- if (conditions) {
205
- where[state.associationForeignKey] = {
206
- in: state.relatedTableQuery
207
- .where<Query>(
208
- Array.isArray(conditions) ? { OR: conditions } : conditions,
209
- )
210
- ._select(state.associationPrimaryKey),
211
- };
212
- }
213
-
214
- return t._where(where);
215
- };
216
-
217
- const queryRelatedTable = (
218
- query: Query,
219
- q: Query,
220
- conditions: MaybeArray<WhereArg<Query>>,
221
- ) => {
222
- return query
223
- .transacting(q)
224
- ._where<Query>(Array.isArray(conditions) ? { OR: conditions } : conditions);
225
- };
226
-
227
- const insertToJoinTable = (
228
- state: State,
229
- joinTableTransaction: Query,
230
- data: Record<string, unknown>[],
231
- ids: unknown[],
232
- ) => {
233
- return joinTableTransaction._count()._createMany(
234
- data.flatMap((item) =>
235
- ids.map((id) => ({
236
- [state.foreignKey]: item[state.primaryKey],
237
- [state.associationForeignKey]: id,
238
- })),
239
- ),
240
- );
241
- };
242
-
243
- const nestedInsert = ({
244
- relatedTableQuery,
245
- joinTableQuery,
246
- primaryKey,
247
- foreignKey,
248
- associationPrimaryKey,
249
- associationForeignKey,
250
- }: State) => {
251
- return (async (q, data) => {
252
- const connect = data.filter(
253
- (
254
- item,
255
- ): item is [
256
- selfData: Record<string, unknown>,
257
- relationData: {
258
- connect: WhereArg<QueryBase>[];
259
- },
260
- ] => Boolean(item[1].connect),
261
- );
262
-
263
- const t = relatedTableQuery.transacting(q);
264
-
265
- let connected: Record<string, unknown>[];
266
- if (connect.length) {
267
- connected = (await Promise.all(
268
- connect.flatMap(([, { connect }]) =>
269
- connect.map((item) =>
270
- t.select(associationPrimaryKey)._findBy(item)._take(),
271
- ),
272
- ),
273
- )) as Record<string, unknown[]>[];
274
- } else {
275
- connected = [];
276
- }
277
-
278
- const connectOrCreate = data.filter(
279
- (
280
- item,
281
- ): item is [
282
- Record<string, unknown>,
283
- {
284
- connectOrCreate: {
285
- where: WhereArg<QueryBase>;
286
- create: Record<string, unknown>;
287
- }[];
288
- },
289
- ] => Boolean(item[1].connectOrCreate),
290
- );
291
-
292
- let connectOrCreated: (Record<string, unknown> | undefined)[];
293
- if (connectOrCreate.length) {
294
- connectOrCreated = await Promise.all(
295
- connectOrCreate.flatMap(([, { connectOrCreate }]) =>
296
- connectOrCreate.map((item) =>
297
- t.select(associationPrimaryKey)._findBy(item.where)._takeOptional(),
298
- ),
299
- ),
300
- );
301
- } else {
302
- connectOrCreated = [];
303
- }
304
-
305
- let connectOrCreateI = 0;
306
- const create = data.filter(
307
- (
308
- item,
309
- ): item is [
310
- Record<string, unknown>,
311
- {
312
- create?: Record<string, unknown>[];
313
- connectOrCreate?: {
314
- where: WhereArg<QueryBase>;
315
- create: Record<string, unknown>;
316
- }[];
317
- },
318
- ] => {
319
- if (item[1].connectOrCreate) {
320
- const length = item[1].connectOrCreate.length;
321
- connectOrCreateI += length;
322
- for (let i = length; i > 0; i--) {
323
- if (!connectOrCreated[connectOrCreateI - i]) return true;
324
- }
325
- }
326
- return Boolean(item[1].create);
327
- },
328
- );
329
-
330
- connectOrCreateI = 0;
331
- let created: Record<string, unknown>[];
332
- if (create.length) {
333
- created = (await t
334
- .select(associationPrimaryKey)
335
- ._createMany(
336
- create.flatMap(([, { create = [], connectOrCreate = [] }]) => [
337
- ...create,
338
- ...connectOrCreate
339
- .filter(() => !connectOrCreated[connectOrCreateI++])
340
- .map((item) => item.create),
341
- ]),
342
- )) as Record<string, unknown>[];
343
- } else {
344
- created = [];
345
- }
346
-
347
- const allKeys = data as unknown as [
348
- selfData: Record<string, unknown>,
349
- relationKeys: Record<string, unknown>[],
350
- ][];
351
-
352
- let createI = 0;
353
- let connectI = 0;
354
- connectOrCreateI = 0;
355
- data.forEach(([, data], index) => {
356
- if (data.create || data.connectOrCreate) {
357
- if (data.create) {
358
- const len = data.create.length;
359
- allKeys[index][1] = created.slice(createI, createI + len);
360
- createI += len;
361
- }
362
- if (data.connectOrCreate) {
363
- const arr: Record<string, unknown>[] = [];
364
- allKeys[index][1] = arr;
365
-
366
- const len = data.connectOrCreate.length;
367
- for (let i = 0; i < len; i++) {
368
- const item = connectOrCreated[connectOrCreateI++];
369
- if (item) {
370
- arr.push(item);
371
- } else {
372
- arr.push(created[createI++]);
373
- }
374
- }
375
- }
376
- }
377
-
378
- if (data.connect) {
379
- const len = data.connect.length;
380
- allKeys[index][1] = connected.slice(connectI, connectI + len);
381
- connectI += len;
382
- }
383
- });
384
-
385
- await joinTableQuery
386
- .transacting(q)
387
- ._count()
388
- ._createMany(
389
- allKeys.flatMap(([selfData, relationKeys]) => {
390
- const selfKey = selfData[primaryKey];
391
- return relationKeys.map((relationData) => ({
392
- [foreignKey]: selfKey,
393
- [associationForeignKey]: relationData[associationPrimaryKey],
394
- }));
395
- }),
396
- );
397
- }) as HasManyNestedInsert;
398
- };
399
-
400
- const nestedUpdate = (state: State) => {
401
- return (async (q, data, params) => {
402
- if (params.create) {
403
- const ids = await state.relatedTableQuery
404
- .transacting(q)
405
- ._pluck(state.associationPrimaryKey)
406
- ._createMany(params.create);
407
-
408
- await state.joinTableQuery.transacting(q)._createMany(
409
- data.flatMap((item) =>
410
- ids.map((id) => ({
411
- [state.foreignKey]: item[state.primaryKey],
412
- [state.associationForeignKey]: id,
413
- })),
414
- ),
415
- );
416
- }
417
-
418
- if (params.update) {
419
- await (
420
- state.relatedTableQuery
421
- .transacting(q)
422
- ._whereExists(state.joinTableQuery, (q) =>
423
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
424
- (q as any)
425
- ._on(
426
- state.associationForeignKeyFull,
427
- state.associationPrimaryKeyFull,
428
- )
429
- ._where({
430
- IN: {
431
- columns: [state.foreignKeyFull],
432
- values: [data.map((item) => item[state.primaryKey])],
433
- },
434
- }),
435
- )
436
- ._where(
437
- Array.isArray(params.update.where)
438
- ? { OR: params.update.where }
439
- : params.update.where,
440
- ) as WhereResult<Query>
441
- )._update<WhereResult<Query>>(params.update.data);
442
- }
443
-
444
- if (params.disconnect) {
445
- await queryJoinTable(state, q, data, params.disconnect)._delete();
446
- }
447
-
448
- if (params.delete) {
449
- const j = queryJoinTable(state, q, data, params.delete);
450
-
451
- const ids = await j._pluck(state.associationForeignKey)._delete();
452
-
453
- await queryRelatedTable(state.relatedTableQuery, q, {
454
- [state.associationPrimaryKey]: { in: ids },
455
- })._delete();
456
- }
457
-
458
- if (params.set) {
459
- const j = queryJoinTable(state, q, data);
460
- await j._delete();
461
- delete j.query[toSqlCacheKey];
462
-
463
- const ids = await queryRelatedTable(
464
- state.relatedTableQuery,
465
- q,
466
- params.set,
467
- )._pluck(state.associationPrimaryKey);
468
-
469
- await insertToJoinTable(state, j, data, ids);
470
- }
471
- }) as HasManyNestedUpdate;
472
- };