befly 3.15.27 → 3.16.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/dist/befly.js +184 -101
- package/dist/befly.min.js +18 -18
- package/dist/checks/checkTable.js +76 -62
- package/dist/lib/validator.js +12 -10
- package/dist/sync/syncTable.d.ts +1 -1
- package/dist/sync/syncTable.js +34 -7
- package/dist/types/validate.d.ts +1 -1
- package/dist/utils/dbFieldRules.d.ts +31 -0
- package/dist/utils/dbFieldRules.js +94 -0
- package/dist/utils/normalizeFieldDefinition.js +3 -33
- package/package.json +2 -2
package/dist/befly.js
CHANGED
|
@@ -8555,48 +8555,90 @@ async function checkPlugin(plugins) {
|
|
|
8555
8555
|
|
|
8556
8556
|
// checks/checkTable.ts
|
|
8557
8557
|
init_logger();
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
var
|
|
8561
|
-
var
|
|
8562
|
-
var
|
|
8563
|
-
var
|
|
8564
|
-
var
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
8558
|
+
|
|
8559
|
+
// utils/dbFieldRules.ts
|
|
8560
|
+
var STRING_DB_TYPES = new Set(["char", "varchar", "enum", "tinytext", "text", "mediumtext", "longtext"]);
|
|
8561
|
+
var TEXT_DB_TYPES = new Set(["tinytext", "text", "mediumtext", "longtext"]);
|
|
8562
|
+
var INT_DB_TYPES = new Set(["tinyint", "smallint", "mediumint", "int", "bigint"]);
|
|
8563
|
+
var DECIMAL_DB_TYPES = new Set(["decimal"]);
|
|
8564
|
+
var FLOAT_DB_TYPES = new Set(["float", "double"]);
|
|
8565
|
+
var JSON_DB_TYPES = new Set(["json"]);
|
|
8566
|
+
var ENUM_DB_TYPES = new Set(["enum"]);
|
|
8567
|
+
function normalizeDbType(dbType) {
|
|
8568
|
+
return String(dbType || "").trim().toLowerCase();
|
|
8569
|
+
}
|
|
8570
|
+
function isStringDbType(dbType) {
|
|
8571
|
+
return STRING_DB_TYPES.has(normalizeDbType(dbType));
|
|
8572
|
+
}
|
|
8573
|
+
function isTextDbType(dbType) {
|
|
8574
|
+
return TEXT_DB_TYPES.has(normalizeDbType(dbType));
|
|
8575
|
+
}
|
|
8576
|
+
function isIntDbType(dbType) {
|
|
8577
|
+
return INT_DB_TYPES.has(normalizeDbType(dbType));
|
|
8578
|
+
}
|
|
8579
|
+
function isDecimalDbType(dbType) {
|
|
8580
|
+
return DECIMAL_DB_TYPES.has(normalizeDbType(dbType));
|
|
8581
|
+
}
|
|
8582
|
+
function isFloatDbType(dbType) {
|
|
8583
|
+
return FLOAT_DB_TYPES.has(normalizeDbType(dbType));
|
|
8584
|
+
}
|
|
8585
|
+
function isJsonDbType(dbType) {
|
|
8586
|
+
return JSON_DB_TYPES.has(normalizeDbType(dbType));
|
|
8587
|
+
}
|
|
8588
|
+
function isEnumDbType(dbType) {
|
|
8589
|
+
return ENUM_DB_TYPES.has(normalizeDbType(dbType));
|
|
8590
|
+
}
|
|
8591
|
+
function isNumericDbType(dbType) {
|
|
8592
|
+
const normalized = normalizeDbType(dbType);
|
|
8593
|
+
return INT_DB_TYPES.has(normalized) || DECIMAL_DB_TYPES.has(normalized) || FLOAT_DB_TYPES.has(normalized);
|
|
8594
|
+
}
|
|
8595
|
+
function inferInputByDbType(dbType) {
|
|
8596
|
+
const normalized = normalizeDbType(dbType);
|
|
8597
|
+
if (INT_DB_TYPES.has(normalized)) {
|
|
8598
|
+
return "integer";
|
|
8599
|
+
}
|
|
8600
|
+
if (DECIMAL_DB_TYPES.has(normalized) || FLOAT_DB_TYPES.has(normalized)) {
|
|
8601
|
+
return "number";
|
|
8590
8602
|
}
|
|
8603
|
+
if (STRING_DB_TYPES.has(normalized) || normalized === "datetime" || normalized === "timestamp") {
|
|
8604
|
+
return "string";
|
|
8605
|
+
}
|
|
8606
|
+
if (normalized === "json") {
|
|
8607
|
+
return "json";
|
|
8608
|
+
}
|
|
8609
|
+
return "string";
|
|
8591
8610
|
}
|
|
8592
8611
|
function normalizeTypeAndInput(type, input) {
|
|
8593
8612
|
const rawType = String(type || "").trim();
|
|
8594
8613
|
const rawInput = String(input || "").trim();
|
|
8595
8614
|
return {
|
|
8596
8615
|
type: rawType,
|
|
8597
|
-
input: rawInput ||
|
|
8616
|
+
input: rawInput || inferInputByDbType(rawType)
|
|
8598
8617
|
};
|
|
8599
8618
|
}
|
|
8619
|
+
function parseEnumRuleValues(enumInput) {
|
|
8620
|
+
const raw = String(enumInput || "").trim();
|
|
8621
|
+
if (raw === "") {
|
|
8622
|
+
return [];
|
|
8623
|
+
}
|
|
8624
|
+
const parts = raw.split("|").map((x) => x.trim()).filter((x) => x !== "");
|
|
8625
|
+
const out = [];
|
|
8626
|
+
for (const p of parts) {
|
|
8627
|
+
if (!out.includes(p)) {
|
|
8628
|
+
out.push(p);
|
|
8629
|
+
}
|
|
8630
|
+
}
|
|
8631
|
+
return out;
|
|
8632
|
+
}
|
|
8633
|
+
|
|
8634
|
+
// checks/checkTable.ts
|
|
8635
|
+
init_util();
|
|
8636
|
+
var RESERVED_FIELDS = ["id", "created_at", "updated_at", "deleted_at", "state"];
|
|
8637
|
+
var RESERVED_FIELD_SET = new Set(RESERVED_FIELDS);
|
|
8638
|
+
var FIELD_TYPES = ["tinyint", "smallint", "mediumint", "int", "bigint", "decimal", "float", "double", "char", "varchar", "enum", "tinytext", "text", "mediumtext", "longtext", "datetime", "timestamp", "json"];
|
|
8639
|
+
var FIELD_TYPE_SET = new Set(FIELD_TYPES);
|
|
8640
|
+
var INPUT_TYPES = ["number", "integer", "string", "char", "array", "array_number", "array_integer", "json", "json_number", "json_integer"];
|
|
8641
|
+
var INPUT_TYPE_SET = new Set(INPUT_TYPES);
|
|
8600
8642
|
var ALLOWED_FIELD_PROPERTIES = ["name", "type", "input", "min", "max", "default", "detail", "precision", "scale", "index", "unique", "nullable", "unsigned"];
|
|
8601
8643
|
var ALLOWED_FIELD_PROPERTY_SET = new Set(ALLOWED_FIELD_PROPERTIES);
|
|
8602
8644
|
var LOWER_CAMEL_CASE_REGEX = /^_?[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$/;
|
|
@@ -8723,42 +8765,52 @@ async function checkTable(tables, config2) {
|
|
|
8723
8765
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5 input "${normalizedInput}" \u4E0D\u5408\u6CD5\uFF0C` + `\u5FC5\u987B\u4E3A${INPUT_TYPES.join("\u3001")}\u4E4B\u4E00\uFF0C\u6216\u6B63\u5219/\u679A\u4E3E/\u6B63\u5219\u522B\u540D`);
|
|
8724
8766
|
hasError = true;
|
|
8725
8767
|
}
|
|
8726
|
-
const
|
|
8727
|
-
const
|
|
8728
|
-
const
|
|
8729
|
-
const
|
|
8730
|
-
const
|
|
8731
|
-
const
|
|
8732
|
-
const
|
|
8768
|
+
const isDecimalDbType2 = isDecimalDbType(effectiveType);
|
|
8769
|
+
const isFloatDbType2 = isFloatDbType(effectiveType);
|
|
8770
|
+
const isJsonDbType2 = isJsonDbType(effectiveType);
|
|
8771
|
+
const isEnumDbType2 = isEnumDbType(effectiveType);
|
|
8772
|
+
const isNumericDbType2 = isNumericDbType(effectiveType);
|
|
8773
|
+
const isStringDbTypeNormalized = isStringDbType(effectiveType);
|
|
8774
|
+
const isTextDbTypeNormalized = isTextDbType(effectiveType);
|
|
8775
|
+
const isIntDbTypeNormalized = isIntDbType(effectiveType);
|
|
8776
|
+
if (isEnumDbType2) {
|
|
8777
|
+
if (normalizedInput.trim() === "") {
|
|
8778
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0C\u5FC5\u987B\u8BBE\u7F6E input \u679A\u4E3E\u89C4\u5219\uFF08\u4F8B\u5982 a|b|c\uFF09`);
|
|
8779
|
+
hasError = true;
|
|
8780
|
+
} else if (!isEnumInput(normalizedInput)) {
|
|
8781
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0Cinput \u5FC5\u987B\u4E3A\u679A\u4E3E\u89C4\u5219\uFF08\u4F8B\u5982 a|b|c\uFF09\uFF0C\u5F53\u524D\u4E3A ${formatValuePreview(normalizedInput)}`);
|
|
8782
|
+
hasError = true;
|
|
8783
|
+
}
|
|
8784
|
+
}
|
|
8733
8785
|
if (isRegexInput(normalizedInput) || isEnumInput(normalizedInput) || isAliasInput(normalizedInput)) {
|
|
8734
|
-
if (!
|
|
8735
|
-
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5 input \u4F7F\u7528\u6B63\u5219/\u679A\u4E3E/\u6B63\u5219\u522B\u540D\uFF0C\u4EC5\u5141\u8BB8\u5B57\u7B26\u4E32\u7C7B\u5B57\u6BB5\uFF08char/varchar/text\uFF09`);
|
|
8786
|
+
if (!isStringDbTypeNormalized) {
|
|
8787
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5 input \u4F7F\u7528\u6B63\u5219/\u679A\u4E3E/\u6B63\u5219\u522B\u540D\uFF0C\u4EC5\u5141\u8BB8\u5B57\u7B26\u4E32\u7C7B\u5B57\u6BB5\uFF08char/varchar/enum/text\uFF09`);
|
|
8736
8788
|
hasError = true;
|
|
8737
8789
|
}
|
|
8738
8790
|
}
|
|
8739
8791
|
if (normalizedInput === "number" || normalizedInput === "integer") {
|
|
8740
|
-
if (normalizedInput === "integer" && !
|
|
8792
|
+
if (normalizedInput === "integer" && !isIntDbTypeNormalized) {
|
|
8741
8793
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5 input=${normalizedInput} \u4EC5\u5141\u8BB8\u6574\u6570\u7C7B\u5B57\u6BB5\uFF08tinyint/smallint/mediumint/int/bigint\uFF09`);
|
|
8742
8794
|
hasError = true;
|
|
8743
8795
|
}
|
|
8744
|
-
if (normalizedInput === "number" && !
|
|
8796
|
+
if (normalizedInput === "number" && !isNumericDbType2) {
|
|
8745
8797
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5 input=${normalizedInput} \u4EC5\u5141\u8BB8\u6570\u503C\u7C7B\u5B57\u6BB5\uFF08tinyint/smallint/mediumint/int/bigint/decimal\uFF09`);
|
|
8746
8798
|
hasError = true;
|
|
8747
8799
|
}
|
|
8748
8800
|
}
|
|
8749
8801
|
if (normalizedInput === "array" || normalizedInput === "array_number" || normalizedInput === "array_integer") {
|
|
8750
|
-
if (!
|
|
8802
|
+
if (!isStringDbTypeNormalized) {
|
|
8751
8803
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5 input=${normalizedInput} \u4EC5\u5141\u8BB8\u5B57\u7B26\u4E32\u7C7B\u5B57\u6BB5\uFF08char/varchar/text\uFF09`);
|
|
8752
8804
|
hasError = true;
|
|
8753
8805
|
}
|
|
8754
8806
|
}
|
|
8755
8807
|
if (normalizedInput === "json" || normalizedInput === "json_number" || normalizedInput === "json_integer") {
|
|
8756
|
-
if (!(
|
|
8808
|
+
if (!(isJsonDbType2 || isTextDbTypeNormalized)) {
|
|
8757
8809
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5 input=${normalizedInput} \u4EC5\u5141\u8BB8 json \u6216 text \u7C7B\u5B57\u6BB5`);
|
|
8758
8810
|
hasError = true;
|
|
8759
8811
|
}
|
|
8760
8812
|
}
|
|
8761
|
-
if (!
|
|
8813
|
+
if (!isNumericDbType2 && field.unsigned !== undefined) {
|
|
8762
8814
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u5B57\u6BB5\u7C7B\u578B\u4E3A ${effectiveType}\uFF0C\u4E0D\u5141\u8BB8\u8BBE\u7F6E unsigned\uFF08\u4EC5\u6570\u503C\u7C7B\u578B\u6709\u6548\uFF09`);
|
|
8763
8815
|
hasError = true;
|
|
8764
8816
|
}
|
|
@@ -8772,7 +8824,7 @@ async function checkTable(tables, config2) {
|
|
|
8772
8824
|
hasError = true;
|
|
8773
8825
|
}
|
|
8774
8826
|
}
|
|
8775
|
-
if (
|
|
8827
|
+
if (isTextDbTypeNormalized || isJsonDbType2) {
|
|
8776
8828
|
if (field.min !== undefined && field.min !== null) {
|
|
8777
8829
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u7684 ${effectiveType} \u7C7B\u578B\u6700\u5C0F\u503C\u5E94\u4E3A null\uFF0C\u5F53\u524D\u4E3A "${field.min}"`);
|
|
8778
8830
|
hasError = true;
|
|
@@ -8793,24 +8845,58 @@ async function checkTable(tables, config2) {
|
|
|
8793
8845
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0C\u4E0D\u652F\u6301\u552F\u4E00\u7EA6\u675F\uFF08unique=true \u65E0\u6548\uFF09`);
|
|
8794
8846
|
hasError = true;
|
|
8795
8847
|
}
|
|
8796
|
-
} else if (effectiveType === "datetime") {
|
|
8848
|
+
} else if (effectiveType === "datetime" || effectiveType === "timestamp") {
|
|
8797
8849
|
if (field.min !== undefined && field.min !== null) {
|
|
8798
|
-
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A
|
|
8850
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0Cmin \u5FC5\u987B\u4E3A null\uFF0C\u5F53\u524D\u4E3A "${field.min}"`);
|
|
8799
8851
|
hasError = true;
|
|
8800
8852
|
}
|
|
8801
8853
|
if (field.max !== undefined && field.max !== null) {
|
|
8802
|
-
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A
|
|
8854
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0Cmax \u5FC5\u987B\u4E3A null\uFF0C\u5F53\u524D\u4E3A "${field.max}"`);
|
|
8803
8855
|
hasError = true;
|
|
8804
8856
|
}
|
|
8805
8857
|
if (field.default !== undefined && field.default !== null) {
|
|
8806
|
-
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A
|
|
8858
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0C\u9ED8\u8BA4\u503C\u5FC5\u987B\u4E3A null\uFF08\u5982\u9700\u5F53\u524D\u65F6\u95F4\uFF0C\u8BF7\u5728\u4E1A\u52A1\u5199\u5165\u65F6\u8D4B\u503C\uFF09\u3002\u5F53\u524D\u4E3A ${formatValuePreview(field.default)}`);
|
|
8859
|
+
hasError = true;
|
|
8860
|
+
}
|
|
8861
|
+
if (field.unsigned !== undefined) {
|
|
8862
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0C\u4E0D\u5141\u8BB8\u8BBE\u7F6E unsigned`);
|
|
8863
|
+
hasError = true;
|
|
8864
|
+
}
|
|
8865
|
+
} else if (effectiveType === "enum") {
|
|
8866
|
+
if (field.min !== undefined && field.min !== null) {
|
|
8867
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0Cmin \u5FC5\u987B\u4E3A null\uFF0C\u5F53\u524D\u4E3A "${field.min}"`);
|
|
8868
|
+
hasError = true;
|
|
8869
|
+
}
|
|
8870
|
+
if (field.max !== undefined && field.max !== null) {
|
|
8871
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0Cmax \u5FC5\u987B\u4E3A null\uFF0C\u5F53\u524D\u4E3A "${field.max}"`);
|
|
8872
|
+
hasError = true;
|
|
8873
|
+
}
|
|
8874
|
+
if (field.precision !== undefined && field.precision !== null) {
|
|
8875
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0C\u4E0D\u5141\u8BB8\u8BBE\u7F6E precision`);
|
|
8876
|
+
hasError = true;
|
|
8877
|
+
}
|
|
8878
|
+
if (field.scale !== undefined && field.scale !== null) {
|
|
8879
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0C\u4E0D\u5141\u8BB8\u8BBE\u7F6E scale`);
|
|
8807
8880
|
hasError = true;
|
|
8808
8881
|
}
|
|
8809
8882
|
if (field.unsigned !== undefined) {
|
|
8810
|
-
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A
|
|
8883
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0C\u4E0D\u5141\u8BB8\u8BBE\u7F6E unsigned`);
|
|
8811
8884
|
hasError = true;
|
|
8812
8885
|
}
|
|
8813
|
-
|
|
8886
|
+
const enumValues = parseEnumRuleValues(normalizedInput);
|
|
8887
|
+
if (field.default === undefined || field.default === null) {
|
|
8888
|
+
if (field.nullable !== true) {
|
|
8889
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0Cnullable!=true \u65F6\u5FC5\u987B\u8BBE\u7F6E default\uFF08\u4E14 default \u5FC5\u987B\u4E3A\u679A\u4E3E\u503C\u4E4B\u4E00\uFF09`);
|
|
8890
|
+
hasError = true;
|
|
8891
|
+
}
|
|
8892
|
+
} else if (typeof field.default !== "string") {
|
|
8893
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0C\u9ED8\u8BA4\u503C\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6216 null` + `\uFF08typeof=${typeof field.default}\uFF0Cvalue=${formatValuePreview(field.default)}\uFF09`);
|
|
8894
|
+
hasError = true;
|
|
8895
|
+
} else if (!enumValues.includes(field.default)) {
|
|
8896
|
+
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A enum \u7C7B\u578B\uFF0C\u9ED8\u8BA4\u503C\u4E0D\u5728\u679A\u4E3E\u8303\u56F4\u5185\uFF08default=${formatValuePreview(field.default)}\uFF0Cenums=${formatValuePreview(normalizedInput)}\uFF09`);
|
|
8897
|
+
hasError = true;
|
|
8898
|
+
}
|
|
8899
|
+
} else if (isDecimalDbType2) {
|
|
8814
8900
|
const precision = field.precision;
|
|
8815
8901
|
const scale = field.scale;
|
|
8816
8902
|
if (typeof precision !== "number") {
|
|
@@ -8860,12 +8946,12 @@ async function checkTable(tables, config2) {
|
|
|
8860
8946
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0C\u9ED8\u8BA4\u503C\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6216 null` + `\uFF08typeof=${typeof field.default}\uFF0Cvalue=${formatValuePreview(field.default)}\uFF09`);
|
|
8861
8947
|
hasError = true;
|
|
8862
8948
|
}
|
|
8863
|
-
} else if (
|
|
8949
|
+
} else if (isIntDbTypeNormalized) {
|
|
8864
8950
|
if (field.default !== undefined && field.default !== null && typeof field.default !== "number") {
|
|
8865
8951
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0C\u9ED8\u8BA4\u503C\u5FC5\u987B\u4E3A\u6570\u5B57\u6216 null` + `\uFF08typeof=${typeof field.default}\uFF0Cvalue=${formatValuePreview(field.default)}\uFF09`);
|
|
8866
8952
|
hasError = true;
|
|
8867
8953
|
}
|
|
8868
|
-
} else if (
|
|
8954
|
+
} else if (isFloatDbType2) {
|
|
8869
8955
|
if (field.default !== undefined && field.default !== null && typeof field.default !== "number") {
|
|
8870
8956
|
Logger.warn(`${tablePrefix}${fileName} \u6587\u4EF6 ${colKey} \u4E3A ${effectiveType} \u7C7B\u578B\uFF0C\u9ED8\u8BA4\u503C\u5FC5\u987B\u4E3A\u6570\u5B57\u6216 null` + `\uFF08typeof=${typeof field.default}\uFF0Cvalue=${formatValuePreview(field.default)}\uFF09`);
|
|
8871
8957
|
hasError = true;
|
|
@@ -10337,41 +10423,10 @@ async function syncMenu(ctx, mergedMenus) {
|
|
|
10337
10423
|
init_logger();
|
|
10338
10424
|
|
|
10339
10425
|
// utils/normalizeFieldDefinition.ts
|
|
10340
|
-
function
|
|
10341
|
-
switch (dbType.toLowerCase()) {
|
|
10342
|
-
case "tinyint":
|
|
10343
|
-
case "smallint":
|
|
10344
|
-
case "mediumint":
|
|
10345
|
-
case "int":
|
|
10346
|
-
case "bigint":
|
|
10347
|
-
return "integer";
|
|
10348
|
-
case "decimal":
|
|
10349
|
-
case "float":
|
|
10350
|
-
case "double":
|
|
10351
|
-
return "number";
|
|
10352
|
-
case "char":
|
|
10353
|
-
case "varchar":
|
|
10354
|
-
case "tinytext":
|
|
10355
|
-
case "text":
|
|
10356
|
-
case "mediumtext":
|
|
10357
|
-
case "longtext":
|
|
10358
|
-
return "string";
|
|
10359
|
-
case "datetime":
|
|
10360
|
-
return "string";
|
|
10361
|
-
case "json":
|
|
10362
|
-
return "json";
|
|
10363
|
-
default:
|
|
10364
|
-
return "string";
|
|
10365
|
-
}
|
|
10366
|
-
}
|
|
10367
|
-
function normalizeTypeAndInput2(fieldDef) {
|
|
10426
|
+
function normalizeFieldDefinition(fieldDef) {
|
|
10368
10427
|
const rawType = String(fieldDef.type ?? "").trim();
|
|
10369
10428
|
const rawInput = typeof fieldDef.input === "string" ? fieldDef.input.trim() : "";
|
|
10370
|
-
const
|
|
10371
|
-
return { type: rawType, input: inferredInput };
|
|
10372
|
-
}
|
|
10373
|
-
function normalizeFieldDefinition(fieldDef) {
|
|
10374
|
-
const typeAndInput = normalizeTypeAndInput2(fieldDef);
|
|
10429
|
+
const typeAndInput = normalizeTypeAndInput(rawType, rawInput);
|
|
10375
10430
|
let normalizedDefault = fieldDef.default ?? null;
|
|
10376
10431
|
if (normalizedDefault === null) {
|
|
10377
10432
|
if (typeAndInput.input === "array" || typeAndInput.input === "array_number" || typeAndInput.input === "array_integer") {
|
|
@@ -10549,7 +10604,9 @@ class SyncTable {
|
|
|
10549
10604
|
double: "DOUBLE",
|
|
10550
10605
|
char: "CHAR",
|
|
10551
10606
|
varchar: "VARCHAR",
|
|
10607
|
+
enum: "ENUM",
|
|
10552
10608
|
datetime: "DATETIME",
|
|
10609
|
+
timestamp: "TIMESTAMP",
|
|
10553
10610
|
tinytext: "TINYTEXT",
|
|
10554
10611
|
text: "MEDIUMTEXT",
|
|
10555
10612
|
mediumtext: "MEDIUMTEXT",
|
|
@@ -10767,9 +10824,21 @@ class SyncTable {
|
|
|
10767
10824
|
}
|
|
10768
10825
|
return `\`${trimmed}\``;
|
|
10769
10826
|
}
|
|
10770
|
-
static getSqlType(fieldType, fieldMax, unsigned = false, precision = null, scale = null) {
|
|
10827
|
+
static getSqlType(fieldType, fieldMax, unsigned = false, precision = null, scale = null, enumInput = null) {
|
|
10771
10828
|
const normalizedType = String(fieldType || "").toLowerCase();
|
|
10772
10829
|
const typeMapping = SyncTable.TYPE_MAPPING;
|
|
10830
|
+
if (normalizedType === "enum") {
|
|
10831
|
+
const values = parseEnumRuleValues(String(enumInput || ""));
|
|
10832
|
+
if (values.length === 0) {
|
|
10833
|
+
throw new Error(`\u540C\u6B65\u8868\uFF1A\u5185\u90E8\u9519\u8BEF\uFF1Aenum \u7C7B\u578B\u7F3A\u5931 input \u679A\u4E3E\u503C\uFF08\u5E94\u7531 checkTable \u963B\u65AD\uFF09`);
|
|
10834
|
+
}
|
|
10835
|
+
const quoted = [];
|
|
10836
|
+
for (const v of values) {
|
|
10837
|
+
const escaped = String(v).replace(/'/g, "''");
|
|
10838
|
+
quoted.push(`'${escaped}'`);
|
|
10839
|
+
}
|
|
10840
|
+
return `${typeMapping[normalizedType]}(${quoted.join(",")})`;
|
|
10841
|
+
}
|
|
10773
10842
|
if (SyncTable.isStringOrArrayType(normalizedType)) {
|
|
10774
10843
|
if (typeof fieldMax !== "number") {
|
|
10775
10844
|
throw new Error(`\u540C\u6B65\u8868\uFF1A\u5185\u90E8\u9519\u8BEF\uFF1A${normalizedType} \u7C7B\u578B\u7F3A\u5931 max\uFF08\u5E94\u7531 checkTable \u963B\u65AD\uFF09`);
|
|
@@ -10807,8 +10876,12 @@ class SyncTable {
|
|
|
10807
10876
|
case "char":
|
|
10808
10877
|
case "varchar":
|
|
10809
10878
|
return "";
|
|
10879
|
+
case "enum":
|
|
10880
|
+
return "null";
|
|
10810
10881
|
case "datetime":
|
|
10811
10882
|
return "null";
|
|
10883
|
+
case "timestamp":
|
|
10884
|
+
return "null";
|
|
10812
10885
|
case "tinytext":
|
|
10813
10886
|
case "text":
|
|
10814
10887
|
case "mediumtext":
|
|
@@ -10824,6 +10897,10 @@ class SyncTable {
|
|
|
10824
10897
|
if (SyncTable.TEXT_FAMILY.has(normalizedType) || normalizedType === "json" || actualDefault === "null") {
|
|
10825
10898
|
return "";
|
|
10826
10899
|
}
|
|
10900
|
+
if (normalizedType === "enum") {
|
|
10901
|
+
const escaped = String(actualDefault).replace(/'/g, "''");
|
|
10902
|
+
return ` DEFAULT '${escaped}'`;
|
|
10903
|
+
}
|
|
10827
10904
|
if (SyncTable.INT_TYPES.has(normalizedType) || SyncTable.DECIMAL_TYPES.has(normalizedType) || SyncTable.FLOAT_TYPES.has(normalizedType) || SyncTable.isStringOrArrayType(normalizedType)) {
|
|
10828
10905
|
if (typeof actualDefault === "number" && !Number.isNaN(actualDefault)) {
|
|
10829
10906
|
return ` DEFAULT ${actualDefault}`;
|
|
@@ -10832,7 +10909,7 @@ class SyncTable {
|
|
|
10832
10909
|
return ` DEFAULT '${escaped}'`;
|
|
10833
10910
|
}
|
|
10834
10911
|
}
|
|
10835
|
-
if (normalizedType === "datetime") {
|
|
10912
|
+
if (normalizedType === "datetime" || normalizedType === "timestamp") {
|
|
10836
10913
|
if (typeof actualDefault === "string") {
|
|
10837
10914
|
const trimmed = actualDefault.trim();
|
|
10838
10915
|
if (/^current_timestamp(\(\s*\d+\s*\)|\(\s*\))?$/i.test(trimmed)) {
|
|
@@ -10928,7 +11005,7 @@ class SyncTable {
|
|
|
10928
11005
|
const normalized = normalizeFieldDefinition(fieldDef);
|
|
10929
11006
|
const dbFieldName = snakeCase(fieldKey);
|
|
10930
11007
|
const colQuoted = SyncTable.quoteIdentifier(dbFieldName);
|
|
10931
|
-
const sqlType = SyncTable.getSqlType(normalized.type, normalized.max, normalized.unsigned, normalized.precision, normalized.scale);
|
|
11008
|
+
const sqlType = SyncTable.getSqlType(normalized.type, normalized.max, normalized.unsigned, normalized.precision, normalized.scale, normalized.input);
|
|
10932
11009
|
const actualDefault = SyncTable.resolveDefaultValue(normalized.default, normalized.type);
|
|
10933
11010
|
const defaultSql = SyncTable.generateDefaultSql(actualDefault, normalized.type);
|
|
10934
11011
|
const uniqueSql = normalized.unique ? " UNIQUE" : "";
|
|
@@ -10996,7 +11073,8 @@ class SyncTable {
|
|
|
10996
11073
|
changeDetails.push({ fieldKey, dbFieldName, changes: comparison });
|
|
10997
11074
|
const typeChange = comparison.find((c) => c.type === "datatype");
|
|
10998
11075
|
if (typeChange) {
|
|
10999
|
-
const
|
|
11076
|
+
const expectedNormalized = normalizeFieldDefinition(fieldDef);
|
|
11077
|
+
const expectedType = SyncTable.getSqlType(expectedNormalized.type, expectedNormalized.max, expectedNormalized.unsigned, expectedNormalized.precision, expectedNormalized.scale, expectedNormalized.input);
|
|
11000
11078
|
const incompatible = SyncTable.getIncompatibleTypeChange(options.tableName, dbFieldName, String(typeChange.current ?? ""), expectedType);
|
|
11001
11079
|
if (incompatible) {
|
|
11002
11080
|
incompatibleTypeChanges.push(incompatible);
|
|
@@ -11071,7 +11149,8 @@ class SyncTable {
|
|
|
11071
11149
|
const typeChange = comparison.find((c) => c.type === "datatype");
|
|
11072
11150
|
if (!typeChange)
|
|
11073
11151
|
continue;
|
|
11074
|
-
const
|
|
11152
|
+
const expectedNormalized = normalizeFieldDefinition(fieldDef);
|
|
11153
|
+
const expectedType = SyncTable.getSqlType(expectedNormalized.type, expectedNormalized.max, expectedNormalized.unsigned, expectedNormalized.precision, expectedNormalized.scale, expectedNormalized.input);
|
|
11075
11154
|
const incompatible = SyncTable.getIncompatibleTypeChange(tableName, dbFieldName, String(typeChange.current ?? ""), expectedType);
|
|
11076
11155
|
if (incompatible) {
|
|
11077
11156
|
out.push(incompatible);
|
|
@@ -11225,7 +11304,7 @@ SQL: ${sqlLine}
|
|
|
11225
11304
|
static compareFieldDefinition(existingColumn, fieldDef) {
|
|
11226
11305
|
const changes = [];
|
|
11227
11306
|
const normalized = normalizeFieldDefinition(fieldDef);
|
|
11228
|
-
const expectedType = SyncTable.getSqlType(normalized.type, normalized.max, normalized.unsigned, normalized.precision, normalized.scale).toLowerCase().replace(/\s+/g, " ").trim();
|
|
11307
|
+
const expectedType = SyncTable.getSqlType(normalized.type, normalized.max, normalized.unsigned, normalized.precision, normalized.scale, normalized.input).toLowerCase().replace(/\s+/g, " ").trim();
|
|
11229
11308
|
const currentType = (typeof existingColumn.columnType === "string" && existingColumn.columnType.trim() !== "" ? existingColumn.columnType : typeof existingColumn.type === "string" && existingColumn.type.trim() !== "" ? SyncTable.isStringOrArrayType(normalized.type) && typeof existingColumn.max === "number" ? `${existingColumn.type.trim()}(${existingColumn.max})` : existingColumn.type.trim() : String(existingColumn.type ?? "")).toLowerCase().replace(/\s+/g, " ").trim();
|
|
11230
11309
|
const currentBase = currentType.replace(/\s*unsigned/gi, "").replace(/\([^)]*\)/g, "").trim();
|
|
11231
11310
|
const normalizedCurrentType = SyncTable.INT_TYPES.has(currentBase) ? currentType.replace(/\([^)]*\)/g, "").replace(/\s+/g, " ").trim() : currentType;
|
|
@@ -13371,13 +13450,15 @@ class Validator {
|
|
|
13371
13450
|
}
|
|
13372
13451
|
case "string": {
|
|
13373
13452
|
if (typeof value === "string") {
|
|
13374
|
-
|
|
13453
|
+
const dbTypeNormalized2 = String(dbType || "").toLowerCase();
|
|
13454
|
+
if (dbTypeNormalized2 === "datetime" || dbTypeNormalized2 === "timestamp") {
|
|
13375
13455
|
const trimmed = value.trim();
|
|
13376
13456
|
return { value: trimmed, error: null };
|
|
13377
13457
|
}
|
|
13378
13458
|
return { value, error: null };
|
|
13379
13459
|
}
|
|
13380
|
-
|
|
13460
|
+
const dbTypeNormalized = String(dbType || "").toLowerCase();
|
|
13461
|
+
if (dbTypeNormalized === "datetime" || dbTypeNormalized === "timestamp") {
|
|
13381
13462
|
return { value: null, error: "\u5FC5\u987B\u662F\u65F6\u95F4\u5B57\u7B26\u4E32" };
|
|
13382
13463
|
}
|
|
13383
13464
|
return { value: null, error: "\u5FC5\u987B\u662F\u5B57\u7B26\u4E32" };
|
|
@@ -13419,7 +13500,8 @@ class Validator {
|
|
|
13419
13500
|
return { value: null, error: "\u5FC5\u987B\u662FJSON\u5BF9\u8C61\u6216\u6570\u7EC4" };
|
|
13420
13501
|
return checkJsonLeaves(value, "integer") ? { value, error: null } : { value: null, error: "JSON\u503C\u5FC5\u987B\u662F\u6574\u6570" };
|
|
13421
13502
|
default: {
|
|
13422
|
-
|
|
13503
|
+
const dbTypeNormalized = String(dbType || "").toLowerCase();
|
|
13504
|
+
if (dbTypeNormalized === "datetime" || dbTypeNormalized === "timestamp") {
|
|
13423
13505
|
if (typeof value !== "string")
|
|
13424
13506
|
return { value: null, error: "\u5FC5\u987B\u662F\u65F6\u95F4\u5B57\u7B26\u4E32" };
|
|
13425
13507
|
const trimmed = value.trim();
|
|
@@ -13461,7 +13543,7 @@ class Validator {
|
|
|
13461
13543
|
return "\u683C\u5F0F\u4E0D\u6B63\u786E";
|
|
13462
13544
|
}
|
|
13463
13545
|
if (isEnum) {
|
|
13464
|
-
const enums = inputRaw
|
|
13546
|
+
const enums = parseEnumRuleValues(inputRaw);
|
|
13465
13547
|
if (!enums.includes(value))
|
|
13466
13548
|
return "\u503C\u4E0D\u5728\u679A\u4E3E\u8303\u56F4\u5185";
|
|
13467
13549
|
}
|
|
@@ -13476,7 +13558,8 @@ class Validator {
|
|
|
13476
13558
|
if (!isJsonStructure(value))
|
|
13477
13559
|
return "\u5FC5\u987B\u662FJSON\u5BF9\u8C61\u6216\u6570\u7EC4";
|
|
13478
13560
|
}
|
|
13479
|
-
|
|
13561
|
+
const normalizedTypeForDb = String(type || "").toLowerCase();
|
|
13562
|
+
if (normalizedTypeForDb === "datetime" || normalizedTypeForDb === "timestamp") {
|
|
13480
13563
|
if (typeof value !== "string")
|
|
13481
13564
|
return "\u5FC5\u987B\u662F\u65F6\u95F4\u5B57\u7B26\u4E32";
|
|
13482
13565
|
if (!/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(value))
|
|
@@ -13545,7 +13628,7 @@ class Validator {
|
|
|
13545
13628
|
return defaultValue;
|
|
13546
13629
|
}
|
|
13547
13630
|
const normalizedType = String(type || "").toLowerCase();
|
|
13548
|
-
if (normalizedType === "datetime" || normalizedType === "json") {
|
|
13631
|
+
if (normalizedType === "datetime" || normalizedType === "timestamp" || normalizedType === "json" || normalizedType === "enum") {
|
|
13549
13632
|
return null;
|
|
13550
13633
|
}
|
|
13551
13634
|
const normalizedInput = String(input || "").toLowerCase();
|