UNPKG

juniper

Version:

ESM JSON Schema builder for static Typescript inference.

142 lines (141 loc) 4.32 kB
import { AbstractSchema } from '../lib/schema.js'; import { mergeAllOf } from '../lib/utils.js'; const gcd = (x, y)=>{ let a = x; let b = y; while(b){ const t = b; b = a % b; a = t; } return a; }; const lcm = (x, y)=>x * y / gcd(x, y); const numToExclusive = (value)=>typeof value === 'number' ? { value, exclusive: false } : value; export class NumberSchema extends AbstractSchema { #maximum; #minimum; #multipleOfs; constructor(options = {}){ super(options); this.schemaType = options.type ?? 'number'; this.#maximum = numToExclusive(options.maximum ?? Number.POSITIVE_INFINITY); this.#minimum = numToExclusive(options.minimum ?? Number.NEGATIVE_INFINITY); this.#multipleOfs = [ options.multipleOf ?? [] ].flat(); } static create(options) { return new NumberSchema(options); } type(type) { return this.clone({ type }); } multipleOf(multipleOf) { return this.clone({ multipleOf: [ ...this.#multipleOfs, multipleOf ] }); } maximum(maximum) { return this.clone({ maximum: numToExclusive(maximum) }); } exclusiveMaximum(exclusiveMaximum) { return this.maximum({ value: exclusiveMaximum, exclusive: true }); } minimum(minimum) { return this.clone({ minimum: numToExclusive(minimum) }); } exclusiveMinimum(exclusiveMinimum) { return this.minimum({ value: exclusiveMinimum, exclusive: true }); } getCloneParams() { return { ...super.getCloneParams(), maximum: this.#maximum, minimum: this.#minimum, multipleOf: [ ...this.#multipleOfs ], type: this.schemaType }; } static getDefaultValues(params) { const superParams = super.getDefaultValues(params); if (params.openApi30) { return { ...superParams, minimum: -Number.MAX_VALUE, exclusiveMinimum: false, maximum: Number.MAX_VALUE, exclusiveMaximum: false }; } return { ...superParams, minimum: -Number.MAX_VALUE, exclusiveMinimum: -Number.MAX_VALUE, maximum: Number.MAX_VALUE, exclusiveMaximum: Number.MAX_VALUE }; } toSchema(params) { const base = super.toSchema(params); if (this.#minimum.value > Number.NEGATIVE_INFINITY) { if (this.#minimum.exclusive) { if (params.openApi30) { base.minimum = this.#minimum.value; base.exclusiveMinimum = true; } else { base.exclusiveMinimum = this.#minimum.value; } } else { base.minimum = this.#minimum.value; } } if (this.#maximum.value < Number.POSITIVE_INFINITY) { if (this.#maximum.exclusive) { if (params.openApi30) { base.maximum = this.#maximum.value; base.exclusiveMaximum = true; } else { base.exclusiveMaximum = this.#maximum.value; } } else { base.maximum = this.#maximum.value; } } const integerMultiples = this.#multipleOfs.filter((x)=>Number.isInteger(x)); const floatMultiples = this.#multipleOfs.filter((x)=>!Number.isInteger(x)); if (integerMultiples.length > 0) { base.multipleOf = integerMultiples.reduce((acc, val)=>lcm(acc, val), 1); mergeAllOf(base, floatMultiples.map((multipleOf)=>({ multipleOf }))); } else if (floatMultiples.length > 0) { [base.multipleOf] = floatMultiples; mergeAllOf(base, floatMultiples.slice(1).map((multipleOf)=>({ multipleOf }))); } return base; } } //# sourceMappingURL=number.js.map