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.
@@ -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
- const rangeMatch = constraint.match(/^(\d*)-(\d*)$/);
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 = parseInt(min, 10);
295
- if (max) result.maximum = parseInt(max, 10);
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
- const singleMatch = constraint.match(/^(\d+)$/);
349
+ // 支持小数: 99.99
350
+ const singleMatch = constraint.match(/^(\d+(?:\.\d+)?)$/);
302
351
  if (singleMatch) {
303
- const value = parseInt(singleMatch[1], 10);
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
  }
@@ -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
- // 范围约束: min-max
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schema-dsl",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "简洁强大的JSON Schema验证库 - DSL语法 + String扩展 + 便捷validate",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",