shelving
Version:
Toolkit for using data in JavaScript.
48 lines (47 loc) • 1.76 kB
JavaScript
import { isArray, requireFirst } from "../util/array.js";
import { getKeys, getProps, isProp } from "../util/object.js";
import { Schema } from "./Schema.js";
/** Get the options for a choice field as an array. */
export function getChoiceEntries(options) {
return isArray(options) ? options.map(_makeKeyEntry) : getProps(options);
}
function _makeKeyEntry(k) {
return [k, k];
}
/** Get the keys for a choice field as an array. */
export function getChoiceKeys(options) {
return isArray(options) ? options : getKeys(options);
}
/** Get the options for a choice field as an array. */
export function isOption(options, option) {
return isArray(options) ? options.includes(option) : isProp(options, option);
}
/** Choose from an allowed set of values. */
export class ChoiceSchema extends Schema {
options;
constructor({ one = "choice", title = "Choice", placeholder = `No ${one}`, options, value = requireFirst(isArray(options) ? options : getKeys(options)), ...rest }) {
super({ one, title, value, placeholder, ...rest });
this.options = options;
}
validate(unsafeValue = this.value) {
if (typeof unsafeValue === "string" && isOption(this.options, unsafeValue))
return unsafeValue;
throw "Unknown value";
}
// Implement iterable.
*[Symbol.iterator]() {
yield* getChoiceEntries(this.options);
}
// Get the current list of keys for this choice.
keys() {
return getChoiceKeys(this.options);
}
// Get the current list of entries for this choice.
entries() {
return getChoiceEntries(this.options);
}
}
/** Choose from an allowed set of values. */
export function CHOICE(options) {
return new ChoiceSchema({ options });
}