schema-dsl 1.1.1 → 1.1.2
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/CHANGELOG.md +173 -0
- package/README.md +626 -8
- package/docs/number-operators.md +442 -0
- package/index.d.ts +3268 -3455
- package/lib/adapters/DslAdapter.js +56 -7
- package/lib/core/DslBuilder.js +47 -1
- package/package.json +1 -1
|
@@ -268,12 +268,59 @@ class DslAdapter {
|
|
|
268
268
|
* @param {string} baseType - 基础类型
|
|
269
269
|
* @param {string} constraint - 约束字符串
|
|
270
270
|
* @returns {Object} 约束对象
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* // 比较运算符 (v1.2.0+)
|
|
274
|
+
* _parseConstraint('number', '>0') // { exclusiveMinimum: 0 }
|
|
275
|
+
* _parseConstraint('number', '>=18') // { minimum: 18 }
|
|
276
|
+
* _parseConstraint('number', '<100') // { exclusiveMaximum: 100 }
|
|
277
|
+
* _parseConstraint('number', '<=100') // { maximum: 100 }
|
|
278
|
+
* _parseConstraint('number', '=100') // { enum: [100] }
|
|
279
|
+
* _parseConstraint('number', '>0.5') // { exclusiveMinimum: 0.5 } 支持小数
|
|
271
280
|
*/
|
|
272
281
|
static _parseConstraint(baseType, constraint) {
|
|
273
282
|
if (!constraint) return {};
|
|
274
283
|
|
|
275
284
|
const result = {};
|
|
276
285
|
|
|
286
|
+
// ========== 比较运算符(v1.1.2新增,最高优先级)==========
|
|
287
|
+
if (baseType === 'number' || baseType === 'integer') {
|
|
288
|
+
// 1. 大于等于: >=18, >=-10 (支持负数)
|
|
289
|
+
const gteMatch = constraint.match(/^>=(-?\d+(?:\.\d+)?)$/);
|
|
290
|
+
if (gteMatch) {
|
|
291
|
+
result.minimum = parseFloat(gteMatch[1]);
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// 2. 小于等于: <=100, <=-10 (支持负数)
|
|
296
|
+
const lteMatch = constraint.match(/^<=(-?\d+(?:\.\d+)?)$/);
|
|
297
|
+
if (lteMatch) {
|
|
298
|
+
result.maximum = parseFloat(lteMatch[1]);
|
|
299
|
+
return result;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// 3. 大于: >0, >-10 (不包括边界值,支持负数)
|
|
303
|
+
const gtMatch = constraint.match(/^>(-?\d+(?:\.\d+)?)$/);
|
|
304
|
+
if (gtMatch) {
|
|
305
|
+
result.exclusiveMinimum = parseFloat(gtMatch[1]);
|
|
306
|
+
return result;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// 4. 小于: <100, <-10 (不包括边界值,支持负数)
|
|
310
|
+
const ltMatch = constraint.match(/^<(-?\d+(?:\.\d+)?)$/);
|
|
311
|
+
if (ltMatch) {
|
|
312
|
+
result.exclusiveMaximum = parseFloat(ltMatch[1]);
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// 5. 等于: =100, =-10 (支持负数)
|
|
317
|
+
const eqMatch = constraint.match(/^=(-?\d+(?:\.\d+)?)$/);
|
|
318
|
+
if (eqMatch) {
|
|
319
|
+
result.enum = [parseFloat(eqMatch[1])];
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
277
324
|
// 枚举: value1|value2|value3 (优先检查,避免被数字范围误判)
|
|
278
325
|
if (constraint.includes('|') && !/^\d+-\d+$/.test(constraint)) {
|
|
279
326
|
result.enum = constraint.split('|').map(v => v.trim());
|
|
@@ -281,7 +328,8 @@ class DslAdapter {
|
|
|
281
328
|
}
|
|
282
329
|
|
|
283
330
|
// 范围约束: min-max 或 min- 或 -max
|
|
284
|
-
|
|
331
|
+
// 支持小数: 0.5-99.9
|
|
332
|
+
const rangeMatch = constraint.match(/^(\d*\.?\d*)-(\d*\.?\d*)$/);
|
|
285
333
|
if (rangeMatch) {
|
|
286
334
|
const [, min, max] = rangeMatch;
|
|
287
335
|
if (baseType === 'string') {
|
|
@@ -291,20 +339,21 @@ class DslAdapter {
|
|
|
291
339
|
if (min) result.minItems = parseInt(min, 10);
|
|
292
340
|
if (max) result.maxItems = parseInt(max, 10);
|
|
293
341
|
} else {
|
|
294
|
-
if (min) result.minimum =
|
|
295
|
-
if (max) result.maximum =
|
|
342
|
+
if (min) result.minimum = parseFloat(min);
|
|
343
|
+
if (max) result.maximum = parseFloat(max);
|
|
296
344
|
}
|
|
297
345
|
return result;
|
|
298
346
|
}
|
|
299
347
|
|
|
300
348
|
// 单个约束: min, max
|
|
301
|
-
|
|
349
|
+
// 支持小数: 99.99
|
|
350
|
+
const singleMatch = constraint.match(/^(\d+(?:\.\d+)?)$/);
|
|
302
351
|
if (singleMatch) {
|
|
303
|
-
const value =
|
|
352
|
+
const value = parseFloat(singleMatch[1]);
|
|
304
353
|
if (baseType === 'string') {
|
|
305
|
-
result.maxLength = value;
|
|
354
|
+
result.maxLength = Math.floor(value);
|
|
306
355
|
} else if (baseType === 'array') {
|
|
307
|
-
result.maxItems = value;
|
|
356
|
+
result.maxItems = Math.floor(value);
|
|
308
357
|
} else {
|
|
309
358
|
result.maximum = value;
|
|
310
359
|
}
|
package/lib/core/DslBuilder.js
CHANGED
|
@@ -383,12 +383,58 @@ class DslBuilder {
|
|
|
383
383
|
/**
|
|
384
384
|
* 解析约束
|
|
385
385
|
* @private
|
|
386
|
+
*
|
|
387
|
+
* @example
|
|
388
|
+
* // 比较运算符 (v1.2.0+)
|
|
389
|
+
* _parseConstraint('number', '>0') // { exclusiveMinimum: 0 }
|
|
390
|
+
* _parseConstraint('number', '>=18') // { minimum: 18 }
|
|
391
|
+
* _parseConstraint('number', '<100') // { exclusiveMaximum: 100 }
|
|
392
|
+
* _parseConstraint('number', '<=100') // { maximum: 100 }
|
|
393
|
+
* _parseConstraint('number', '=100') // { enum: [100] }
|
|
386
394
|
*/
|
|
387
395
|
_parseConstraint(type, constraint) {
|
|
388
396
|
const result = {};
|
|
389
397
|
|
|
390
398
|
if (type === 'string' || type === 'number' || type === 'integer') {
|
|
391
|
-
//
|
|
399
|
+
// ========== 比较运算符(v1.1.2新增,仅number/integer,最高优先级)==========
|
|
400
|
+
if (type === 'number' || type === 'integer') {
|
|
401
|
+
// 1. 大于等于: >=18, >=-10 (支持负数)
|
|
402
|
+
const gteMatch = constraint.match(/^>=(-?\d+(?:\.\d+)?)$/);
|
|
403
|
+
if (gteMatch) {
|
|
404
|
+
result.minimum = parseFloat(gteMatch[1]);
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// 2. 小于等于: <=100, <=-10 (支持负数)
|
|
409
|
+
const lteMatch = constraint.match(/^<=(-?\d+(?:\.\d+)?)$/);
|
|
410
|
+
if (lteMatch) {
|
|
411
|
+
result.maximum = parseFloat(lteMatch[1]);
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// 3. 大于: >0, >-10 (不包括边界值,支持负数)
|
|
416
|
+
const gtMatch = constraint.match(/^>(-?\d+(?:\.\d+)?)$/);
|
|
417
|
+
if (gtMatch) {
|
|
418
|
+
result.exclusiveMinimum = parseFloat(gtMatch[1]);
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// 4. 小于: <100, <-10 (不包括边界值,支持负数)
|
|
423
|
+
const ltMatch = constraint.match(/^<(-?\d+(?:\.\d+)?)$/);
|
|
424
|
+
if (ltMatch) {
|
|
425
|
+
result.exclusiveMaximum = parseFloat(ltMatch[1]);
|
|
426
|
+
return result;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// 5. 等于: =100, =-10 (支持负数)
|
|
430
|
+
const eqMatch = constraint.match(/^=(-?\d+(?:\.\d+)?)$/);
|
|
431
|
+
if (eqMatch) {
|
|
432
|
+
result.enum = [parseFloat(eqMatch[1])];
|
|
433
|
+
return result;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ========== 范围约束: min-max ==========
|
|
392
438
|
if (constraint.includes('-')) {
|
|
393
439
|
const [min, max] = constraint.split('-').map(v => v.trim());
|
|
394
440
|
|