juniper
Version:
ESM JSON Schema builder for static Typescript inference.
175 lines (174 loc) • 5.36 kB
JavaScript
import { maxInt } from '../lib/constants.js';
import { AbstractSchema } from '../lib/schema.js';
import { NeverSchema } from './never.js';
const containsSym = Symbol('contains');
export const prefixItemsSym = Symbol('prefixItems');
export class ArraySchema extends AbstractSchema {
static falseItems = new NeverSchema();
#contains;
#items;
#maxContains;
#maxItems;
#minContains;
#minItems;
#prefixItems;
#uniqueItems;
schemaType = 'array';
constructor(items = {}){
const options = items instanceof AbstractSchema ? {
items
} : items;
super(options);
this.#items = options.items ?? null;
this.#maxContains = options.maxContains ?? Number.POSITIVE_INFINITY;
this.#maxItems = options.maxItems ?? Number.POSITIVE_INFINITY;
this.#minContains = options.minContains ?? 1;
this.#minItems = options.minItems ?? 0;
this.#uniqueItems = options.uniqueItems ?? false;
this.#contains = options[containsSym] ?? null;
this.#prefixItems = options[prefixItemsSym] ?? [];
}
static create(options) {
return new ArraySchema(options);
}
items(items) {
return this.clone({
items
});
}
maxItems(maxItems) {
return this.clone({
maxItems
});
}
minItems(minItems) {
return this.clone({
minItems
});
}
uniqueItems(uniqueItems) {
return this.clone({
uniqueItems
});
}
contains(contains) {
return this.clone({
[containsSym]: contains
});
}
maxContains(maxContains) {
return this.clone({
maxContains
});
}
minContains(minContains) {
return this.clone({
minContains
});
}
prefixItem(schema) {
return this.clone({
[prefixItemsSym]: [
...this.#prefixItems,
schema
]
});
}
prependPrefixItem(schema) {
return this.clone({
[prefixItemsSym]: [
schema,
...this.#prefixItems
]
});
}
getCloneParams() {
return {
...super.getCloneParams(),
items: this.#items,
maxContains: this.#maxContains,
maxItems: this.#maxItems,
minContains: this.#minContains,
minItems: this.#minItems,
uniqueItems: this.#uniqueItems,
[containsSym]: this.#contains,
[prefixItemsSym]: [
...this.#prefixItems
]
};
}
static getDefaultValues(params) {
return {
...super.getDefaultValues(params),
maxContains: maxInt,
minContains: 1,
maxItems: maxInt,
minItems: 0,
uniqueItems: false
};
}
toSchema(params) {
const base = super.toSchema(params);
if (this.#maxItems < Number.POSITIVE_INFINITY) {
base.maxItems = this.#maxItems;
}
if (this.#minItems > 0) {
base.minItems = this.#minItems;
}
if (this.#uniqueItems) {
base.uniqueItems = true;
}
let items = null;
if (this.#items) {
items = this.#items === ArraySchema.falseItems ? false : ArraySchema.getSchema(this.#items, params);
}
const prefixItems = this.#prefixItems.map((schema)=>ArraySchema.getSchema(schema, params));
if (params.openApi30) {
if (items !== null) {
if (items === false) {
if (prefixItems.length > 0) {
base.items = prefixItems.length === 1 ? prefixItems[0] : {
anyOf: prefixItems
};
} else {
base.items = ArraySchema.getSchema(ArraySchema.falseItems, params);
}
} else {
const allItems = [
items,
...prefixItems
];
base.items = allItems.length === 1 ? allItems[0] : {
anyOf: allItems
};
}
}
const minItems = this.#contains ? Math.max(this.#minItems, this.#minContains) : this.#minItems;
if (minItems) {
base.minItems = minItems;
}
} else {
if (items !== null) {
base.items = items;
}
if (this.#minItems > 0) {
base.minItems = this.#minItems;
}
if (prefixItems.length > 0) {
base.prefixItems = prefixItems;
}
if (this.#contains) {
base.contains = ArraySchema.getSchema(this.#contains, params);
if (this.#maxContains < Number.POSITIVE_INFINITY) {
base.maxContains = this.#maxContains;
}
if (this.#minContains !== 1) {
base.minContains = this.#minContains;
}
}
}
return base;
}
}
export const ArraySchemaOverride = ArraySchema;
//# sourceMappingURL=array.js.map