orchid-orm 1.5.29 → 1.5.30
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/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -22
- package/.env.example +0 -1
- package/.turbo/turbo-check.log +0 -26
- package/.turbo/turbo-test.log +0 -26
- package/.turbo/turbo-test:ci.log +0 -26
- package/CHANGELOG.md +0 -382
- package/coverage/coverage-summary.json +0 -28
- package/jest-setup.ts +0 -11
- package/rollup.config.js +0 -18
- package/src/bin/bin.ts +0 -3
- package/src/bin/init.test.ts +0 -810
- package/src/bin/init.ts +0 -529
- package/src/codegen/appCodeUpdater.test.ts +0 -75
- package/src/codegen/appCodeUpdater.ts +0 -53
- package/src/codegen/createBaseTableFile.test.ts +0 -53
- package/src/codegen/createBaseTableFile.ts +0 -31
- package/src/codegen/fileChanges.ts +0 -41
- package/src/codegen/testUtils.ts +0 -56
- package/src/codegen/tsUtils.ts +0 -180
- package/src/codegen/updateMainFile.test.ts +0 -253
- package/src/codegen/updateMainFile.ts +0 -210
- package/src/codegen/updateTableFile/changeTable.test.ts +0 -804
- package/src/codegen/updateTableFile/changeTable.ts +0 -536
- package/src/codegen/updateTableFile/createTable.test.ts +0 -139
- package/src/codegen/updateTableFile/createTable.ts +0 -51
- package/src/codegen/updateTableFile/renameTable.test.ts +0 -124
- package/src/codegen/updateTableFile/renameTable.ts +0 -67
- package/src/codegen/updateTableFile/updateTableFile.ts +0 -22
- package/src/codegen/utils.ts +0 -13
- package/src/index.ts +0 -5
- package/src/orm.test.ts +0 -92
- package/src/orm.ts +0 -98
- package/src/relations/belongsTo.test.ts +0 -1122
- package/src/relations/belongsTo.ts +0 -352
- package/src/relations/hasAndBelongsToMany.test.ts +0 -1335
- package/src/relations/hasAndBelongsToMany.ts +0 -472
- package/src/relations/hasMany.test.ts +0 -2616
- package/src/relations/hasMany.ts +0 -401
- package/src/relations/hasOne.test.ts +0 -1701
- package/src/relations/hasOne.ts +0 -351
- package/src/relations/relations.test.ts +0 -37
- package/src/relations/relations.ts +0 -363
- package/src/relations/utils.ts +0 -162
- package/src/repo.test.ts +0 -200
- package/src/repo.ts +0 -119
- package/src/table.test.ts +0 -121
- package/src/table.ts +0 -184
- package/src/test-utils/test-db.ts +0 -32
- package/src/test-utils/test-tables.ts +0 -194
- package/src/test-utils/test-utils.ts +0 -119
- package/src/transaction.test.ts +0 -47
- package/src/transaction.ts +0 -27
- package/src/utils.ts +0 -9
- package/tsconfig.json +0 -14
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
import { BelongsTo, BelongsToInfo, makeBelongsToMethod } from './belongsTo';
|
|
2
|
-
import { HasOne, HasOneInfo, makeHasOneMethod } from './hasOne';
|
|
3
|
-
import { DbTable, Table, TableClass, TableClasses } from '../table';
|
|
4
|
-
import { OrchidORM } from '../orm';
|
|
5
|
-
import {
|
|
6
|
-
Query,
|
|
7
|
-
QueryWithTable,
|
|
8
|
-
RelationQuery,
|
|
9
|
-
SetQueryReturnsAll,
|
|
10
|
-
SetQueryReturnsOne,
|
|
11
|
-
SetQueryReturnsOneOptional,
|
|
12
|
-
BaseRelation,
|
|
13
|
-
defaultsKey,
|
|
14
|
-
relationQueryKey,
|
|
15
|
-
EmptyObject,
|
|
16
|
-
VirtualColumn,
|
|
17
|
-
} from 'pqb';
|
|
18
|
-
import { HasMany, HasManyInfo, makeHasManyMethod } from './hasMany';
|
|
19
|
-
import {
|
|
20
|
-
HasAndBelongsToMany,
|
|
21
|
-
HasAndBelongsToManyInfo,
|
|
22
|
-
makeHasAndBelongsToManyMethod,
|
|
23
|
-
} from './hasAndBelongsToMany';
|
|
24
|
-
import { getSourceRelation, getThroughRelation } from './utils';
|
|
25
|
-
|
|
26
|
-
export interface RelationThunkBase {
|
|
27
|
-
type: string;
|
|
28
|
-
returns: 'one' | 'many';
|
|
29
|
-
fn(): TableClass;
|
|
30
|
-
options: BaseRelation['options'];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type RelationThunk = BelongsTo | HasOne | HasMany | HasAndBelongsToMany;
|
|
34
|
-
|
|
35
|
-
export type RelationThunks = Record<string, RelationThunk>;
|
|
36
|
-
|
|
37
|
-
export type RelationData = {
|
|
38
|
-
returns: 'one' | 'many';
|
|
39
|
-
method(params: Record<string, unknown>): Query;
|
|
40
|
-
virtualColumn?: VirtualColumn;
|
|
41
|
-
joinQuery(fromQuery: Query, toQuery: Query): Query;
|
|
42
|
-
reverseJoin(fromQuery: Query, toQuery: Query): Query;
|
|
43
|
-
primaryKey: string;
|
|
44
|
-
modifyRelatedQuery?(relatedQuery: Query): (query: Query) => void;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export type Relation<
|
|
48
|
-
T extends Table,
|
|
49
|
-
Relations extends RelationThunks,
|
|
50
|
-
K extends keyof Relations,
|
|
51
|
-
M extends Query = DbTable<ReturnType<Relations[K]['fn']>>,
|
|
52
|
-
Info extends RelationInfo = RelationInfo<T, Relations, Relations[K]>,
|
|
53
|
-
> = {
|
|
54
|
-
type: Relations[K]['type'];
|
|
55
|
-
returns: Relations[K]['returns'];
|
|
56
|
-
key: K;
|
|
57
|
-
table: M;
|
|
58
|
-
query: M;
|
|
59
|
-
joinQuery(fromQuery: Query, toQuery: Query): Query;
|
|
60
|
-
defaults: Info['populate'];
|
|
61
|
-
nestedCreateQuery: [Info['populate']] extends [never]
|
|
62
|
-
? M
|
|
63
|
-
: M & {
|
|
64
|
-
[defaultsKey]: Record<Info['populate'], true>;
|
|
65
|
-
};
|
|
66
|
-
primaryKey: string;
|
|
67
|
-
options: Relations[K]['options'];
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
export type RelationScopeOrTable<Relation extends RelationThunkBase> =
|
|
71
|
-
Relation['options']['scope'] extends (q: Query) => Query
|
|
72
|
-
? ReturnType<Relation['options']['scope']>
|
|
73
|
-
: DbTable<ReturnType<Relation['fn']>>;
|
|
74
|
-
|
|
75
|
-
export type RelationInfo<
|
|
76
|
-
T extends Table = Table,
|
|
77
|
-
Relations extends RelationThunks = RelationThunks,
|
|
78
|
-
Relation extends RelationThunk = RelationThunk,
|
|
79
|
-
> = Relation extends BelongsTo
|
|
80
|
-
? BelongsToInfo<T, Relation>
|
|
81
|
-
: Relation extends HasOne
|
|
82
|
-
? HasOneInfo<T, Relations, Relation>
|
|
83
|
-
: Relation extends HasMany
|
|
84
|
-
? HasManyInfo<T, Relations, Relation>
|
|
85
|
-
: Relation extends HasAndBelongsToMany
|
|
86
|
-
? HasAndBelongsToManyInfo<T, Relation>
|
|
87
|
-
: never;
|
|
88
|
-
|
|
89
|
-
export type MapRelation<
|
|
90
|
-
T extends Table,
|
|
91
|
-
Relations extends RelationThunks,
|
|
92
|
-
RelationName extends keyof Relations,
|
|
93
|
-
Relation extends RelationThunk = Relations[RelationName],
|
|
94
|
-
RelatedQuery extends Query = RelationScopeOrTable<Relation>,
|
|
95
|
-
Info extends {
|
|
96
|
-
params: Record<string, unknown>;
|
|
97
|
-
populate: string;
|
|
98
|
-
chainedCreate: boolean;
|
|
99
|
-
chainedDelete: boolean;
|
|
100
|
-
} = RelationInfo<T, Relations, Relation>,
|
|
101
|
-
> = RelationQuery<
|
|
102
|
-
RelationName,
|
|
103
|
-
Info['params'],
|
|
104
|
-
Info['populate'],
|
|
105
|
-
Relation['returns'] extends 'one'
|
|
106
|
-
? Relation['options']['required'] extends true
|
|
107
|
-
? SetQueryReturnsOne<RelatedQuery>
|
|
108
|
-
: SetQueryReturnsOneOptional<RelatedQuery>
|
|
109
|
-
: SetQueryReturnsAll<RelatedQuery>,
|
|
110
|
-
Relation['options']['required'] extends boolean
|
|
111
|
-
? Relation['options']['required']
|
|
112
|
-
: false,
|
|
113
|
-
Info['chainedCreate'],
|
|
114
|
-
Info['chainedDelete']
|
|
115
|
-
>;
|
|
116
|
-
|
|
117
|
-
export type MapRelations<T extends Table> = 'relations' extends keyof T
|
|
118
|
-
? T['relations'] extends RelationThunks
|
|
119
|
-
? {
|
|
120
|
-
[K in keyof T['relations']]: MapRelation<T, T['relations'], K>;
|
|
121
|
-
}
|
|
122
|
-
: EmptyObject
|
|
123
|
-
: EmptyObject;
|
|
124
|
-
|
|
125
|
-
type ApplyRelationData = {
|
|
126
|
-
relationName: string;
|
|
127
|
-
relation: RelationThunk;
|
|
128
|
-
dbTable: DbTable<TableClass>;
|
|
129
|
-
otherDbTable: DbTable<TableClass>;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
type DelayedRelations = Map<Query, Record<string, ApplyRelationData[]>>;
|
|
133
|
-
|
|
134
|
-
export const applyRelations = (
|
|
135
|
-
qb: Query,
|
|
136
|
-
tables: Record<string, Table>,
|
|
137
|
-
result: OrchidORM<TableClasses>,
|
|
138
|
-
) => {
|
|
139
|
-
const tableEntries = Object.entries(tables);
|
|
140
|
-
|
|
141
|
-
const delayedRelations: DelayedRelations = new Map();
|
|
142
|
-
|
|
143
|
-
for (const name in tables) {
|
|
144
|
-
const table = tables[name] as Table & {
|
|
145
|
-
relations?: RelationThunks;
|
|
146
|
-
};
|
|
147
|
-
if (!('relations' in table) || typeof table.relations !== 'object')
|
|
148
|
-
continue;
|
|
149
|
-
|
|
150
|
-
const dbTable = result[name];
|
|
151
|
-
for (const relationName in table.relations) {
|
|
152
|
-
const relation = table.relations[relationName];
|
|
153
|
-
const otherTableClass = relation.fn();
|
|
154
|
-
const otherTable = tableEntries.find(
|
|
155
|
-
(pair) => pair[1] instanceof otherTableClass,
|
|
156
|
-
);
|
|
157
|
-
if (!otherTable) {
|
|
158
|
-
throw new Error(
|
|
159
|
-
`Cannot find table class for class ${otherTableClass.name}`,
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
const otherTableName = otherTable[0];
|
|
163
|
-
const otherDbTable = result[otherTableName];
|
|
164
|
-
if (!otherDbTable)
|
|
165
|
-
throw new Error(`Cannot find table class by name ${otherTableName}`);
|
|
166
|
-
|
|
167
|
-
const data: ApplyRelationData = {
|
|
168
|
-
relationName,
|
|
169
|
-
relation,
|
|
170
|
-
dbTable,
|
|
171
|
-
otherDbTable,
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const options = relation.options as { through?: string; source?: string };
|
|
175
|
-
if (
|
|
176
|
-
typeof options.through === 'string' &&
|
|
177
|
-
typeof options.source === 'string'
|
|
178
|
-
) {
|
|
179
|
-
const throughRelation = getThroughRelation(dbTable, options.through);
|
|
180
|
-
if (!throughRelation) {
|
|
181
|
-
delayRelation(delayedRelations, dbTable, options.through, data);
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const sourceRelation = getSourceRelation(
|
|
186
|
-
throughRelation,
|
|
187
|
-
options.source,
|
|
188
|
-
);
|
|
189
|
-
if (!sourceRelation) {
|
|
190
|
-
delayRelation(
|
|
191
|
-
delayedRelations,
|
|
192
|
-
throughRelation.table,
|
|
193
|
-
options.source,
|
|
194
|
-
data,
|
|
195
|
-
);
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
applyRelation(qb, data, delayedRelations);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (delayedRelations.size) {
|
|
205
|
-
const { value } = delayedRelations.values().next() as {
|
|
206
|
-
value: Record<string, ApplyRelationData[]>;
|
|
207
|
-
};
|
|
208
|
-
for (const key in value) {
|
|
209
|
-
for (const item of value[key]) {
|
|
210
|
-
const { relation } = item;
|
|
211
|
-
|
|
212
|
-
if (item.dbTable.relations[item.relationName as never]) continue;
|
|
213
|
-
|
|
214
|
-
const as = item.dbTable.definedAs;
|
|
215
|
-
let message = `Cannot define a \`${item.relationName}\` relation on \`${as}\``;
|
|
216
|
-
const table = result[as];
|
|
217
|
-
|
|
218
|
-
const { through, source } = relation.options as {
|
|
219
|
-
through: string;
|
|
220
|
-
source: string;
|
|
221
|
-
};
|
|
222
|
-
const throughRel = table.relations[
|
|
223
|
-
through as never
|
|
224
|
-
] as unknown as BaseRelation;
|
|
225
|
-
|
|
226
|
-
if (through && !throughRel) {
|
|
227
|
-
message += `: cannot find \`${through}\` relation required by the \`through\` option`;
|
|
228
|
-
} else if (
|
|
229
|
-
source &&
|
|
230
|
-
throughRel &&
|
|
231
|
-
!throughRel.table.relations[source as never]
|
|
232
|
-
) {
|
|
233
|
-
message += `: cannot find \`${source}\` relation in \`${
|
|
234
|
-
(throughRel.table as DbTable<TableClass>).definedAs
|
|
235
|
-
}\` required by the \`source\` option`;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
throw new Error(message);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
const delayRelation = (
|
|
245
|
-
delayedRelations: DelayedRelations,
|
|
246
|
-
table: Query,
|
|
247
|
-
relationName: string,
|
|
248
|
-
data: ApplyRelationData,
|
|
249
|
-
) => {
|
|
250
|
-
let tableRelations = delayedRelations.get(table);
|
|
251
|
-
if (!tableRelations) {
|
|
252
|
-
tableRelations = {};
|
|
253
|
-
delayedRelations.set(table, tableRelations);
|
|
254
|
-
}
|
|
255
|
-
if (tableRelations[relationName]) {
|
|
256
|
-
tableRelations[relationName].push(data);
|
|
257
|
-
} else {
|
|
258
|
-
tableRelations[relationName] = [data];
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
const applyRelation = (
|
|
263
|
-
qb: Query,
|
|
264
|
-
{ relationName, relation, dbTable, otherDbTable }: ApplyRelationData,
|
|
265
|
-
delayedRelations: DelayedRelations,
|
|
266
|
-
) => {
|
|
267
|
-
const query = (
|
|
268
|
-
relation.options.scope
|
|
269
|
-
? relation.options.scope(otherDbTable)
|
|
270
|
-
: (otherDbTable as unknown as QueryWithTable)
|
|
271
|
-
).as(relationName);
|
|
272
|
-
|
|
273
|
-
const definedAs = (query as unknown as { definedAs?: string }).definedAs;
|
|
274
|
-
if (!definedAs) {
|
|
275
|
-
throw new Error(
|
|
276
|
-
`Table class for table ${query.table} is not attached to db instance`,
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const { type } = relation;
|
|
281
|
-
let data;
|
|
282
|
-
if (type === 'belongsTo') {
|
|
283
|
-
data = makeBelongsToMethod(relation, relationName, query);
|
|
284
|
-
} else if (type === 'hasOne') {
|
|
285
|
-
data = makeHasOneMethod(dbTable, relation, relationName, query);
|
|
286
|
-
} else if (type === 'hasMany') {
|
|
287
|
-
data = makeHasManyMethod(dbTable, relation, relationName, query);
|
|
288
|
-
} else if (type === 'hasAndBelongsToMany') {
|
|
289
|
-
data = makeHasAndBelongsToManyMethod(
|
|
290
|
-
dbTable,
|
|
291
|
-
qb,
|
|
292
|
-
relation,
|
|
293
|
-
relationName,
|
|
294
|
-
query,
|
|
295
|
-
);
|
|
296
|
-
} else {
|
|
297
|
-
throw new Error(`Unknown relation type ${type}`);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (data.returns === 'one') {
|
|
301
|
-
query._take();
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (data.virtualColumn) {
|
|
305
|
-
dbTable.shape[relationName] = data.virtualColumn;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
makeRelationQuery(dbTable, definedAs, relationName, data);
|
|
309
|
-
|
|
310
|
-
(dbTable.relations as Record<string, unknown>)[relationName] = {
|
|
311
|
-
type,
|
|
312
|
-
key: relationName,
|
|
313
|
-
table: otherDbTable,
|
|
314
|
-
query,
|
|
315
|
-
joinQuery: data.joinQuery,
|
|
316
|
-
primaryKey: data.primaryKey,
|
|
317
|
-
options: relation.options,
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
const tableRelations = delayedRelations.get(dbTable);
|
|
321
|
-
if (!tableRelations) return;
|
|
322
|
-
|
|
323
|
-
tableRelations[relationName]?.forEach((data) => {
|
|
324
|
-
applyRelation(qb, data, delayedRelations);
|
|
325
|
-
});
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
const makeRelationQuery = (
|
|
329
|
-
table: Query,
|
|
330
|
-
definedAs: string,
|
|
331
|
-
relationName: string,
|
|
332
|
-
data: RelationData,
|
|
333
|
-
) => {
|
|
334
|
-
Object.defineProperty(table, relationName, {
|
|
335
|
-
get() {
|
|
336
|
-
const toTable = this.db[definedAs].as(relationName) as Query;
|
|
337
|
-
|
|
338
|
-
if (data.returns === 'one') {
|
|
339
|
-
toTable._take();
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const query = this.isSubQuery
|
|
343
|
-
? toTable
|
|
344
|
-
: toTable._whereExists(data.reverseJoin(this, toTable), (q) => q);
|
|
345
|
-
|
|
346
|
-
query.query[relationQueryKey] = {
|
|
347
|
-
relationName,
|
|
348
|
-
sourceQuery: this,
|
|
349
|
-
relationQuery: toTable,
|
|
350
|
-
joinQuery: data.joinQuery,
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const setQuery = data.modifyRelatedQuery?.(query);
|
|
354
|
-
setQuery?.(this);
|
|
355
|
-
|
|
356
|
-
return new Proxy(data.method, {
|
|
357
|
-
get(_, prop) {
|
|
358
|
-
return (query as unknown as Record<string, unknown>)[prop as string];
|
|
359
|
-
},
|
|
360
|
-
}) as unknown as RelationQuery;
|
|
361
|
-
},
|
|
362
|
-
});
|
|
363
|
-
};
|
package/src/relations/utils.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CreateCtx,
|
|
3
|
-
MaybeArray,
|
|
4
|
-
pushQueryValue,
|
|
5
|
-
Query,
|
|
6
|
-
QueryBase,
|
|
7
|
-
Relation,
|
|
8
|
-
UpdateCtx,
|
|
9
|
-
UpdateData,
|
|
10
|
-
WhereArg,
|
|
11
|
-
} from 'pqb';
|
|
12
|
-
import { HasOneNestedInsert, HasOneNestedUpdate } from './hasOne';
|
|
13
|
-
import { HasManyNestedInsert, HasManyNestedUpdate } from './hasMany';
|
|
14
|
-
|
|
15
|
-
export type NestedInsertOneItem = {
|
|
16
|
-
create?: Record<string, unknown>;
|
|
17
|
-
connect?: WhereArg<QueryBase>;
|
|
18
|
-
connectOrCreate?: {
|
|
19
|
-
where: WhereArg<QueryBase>;
|
|
20
|
-
create: Record<string, unknown>;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type NestedInsertManyItems = {
|
|
25
|
-
create?: Record<string, unknown>[];
|
|
26
|
-
connect?: WhereArg<QueryBase>[];
|
|
27
|
-
connectOrCreate?: {
|
|
28
|
-
where: WhereArg<QueryBase>;
|
|
29
|
-
create: Record<string, unknown>;
|
|
30
|
-
}[];
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export type NestedInsertItem = NestedInsertOneItem | NestedInsertManyItems;
|
|
34
|
-
|
|
35
|
-
export type NestedUpdateOneItem = {
|
|
36
|
-
disconnect?: boolean;
|
|
37
|
-
set?: WhereArg<QueryBase>;
|
|
38
|
-
delete?: boolean;
|
|
39
|
-
update?: UpdateData<Query>;
|
|
40
|
-
upsert?: {
|
|
41
|
-
update: UpdateData<Query>;
|
|
42
|
-
create: Record<string, unknown>;
|
|
43
|
-
};
|
|
44
|
-
create: Record<string, unknown>;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export type NestedUpdateManyItems = {
|
|
48
|
-
disconnect?: MaybeArray<WhereArg<QueryBase>>;
|
|
49
|
-
set?: MaybeArray<WhereArg<QueryBase>>;
|
|
50
|
-
delete?: MaybeArray<WhereArg<QueryBase>>;
|
|
51
|
-
update?: {
|
|
52
|
-
where: MaybeArray<WhereArg<QueryBase>>;
|
|
53
|
-
data: UpdateData<Query>;
|
|
54
|
-
};
|
|
55
|
-
create: Record<string, unknown>[];
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export type NestedUpdateItem = NestedUpdateOneItem | NestedUpdateManyItems;
|
|
59
|
-
|
|
60
|
-
export const getThroughRelation = (table: Query, through: string) => {
|
|
61
|
-
return (table.relations as Record<string, Relation>)[through];
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const getSourceRelation = (
|
|
65
|
-
throughRelation: Relation,
|
|
66
|
-
source: string,
|
|
67
|
-
) => {
|
|
68
|
-
return (throughRelation.table.relations as Record<string, Relation>)[source];
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const hasRelationHandleCreate = (
|
|
72
|
-
q: Query,
|
|
73
|
-
ctx: CreateCtx,
|
|
74
|
-
item: Record<string, unknown>,
|
|
75
|
-
rowIndex: number,
|
|
76
|
-
key: string,
|
|
77
|
-
primaryKey: string,
|
|
78
|
-
nestedInsert: HasOneNestedInsert | HasManyNestedInsert,
|
|
79
|
-
) => {
|
|
80
|
-
const value = item[key] as NestedInsertItem;
|
|
81
|
-
if (
|
|
82
|
-
(!value.create ||
|
|
83
|
-
(Array.isArray(value.create) && value.create.length === 0)) &&
|
|
84
|
-
(!value.connect ||
|
|
85
|
-
(Array.isArray(value.connect) && value.connect.length === 0)) &&
|
|
86
|
-
(!value.connectOrCreate ||
|
|
87
|
-
(Array.isArray(value.connectOrCreate) &&
|
|
88
|
-
value.connectOrCreate.length === 0))
|
|
89
|
-
)
|
|
90
|
-
return;
|
|
91
|
-
|
|
92
|
-
const store = ctx as unknown as {
|
|
93
|
-
hasRelation?: Record<string, [number, NestedInsertItem][]>;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
if (!store.hasRelation) store.hasRelation = {};
|
|
97
|
-
|
|
98
|
-
const values = [rowIndex, value] as [number, NestedInsertItem];
|
|
99
|
-
|
|
100
|
-
if (store.hasRelation[key]) {
|
|
101
|
-
store.hasRelation[key].push(values);
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
q.query.wrapInTransaction = true;
|
|
106
|
-
ctx.returnTypeAll = true;
|
|
107
|
-
ctx.requiredReturning[primaryKey] = true;
|
|
108
|
-
|
|
109
|
-
const relationData = [values];
|
|
110
|
-
store.hasRelation[key] = relationData;
|
|
111
|
-
|
|
112
|
-
pushQueryValue(q, 'afterCreate', async (q: Query) => {
|
|
113
|
-
const { resultAll } = ctx;
|
|
114
|
-
return (nestedInsert as HasOneNestedInsert)(
|
|
115
|
-
q,
|
|
116
|
-
relationData.map(([rowIndex, data]) => [
|
|
117
|
-
resultAll[rowIndex],
|
|
118
|
-
data as NestedInsertOneItem,
|
|
119
|
-
]),
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
export const hasRelationHandleUpdate = (
|
|
125
|
-
q: Query,
|
|
126
|
-
ctx: UpdateCtx,
|
|
127
|
-
set: Record<string, unknown>,
|
|
128
|
-
key: string,
|
|
129
|
-
primaryKey: string,
|
|
130
|
-
nestedUpdate: HasOneNestedUpdate | HasManyNestedUpdate,
|
|
131
|
-
) => {
|
|
132
|
-
const value = set[key] as NestedUpdateItem;
|
|
133
|
-
|
|
134
|
-
if (
|
|
135
|
-
!value.set &&
|
|
136
|
-
!('upsert' in value) &&
|
|
137
|
-
(!value.disconnect ||
|
|
138
|
-
(Array.isArray(value.disconnect) && value.disconnect.length === 0)) &&
|
|
139
|
-
(!value.delete ||
|
|
140
|
-
(Array.isArray(value.delete) && value.delete.length === 0)) &&
|
|
141
|
-
(!value.update ||
|
|
142
|
-
(Array.isArray(value.update.where) && value.update.where.length === 0)) &&
|
|
143
|
-
(!value.create ||
|
|
144
|
-
(Array.isArray(value.create) && value.create.length === 0))
|
|
145
|
-
)
|
|
146
|
-
return;
|
|
147
|
-
|
|
148
|
-
if (!q.query.select?.includes('*') && !q.query.select?.includes(primaryKey)) {
|
|
149
|
-
q._select(primaryKey);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
q.query.wrapInTransaction = true;
|
|
153
|
-
ctx.returnTypeAll = true;
|
|
154
|
-
|
|
155
|
-
pushQueryValue(q, 'afterUpdate', (q: Query) => {
|
|
156
|
-
return (nestedUpdate as HasOneNestedUpdate)(
|
|
157
|
-
q,
|
|
158
|
-
ctx.resultAll,
|
|
159
|
-
value as NestedUpdateOneItem,
|
|
160
|
-
);
|
|
161
|
-
});
|
|
162
|
-
};
|