befly 3.20.0 → 3.20.1

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/lib/connect.js CHANGED
@@ -42,7 +42,8 @@ export class Connect {
42
42
  database: config.database,
43
43
  username: config.username,
44
44
  password: config.password,
45
- max: config.max
45
+ max: config.max,
46
+ bigint: true
46
47
  };
47
48
 
48
49
  this.mysqlClient = new SQL(sqlConfig);
@@ -2,7 +2,7 @@ import { fieldClear } from "../../utils/fieldClear.js";
2
2
  import { isFiniteNumber, isNonEmptyString, isNullable, isPlainObject, isString } from "../../utils/is.js";
3
3
  import { arrayKeysToCamel, keysToCamel, keysToSnake, snakeCase } from "../../utils/util.js";
4
4
  import { SqlBuilder } from "../sqlBuilder/index.js";
5
- import { convertBigIntFields, getJoinMainQualifier, normalizeTableRef, quoteIdentMySql } from "./util.js";
5
+ import { getJoinMainQualifier, normalizeBigIntValues, normalizeTableRef, quoteIdentMySql } from "./util.js";
6
6
  import { assertNoExprField, validateAndClassifyFields, validateExcludeFieldsResult, validateQueryOptions, validateTimeIdValue } from "./validate.js";
7
7
 
