befly 3.20.4 → 3.20.6
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/apis/dict/all.js +1 -6
- package/apis/dict/detail.js +1 -6
- package/apis/dict/list.js +1 -6
- package/configs/beflyConfig.json +2 -2
- package/lib/connect.js +9 -2
- package/lib/dbHelper/builders.js +46 -31
- package/lib/dbHelper/dataOps.js +16 -16
- package/lib/dbHelper/validate.js +49 -22
- package/package.json +3 -3
package/apis/dict/all.js
CHANGED
|
@@ -11,12 +11,7 @@ export default {
|
|
|
11
11
|
handler: async (befly) => {
|
|
12
12
|
const result = await befly.mysql.getAll({
|
|
13
13
|
table: "beflyDict",
|
|
14
|
-
|
|
15
|
-
{
|
|
16
|
-
table: "beflyDictType",
|
|
17
|
-
on: "beflyDict.typeCode = beflyDictType.code"
|
|
18
|
-
}
|
|
19
|
-
],
|
|
14
|
+
leftJoin: ["beflyDictType ON beflyDict.typeCode = beflyDictType.code"],
|
|
20
15
|
fields: ["beflyDict.id", "beflyDict.typeCode", "beflyDict.key", "beflyDict.label", "beflyDict.sort", "beflyDict.remark", "beflyDict.createdAt", "beflyDict.updatedAt", "beflyDictType.name AS typeName"],
|
|
21
16
|
orderBy: ["beflyDict.sort#ASC", "beflyDict.id#ASC"]
|
|
22
17
|
});
|
package/apis/dict/detail.js
CHANGED
|
@@ -10,12 +10,7 @@ export default {
|
|
|
10
10
|
handler: async (befly, ctx) => {
|
|
11
11
|
const dict = await befly.mysql.getOne({
|
|
12
12
|
table: "beflyDict",
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
table: "beflyDictType",
|
|
16
|
-
on: "beflyDict.typeCode = beflyDictType.code"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
13
|
+
leftJoin: ["beflyDictType ON beflyDict.typeCode = beflyDictType.code"],
|
|
19
14
|
fields: ["beflyDict.id", "beflyDict.typeCode", "beflyDict.key", "beflyDict.label", "beflyDict.sort", "beflyDict.remark", "beflyDict.createdAt", "beflyDict.updatedAt", "beflyDictType.name AS typeName"],
|
|
20
15
|
where: { "beflyDict.id": ctx.body.id }
|
|
21
16
|
});
|
package/apis/dict/list.js
CHANGED
|
@@ -15,12 +15,7 @@ export default {
|
|
|
15
15
|
handler: async (befly, ctx) => {
|
|
16
16
|
const result = await befly.mysql.getList({
|
|
17
17
|
table: "beflyDict",
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
table: "beflyDictType",
|
|
21
|
-
on: "beflyDict.typeCode = beflyDictType.code"
|
|
22
|
-
}
|
|
23
|
-
],
|
|
18
|
+
leftJoin: ["beflyDictType ON beflyDict.typeCode = beflyDictType.code"],
|
|
24
19
|
fields: ["beflyDict.id", "beflyDict.typeCode", "beflyDict.key", "beflyDict.label", "beflyDict.sort", "beflyDict.remark", "beflyDict.createdAt", "beflyDict.updatedAt", "beflyDictType.name AS typeName"],
|
|
25
20
|
where: {
|
|
26
21
|
"beflyDict.typeCode": ctx.body.typeCode
|
package/configs/beflyConfig.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"port": 3306,
|
|
25
25
|
"username": "root",
|
|
26
26
|
"password": "root",
|
|
27
|
-
"database": "
|
|
27
|
+
"database": "befly",
|
|
28
28
|
"max": 10,
|
|
29
29
|
"beflyMode": "auto"
|
|
30
30
|
},
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"username": "",
|
|
36
36
|
"password": "",
|
|
37
37
|
"db": 0,
|
|
38
|
-
"prefix": "
|
|
38
|
+
"prefix": "befly"
|
|
39
39
|
},
|
|
40
40
|
|
|
41
41
|
"session": {
|
package/lib/connect.js
CHANGED
|
@@ -89,9 +89,16 @@ export class Connect {
|
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
// Called when disconnected from Redis server
|
|
92
|
-
this.redisClient.onclose = () => {
|
|
93
|
-
|
|
92
|
+
this.redisClient.onclose = (error) => {
|
|
93
|
+
if (error) {
|
|
94
|
+
Logger.warn(`Redis 断开连接:${error.message ?? error}`);
|
|
95
|
+
} else {
|
|
96
|
+
Logger.warn("Redis 断开连接");
|
|
97
|
+
}
|
|
94
98
|
};
|
|
99
|
+
|
|
100
|
+
// Eagerly verify the connection before returning
|
|
101
|
+
await this.redisClient.ping();
|
|
95
102
|
} catch (error) {
|
|
96
103
|
await this.redisClient?.close();
|
|
97
104
|
this.redisClient = null;
|
package/lib/dbHelper/builders.js
CHANGED
|
@@ -349,6 +349,29 @@ export function processJoinOrderBy(orderBy) {
|
|
|
349
349
|
});
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
+
export function parseLeftJoinItem(joinItem) {
|
|
353
|
+
if (!isString(joinItem)) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const parts = joinItem.split(/\s+ON\s+/i);
|
|
358
|
+
if (parts.length !== 2) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const table = parts[0]?.trim();
|
|
363
|
+
const on = parts[1]?.trim();
|
|
364
|
+
if (!isNonEmptyString(table) || !isNonEmptyString(on)) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return {
|
|
369
|
+
type: "left",
|
|
370
|
+
table: normalizeTableRef(table),
|
|
371
|
+
on: processJoinOn(on)
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
352
375
|
export function processJoinOn(on) {
|
|
353
376
|
if (!isString(on)) {
|
|
354
377
|
return String(on);
|
|
@@ -402,7 +425,7 @@ export function processJoinOn(on) {
|
|
|
402
425
|
return result;
|
|
403
426
|
}
|
|
404
427
|
|
|
405
|
-
export function addDefaultStateFilter(where = {}, table,
|
|
428
|
+
export function addDefaultStateFilter(where = {}, table, hasLeftJoin = false, beflyMode = "auto") {
|
|
406
429
|
if (beflyMode === "manual") {
|
|
407
430
|
return where;
|
|
408
431
|
}
|
|
@@ -412,7 +435,7 @@ export function addDefaultStateFilter(where = {}, table, hasJoins = false, befly
|
|
|
412
435
|
return where;
|
|
413
436
|
}
|
|
414
437
|
|
|
415
|
-
if (
|
|
438
|
+
if (hasLeftJoin && table) {
|
|
416
439
|
const result = {};
|
|
417
440
|
for (const [key, value] of Object.entries(where)) {
|
|
418
441
|
result[key] = value;
|
|
@@ -575,7 +598,7 @@ export const builderMethods = {
|
|
|
575
598
|
|
|
576
599
|
createListBuilder(prepared, whereFiltered, limit, offset) {
|
|
577
600
|
const builder = this.createSqlBuilder().select(prepared.fields).from(prepared.table).where(whereFiltered).limit(limit);
|
|
578
|
-
this.
|
|
601
|
+
this.applyLeftJoins(builder, prepared.leftJoins);
|
|
579
602
|
if (!isNullable(offset)) {
|
|
580
603
|
builder.offset(offset);
|
|
581
604
|
}
|
|
@@ -587,7 +610,7 @@ export const builderMethods = {
|
|
|
587
610
|
|
|
588
611
|
async fetchCount(prepared, whereFiltered, alias) {
|
|
589
612
|
const builder = this.createSqlBuilder().selectRaw(alias).from(prepared.table).where(whereFiltered);
|
|
590
|
-
this.
|
|
613
|
+
this.applyLeftJoins(builder, prepared.leftJoins);
|
|
591
614
|
const result = builder.toSelectSql();
|
|
592
615
|
const executeRes = await this.execute(result.sql, result.params);
|
|
593
616
|
const countRow = executeRes.data?.[0] || null;
|
|
@@ -624,17 +647,24 @@ export const builderMethods = {
|
|
|
624
647
|
return normalizeBigIntValues(deserializedList);
|
|
625
648
|
},
|
|
626
649
|
|
|
627
|
-
|
|
650
|
+
normalizeLeftJoinOptions(options, cleanWhere) {
|
|
628
651
|
const processedFields = (options.fields || []).map((field) => processJoinField(field));
|
|
629
652
|
const normalizedTableRef = normalizeTableRef(options.table);
|
|
630
653
|
const mainQualifier = getJoinMainQualifier(options.table);
|
|
654
|
+
const leftJoins = [];
|
|
655
|
+
for (const joinItem of options.leftJoin || []) {
|
|
656
|
+
const parsedJoin = parseLeftJoinItem(joinItem);
|
|
657
|
+
if (parsedJoin) {
|
|
658
|
+
leftJoins.push(parsedJoin);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
631
661
|
|
|
632
662
|
return {
|
|
633
663
|
table: normalizedTableRef,
|
|
634
664
|
tableQualifier: mainQualifier,
|
|
635
665
|
fields: processedFields.length > 0 ? processedFields : ["*"],
|
|
636
666
|
where: processJoinWhere(cleanWhere),
|
|
637
|
-
|
|
667
|
+
leftJoins: leftJoins,
|
|
638
668
|
orderBy: processJoinOrderBy(options.orderBy || []),
|
|
639
669
|
page: options.page || 1,
|
|
640
670
|
limit: options.limit || 10
|
|
@@ -650,7 +680,7 @@ export const builderMethods = {
|
|
|
650
680
|
tableQualifier: snakeTable,
|
|
651
681
|
fields: processedFields,
|
|
652
682
|
where: whereKeysToSnake(cleanWhere),
|
|
653
|
-
|
|
683
|
+
leftJoins: undefined,
|
|
654
684
|
orderBy: orderByToSnake(options.orderBy || []),
|
|
655
685
|
page: options.page || 1,
|
|
656
686
|
limit: options.limit || 10
|
|
@@ -666,7 +696,7 @@ export const builderMethods = {
|
|
|
666
696
|
|
|
667
697
|
if (options.fields !== undefined) output.fields = options.fields;
|
|
668
698
|
if (options.where !== undefined) output.where = options.where;
|
|
669
|
-
if (options.
|
|
699
|
+
if (options.leftJoin !== undefined) output.leftJoin = options.leftJoin;
|
|
670
700
|
if (options.orderBy !== undefined) output.orderBy = options.orderBy;
|
|
671
701
|
return output;
|
|
672
702
|
},
|
|
@@ -720,35 +750,20 @@ export const builderMethods = {
|
|
|
720
750
|
async prepareQueryOptions(options, label = "queryOptions") {
|
|
721
751
|
validateQueryOptions(options, label);
|
|
722
752
|
const cleanWhere = clearDeep(options.where || {});
|
|
723
|
-
const
|
|
753
|
+
const hasLeftJoin = options.leftJoin && options.leftJoin.length > 0;
|
|
724
754
|
|
|
725
|
-
if (
|
|
726
|
-
return this.
|
|
755
|
+
if (hasLeftJoin) {
|
|
756
|
+
return this.normalizeLeftJoinOptions(options, cleanWhere);
|
|
727
757
|
}
|
|
728
758
|
|
|
729
759
|
return await this.normalizeSingleTableOptions(options, cleanWhere);
|
|
730
760
|
},
|
|
731
761
|
|
|
732
|
-
|
|
733
|
-
if (!
|
|
734
|
-
|
|
735
|
-
for (const join of
|
|
736
|
-
|
|
737
|
-
const processedOn = processJoinOn(join.on);
|
|
738
|
-
const type = join.type || "left";
|
|
739
|
-
|
|
740
|
-
switch (type) {
|
|
741
|
-
case "inner":
|
|
742
|
-
builder.innerJoin(processedTable, processedOn);
|
|
743
|
-
break;
|
|
744
|
-
case "right":
|
|
745
|
-
builder.rightJoin(processedTable, processedOn);
|
|
746
|
-
break;
|
|
747
|
-
case "left":
|
|
748
|
-
default:
|
|
749
|
-
builder.leftJoin(processedTable, processedOn);
|
|
750
|
-
break;
|
|
751
|
-
}
|
|
762
|
+
applyLeftJoins(builder, leftJoins) {
|
|
763
|
+
if (!leftJoins || leftJoins.length === 0) return;
|
|
764
|
+
|
|
765
|
+
for (const join of leftJoins) {
|
|
766
|
+
builder.leftJoin(join.table, join.on);
|
|
752
767
|
}
|
|
753
768
|
}
|
|
754
769
|
};
|
package/lib/dbHelper/dataOps.js
CHANGED
|
@@ -4,16 +4,16 @@ import { Logger } from "../logger.js";
|
|
|
4
4
|
import { SqlBuilder } from "../sqlBuilder/index.js";
|
|
5
5
|
import { normalizeSqlMetaNumber, quoteIdentMySql } from "./util.js";
|
|
6
6
|
import { addDefaultStateFilter, buildInsertRow, buildPartialUpdateData, buildUpdateRow, clearDeep, whereKeysToSnake } from "./builders.js";
|
|
7
|
-
import { assertBatchInsertRowsConsistent, assertNoUndefinedInRecord, validateGeneratedBatchId, validateIncrementOptions, validateInsertBatchSize,
|
|
7
|
+
import { assertBatchInsertRowsConsistent, assertNoUndefinedInRecord, validateGeneratedBatchId, validateIncrementOptions, validateInsertBatchSize, validateNoLeftJoinReadOptions, validatePageLimitRange, validateSafeFieldName, validateTableBatchDataOptions, validateTableDataOptions, validateTableName, validateTableWhereOptions } from "./validate.js";
|
|
8
8
|
|
|
9
9
|
export const dataOpsMethods = {
|
|
10
10
|
// 读取操作
|
|
11
11
|
async getCount(options) {
|
|
12
|
-
const { table, where,
|
|
13
|
-
const
|
|
12
|
+
const { table, where, leftJoins, tableQualifier } = await this.prepareQueryOptions(options, "getCount.options");
|
|
13
|
+
const hasLeftJoin = Array.isArray(leftJoins) && leftJoins.length > 0;
|
|
14
14
|
|
|
15
|
-
const whereFiltered = addDefaultStateFilter(where, tableQualifier,
|
|
16
|
-
const result = await this.fetchCount({ table: table,
|
|
15
|
+
const whereFiltered = addDefaultStateFilter(where, tableQualifier, hasLeftJoin, this.beflyMode);
|
|
16
|
+
const result = await this.fetchCount({ table: table, leftJoins: leftJoins }, whereFiltered, "COUNT(*) as count");
|
|
17
17
|
|
|
18
18
|
return {
|
|
19
19
|
data: result.total,
|
|
@@ -22,12 +22,12 @@ export const dataOpsMethods = {
|
|
|
22
22
|
},
|
|
23
23
|
|
|
24
24
|
async getOne(options) {
|
|
25
|
-
const { table, fields, where,
|
|
26
|
-
const
|
|
25
|
+
const { table, fields, where, leftJoins, tableQualifier } = await this.prepareQueryOptions(options, "getOne.options");
|
|
26
|
+
const hasLeftJoin = Array.isArray(leftJoins) && leftJoins.length > 0;
|
|
27
27
|
|
|
28
|
-
const whereFiltered = addDefaultStateFilter(where, tableQualifier,
|
|
28
|
+
const whereFiltered = addDefaultStateFilter(where, tableQualifier, hasLeftJoin, this.beflyMode);
|
|
29
29
|
const builder = this.createSqlBuilder().select(fields).from(table).where(whereFiltered);
|
|
30
|
-
this.
|
|
30
|
+
this.applyLeftJoins(builder, leftJoins);
|
|
31
31
|
|
|
32
32
|
const { sql, params } = builder.toSelectSql();
|
|
33
33
|
const executeRes = await this.execute(sql, params);
|
|
@@ -48,8 +48,8 @@ export const dataOpsMethods = {
|
|
|
48
48
|
const prepared = await this.prepareQueryOptions(options, "getList.options");
|
|
49
49
|
validatePageLimitRange(prepared, options.table);
|
|
50
50
|
|
|
51
|
-
const
|
|
52
|
-
const whereFiltered = addDefaultStateFilter(prepared.where, prepared.tableQualifier,
|
|
51
|
+
const hasLeftJoin = Array.isArray(prepared.leftJoins) && prepared.leftJoins.length > 0;
|
|
52
|
+
const whereFiltered = addDefaultStateFilter(prepared.where, prepared.tableQualifier, hasLeftJoin, this.beflyMode);
|
|
53
53
|
const countResult = await this.fetchCount(prepared, whereFiltered, "COUNT(*) as total");
|
|
54
54
|
const total = countResult.total;
|
|
55
55
|
|
|
@@ -100,8 +100,8 @@ export const dataOpsMethods = {
|
|
|
100
100
|
const prepareOptions = this.buildQueryOptions(options, { page: 1, limit: 10 });
|
|
101
101
|
const prepared = await this.prepareQueryOptions(prepareOptions, "getAll.options");
|
|
102
102
|
|
|
103
|
-
const
|
|
104
|
-
const whereFiltered = addDefaultStateFilter(prepared.where, prepared.tableQualifier,
|
|
103
|
+
const hasLeftJoin = Array.isArray(prepared.leftJoins) && prepared.leftJoins.length > 0;
|
|
104
|
+
const whereFiltered = addDefaultStateFilter(prepared.where, prepared.tableQualifier, hasLeftJoin, this.beflyMode);
|
|
105
105
|
const countResult = await this.fetchCount(prepared, whereFiltered, "COUNT(*) as total");
|
|
106
106
|
const total = countResult.total;
|
|
107
107
|
|
|
@@ -146,7 +146,7 @@ export const dataOpsMethods = {
|
|
|
146
146
|
},
|
|
147
147
|
|
|
148
148
|
async exists(options) {
|
|
149
|
-
|
|
149
|
+
validateNoLeftJoinReadOptions(options, "exists", "exists 不支持 leftJoin(请使用显式 query 或拆分查询)");
|
|
150
150
|
const snakeTable = snakeCase(options.table);
|
|
151
151
|
const snakeWhere = whereKeysToSnake(clearDeep(options.where || {}));
|
|
152
152
|
const whereFiltered = addDefaultStateFilter(snakeWhere, snakeTable, false, this.beflyMode);
|
|
@@ -159,7 +159,7 @@ export const dataOpsMethods = {
|
|
|
159
159
|
},
|
|
160
160
|
|
|
161
161
|
async getFieldValue(options) {
|
|
162
|
-
|
|
162
|
+
validateNoLeftJoinReadOptions(options, "getFieldValue", "getFieldValue 不支持 leftJoin(请使用 getOne/getList 并自行取字段)");
|
|
163
163
|
const field = options.field;
|
|
164
164
|
validateSafeFieldName(field);
|
|
165
165
|
|
|
@@ -167,7 +167,7 @@ export const dataOpsMethods = {
|
|
|
167
167
|
table: options.table
|
|
168
168
|
};
|
|
169
169
|
if (options.where !== undefined) oneOptions.where = options.where;
|
|
170
|
-
if (options.
|
|
170
|
+
if (options.leftJoin !== undefined) oneOptions.leftJoin = options.leftJoin;
|
|
171
171
|
if (options.orderBy !== undefined) oneOptions.orderBy = options.orderBy;
|
|
172
172
|
if (options.page !== undefined) oneOptions.page = options.page;
|
|
173
173
|
if (options.limit !== undefined) oneOptions.limit = options.limit;
|
package/lib/dbHelper/validate.js
CHANGED
|
@@ -130,34 +130,58 @@ function validateOrderByItems(orderBy, label) {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
function
|
|
134
|
-
if (!Array.isArray(
|
|
133
|
+
function validateLeftJoinItems(leftJoin, label) {
|
|
134
|
+
if (!Array.isArray(leftJoin)) {
|
|
135
135
|
throw new Error(`${label} 必须是数组`, {
|
|
136
136
|
cause: null,
|
|
137
137
|
code: "validation"
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
for (let i = 0; i <
|
|
142
|
-
const
|
|
143
|
-
if (!
|
|
144
|
-
throw new Error(`${label}[${i}]
|
|
141
|
+
for (let i = 0; i < leftJoin.length; i++) {
|
|
142
|
+
const joinItem = leftJoin[i];
|
|
143
|
+
if (!isNonEmptyString(joinItem)) {
|
|
144
|
+
throw new Error(`${label}[${i}] 必须是非空字符串`, {
|
|
145
145
|
cause: null,
|
|
146
146
|
code: "validation"
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
const parts = joinItem.split(/\s+ON\s+/i);
|
|
151
|
+
if (parts.length !== 2) {
|
|
152
|
+
throw new Error(`${label}[${i}] 必须是 "table alias ON left.field = right.field" 格式`, {
|
|
153
|
+
cause: null,
|
|
154
|
+
code: "validation"
|
|
155
|
+
});
|
|
156
|
+
}
|
|
152
157
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
const tableRef = parts[0]?.trim();
|
|
159
|
+
const on = parts[1]?.trim();
|
|
160
|
+
if (!isNonEmptyString(tableRef)) {
|
|
161
|
+
throw new Error(`${label}[${i}] 缺少 leftJoin 表名`, {
|
|
162
|
+
cause: null,
|
|
163
|
+
code: "validation"
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (!isNonEmptyString(on)) {
|
|
167
|
+
throw new Error(`${label}[${i}] 缺少 leftJoin 的 ON 条件`, {
|
|
168
|
+
cause: null,
|
|
169
|
+
code: "validation"
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
parseTableRef(tableRef);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function validateLegacyJoinOptions(options, label) {
|
|
178
|
+
const legacyJoinKeys = ["joins", "innerJoin", "rightJoin"];
|
|
179
|
+
for (const key of legacyJoinKeys) {
|
|
180
|
+
if (!isNullable(options[key])) {
|
|
181
|
+
throw new Error(`${label} 仅支持 leftJoin,${label}.${key} 已废弃`, {
|
|
182
|
+
cause: null,
|
|
183
|
+
code: "validation"
|
|
184
|
+
});
|
|
161
185
|
}
|
|
162
186
|
}
|
|
163
187
|
}
|
|
@@ -187,8 +211,10 @@ export function validateQueryOptions(options, label) {
|
|
|
187
211
|
validateOrderByItems(options.orderBy, `${label}.orderBy`);
|
|
188
212
|
}
|
|
189
213
|
|
|
190
|
-
|
|
191
|
-
|
|
214
|
+
validateLegacyJoinOptions(options, label);
|
|
215
|
+
|
|
216
|
+
if (!isNullable(options.leftJoin)) {
|
|
217
|
+
validateLeftJoinItems(options.leftJoin, `${label}.leftJoin`);
|
|
192
218
|
}
|
|
193
219
|
|
|
194
220
|
if (!isNullable(options.page) && (!isFiniteNumber(options.page) || Math.floor(options.page) !== options.page)) {
|
|
@@ -247,9 +273,10 @@ export function validateTableBatchDataOptions(table, dataList, label) {
|
|
|
247
273
|
validateBatchDataList(dataList, `${label}.dataList`);
|
|
248
274
|
}
|
|
249
275
|
|
|
250
|
-
export function
|
|
276
|
+
export function validateNoLeftJoinReadOptions(options, label, joinErrorMessage) {
|
|
251
277
|
validateTableWhereOptions(options, label, false);
|
|
252
|
-
|
|
278
|
+
validateNoLeftJoin(options.leftJoin, joinErrorMessage);
|
|
279
|
+
validateLegacyJoinOptions(options, label);
|
|
253
280
|
validateSimpleTableName(options.table, label);
|
|
254
281
|
}
|
|
255
282
|
|
|
@@ -306,8 +333,8 @@ export function validatePageLimitRange(prepared, rawTable) {
|
|
|
306
333
|
}
|
|
307
334
|
}
|
|
308
335
|
|
|
309
|
-
export function
|
|
310
|
-
if (Array.isArray(
|
|
336
|
+
export function validateNoLeftJoin(leftJoin, message) {
|
|
337
|
+
if (Array.isArray(leftJoin) && leftJoin.length > 0) {
|
|
311
338
|
throw new Error(message, {
|
|
312
339
|
cause: null,
|
|
313
340
|
code: "validation"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly",
|
|
3
|
-
"version": "3.20.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "3.20.6",
|
|
4
|
+
"gitHead": "fc0f4f7193f9e234c87732cd7fc0b3b53591cee5",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
|
|
7
7
|
"keywords": [
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"test": "bun test"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"fast-xml-parser": "^5.5.
|
|
55
|
+
"fast-xml-parser": "^5.5.7",
|
|
56
56
|
"nodemailer": "^8.0.2",
|
|
57
57
|
"pathe": "^2.0.3",
|
|
58
58
|
"ua-parser-js": "^2.0.9",
|