@famgia/omnify-core 0.0.136 → 0.0.137
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/index.cjs +300 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +300 -38
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1217,10 +1217,89 @@ var BASE_PROPERTY_FIELDS = [
|
|
|
1217
1217
|
// Per-field settings for compound types
|
|
1218
1218
|
];
|
|
1219
1219
|
var VALID_RULES_FIELDS = [
|
|
1220
|
+
// Basic
|
|
1220
1221
|
"required",
|
|
1222
|
+
// String length
|
|
1221
1223
|
"minLength",
|
|
1222
|
-
"maxLength"
|
|
1224
|
+
"maxLength",
|
|
1225
|
+
// Format (String only)
|
|
1226
|
+
"url",
|
|
1227
|
+
"uuid",
|
|
1228
|
+
"ip",
|
|
1229
|
+
"ipv4",
|
|
1230
|
+
"ipv6",
|
|
1231
|
+
// Character pattern (String only)
|
|
1232
|
+
"alpha",
|
|
1233
|
+
"alphaNum",
|
|
1234
|
+
"alphaDash",
|
|
1235
|
+
"numeric",
|
|
1236
|
+
"digits",
|
|
1237
|
+
"digitsBetween",
|
|
1238
|
+
// String matching (String only)
|
|
1239
|
+
"startsWith",
|
|
1240
|
+
"endsWith",
|
|
1241
|
+
"lowercase",
|
|
1242
|
+
"uppercase",
|
|
1243
|
+
// Numeric (Int/Float only)
|
|
1244
|
+
"min",
|
|
1245
|
+
"max",
|
|
1246
|
+
"between",
|
|
1247
|
+
"gt",
|
|
1248
|
+
"lt",
|
|
1249
|
+
"multipleOf",
|
|
1250
|
+
// Array
|
|
1251
|
+
"arrayMin",
|
|
1252
|
+
"arrayMax"
|
|
1223
1253
|
];
|
|
1254
|
+
var RULES_TYPE_GROUPS = {
|
|
1255
|
+
string: ["String", "Text", "MediumText", "LongText", "Password", "Email"],
|
|
1256
|
+
numeric: ["TinyInt", "Int", "BigInt", "Float", "Decimal"],
|
|
1257
|
+
date: ["Date", "DateTime", "Time", "Timestamp"],
|
|
1258
|
+
any: []
|
|
1259
|
+
// 全タイプに適用可能
|
|
1260
|
+
};
|
|
1261
|
+
var RULES_TYPE_COMPATIBILITY = {
|
|
1262
|
+
// Basic - any type
|
|
1263
|
+
required: "any",
|
|
1264
|
+
// String length rules
|
|
1265
|
+
minLength: "string",
|
|
1266
|
+
maxLength: "string",
|
|
1267
|
+
// Format rules (String only)
|
|
1268
|
+
url: "string",
|
|
1269
|
+
uuid: "string",
|
|
1270
|
+
ip: "string",
|
|
1271
|
+
ipv4: "string",
|
|
1272
|
+
ipv6: "string",
|
|
1273
|
+
// Character pattern rules (String only)
|
|
1274
|
+
alpha: "string",
|
|
1275
|
+
alphaNum: "string",
|
|
1276
|
+
alphaDash: "string",
|
|
1277
|
+
numeric: "string",
|
|
1278
|
+
digits: "string",
|
|
1279
|
+
digitsBetween: "string",
|
|
1280
|
+
// String matching rules (String only)
|
|
1281
|
+
startsWith: "string",
|
|
1282
|
+
endsWith: "string",
|
|
1283
|
+
lowercase: "string",
|
|
1284
|
+
uppercase: "string",
|
|
1285
|
+
// Numeric rules (Int/Float only)
|
|
1286
|
+
min: "numeric",
|
|
1287
|
+
max: "numeric",
|
|
1288
|
+
between: "numeric",
|
|
1289
|
+
gt: "numeric",
|
|
1290
|
+
lt: "numeric",
|
|
1291
|
+
multipleOf: "numeric",
|
|
1292
|
+
// Array rules - handled separately
|
|
1293
|
+
arrayMin: "any",
|
|
1294
|
+
arrayMax: "any"
|
|
1295
|
+
};
|
|
1296
|
+
function isRuleCompatibleWithType(rule, propertyType) {
|
|
1297
|
+
const category = RULES_TYPE_COMPATIBILITY[rule];
|
|
1298
|
+
if (!category) return false;
|
|
1299
|
+
if (category === "any") return true;
|
|
1300
|
+
const allowedTypes = RULES_TYPE_GROUPS[category];
|
|
1301
|
+
return allowedTypes.includes(propertyType);
|
|
1302
|
+
}
|
|
1224
1303
|
function createValidFields(additionalFields) {
|
|
1225
1304
|
return [...BASE_PROPERTY_FIELDS, ...additionalFields];
|
|
1226
1305
|
}
|
|
@@ -2693,13 +2772,13 @@ Example:
|
|
|
2693
2772
|
}
|
|
2694
2773
|
return `Unknown field '${field}'. Valid property fields: type, displayName, placeholder, nullable, default, unique, primary, description, length, unsigned, precision, scale, enum, relation, target, onDelete, onUpdate, joinTable, rules, hidden, fillable, fields`;
|
|
2695
2774
|
}
|
|
2696
|
-
var STRING_TYPES_WITH_LENGTH_RULES = ["String", "Email", "Password"];
|
|
2697
2775
|
function validateRules(propertyName, property, filePath) {
|
|
2698
2776
|
const errors = [];
|
|
2699
2777
|
const rules = property.rules;
|
|
2700
2778
|
if (!rules || typeof rules !== "object") {
|
|
2701
2779
|
return errors;
|
|
2702
2780
|
}
|
|
2781
|
+
const propertyType = property.type;
|
|
2703
2782
|
const validRulesSet = new Set(VALID_RULES_FIELDS);
|
|
2704
2783
|
for (const field of Object.keys(rules)) {
|
|
2705
2784
|
if (!validRulesSet.has(field)) {
|
|
@@ -2712,77 +2791,260 @@ function validateRules(propertyName, property, filePath) {
|
|
|
2712
2791
|
);
|
|
2713
2792
|
}
|
|
2714
2793
|
}
|
|
2715
|
-
const
|
|
2716
|
-
|
|
2794
|
+
for (const [ruleName, ruleValue] of Object.entries(rules)) {
|
|
2795
|
+
if (ruleValue === void 0 || ruleValue === null) continue;
|
|
2796
|
+
if (!validRulesSet.has(ruleName)) continue;
|
|
2797
|
+
if (!isRuleCompatibleWithType(ruleName, propertyType)) {
|
|
2798
|
+
const stringTypes = RULES_TYPE_GROUPS.string.join(", ");
|
|
2799
|
+
const numericTypes2 = RULES_TYPE_GROUPS.numeric.join(", ");
|
|
2800
|
+
let allowedTypes = "";
|
|
2801
|
+
if ([
|
|
2802
|
+
"minLength",
|
|
2803
|
+
"maxLength",
|
|
2804
|
+
"url",
|
|
2805
|
+
"uuid",
|
|
2806
|
+
"ip",
|
|
2807
|
+
"ipv4",
|
|
2808
|
+
"ipv6",
|
|
2809
|
+
"alpha",
|
|
2810
|
+
"alphaNum",
|
|
2811
|
+
"alphaDash",
|
|
2812
|
+
"numeric",
|
|
2813
|
+
"digits",
|
|
2814
|
+
"digitsBetween",
|
|
2815
|
+
"startsWith",
|
|
2816
|
+
"endsWith",
|
|
2817
|
+
"lowercase",
|
|
2818
|
+
"uppercase"
|
|
2819
|
+
].includes(ruleName)) {
|
|
2820
|
+
allowedTypes = stringTypes;
|
|
2821
|
+
} else if (["min", "max", "between", "gt", "lt", "multipleOf"].includes(ruleName)) {
|
|
2822
|
+
allowedTypes = numericTypes2;
|
|
2823
|
+
}
|
|
2824
|
+
if (allowedTypes) {
|
|
2825
|
+
errors.push(
|
|
2826
|
+
validationError(
|
|
2827
|
+
`Property '${propertyName}' of type '${propertyType}' cannot use rules.${ruleName}`,
|
|
2828
|
+
buildLocation7(filePath),
|
|
2829
|
+
`rules.${ruleName} is only valid for types: ${allowedTypes}`
|
|
2830
|
+
)
|
|
2831
|
+
);
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
const {
|
|
2836
|
+
required,
|
|
2837
|
+
minLength,
|
|
2838
|
+
maxLength,
|
|
2839
|
+
url,
|
|
2840
|
+
uuid,
|
|
2841
|
+
ip,
|
|
2842
|
+
ipv4,
|
|
2843
|
+
ipv6,
|
|
2844
|
+
alpha,
|
|
2845
|
+
alphaNum,
|
|
2846
|
+
alphaDash,
|
|
2847
|
+
numeric,
|
|
2848
|
+
lowercase,
|
|
2849
|
+
uppercase,
|
|
2850
|
+
digits,
|
|
2851
|
+
digitsBetween,
|
|
2852
|
+
startsWith,
|
|
2853
|
+
endsWith,
|
|
2854
|
+
min,
|
|
2855
|
+
max,
|
|
2856
|
+
between,
|
|
2857
|
+
gt,
|
|
2858
|
+
lt,
|
|
2859
|
+
multipleOf,
|
|
2860
|
+
arrayMin,
|
|
2861
|
+
arrayMax
|
|
2862
|
+
} = rules;
|
|
2863
|
+
const booleanRules = { required, url, uuid, ip, ipv4, ipv6, alpha, alphaNum, alphaDash, numeric, lowercase, uppercase };
|
|
2864
|
+
for (const [name, value] of Object.entries(booleanRules)) {
|
|
2865
|
+
if (value !== void 0 && typeof value !== "boolean") {
|
|
2866
|
+
errors.push(
|
|
2867
|
+
validationError(
|
|
2868
|
+
`Property '${propertyName}' has invalid rules.${name} value`,
|
|
2869
|
+
buildLocation7(filePath),
|
|
2870
|
+
`rules.${name} must be a boolean (true or false)`
|
|
2871
|
+
)
|
|
2872
|
+
);
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
if (minLength !== void 0 && isRuleCompatibleWithType("minLength", propertyType)) {
|
|
2876
|
+
if (typeof minLength !== "number" || minLength < 0 || !Number.isInteger(minLength)) {
|
|
2877
|
+
errors.push(
|
|
2878
|
+
validationError(
|
|
2879
|
+
`Property '${propertyName}' has invalid rules.minLength '${minLength}'`,
|
|
2880
|
+
buildLocation7(filePath),
|
|
2881
|
+
"rules.minLength must be a non-negative integer"
|
|
2882
|
+
)
|
|
2883
|
+
);
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
if (maxLength !== void 0 && isRuleCompatibleWithType("maxLength", propertyType)) {
|
|
2887
|
+
if (typeof maxLength !== "number" || maxLength < 1 || !Number.isInteger(maxLength)) {
|
|
2888
|
+
errors.push(
|
|
2889
|
+
validationError(
|
|
2890
|
+
`Property '${propertyName}' has invalid rules.maxLength '${maxLength}'`,
|
|
2891
|
+
buildLocation7(filePath),
|
|
2892
|
+
"rules.maxLength must be a positive integer"
|
|
2893
|
+
)
|
|
2894
|
+
);
|
|
2895
|
+
} else {
|
|
2896
|
+
const dbLength = property.length;
|
|
2897
|
+
if (dbLength !== void 0 && typeof dbLength === "number" && maxLength > dbLength) {
|
|
2898
|
+
errors.push(
|
|
2899
|
+
validationError(
|
|
2900
|
+
`Property '${propertyName}' has rules.maxLength (${maxLength}) greater than length (${dbLength})`,
|
|
2901
|
+
buildLocation7(filePath),
|
|
2902
|
+
"rules.maxLength must be <= length (database column size)"
|
|
2903
|
+
)
|
|
2904
|
+
);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
if (typeof minLength === "number" && typeof maxLength === "number" && minLength > maxLength) {
|
|
2717
2909
|
errors.push(
|
|
2718
2910
|
validationError(
|
|
2719
|
-
`Property '${propertyName}' has
|
|
2911
|
+
`Property '${propertyName}' has rules.minLength (${minLength}) > rules.maxLength (${maxLength})`,
|
|
2720
2912
|
buildLocation7(filePath),
|
|
2721
|
-
"rules.
|
|
2913
|
+
"rules.minLength must be <= rules.maxLength"
|
|
2722
2914
|
)
|
|
2723
2915
|
);
|
|
2724
2916
|
}
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2917
|
+
if (digits !== void 0) {
|
|
2918
|
+
if (typeof digits !== "number" || digits < 1 || !Number.isInteger(digits)) {
|
|
2919
|
+
errors.push(
|
|
2920
|
+
validationError(
|
|
2921
|
+
`Property '${propertyName}' has invalid rules.digits '${digits}'`,
|
|
2922
|
+
buildLocation7(filePath),
|
|
2923
|
+
"rules.digits must be a positive integer"
|
|
2924
|
+
)
|
|
2925
|
+
);
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
if (digitsBetween !== void 0) {
|
|
2929
|
+
if (!Array.isArray(digitsBetween) || digitsBetween.length !== 2 || typeof digitsBetween[0] !== "number" || typeof digitsBetween[1] !== "number") {
|
|
2930
|
+
errors.push(
|
|
2931
|
+
validationError(
|
|
2932
|
+
`Property '${propertyName}' has invalid rules.digitsBetween`,
|
|
2933
|
+
buildLocation7(filePath),
|
|
2934
|
+
"rules.digitsBetween must be [min, max] tuple of numbers"
|
|
2935
|
+
)
|
|
2936
|
+
);
|
|
2937
|
+
} else if (digitsBetween[0] > digitsBetween[1]) {
|
|
2938
|
+
errors.push(
|
|
2939
|
+
validationError(
|
|
2940
|
+
`Property '${propertyName}' has rules.digitsBetween[0] (${digitsBetween[0]}) > [1] (${digitsBetween[1]})`,
|
|
2941
|
+
buildLocation7(filePath),
|
|
2942
|
+
"First value must be <= second value"
|
|
2943
|
+
)
|
|
2944
|
+
);
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
if (startsWith !== void 0) {
|
|
2948
|
+
if (typeof startsWith !== "string" && (!Array.isArray(startsWith) || !startsWith.every((s) => typeof s === "string"))) {
|
|
2949
|
+
errors.push(
|
|
2950
|
+
validationError(
|
|
2951
|
+
`Property '${propertyName}' has invalid rules.startsWith`,
|
|
2952
|
+
buildLocation7(filePath),
|
|
2953
|
+
"rules.startsWith must be a string or array of strings"
|
|
2954
|
+
)
|
|
2955
|
+
);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
if (endsWith !== void 0) {
|
|
2959
|
+
if (typeof endsWith !== "string" && (!Array.isArray(endsWith) || !endsWith.every((s) => typeof s === "string"))) {
|
|
2960
|
+
errors.push(
|
|
2961
|
+
validationError(
|
|
2962
|
+
`Property '${propertyName}' has invalid rules.endsWith`,
|
|
2963
|
+
buildLocation7(filePath),
|
|
2964
|
+
"rules.endsWith must be a string or array of strings"
|
|
2965
|
+
)
|
|
2966
|
+
);
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
const numericSingleRules = { min, max, gt, lt, multipleOf };
|
|
2970
|
+
for (const [name, value] of Object.entries(numericSingleRules)) {
|
|
2971
|
+
if (value !== void 0 && isRuleCompatibleWithType(name, propertyType)) {
|
|
2972
|
+
if (typeof value !== "number") {
|
|
2973
|
+
errors.push(
|
|
2974
|
+
validationError(
|
|
2975
|
+
`Property '${propertyName}' has invalid rules.${name} '${value}'`,
|
|
2976
|
+
buildLocation7(filePath),
|
|
2977
|
+
`rules.${name} must be a number`
|
|
2978
|
+
)
|
|
2979
|
+
);
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
if (between !== void 0 && isRuleCompatibleWithType("between", propertyType)) {
|
|
2984
|
+
if (!Array.isArray(between) || between.length !== 2 || typeof between[0] !== "number" || typeof between[1] !== "number") {
|
|
2985
|
+
errors.push(
|
|
2986
|
+
validationError(
|
|
2987
|
+
`Property '${propertyName}' has invalid rules.between`,
|
|
2988
|
+
buildLocation7(filePath),
|
|
2989
|
+
"rules.between must be [min, max] tuple of numbers"
|
|
2990
|
+
)
|
|
2991
|
+
);
|
|
2992
|
+
} else if (between[0] > between[1]) {
|
|
2993
|
+
errors.push(
|
|
2994
|
+
validationError(
|
|
2995
|
+
`Property '${propertyName}' has rules.between[0] (${between[0]}) > [1] (${between[1]})`,
|
|
2996
|
+
buildLocation7(filePath),
|
|
2997
|
+
"First value must be <= second value"
|
|
2998
|
+
)
|
|
2999
|
+
);
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
if (typeof min === "number" && typeof max === "number" && min > max) {
|
|
2730
3003
|
errors.push(
|
|
2731
3004
|
validationError(
|
|
2732
|
-
`Property '${propertyName}'
|
|
3005
|
+
`Property '${propertyName}' has rules.min (${min}) > rules.max (${max})`,
|
|
2733
3006
|
buildLocation7(filePath),
|
|
2734
|
-
|
|
3007
|
+
"rules.min must be <= rules.max"
|
|
2735
3008
|
)
|
|
2736
3009
|
);
|
|
2737
3010
|
}
|
|
2738
|
-
if (
|
|
3011
|
+
if (typeof multipleOf === "number" && multipleOf <= 0) {
|
|
2739
3012
|
errors.push(
|
|
2740
3013
|
validationError(
|
|
2741
|
-
`Property '${propertyName}'
|
|
3014
|
+
`Property '${propertyName}' has invalid rules.multipleOf '${multipleOf}'`,
|
|
2742
3015
|
buildLocation7(filePath),
|
|
2743
|
-
|
|
3016
|
+
"rules.multipleOf must be a positive number"
|
|
2744
3017
|
)
|
|
2745
3018
|
);
|
|
2746
3019
|
}
|
|
2747
|
-
if (
|
|
2748
|
-
if (typeof
|
|
3020
|
+
if (arrayMin !== void 0) {
|
|
3021
|
+
if (typeof arrayMin !== "number" || arrayMin < 0 || !Number.isInteger(arrayMin)) {
|
|
2749
3022
|
errors.push(
|
|
2750
3023
|
validationError(
|
|
2751
|
-
`Property '${propertyName}' has invalid rules.
|
|
3024
|
+
`Property '${propertyName}' has invalid rules.arrayMin '${arrayMin}'`,
|
|
2752
3025
|
buildLocation7(filePath),
|
|
2753
|
-
"rules.
|
|
3026
|
+
"rules.arrayMin must be a non-negative integer"
|
|
2754
3027
|
)
|
|
2755
3028
|
);
|
|
2756
3029
|
}
|
|
2757
3030
|
}
|
|
2758
|
-
if (
|
|
2759
|
-
if (typeof
|
|
3031
|
+
if (arrayMax !== void 0) {
|
|
3032
|
+
if (typeof arrayMax !== "number" || arrayMax < 1 || !Number.isInteger(arrayMax)) {
|
|
2760
3033
|
errors.push(
|
|
2761
3034
|
validationError(
|
|
2762
|
-
`Property '${propertyName}' has invalid rules.
|
|
3035
|
+
`Property '${propertyName}' has invalid rules.arrayMax '${arrayMax}'`,
|
|
2763
3036
|
buildLocation7(filePath),
|
|
2764
|
-
"rules.
|
|
3037
|
+
"rules.arrayMax must be a positive integer"
|
|
2765
3038
|
)
|
|
2766
3039
|
);
|
|
2767
|
-
} else {
|
|
2768
|
-
const dbLength = property.length;
|
|
2769
|
-
if (dbLength !== void 0 && typeof dbLength === "number" && maxLength > dbLength) {
|
|
2770
|
-
errors.push(
|
|
2771
|
-
validationError(
|
|
2772
|
-
`Property '${propertyName}' has rules.maxLength (${maxLength}) greater than length (${dbLength})`,
|
|
2773
|
-
buildLocation7(filePath),
|
|
2774
|
-
"rules.maxLength must be less than or equal to length (database column size)"
|
|
2775
|
-
)
|
|
2776
|
-
);
|
|
2777
|
-
}
|
|
2778
3040
|
}
|
|
2779
3041
|
}
|
|
2780
|
-
if (
|
|
3042
|
+
if (typeof arrayMin === "number" && typeof arrayMax === "number" && arrayMin > arrayMax) {
|
|
2781
3043
|
errors.push(
|
|
2782
3044
|
validationError(
|
|
2783
|
-
`Property '${propertyName}' has rules.
|
|
3045
|
+
`Property '${propertyName}' has rules.arrayMin (${arrayMin}) > rules.arrayMax (${arrayMax})`,
|
|
2784
3046
|
buildLocation7(filePath),
|
|
2785
|
-
"rules.
|
|
3047
|
+
"rules.arrayMin must be <= rules.arrayMax"
|
|
2786
3048
|
)
|
|
2787
3049
|
);
|
|
2788
3050
|
}
|