8
8
  export function clearDeep(value, options) {
@@ -542,14 +542,16 @@ export const builderMethods = {
542
542
  this.applyJoins(builder, prepared.joins);
543
543
  const result = builder.toSelectSql();
544
544
  const executeRes = await this.execute(result.sql, result.params);
545
- const total = executeRes.data?.[0]?.total || executeRes.data?.[0]?.count || 0;
545
+ const countRow = executeRes.data?.[0] || null;
546
+ const normalizedCountRow = countRow ? normalizeBigIntValues(countRow) : null;
547
+ const total = normalizedCountRow?.total ?? normalizedCountRow?.count ?? 0;
546
548
  return {
547
549
  total: total,
548
550
  sql: executeRes.sql
549
551
  };
550
552
  },
551
553
 
552
- normalizeRowData(row, bigintFields) {
554
+ normalizeRowData(row) {
553
555
  if (!row) {
554
556
  return {};
555
557
  }
@@ -560,7 +562,7 @@ export const builderMethods = {
560
562
  return {};
561
563
  }
562
564
 
563
- const convertedList = convertBigIntFields([deserialized], bigintFields);
565
+ const convertedList = normalizeBigIntValues([deserialized]);
564
566
  if (convertedList && convertedList.length > 0) {
565
567
  return convertedList[0];
566
568
  }
@@ -568,10 +570,10 @@ export const builderMethods = {
568
570
  return deserialized;
569
571
  },
570
572
 
571
- normalizeListData(list, bigintFields) {
573
+ normalizeListData(list) {
572
574
  const camelList = arrayKeysToCamel(list);
573
575
  const deserializedList = camelList.map((item) => deserializeArrayFields(item)).filter((item) => item !== null);
574
- return convertBigIntFields(deserializedList, bigintFields);
576
+ return normalizeBigIntValues(deserializedList);
575
577
  },
576
578
 
577
579
  normalizeJoinOptions(options, cleanWhere) {
@@ -615,7 +617,6 @@ export const builderMethods = {
615
617
  };
616
618
 
617
619
  if (options.fields !== undefined) output.fields = options.fields;
618
- if (options.bigint !== undefined) output.bigint = options.bigint;
619
620
  if (options.where !== undefined) output.where = options.where;
620
621
  if (options.joins !== undefined) output.joins = options.joins;
621
622
  if (options.orderBy !== undefined) output.orderBy = options.orderBy;
@@ -2,7 +2,7 @@ import { isNumber } from "../../utils/is.js";
2
2
  import { snakeCase } from "../../utils/util.js";
3
3
  import { Logger } from "../logger.js";
4
4
  import { SqlBuilder } from "../sqlBuilder/index.js";
5
- import { quoteIdentMySql, toNumberFromSql } from "./util.js";
5
+ import { normalizeSqlMetaNumber, quoteIdentMySql } from "./util.js";
6
6
  import { addDefaultStateFilter, buildInsertRow, buildPartialUpdateData, buildUpdateRow, clearDeep, whereKeysToSnake } from "./builders.js";
7
7
  import { assertBatchInsertRowsConsistent, assertNoUndefinedInRecord, validateGeneratedBatchId, validateIncrementOptions, validateInsertBatchSize, validateNoJoinReadOptions, validatePageLimitRange, validateSafeFieldName, validateTableBatchDataOptions, validateTableDataOptions, validateTableName, validateTableWhereOptions } from "./validate.js";
8
8
 
@@ -33,7 +33,7 @@ export const dataOpsMethods = {
33
33
  const executeRes = await this.execute(sql, params);
34
34
  const result = executeRes.data;
35
35
 
36
- const data = this.normalizeRowData(result?.[0] || null, options.bigint);
36
+ const data = this.normalizeRowData(result?.[0] || null);
37
37
  return {
38
38
  data: data,
39
39
  sql: executeRes.sql
@@ -81,7 +81,7 @@ export const dataOpsMethods = {
81
81
 
82
82
  return {
83
83
  data: {
84
- lists: this.normalizeListData(list, options.bigint),
84
+ lists: this.normalizeListData(list),
85
85
  total: total,
86
86
  page: prepared.page,
87
87
  limit: prepared.limit,
@@ -131,7 +131,7 @@ export const dataOpsMethods = {
131
131
  Logger.warn(`getAll 达到最大限制 ${MAX_LIMIT},实际总数 ${total},只返回前 ${MAX_LIMIT} 条`, { table: options.table, limit: MAX_LIMIT, total: total });
132
132
  }
133
133
 
134
- const lists = this.normalizeListData(result, options.bigint);
134
+ const lists = this.normalizeListData(result);
135
135
 
136
136
  return {
137
137
  data: {
@@ -227,7 +227,7 @@ export const dataOpsMethods = {
227
227
 
228
228
  const processedId = processed["id"];
229
229
  const processedIdNum = isNumber(processedId) ? processedId : 0;
230
- const lastInsertRowidNum = toNumberFromSql(executeRes.data?.lastInsertRowid);
230
+ const lastInsertRowidNum = normalizeSqlMetaNumber(executeRes.data?.lastInsertRowid);
231
231
 
232
232
  const insertedId = this.beflyMode === "manual" ? lastInsertRowidNum || 0 : processedIdNum || lastInsertRowidNum || 0;
233
233
  if (this.beflyMode === "manual" && insertedId <= 0) {
@@ -284,7 +284,7 @@ export const dataOpsMethods = {
284
284
  const executeRes = await this.execute(sql, params);
285
285
 
286
286
  if (this.beflyMode === "manual") {
287
- const firstId = toNumberFromSql(executeRes.data?.lastInsertRowid);
287
+ const firstId = normalizeSqlMetaNumber(executeRes.data?.lastInsertRowid);
288
288
  if (firstId <= 0) {
289
289
  throw new Error(`批量插入失败:beflyMode=manual 时无法获取 lastInsertRowid (table: ${table})`, {
290
290
  cause: null,
@@ -345,7 +345,7 @@ export const dataOpsMethods = {
345
345
  quoteIdent: quoteIdentMySql
346
346
  });
347
347
  const executeRes = await this.execute(query.sql, query.params);
348
- const changes = toNumberFromSql(executeRes.data?.changes);
348
+ const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
349
349
  return {
350
350
  data: changes,
351
351
  sql: executeRes.sql
@@ -398,7 +398,7 @@ export const dataOpsMethods = {
398
398
  });
399
399
 
400
400
  const executeRes = await this.execute(query.sql, query.params);
401
- const changes = toNumberFromSql(executeRes.data?.changes);
401
+ const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
402
402
  return {
403
403
  data: changes,
404
404
  sql: executeRes.sql
@@ -418,7 +418,7 @@ export const dataOpsMethods = {
418
418
  const { sql, params } = builder.toUpdateSql(snakeTable, processed);
419
419
 
420
420
  const executeRes = await this.execute(sql, params);
421
- const changes = toNumberFromSql(executeRes.data?.changes);
421
+ const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
422
422
  return {
423
423
  data: changes,
424
424
  sql: executeRes.sql
@@ -428,20 +428,28 @@ export const dataOpsMethods = {
428
428
  async delData(options) {
429
429
  validateTableWhereOptions(options, "delData", true);
430
430
  const { table, where } = options;
431
+ const snakeTable = snakeCase(table);
432
+ const snakeWhere = whereKeysToSnake(clearDeep(where));
433
+ const now = Date.now();
434
+ const processed = {
435
+ state: 0,
436
+ deleted_at: now
437
+ };
431
438
 
432
- // beflyMode=manual:关闭默认 state 软删语义,delData 直接走物理删除
433
- if (this.beflyMode === "manual") {
434
- return await this.delForce({
435
- table: table,
436
- where: where
437
- });
439
+ if (this.beflyMode === "auto") {
440
+ processed.updated_at = now;
438
441
  }
439
442
 
440
- return await this.updData({
441
- table: table,
442
- data: { state: 0, deleted_at: Date.now() },
443
- where: where
444
- });
443
+ const whereFiltered = addDefaultStateFilter(snakeWhere, snakeTable, false, this.beflyMode);
444
+ const builder = this.createSqlBuilder().where(whereFiltered);
445
+ const { sql, params } = builder.toUpdateSql(snakeTable, processed);
446
+ const executeRes = await this.execute(sql, params);
447
+ const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
448
+
449
+ return {
450
+ data: changes,
451
+ sql: executeRes.sql
452
+ };
445
453
  },
446
454
 
447
455
  async delForce(options) {
@@ -455,7 +463,7 @@ export const dataOpsMethods = {
455
463
  const { sql, params } = builder.toDeleteSql(snakeTable);
456
464
 
457
465
  const executeRes = await this.execute(sql, params);
458
- const changes = toNumberFromSql(executeRes.data?.changes);
466
+ const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
459
467
  return {
460
468
  data: changes,
461
469
  sql: executeRes.sql
@@ -508,7 +516,7 @@ export const dataOpsMethods = {
508
516
  }
509
517
 
510
518
  const executeRes = await this.execute(sql, params);
511
- const changes = toNumberFromSql(executeRes.data?.changes);
519
+ const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
512
520
  return {
513
521
  data: changes,
514
522
  sql: executeRes.sql
@@ -1,4 +1,4 @@
1
- import { isNonEmptyString, isNullable, isString } from "../../utils/is.js";
1
+ import { isNullable, isString } from "../../utils/is.js";
2
2
  import { canConvertToNumber, snakeCase } from "../../utils/util.js";
3
3
  import { parseTableRef } from "./validate.js";
4
4
 
@@ -41,101 +41,39 @@ export function getJoinMainQualifier(tableRef) {
41
41
  return snakeCase(parsed.table);
42
42
  }
43
43
 
44
- export function toNumberFromSql(value) {
44
+ export function normalizeSqlMetaNumber(value) {
45
45
  if (isNullable(value)) {
46
46
  return 0;
47
47
  }
48
48
 
49
- if (typeof value === "number") {
50
- if (!Number.isFinite(value)) {
51
- return 0;
52
- }
53
- return value;
54
- }
55
-
56
- if (typeof value === "bigint") {
57
- const maxSafe = BigInt(Number.MAX_SAFE_INTEGER);
58
- const minSafe = BigInt(Number.MIN_SAFE_INTEGER);
59
- if (value <= maxSafe && value >= minSafe) {
60
- return Number(value);
61
- }
49
+ if (typeof value !== "number") {
62
50
  return 0;
63
51
  }
64
52
 
65
- if (typeof value === "string") {
66
- if (!value.trim()) {
67
- return 0;
68
- }
69
- const parsed = Number(value);
70
- if (!Number.isFinite(parsed)) {
71
- return 0;
72
- }
73
- return parsed;
53
+ if (!Number.isFinite(value)) {
54
+ return 0;
74
55
  }
75
56
 
76
- return 0;
57
+ return value;
77
58
  }
78
59
 
79
- export function convertBigIntFields(arr, fields) {
60
+ export function normalizeBigIntValues(arr) {
80
61
  if (isNullable(arr)) {
81
62
  return arr;
82
63
  }
83
64
 
84
- const defaultFields = ["id", "pid", "sort"];
85
-
86
- const buildFields = (userFields) => {
87
- if (!userFields || userFields.length === 0) {
88
- return defaultFields;
89
- }
90
-
91
- const merged = ["id", "pid", "sort"];
92
- for (const f of userFields) {
93
- if (!isString(f)) {
94
- continue;
95
- }
96
- if (!isNonEmptyString(f)) {
97
- continue;
98
- }
99
- const trimmed = f.trim();
100
- if (!merged.includes(trimmed)) {
101
- merged.push(trimmed);
102
- }
103
- }
104
- return merged;
105
- };
106
-
107
- const effectiveFields = buildFields(fields);
108
- const fieldSet = new Set(effectiveFields);
109
-
110
65
  const convertRecord = (source) => {
111
66
  const converted = {};
112
67
 
113
68
  for (const [key, value] of Object.entries(source)) {
114
69
  let nextValue = value;
115
70
 
116
- if (!isNullable(value)) {
117
- const shouldConvert = fieldSet.has(key) || key.endsWith("Id") || key.endsWith("_id") || key.endsWith("At") || key.endsWith("_at");
118
-
119
- if (shouldConvert) {
120
- let bigintValue = null;
121
- if (typeof value === "bigint") {
122
- bigintValue = value;
123
- } else if (isString(value)) {
124
- if (/^-?\d+$/.test(value)) {
125
- try {
126
- bigintValue = BigInt(value);
127
- } catch {
128
- bigintValue = null;
129
- }
130
- }
131
- }
132
-
133
- if (bigintValue !== null) {
134
- const convertedNumber = canConvertToNumber(bigintValue);
135
- if (convertedNumber !== null) {
136
- nextValue = convertedNumber;
137
- }
138
- }
71
+ if (typeof value === "bigint") {
72
+ const convertedNumber = canConvertToNumber(value);
73
+ if (convertedNumber !== null) {
74
+ nextValue = convertedNumber;
75
+ } else {
76
+ nextValue = String(value);
139
77
  }
140
78
  }
141
79
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.20.0",
4
- "gitHead": "218c4ffe07983e46bbb85f9e0a626a6b3b38c179",
3
+ "version": "3.20.1",
4
+ "gitHead": "8563274caa09eace7480d14da3552aec0ca24296",
5
5
  "private": false,
6
6
  "description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
7
7
  "keywords": [