prisma-ts-select 0.1.5 → 0.1.7
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/README.md +6 -6
- package/dist/bin.cjs +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-NFKUA5XM.js → chunk-F7HSD6UA.js} +23 -1
- package/dist/{chunk-GSIFF2TF.cjs → chunk-RX2M26LV.cjs} +23 -1
- package/dist/extend/dialects/mysql-v6.d.ts +1 -1
- package/dist/extend/dialects/sqlite.d.ts +2 -2
- package/dist/extend/extend.d.ts +12 -8
- package/dist/extend/extend.js +44 -43
- package/dist/generator.cjs +7 -1
- package/dist/generator.d.cts +2 -1
- package/dist/generator.d.ts +2 -1
- package/dist/generator.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -757,7 +757,7 @@ Joins through Prisma's implicit or explicit many-to-many junction tables. Automa
|
|
|
757
757
|
##### Example
|
|
758
758
|
```typescript file=../usage-sqlite-v7/tests/readme/join-many-to-many.ts region=m2m-basic
|
|
759
759
|
prisma.$from("M2M_Post")
|
|
760
|
-
.manyToManyJoin("M2M_Category");
|
|
760
|
+
.manyToManyJoin("M2M_Post", "M2M_Category");
|
|
761
761
|
```
|
|
762
762
|
|
|
763
763
|
##### SQL
|
|
@@ -777,7 +777,7 @@ JOIN M2M_Category ON M2M_Category.id = _M2M_CategoryToM2M_Post.A;
|
|
|
777
777
|
##### With Alias
|
|
778
778
|
```typescript file=../usage-sqlite-v7/tests/readme/join-many-to-many.ts region=m2m-alias
|
|
779
779
|
prisma.$from("M2M_Post")
|
|
780
|
-
.manyToManyJoin("M2M_Category mc");
|
|
780
|
+
.manyToManyJoin("M2M_Post", "M2M_Category mc");
|
|
781
781
|
```
|
|
782
782
|
|
|
783
783
|
```sql file=../usage-sqlite-v7/tests/readme/join-many-to-many.ts region=m2m-alias-sql
|
|
@@ -792,7 +792,7 @@ Use `refName` when a model has multiple M2M relations to the same target:
|
|
|
792
792
|
|
|
793
793
|
```typescript file=../usage-sqlite-v7/tests/readme/join-many-to-many.ts region=m2m-refname
|
|
794
794
|
prisma.$from("MMM_Post")
|
|
795
|
-
.manyToManyJoin("MMM_Category", { refName: "M2M_NC_M1" });
|
|
795
|
+
.manyToManyJoin("MMM_Post", "MMM_Category", { refName: "M2M_NC_M1" });
|
|
796
796
|
```
|
|
797
797
|
|
|
798
798
|
```sql file=../usage-sqlite-v7/tests/readme/join-many-to-many.ts region=m2m-refname-sql
|
|
@@ -807,7 +807,7 @@ Use `source` to pin the source alias and column when the source table is aliased
|
|
|
807
807
|
|
|
808
808
|
```typescript file=../usage-sqlite-v7/tests/readme/join-many-to-many.ts region=m2m-source
|
|
809
809
|
prisma.$from("M2M_Post mp")
|
|
810
|
-
.manyToManyJoin("
|
|
810
|
+
.manyToManyJoin("mp", "M2M_Category mc");
|
|
811
811
|
```
|
|
812
812
|
|
|
813
813
|
```sql file=../usage-sqlite-v7/tests/readme/join-many-to-many.ts region=m2m-source-sql
|
|
@@ -1310,8 +1310,8 @@ prisma.$from("User")
|
|
|
1310
1310
|
|
|
1311
1311
|
##### SQL
|
|
1312
1312
|
```sql file=../usage-sqlite-v7/tests/readme/select-all-omit.ts region=single-omit-sql
|
|
1313
|
-
SELECT
|
|
1314
|
-
FROM
|
|
1313
|
+
SELECT id, name, age
|
|
1314
|
+
FROM User;
|
|
1315
1315
|
```
|
|
1316
1316
|
|
|
1317
1317
|
#### Example - Multiple Columns
|
package/dist/bin.cjs
CHANGED
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import './chunk-
|
|
2
|
+
import './chunk-F7HSD6UA.js';
|
|
@@ -51,6 +51,7 @@ generatorHandler({
|
|
|
51
51
|
}, []).join(", ")}`);
|
|
52
52
|
}
|
|
53
53
|
const modelToId = {};
|
|
54
|
+
const m2mMap = {};
|
|
54
55
|
const models = options.dmmf.datamodel.models.reduce((acc, model) => {
|
|
55
56
|
const modelObj = acc[model.name] = acc[model.name] ?? {
|
|
56
57
|
fields: {},
|
|
@@ -79,6 +80,11 @@ generatorHandler({
|
|
|
79
80
|
} else {
|
|
80
81
|
if (!isManyToManyRelationShip(field)) continue;
|
|
81
82
|
const joinTableName = "_" + field.relationName;
|
|
83
|
+
const src = model.name, tgt = field.type;
|
|
84
|
+
(m2mMap[src] ??= {})[tgt] ??= /* @__PURE__ */ new Set();
|
|
85
|
+
m2mMap[src][tgt].add(joinTableName);
|
|
86
|
+
(m2mMap[tgt] ??= {})[src] ??= /* @__PURE__ */ new Set();
|
|
87
|
+
m2mMap[tgt][src].add(joinTableName);
|
|
82
88
|
const joinTableModel = acc[joinTableName] = acc[joinTableName] ?? {
|
|
83
89
|
fields: {
|
|
84
90
|
"A": "",
|
|
@@ -214,7 +220,7 @@ export { ${provider}Dialect as dialect, ${provider}Dialect, ${ctxName} as dialec
|
|
|
214
220
|
const PLACEHOLDER = "type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = BaseSelectFnContext<_TSources, _TFields>;";
|
|
215
221
|
const JOIN_RETURN_RE = /type _fJoinReturn<[^>]+>[^;]+;/;
|
|
216
222
|
const joinReturnReplacement = omittedMethods.length > 0 ? `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = Omit<_fJoin<TSources, TFields, TCTEs>, ${omittedMethods.map((m) => `"${m}"`).join(" | ")}>;` : `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = _fJoin<TSources, TFields, TCTEs>;`;
|
|
217
|
-
const replacedExtendDts = extendDts.replace("declare const DB: DBType;", declaration).replace(
|
|
223
|
+
const replacedExtendDts = extendDts.replace("declare const DB: DBType;", declaration).replace("type M2MMap = {};", generateM2MMapDeclaration(m2mMap)).replace(
|
|
218
224
|
PLACEHOLDER,
|
|
219
225
|
`type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = Omit<BaseSelectFnContext<_TSources, _TFields>, keyof DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>> & DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>;`
|
|
220
226
|
).replace(JOIN_RETURN_RE, joinReturnReplacement);
|
|
@@ -300,3 +306,19 @@ function generateReadonlyDeclaration(db) {
|
|
|
300
306
|
${traverse(db, 1)}
|
|
301
307
|
};`;
|
|
302
308
|
}
|
|
309
|
+
function generateM2MMapDeclaration(m2mMap) {
|
|
310
|
+
if (Object.keys(m2mMap).length === 0) return "type M2MMap = {};";
|
|
311
|
+
const lines = ["type M2MMap = {"];
|
|
312
|
+
for (const [source, targets] of Object.entries(m2mMap)) {
|
|
313
|
+
lines.push(` readonly "${source}": {`);
|
|
314
|
+
for (const [target, junctions] of Object.entries(targets)) {
|
|
315
|
+
const junctionLiterals = Array.from(junctions).map((j) => `"${j}"`).join(" | ");
|
|
316
|
+
lines.push(` readonly "${target}": ${junctionLiterals};`);
|
|
317
|
+
}
|
|
318
|
+
lines.push(" };");
|
|
319
|
+
}
|
|
320
|
+
lines.push("};");
|
|
321
|
+
return lines.join("\n");
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export { generateM2MMapDeclaration };
|
|
@@ -59,6 +59,7 @@ generatorHelper.generatorHandler({
|
|
|
59
59
|
}, []).join(", ")}`);
|
|
60
60
|
}
|
|
61
61
|
const modelToId = {};
|
|
62
|
+
const m2mMap = {};
|
|
62
63
|
const models = options.dmmf.datamodel.models.reduce((acc, model) => {
|
|
63
64
|
const modelObj = acc[model.name] = acc[model.name] ?? {
|
|
64
65
|
fields: {},
|
|
@@ -87,6 +88,11 @@ generatorHelper.generatorHandler({
|
|
|
87
88
|
} else {
|
|
88
89
|
if (!isManyToManyRelationShip(field)) continue;
|
|
89
90
|
const joinTableName = "_" + field.relationName;
|
|
91
|
+
const src = model.name, tgt = field.type;
|
|
92
|
+
(m2mMap[src] ??= {})[tgt] ??= /* @__PURE__ */ new Set();
|
|
93
|
+
m2mMap[src][tgt].add(joinTableName);
|
|
94
|
+
(m2mMap[tgt] ??= {})[src] ??= /* @__PURE__ */ new Set();
|
|
95
|
+
m2mMap[tgt][src].add(joinTableName);
|
|
90
96
|
const joinTableModel = acc[joinTableName] = acc[joinTableName] ?? {
|
|
91
97
|
fields: {
|
|
92
98
|
"A": "",
|
|
@@ -222,7 +228,7 @@ export { ${provider}Dialect as dialect, ${provider}Dialect, ${ctxName} as dialec
|
|
|
222
228
|
const PLACEHOLDER = "type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = BaseSelectFnContext<_TSources, _TFields>;";
|
|
223
229
|
const JOIN_RETURN_RE = /type _fJoinReturn<[^>]+>[^;]+;/;
|
|
224
230
|
const joinReturnReplacement = omittedMethods.length > 0 ? `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = Omit<_fJoin<TSources, TFields, TCTEs>, ${omittedMethods.map((m) => `"${m}"`).join(" | ")}>;` : `type _fJoinReturn<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> = _fJoin<TSources, TFields, TCTEs>;`;
|
|
225
|
-
const replacedExtendDts = extendDts.replace("declare const DB: DBType;", declaration).replace(
|
|
231
|
+
const replacedExtendDts = extendDts.replace("declare const DB: DBType;", declaration).replace("type M2MMap = {};", generateM2MMapDeclaration(m2mMap)).replace(
|
|
226
232
|
PLACEHOLDER,
|
|
227
233
|
`type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = Omit<BaseSelectFnContext<_TSources, _TFields>, keyof DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>> & DialectFns<ColEntries<_TSources, _TFields>, WhereCriteria<_TSources, _TFields>>;`
|
|
228
234
|
).replace(JOIN_RETURN_RE, joinReturnReplacement);
|
|
@@ -308,3 +314,19 @@ function generateReadonlyDeclaration(db) {
|
|
|
308
314
|
${traverse(db, 1)}
|
|
309
315
|
};`;
|
|
310
316
|
}
|
|
317
|
+
function generateM2MMapDeclaration(m2mMap) {
|
|
318
|
+
if (Object.keys(m2mMap).length === 0) return "type M2MMap = {};";
|
|
319
|
+
const lines = ["type M2MMap = {"];
|
|
320
|
+
for (const [source, targets] of Object.entries(m2mMap)) {
|
|
321
|
+
lines.push(` readonly "${source}": {`);
|
|
322
|
+
for (const [target, junctions] of Object.entries(targets)) {
|
|
323
|
+
const junctionLiterals = Array.from(junctions).map((j) => `"${j}"`).join(" | ");
|
|
324
|
+
lines.push(` readonly "${target}": ${junctionLiterals};`);
|
|
325
|
+
}
|
|
326
|
+
lines.push(" };");
|
|
327
|
+
}
|
|
328
|
+
lines.push("};");
|
|
329
|
+
return lines.join("\n");
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
exports.generateM2MMapDeclaration = generateM2MMapDeclaration;
|
|
@@ -47,7 +47,7 @@ declare const mysqlV6ContextFns: <TColEntries extends [string, unknown] = never,
|
|
|
47
47
|
hour: (col: SQLExpr<Date> | FilterCols<TColEntries, Date>) => SQLExpr<bigint>;
|
|
48
48
|
minute: (col: SQLExpr<Date> | FilterCols<TColEntries, Date>) => SQLExpr<number>;
|
|
49
49
|
second: (col: SQLExpr<Date> | FilterCols<TColEntries, Date>) => SQLExpr<number>;
|
|
50
|
-
$if: <T>(cond:
|
|
50
|
+
$if: <T>(cond: SQLExpr<unknown> | TCriteria, trueVal: SQLExpr<T>, falseVal: SQLExpr<T>) => SQLExpr<T>;
|
|
51
51
|
ifNull: <T>(col: FilterCols<TColEntries, T> | SQLExpr<T>, fallback: SQLExpr<NonNullable<T>>) => SQLExpr<NonNullable<T>>;
|
|
52
52
|
greatest: <T>(args_0: FilterCols<TColEntries, T> | SQLExpr<T>, ...args: (FilterCols<TColEntries, T> | SQLExpr<T>)[]) => SQLExpr<T | null>;
|
|
53
53
|
least: <T>(args_0: FilterCols<TColEntries, T> | SQLExpr<T>, ...args: (FilterCols<TColEntries, T> | SQLExpr<T>)[]) => SQLExpr<T | null>;
|
|
@@ -26,7 +26,7 @@ declare const sqliteContextFns: <TColEntries extends [string, unknown] = never,
|
|
|
26
26
|
total: (col: ColName<TColEntries>) => SQLExpr<number>;
|
|
27
27
|
min: <Col extends ColName<TColEntries>>(col: Col) => SQLExpr<SqliteMinMaxResult<TColEntries, Col>>;
|
|
28
28
|
max: <Col extends ColName<TColEntries>>(col: Col) => SQLExpr<SqliteMinMaxResult<TColEntries, Col>>;
|
|
29
|
-
concat: (args_0:
|
|
29
|
+
concat: (args_0: SQLExpr<string> | FilterCols<TColEntries, string>, ...args: (SQLExpr<string> | FilterCols<TColEntries, string>)[]) => SQLExpr<string>;
|
|
30
30
|
substr: (col: FilterCols<TColEntries, string> | SQLExpr<string>, start: number, len?: number) => SQLExpr<string>;
|
|
31
31
|
instr: (col: FilterCols<TColEntries, string> | SQLExpr<string>, substr: string) => SQLExpr<bigint>;
|
|
32
32
|
char: (...codes: number[]) => SQLExpr<string>;
|
|
@@ -60,7 +60,7 @@ declare const sqliteContextFns: <TColEntries extends [string, unknown] = never,
|
|
|
60
60
|
log2: (x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
|
|
61
61
|
log10: (x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
|
|
62
62
|
jsonExtract: (col: FilterJsonCols<TColEntries> | SQLExpr<JSONValue>, path: string) => SQLExpr<JSONValue>;
|
|
63
|
-
jsonArray: (args_0:
|
|
63
|
+
jsonArray: (args_0: ColName<TColEntries> | SQLExpr<unknown>, ...args: (ColName<TColEntries> | SQLExpr<unknown>)[]) => SQLExpr<JSONValue[]>;
|
|
64
64
|
jsonObject: (pairs: [string, ColName<TColEntries> | SQLExpr<unknown>][]) => SQLExpr<JSONObject>;
|
|
65
65
|
cast: <T extends keyof SqliteCastTypeMap>(expr: ColName<TColEntries> | SQLExpr<unknown>, type: T) => SQLExpr<SqliteCastTypeMap[T]>;
|
|
66
66
|
};
|
package/dist/extend/extend.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { S as SQLExpr, L as LitToType } from './sql-expr-BGSEwzCi.js';
|
|
|
4
4
|
type PrismaClient = any;
|
|
5
5
|
|
|
6
6
|
declare const DB: DBType;
|
|
7
|
+
type M2MMap = {};
|
|
7
8
|
type TDB = typeof DB;
|
|
8
9
|
type DeepWriteable<T> = {
|
|
9
10
|
-readonly [P in keyof T]: DeepWriteable<T[P]>;
|
|
@@ -346,10 +347,12 @@ type BaseSelectFnContext<_TSources extends TArrSources, _TFields extends TFields
|
|
|
346
347
|
}>], elseVal?: TElse) => TElse extends SQLExpr<T> ? SQLExpr<T> : SQLExpr<T | null>;
|
|
347
348
|
};
|
|
348
349
|
type SelectFnContext<_TSources extends TArrSources, _TFields extends TFieldsType> = BaseSelectFnContext<_TSources, _TFields>;
|
|
349
|
-
type
|
|
350
|
-
type
|
|
351
|
-
type
|
|
352
|
-
type
|
|
350
|
+
type IsUnion<T, _T extends T = T> = _T extends _T ? ([T] extends [_T] ? false : true) : never;
|
|
351
|
+
type ResolveSourceTable<TSources extends TArrSources, TInput extends string> = TSources[number] extends infer T ? T extends TVirtualTableSource ? never : T extends string ? T extends TInput ? T & TTables : never : T extends [infer Table extends TTables, infer Alias extends string] ? Alias extends TInput ? Table : Table extends TInput ? Table : never : never : never;
|
|
352
|
+
type AvailableM2MSources<TSources extends TArrSources> = TSources[number] extends infer T ? T extends TVirtualTableSource ? never : T extends string ? T extends keyof M2MMap ? T : never : T extends [infer Table extends string, infer Alias extends string] ? Table extends keyof M2MMap ? Alias : never : never : never;
|
|
353
|
+
type AvailableM2MTargets<TSource extends TTables> = TSource extends keyof M2MMap ? keyof M2MMap[TSource] & string : never;
|
|
354
|
+
type GetJunctionTable<TSource extends TTables, TTarget extends TTables> = TSource extends keyof M2MMap ? TTarget extends keyof M2MMap[TSource] ? M2MMap[TSource][TTarget & keyof M2MMap[TSource]] & TTables : never : never;
|
|
355
|
+
type AvailableRefNames<TSource extends TTables> = TSource extends keyof M2MMap ? M2MMap[TSource][keyof M2MMap[TSource]] extends infer J ? J extends `_${infer R}` ? R : never : never : never;
|
|
353
356
|
declare class _fJoin<TSources extends TArrSources, TFields extends TFieldsType, TCTEs extends Record<string, Record<string, any>> = {}> extends _fWhere<TSources, TFields> {
|
|
354
357
|
join<const TName extends keyof TCTEs & string>(cteName: TName, local: keyof TCTEs[TName] & string, remote: GetJoinCols<TSources[number]>, opts?: {
|
|
355
358
|
joinType?: JoinType;
|
|
@@ -391,10 +394,11 @@ declare class _fJoin<TSources extends TArrSources, TFields extends TFieldsType,
|
|
|
391
394
|
where?: JoinWhereCriteria<Table, TAlias>;
|
|
392
395
|
joinType?: JoinType;
|
|
393
396
|
}): _fJoinReturn<[...TSources, [TAlias] extends [never] ? Table : [Table, TAlias]], TFields & Record<Table, GetFieldsFromTable<Table>>, TCTEs>;
|
|
394
|
-
manyToManyJoin<const
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
397
|
+
manyToManyJoin<const TSourceInput extends AvailableM2MSources<TSources>, TSource extends TTables = ResolveSourceTable<TSources, TSourceInput>, const TTargetInput extends `${AvailableM2MTargets<TSource>}` | `${AvailableM2MTargets<TSource>} ${string}` = never, TTarget extends TTables = ExtractTableName<TTargetInput> & TTables, TAlias extends string | never = ExtractAlias<TTargetInput>, const TRefName extends AvailableRefNames<TSource> | undefined = undefined, TJunction extends TTables = TRefName extends string ? `_${TRefName}` & TTables : GetJunctionTable<TSource, TTarget>>(sourceTable: TSourceInput, targetTable: TTargetInput, ...args: IsUnion<TJunction> extends true ? [options: {
|
|
398
|
+
refName: AvailableRefNames<TSource>;
|
|
399
|
+
}] : [options?: {
|
|
400
|
+
refName?: AvailableRefNames<TSource>;
|
|
401
|
+
}]): _fJoin<[
|
|
398
402
|
...TSources,
|
|
399
403
|
TJunction,
|
|
400
404
|
[TAlias] extends [never] ? TTarget : [TTarget, TAlias]
|
package/dist/extend/extend.js
CHANGED
|
@@ -284,6 +284,7 @@ var esc = (s2) => s2.replace(/'/g, "''");
|
|
|
284
284
|
|
|
285
285
|
// src/extend.ts
|
|
286
286
|
var DB = {};
|
|
287
|
+
var SAFE_IDENT_RE = /^\w+$/;
|
|
287
288
|
var DbSelect = class {
|
|
288
289
|
constructor(db) {
|
|
289
290
|
this.db = db;
|
|
@@ -793,58 +794,58 @@ var _fJoin = class __fJoin extends _fWhere {
|
|
|
793
794
|
joinUnsafeIgnoreType(tableOrOptions, field, reference, _opts) {
|
|
794
795
|
return this.join(tableOrOptions, field, reference, _opts);
|
|
795
796
|
}
|
|
796
|
-
manyToManyJoin(targetTable,
|
|
797
|
-
const opts =
|
|
797
|
+
manyToManyJoin(sourceTable, targetTable, ...args) {
|
|
798
|
+
const opts = args[0];
|
|
798
799
|
const refName = opts?.refName;
|
|
800
|
+
const safeIdent = (v2, ctx) => {
|
|
801
|
+
if (!SAFE_IDENT_RE.test(v2)) throw new Error(`manyToManyJoin: unsafe identifier in ${ctx}: "${v2}"`);
|
|
802
|
+
return v2;
|
|
803
|
+
};
|
|
804
|
+
const [sourceTblRaw] = sourceTable.split(" ");
|
|
805
|
+
const safeSourceTbl = safeIdent(sourceTblRaw, "source");
|
|
806
|
+
const sourceEntry = this.values.tables.find(
|
|
807
|
+
(t2) => t2.table === safeSourceTbl || t2.alias === safeSourceTbl
|
|
808
|
+
);
|
|
809
|
+
if (!sourceEntry) throw new Error(`manyToManyJoin: source "${safeSourceTbl}" not in joined tables (by table name or alias)`);
|
|
810
|
+
const sourceTableName = sourceEntry.table;
|
|
811
|
+
const sourceAlias = sourceEntry.alias || sourceEntry.table;
|
|
799
812
|
const [tbl, alias] = targetTable.split(" ");
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (opts?.source) {
|
|
804
|
-
const [srcAliasOrTable, col] = opts.source.split(".");
|
|
805
|
-
const entry = this.values.tables.find((t2) => (t2.alias || t2.table) === srcAliasOrTable);
|
|
806
|
-
sourceTableName = entry?.table ?? srcAliasOrTable;
|
|
807
|
-
sourceAlias = srcAliasOrTable;
|
|
808
|
-
srcLocalCol = col;
|
|
809
|
-
} else {
|
|
810
|
-
const candidates = this.values.tables.filter((entry) => {
|
|
811
|
-
const relations = DB[entry.table]?.relations;
|
|
812
|
-
return relations && Object.keys(relations).some(
|
|
813
|
-
(k2) => k2.startsWith("_") && DB[k2]?.relations?.[tbl] !== void 0
|
|
814
|
-
);
|
|
815
|
-
});
|
|
816
|
-
if (candidates.length === 0) throw new Error(
|
|
817
|
-
`manyToManyJoin: no source with junction to "${tbl}" among joined tables`
|
|
818
|
-
);
|
|
819
|
-
if (candidates.length > 1) {
|
|
820
|
-
const names = candidates.map((c2) => c2.alias ?? c2.table).join(", ");
|
|
821
|
-
throw new Error(`manyToManyJoin: ambiguous source for "${tbl}" (${names}). Pass { source: "alias.col" }.`);
|
|
822
|
-
}
|
|
823
|
-
const found = candidates[0];
|
|
824
|
-
sourceTableName = found.table;
|
|
825
|
-
sourceAlias = found.alias || found.table;
|
|
826
|
-
const srcRelations2 = DB[sourceTableName]?.relations;
|
|
827
|
-
const junctionKey = refName ? `_${refName}` : Object.keys(srcRelations2 ?? {}).find(
|
|
828
|
-
(k2) => k2.startsWith("_") && DB[k2]?.relations?.[tbl] !== void 0
|
|
829
|
-
);
|
|
830
|
-
const junctionRelEntry = junctionKey ? srcRelations2[junctionKey] : void 0;
|
|
831
|
-
srcLocalCol = junctionRelEntry ? Object.keys(junctionRelEntry)[0] : "id";
|
|
832
|
-
}
|
|
813
|
+
const safeTbl = safeIdent(tbl, "target");
|
|
814
|
+
const safeAlias = alias ? safeIdent(alias, "alias") : void 0;
|
|
815
|
+
const safeRef = refName ? safeIdent(refName, "refName") : void 0;
|
|
833
816
|
const srcEntry = DB[sourceTableName];
|
|
834
817
|
if (!srcEntry) throw new Error(`manyToManyJoin: unknown source table "${sourceTableName}"`);
|
|
835
818
|
const srcRelations = srcEntry.relations;
|
|
836
|
-
const junctionTable =
|
|
837
|
-
(k2) => k2.startsWith("_") && DB[k2]?.relations?.[
|
|
819
|
+
const junctionTable = safeRef ? `_${safeRef}` : Object.keys(srcRelations).find(
|
|
820
|
+
(k2) => k2.startsWith("_") && DB[k2]?.relations?.[safeTbl] !== void 0
|
|
838
821
|
);
|
|
839
822
|
if (!junctionTable) throw new Error(
|
|
840
|
-
`manyToManyJoin: no junction between "${sourceTableName}" and "${
|
|
823
|
+
`manyToManyJoin: no junction between "${sourceTableName}" and "${safeTbl}"`
|
|
824
|
+
);
|
|
825
|
+
const junctionRelEntry = srcRelations[junctionTable];
|
|
826
|
+
const junctionKeys = junctionRelEntry ? Object.keys(junctionRelEntry) : [];
|
|
827
|
+
if (junctionRelEntry && junctionKeys.length === 0) throw new Error(
|
|
828
|
+
`manyToManyJoin: junction "${junctionTable}" has no relation columns for source "${sourceTableName}"`
|
|
829
|
+
);
|
|
830
|
+
const srcLocalCol = junctionKeys[0] ?? (() => {
|
|
831
|
+
throw new Error(`manyToManyJoin: cannot determine source local col for junction "${junctionTable}"`);
|
|
832
|
+
})();
|
|
833
|
+
const srcJunctionCol = junctionRelEntry?.[srcLocalCol]?.[0] ?? (() => {
|
|
834
|
+
throw new Error(`manyToManyJoin: cannot determine source junction col for "${junctionTable}"`);
|
|
835
|
+
})();
|
|
836
|
+
const tgtRelEntry = DB[junctionTable]?.relations?.[safeTbl];
|
|
837
|
+
const tgtKeys = tgtRelEntry ? Object.keys(tgtRelEntry) : [];
|
|
838
|
+
if (tgtRelEntry && tgtKeys.length === 0) throw new Error(
|
|
839
|
+
`manyToManyJoin: junction "${junctionTable}" has no relation columns for target "${safeTbl}"`
|
|
841
840
|
);
|
|
842
|
-
const
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
const tgtLocalCol = tgtRelEntry?.[tgtJunctionCol]?.[0] ??
|
|
841
|
+
const tgtJunctionCol = tgtKeys[0] ?? (() => {
|
|
842
|
+
throw new Error(`manyToManyJoin: cannot determine target junction col for "${junctionTable}"`);
|
|
843
|
+
})();
|
|
844
|
+
const tgtLocalCol = tgtRelEntry?.[tgtJunctionCol]?.[0] ?? (() => {
|
|
845
|
+
throw new Error(`manyToManyJoin: cannot determine target local col for "${junctionTable}"`);
|
|
846
|
+
})();
|
|
846
847
|
const remoteRef = `${sourceAlias}.${srcLocalCol}`;
|
|
847
|
-
return this.joinUnsafeIgnoreType(junctionTable, srcJunctionCol, remoteRef).joinUnsafeIgnoreType(
|
|
848
|
+
return this.joinUnsafeIgnoreType(junctionTable, srcJunctionCol, remoteRef).joinUnsafeIgnoreType(safeAlias ? `${safeTbl} ${safeAlias}` : safeTbl, tgtLocalCol, `${junctionTable}.${tgtJunctionCol}`);
|
|
848
849
|
}
|
|
849
850
|
innerJoin(tableOrOptions, field, reference) {
|
|
850
851
|
return this._joinImpl("INNER", tableOrOptions, field, reference);
|
package/dist/generator.cjs
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
require('./chunk-
|
|
3
|
+
var chunkRX2M26LV_cjs = require('./chunk-RX2M26LV.cjs');
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "generateM2MMapDeclaration", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkRX2M26LV_cjs.generateM2MMapDeclaration; }
|
|
10
|
+
});
|
package/dist/generator.d.cts
CHANGED
package/dist/generator.d.ts
CHANGED
package/dist/generator.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export { generateM2MMapDeclaration } from './chunk-F7HSD6UA.js';
|