befly 3.16.1 → 3.16.4

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/befly.js CHANGED
@@ -504,10 +504,8 @@ import { createWriteStream, existsSync, mkdirSync } from "fs";
504
504
  import { stat } from "fs/promises";
505
505
  import { hostname as osHostname } from "os";
506
506
  import { isAbsolute as nodePathIsAbsolute, join as nodePathJoin, resolve as nodePathResolve } from "path";
507
- function buildSanitizeOptionsForWrite(writeOptions) {
508
- if (!writeOptions)
509
- return sanitizeOptions;
510
- if (writeOptions.truncate !== false)
507
+ function buildSanitizeOptionsForWriteOptions(writeOptions) {
508
+ if (!writeOptions || writeOptions.truncate !== false)
511
509
  return sanitizeOptions;
512
510
  return {
513
511
  maxStringLen: 200000,
@@ -809,8 +807,6 @@ async function flush() {
809
807
  async function shutdown() {
810
808
  if (mockInstance)
811
809
  return;
812
- const currentInstance = instance;
813
- const currentErrorInstance = errorInstance;
814
810
  const currentAppFileSink = appFileSink;
815
811
  const currentErrorFileSink = errorFileSink;
816
812
  const currentAppConsoleSink = appConsoleSink;
@@ -835,12 +831,6 @@ async function shutdown() {
835
831
  if (appConsoleSink === currentAppConsoleSink) {
836
832
  appConsoleSink = null;
837
833
  }
838
- if (instance === currentInstance) {
839
- instance = null;
840
- }
841
- if (errorInstance === currentErrorInstance) {
842
- errorInstance = null;
843
- }
844
834
  }
845
835
  function resolveLogDir() {
846
836
  const rawDir = config.dir || "./logs";
@@ -876,8 +866,6 @@ function configure(cfg) {
876
866
  mb = 100;
877
867
  config.maxSize = mb;
878
868
  }
879
- instance = null;
880
- errorInstance = null;
881
869
  appFileSink = null;
882
870
  errorFileSink = null;
883
871
  appConsoleSink = null;
@@ -893,35 +881,6 @@ function configure(cfg) {
893
881
  function setMockLogger(mock) {
894
882
  mockInstance = mock;
895
883
  }
896
- function getSink(kind) {
897
- if (mockInstance)
898
- return mockInstance;
899
- if (kind === "app") {
900
- if (instance)
901
- return instance;
902
- } else {
903
- if (errorInstance)
904
- return errorInstance;
905
- }
906
- ensureLogDirExists();
907
- const maxSizeMb = typeof config.maxSize === "number" ? config.maxSize : 20;
908
- const maxFileBytes = Math.floor(maxSizeMb * 1024 * 1024);
909
- if (kind === "app") {
910
- if (!appFileSink) {
911
- appFileSink = new LogFileSink({ prefix: "app", maxFileBytes });
912
- }
913
- if (config.console === 1 && !appConsoleSink) {
914
- appConsoleSink = createStreamSink("stdout");
915
- }
916
- instance = createSinkLogger({ fileSink: appFileSink, consoleSink: config.console === 1 ? appConsoleSink : null });
917
- return instance;
918
- }
919
- if (!errorFileSink) {
920
- errorFileSink = new LogFileSink({ prefix: "error", maxFileBytes });
921
- }
922
- errorInstance = createSinkLogger({ fileSink: errorFileSink, consoleSink: null });
923
- return errorInstance;
924
- }
925
884
  function buildBaseFields(level, timeMs) {
926
885
  const base = {
927
886
  level,
@@ -978,46 +937,39 @@ function safeJsonStringify(obj) {
978
937
  }
979
938
  }
980
939
  }
981
- function createSinkLogger(options) {
982
- const fileSink = options.fileSink;
983
- const consoleSink = options.consoleSink;
984
- const write = (level, record) => {
985
- if (level === "debug" && config.debug !== 1)
986
- return;
987
- const time = Date.now();
988
- const base = buildBaseFields(level, time);
989
- const input = isPlainObject(record) ? record : { value: record };
990
- let writeOptions = null;
991
- if (input && typeof input === "object") {
992
- writeOptions = recordWriteOptions.get(input) ?? null;
993
- if (writeOptions) {
994
- recordWriteOptions.delete(input);
995
- }
940
+ function ensureSinksReady(kind) {
941
+ ensureLogDirExists();
942
+ const maxSizeMb = typeof config.maxSize === "number" ? config.maxSize : 20;
943
+ const maxFileBytes = Math.floor(maxSizeMb * 1024 * 1024);
944
+ if (kind === "app") {
945
+ if (!appFileSink) {
946
+ appFileSink = new LogFileSink({ prefix: "app", maxFileBytes });
996
947
  }
997
- const effectiveSanitizeOptions = buildSanitizeOptionsForWrite(writeOptions);
998
- const sanitizedRecord = sanitizeLogObject(input, effectiveSanitizeOptions);
999
- const fileLine = buildLogLineWithBase(base, sanitizedRecord);
1000
- fileSink.enqueue(fileLine);
1001
- if (consoleSink) {
1002
- if (!writeOptions || writeOptions.console !== false) {
1003
- consoleSink.enqueue(fileLine);
1004
- }
948
+ if (config.console === 1 && !appConsoleSink) {
949
+ appConsoleSink = createStreamSink("stdout");
1005
950
  }
1006
- };
1007
- return {
1008
- info(record) {
1009
- write("info", record);
1010
- },
1011
- warn(record) {
1012
- write("warn", record);
1013
- },
1014
- error(record) {
1015
- write("error", record);
1016
- },
1017
- debug(record) {
1018
- write("debug", record);
951
+ return { fileSink: appFileSink, consoleSink: config.console === 1 ? appConsoleSink : null };
952
+ }
953
+ if (!errorFileSink) {
954
+ errorFileSink = new LogFileSink({ prefix: "error", maxFileBytes });
955
+ }
956
+ return { fileSink: errorFileSink, consoleSink: null };
957
+ }
958
+ function writeJsonl(kind, level, record, options) {
959
+ if (level === "debug" && config.debug !== 1)
960
+ return;
961
+ const sinks = ensureSinksReady(kind);
962
+ const time = Date.now();
963
+ const base = buildBaseFields(level, time);
964
+ const effectiveSanitizeOptions = buildSanitizeOptionsForWriteOptions(options);
965
+ const sanitizedRecord = sanitizeLogObject(record, effectiveSanitizeOptions);
966
+ const fileLine = buildLogLineWithBase(base, sanitizedRecord);
967
+ sinks.fileSink.enqueue(fileLine);
968
+ if (sinks.consoleSink) {
969
+ if (!options || options.console !== false) {
970
+ sinks.consoleSink.enqueue(fileLine);
1019
971
  }
1020
- };
972
+ }
1021
973
  }
1022
974
  function metaToObject() {
1023
975
  const meta = getCtx();
@@ -1080,48 +1032,59 @@ function withRequestMetaRecord(record) {
1080
1032
  }
1081
1033
 
1082
1034
  class LoggerFacade {
1083
- maybeSanitizeForMock(record, options) {
1084
- if (!mockInstance)
1085
- return record;
1086
- const effective = buildSanitizeOptionsForWrite(options ? options : null);
1087
- return sanitizeLogObject(record, effective);
1088
- }
1089
- info(input, options) {
1035
+ write(level, input, options) {
1036
+ if (level === "debug" && config.debug !== 1)
1037
+ return;
1090
1038
  const record0 = withRequestMetaRecord(toRecord(input));
1091
- if (!mockInstance && options && isPlainObject(record0)) {
1092
- recordWriteOptions.set(record0, options);
1039
+ if (mockInstance) {
1040
+ const effective = buildSanitizeOptionsForWriteOptions(options);
1041
+ const sanitized = sanitizeLogObject(record0, effective);
1042
+ if (level === "info") {
1043
+ mockInstance.info(sanitized);
1044
+ } else if (level === "warn") {
1045
+ mockInstance.warn(sanitized);
1046
+ } else if (level === "error") {
1047
+ mockInstance.error(sanitized);
1048
+ } else {
1049
+ mockInstance.debug(sanitized);
1050
+ }
1051
+ return;
1093
1052
  }
1094
- const record = this.maybeSanitizeForMock(record0, options);
1095
- getSink("app").info(record);
1053
+ writeJsonl("app", level, record0, options);
1054
+ if (level === "error") {
1055
+ writeJsonl("error", "error", record0, options);
1056
+ }
1057
+ }
1058
+ info(input, options) {
1059
+ this.write("info", input, options);
1096
1060
  }
1097
1061
  warn(input, options) {
1098
- const record0 = withRequestMetaRecord(toRecord(input));
1099
- if (!mockInstance && options && isPlainObject(record0)) {
1100
- recordWriteOptions.set(record0, options);
1101
- }
1102
- const record = this.maybeSanitizeForMock(record0, options);
1103
- getSink("app").warn(record);
1062
+ this.write("warn", input, options);
1104
1063
  }
1105
1064
  error(input, options) {
1106
- const record0 = withRequestMetaRecord(toRecord(input));
1107
- if (!mockInstance && options && isPlainObject(record0)) {
1108
- recordWriteOptions.set(record0, options);
1109
- }
1110
- const record = this.maybeSanitizeForMock(record0, options);
1111
- getSink("app").error(record);
1112
- if (mockInstance)
1113
- return;
1114
- getSink("error").error(record);
1065
+ this.write("error", input, options);
1115
1066
  }
1116
1067
  debug(input, options) {
1117
- if (config.debug !== 1)
1118
- return;
1119
- const record0 = withRequestMetaRecord(toRecord(input));
1120
- if (!mockInstance && options && isPlainObject(record0)) {
1121
- recordWriteOptions.set(record0, options);
1122
- }
1123
- const record = this.maybeSanitizeForMock(record0, options);
1124
- getSink("app").debug(record);
1068
+ this.write("debug", input, options);
1069
+ }
1070
+ printPlainLines(input, options) {
1071
+ const kind = options && options.stream === "stderr" ? "stderr" : "stdout";
1072
+ const stream = kind === "stderr" ? process.stderr : process.stdout;
1073
+ try {
1074
+ if (Array.isArray(input)) {
1075
+ for (const line of input) {
1076
+ stream.write(`${String(line)}
1077
+ `);
1078
+ }
1079
+ return;
1080
+ }
1081
+ const parts = String(input).split(`
1082
+ `);
1083
+ for (let i = 0;i < parts.length; i = i + 1) {
1084
+ stream.write(`${parts[i]}
1085
+ `);
1086
+ }
1087
+ } catch {}
1125
1088
  }
1126
1089
  async flush() {
1127
1090
  await flush();
@@ -1136,7 +1099,7 @@ class LoggerFacade {
1136
1099
  await shutdown();
1137
1100
  }
1138
1101
  }
1139
- var INITIAL_CWD, BUILTIN_SENSITIVE_KEYS, sanitizeOptions, recordWriteOptions, HOSTNAME, instance = null, errorInstance = null, mockInstance = null, appFileSink = null, errorFileSink = null, appConsoleSink = null, config, Logger;
1102
+ var INITIAL_CWD, BUILTIN_SENSITIVE_KEYS, sanitizeOptions, HOSTNAME, mockInstance = null, appFileSink = null, errorFileSink = null, appConsoleSink = null, config, Logger;
1140
1103
  var init_logger = __esm(() => {
1141
1104
  init_loggerUtils();
1142
1105
  init_util();
@@ -1151,7 +1114,6 @@ var init_logger = __esm(() => {
1151
1114
  sanitizeObjectKeys: 500,
1152
1115
  sensitiveKeyMatcher: buildSensitiveKeyMatcher({ builtinPatterns: BUILTIN_SENSITIVE_KEYS, userPatterns: [] })
1153
1116
  };
1154
- recordWriteOptions = new WeakMap;
1155
1117
  HOSTNAME = (() => {
1156
1118
  try {
1157
1119
  return osHostname();
@@ -1443,7 +1405,7 @@ function normalizeViewDirMeta(input) {
1443
1405
  return null;
1444
1406
  }
1445
1407
  const orderRaw = record["order"];
1446
- const order = typeof orderRaw === "number" && Number.isFinite(orderRaw) && Number.isInteger(orderRaw) && orderRaw >= 0 ? orderRaw : undefined;
1408
+ const order = typeof orderRaw === "number" && Number.isFinite(orderRaw) && Number.isInteger(orderRaw) && orderRaw >= 1 ? orderRaw : undefined;
1447
1409
  if (order === undefined) {
1448
1410
  return {
1449
1411
  title
@@ -10707,6 +10669,7 @@ class SyncTable {
10707
10669
  }
10708
10670
  }
10709
10671
  SyncTable.throwIfIncompatibleTypeChanges(incompatibleTypeChanges);
10672
+ const createdTables = [];
10710
10673
  for (const task of tableTasks) {
10711
10674
  const item = task.item;
10712
10675
  const tableName = task.tableName;
@@ -10746,6 +10709,7 @@ class SyncTable {
10746
10709
  }
10747
10710
  } else {
10748
10711
  await SyncTable.createTable(this.db, tableName, tableFields);
10712
+ createdTables.push(tableName);
10749
10713
  }
10750
10714
  } catch (error) {
10751
10715
  const errMsg = String(error?.message || error);
@@ -10768,6 +10732,17 @@ class SyncTable {
10768
10732
  throw error;
10769
10733
  }
10770
10734
  }
10735
+ if (createdTables.length > 0) {
10736
+ const lines = [];
10737
+ lines.push(`\u521B\u5EFA\u8868\u5217\u8868\uFF08\u5171${createdTables.length}\u5F20\uFF09:`);
10738
+ for (const tableName of createdTables) {
10739
+ lines.push(`- ${tableName}`);
10740
+ }
10741
+ const text = lines.join(`
10742
+ `);
10743
+ Logger.debug(text, { truncate: false, console: false });
10744
+ Logger.printPlainLines(text, { stream: "stdout" });
10745
+ }
10771
10746
  } catch (error) {
10772
10747
  if (error?.__syncTableLogged === true) {
10773
10748
  throw error;
@@ -11448,7 +11423,6 @@ SQL: ${sqlLine}
11448
11423
  ${cols}
11449
11424
  ) ENGINE=${ENGINE} DEFAULT CHARSET=${CHARSET} COLLATE=${COLLATE}`;
11450
11425
  await db.unsafe(createSQL);
11451
- Logger.debug(`[\u8868 ${tableName}] + \u521B\u5EFA\u8868\uFF08\u7CFB\u7EDF\u5B57\u6BB5 + \u4E1A\u52A1\u5B57\u6BB5\uFF09`);
11452
11426
  const indexClauses = [];
11453
11427
  for (const sysField of systemIndexFields) {
11454
11428
  const indexName = `idx_${sysField}`;
@@ -13998,6 +13972,9 @@ function convertBigIntFields(arr, fields = ["id", "pid", "sort"]) {
13998
13972
  return arr;
13999
13973
  }
14000
13974
 
13975
+ // lib/dbHelper.ts
13976
+ init_util();
13977
+
14001
13978
  // utils/fieldClear.ts
14002
13979
  function isObject(val) {
14003
13980
  return val !== null && typeof val === "object" && !Array.isArray(val);
@@ -14048,9 +14025,6 @@ function fieldClear(data, options = {}) {
14048
14025
  return data;
14049
14026
  }
14050
14027
 
14051
- // lib/dbHelper.ts
14052
- init_util();
14053
-
14054
14028
  // lib/dbUtils.ts
14055
14029
  init_util();
14056
14030
 
@@ -14163,6 +14137,73 @@ class SqlCheck {
14163
14137
 
14164
14138
  // lib/dbUtils.ts
14165
14139
  class DbUtils {
14140
+ static clearDeep(value, options) {
14141
+ const arrayObjectKeys = Array.isArray(options?.arrayObjectKeys) ? options.arrayObjectKeys : ["$or", "$and"];
14142
+ const arrayObjectKeySet = new Set;
14143
+ for (const key of arrayObjectKeys) {
14144
+ arrayObjectKeySet.add(key);
14145
+ }
14146
+ const depthRaw = typeof options?.depth === "number" && Number.isFinite(options.depth) ? Math.floor(options.depth) : 0;
14147
+ const depth = depthRaw < 0 ? 0 : depthRaw;
14148
+ const clearInternal = (input, remainingDepth) => {
14149
+ if (!input || typeof input !== "object") {
14150
+ return input;
14151
+ }
14152
+ if (Array.isArray(input)) {
14153
+ return input;
14154
+ }
14155
+ const canRecurse = remainingDepth === 0 || remainingDepth > 1;
14156
+ const childDepth = remainingDepth === 0 ? 0 : remainingDepth - 1;
14157
+ const result = {};
14158
+ for (const [key, item] of Object.entries(input)) {
14159
+ if (item === undefined || item === null) {
14160
+ continue;
14161
+ }
14162
+ if (arrayObjectKeySet.has(key)) {
14163
+ if (!Array.isArray(item)) {
14164
+ continue;
14165
+ }
14166
+ const arrayChildDepth = remainingDepth;
14167
+ const outList = [];
14168
+ for (const child of item) {
14169
+ if (!child || typeof child !== "object" || Array.isArray(child)) {
14170
+ continue;
14171
+ }
14172
+ const cleaned = clearInternal(child, arrayChildDepth);
14173
+ if (!cleaned || typeof cleaned !== "object" || Array.isArray(cleaned)) {
14174
+ continue;
14175
+ }
14176
+ if (Object.keys(cleaned).length === 0) {
14177
+ continue;
14178
+ }
14179
+ outList.push(cleaned);
14180
+ }
14181
+ if (outList.length > 0) {
14182
+ result[key] = outList;
14183
+ }
14184
+ continue;
14185
+ }
14186
+ if (typeof item === "object" && !Array.isArray(item)) {
14187
+ if (!canRecurse) {
14188
+ result[key] = item;
14189
+ continue;
14190
+ }
14191
+ const cleanedObj = clearInternal(item, childDepth);
14192
+ if (!cleanedObj || typeof cleanedObj !== "object" || Array.isArray(cleanedObj)) {
14193
+ continue;
14194
+ }
14195
+ if (Object.keys(cleanedObj).length === 0) {
14196
+ continue;
14197
+ }
14198
+ result[key] = cleanedObj;
14199
+ continue;
14200
+ }
14201
+ result[key] = item;
14202
+ }
14203
+ return result;
14204
+ };
14205
+ return clearInternal(value, depth);
14206
+ }
14166
14207
  static parseTableRef(tableRef) {
14167
14208
  if (typeof tableRef !== "string") {
14168
14209
  throw new Error(`tableRef \u5FC5\u987B\u662F\u5B57\u7B26\u4E32 (tableRef: ${String(tableRef)})`);
@@ -15339,7 +15380,7 @@ class DbHelper {
15339
15380
  return columnNames;
15340
15381
  }
15341
15382
  async prepareQueryOptions(options) {
15342
- const cleanWhere = fieldClear(options.where || {}, { excludeValues: [null, undefined] });
15383
+ const cleanWhere = DbUtils.clearDeep(options.where || {});
15343
15384
  const hasJoins = options.joins && options.joins.length > 0;
15344
15385
  if (hasJoins) {
15345
15386
  const processedFields2 = (options.fields || []).map((f) => DbUtils.processJoinField(f));
@@ -15791,7 +15832,7 @@ class DbHelper {
15791
15832
  }
15792
15833
  async updData(options) {
15793
15834
  const { table, data, where } = options;
15794
- const cleanWhere = fieldClear(where, { excludeValues: [null, undefined] });
15835
+ const cleanWhere = DbUtils.clearDeep(where);
15795
15836
  const snakeTable = snakeCase(table);
15796
15837
  const snakeWhere = DbUtils.whereKeysToSnake(cleanWhere);
15797
15838
  const processed = DbUtils.buildUpdateRow({ data, now: Date.now(), allowState: true });
@@ -15816,7 +15857,7 @@ class DbHelper {
15816
15857
  async delForce(options) {
15817
15858
  const { table, where } = options;
15818
15859
  const snakeTable = snakeCase(table);
15819
- const cleanWhere = fieldClear(where, { excludeValues: [null, undefined] });
15860
+ const cleanWhere = DbUtils.clearDeep(where);
15820
15861
  const snakeWhere = DbUtils.whereKeysToSnake(cleanWhere);
15821
15862
  const builder = this.createSqlBuilder().where(snakeWhere);
15822
15863
  const { sql, params } = builder.toDeleteSql(snakeTable);
@@ -15881,7 +15922,7 @@ class DbHelper {
15881
15922
  throw new Error(`exists \u4E0D\u652F\u6301 schema.table \u5199\u6CD5\uFF08table: ${rawTable}\uFF09`);
15882
15923
  }
15883
15924
  const snakeTable = snakeCase(rawTable);
15884
- const cleanWhere = fieldClear(options.where || {}, { excludeValues: [null, undefined] });
15925
+ const cleanWhere = DbUtils.clearDeep(options.where || {});
15885
15926
  const snakeWhere = DbUtils.whereKeysToSnake(cleanWhere);
15886
15927
  const whereFiltered = DbUtils.addDefaultStateFilter(snakeWhere, snakeTable, false);
15887
15928
  const builder = this.createSqlBuilder().selectRaw("COUNT(1) as cnt").from(snakeTable).where(whereFiltered).limit(1);
@@ -15967,7 +16008,7 @@ class DbHelper {
15967
16008
  if (typeof value !== "number" || isNaN(value)) {
15968
16009
  throw new Error(`\u81EA\u589E\u503C\u5FC5\u987B\u662F\u6709\u6548\u7684\u6570\u5B57 (table: ${table}, field: ${field}, value: ${value})`);
15969
16010
  }
15970
- const cleanWhere = fieldClear(where, { excludeValues: [null, undefined] });
16011
+ const cleanWhere = DbUtils.clearDeep(where);
15971
16012
  const snakeWhere = DbUtils.whereKeysToSnake(cleanWhere);
15972
16013
  const whereFiltered = DbUtils.addDefaultStateFilter(snakeWhere, snakeTable, false);
15973
16014
  const builder = this.createSqlBuilder().where(whereFiltered);
@@ -16905,21 +16946,6 @@ class Befly {
16905
16946
  noLog = true;
16906
16947
  }
16907
16948
  }
16908
- const writePlainLinesToConsole = (prefix, errName, message) => {
16909
- const text = String(message || "");
16910
- const parts = text.split(`
16911
- `);
16912
- const firstLine = parts.length > 0 ? String(parts[0] || "") : "";
16913
- const head = `[${prefix}] \u542F\u52A8\u5931\u8D25: ${errName}: ${firstLine}`;
16914
- try {
16915
- process.stderr.write(`${head}
16916
- `);
16917
- for (let i = 1;i < parts.length; i = i + 1) {
16918
- process.stderr.write(`${parts[i]}
16919
- `);
16920
- }
16921
- } catch {}
16922
- };
16923
16949
  if (!alreadyLogged && multiline) {
16924
16950
  const appName = String(this.config?.appName || "\u9879\u76EE");
16925
16951
  const errName = error instanceof Error && error.name ? error.name : "Error";
@@ -16928,7 +16954,18 @@ class Befly {
16928
16954
  errorKind: kind,
16929
16955
  errorMessage: errMessage
16930
16956
  }, { truncate: false, console: false });
16931
- writePlainLinesToConsole(appName, errName, errMessage);
16957
+ {
16958
+ const text = String(errMessage || "");
16959
+ const parts = text.split(`
16960
+ `);
16961
+ const firstLine = parts.length > 0 ? String(parts[0] || "") : "";
16962
+ const lines = [];
16963
+ lines.push(`[${appName}] \u542F\u52A8\u5931\u8D25: ${errName}: ${firstLine}`);
16964
+ for (let i = 1;i < parts.length; i = i + 1) {
16965
+ lines.push(String(parts[i] || ""));
16966
+ }
16967
+ Logger.printPlainLines(lines, { stream: "stderr" });
16968
+ }
16932
16969
  } else if (alreadyLogged) {
16933
16970
  Logger.error({
16934
16971
  msg: "\u9879\u76EE\u542F\u52A8\u5931\u8D25\uFF08\u4E0B\u5C42\u5DF2\u8BB0\u5F55\uFF09",