enum-plus
Version:
A drop-in replacement for native enum. Like native enum but much better!
147 lines (138 loc) • 5.01 kB
JavaScript
import { EnumItemsArray } from "./enum-items.js";
import { localizer } from "./global-config.js";
import { ENUM_OPTIONS, IS_ENUM, ITEMS, KEYS, LABELS, META, NAMED, VALUES } from "./utils.js";
/**
* - **EN:** Enum collection extension base class, used to extend the Enums
* - **CN:** 枚举集合扩展基类,用于扩展枚举
*/
// @ts-expect-error: because don't know which methods are added
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class EnumExtensionClass {}
/**
* - **EN:** Enum collection
* - **CN:** 枚举项集合
*/
export class EnumCollectionClass extends EnumExtensionClass {
__options__;
// used for e2e serialization
__items__;
constructor(init = {}, options) {
super();
// Do not use class field here, because don't want print this field in Node.js
Object.defineProperty(this, '__options__', {
value: options,
writable: false,
enumerable: false,
configurable: false
});
const keys = Object.keys(init);
// Generate enum items array
const items = new EnumItemsArray(init, options);
Object.freeze(items);
// @ts-expect-error: because use ITEMS to avoid naming conflicts in case of 'items' field name is taken
this[keys.includes('items') ? ITEMS : 'items'] = items;
Object.defineProperty(this, '__items__', {
value: items,
writable: false,
enumerable: false,
configurable: false
});
// @ts-expect-error: because use KEYS to avoid naming conflicts in case of 'keys' field name is taken
this[keys.includes('keys') ? KEYS : 'keys'] = items[KEYS];
// @ts-expect-error: because use VALUES to avoid naming conflicts in case of 'values' field name is taken
this[keys.includes('values') ? VALUES : 'values'] = items[VALUES];
// @ts-expect-error: because use NAMED to avoid naming conflicts in case of 'named' field name is taken
this[keys.includes('named') ? NAMED : 'named'] = items.named;
// @ts-expect-error: because use META to avoid naming conflicts in case of 'meta' field name is taken
this[keys.includes('meta') ? META : 'meta'] = items.meta;
// Add keys to the instance, allows picking enum values by keys
items.forEach(item => {
// @ts-expect-error: because of dynamic property
this[item.key] = item.value;
});
// @ts-expect-error: because use LABELS to avoid naming conflicts in case of 'labels' field name is taken
Object.defineProperty(this, keys.includes('labels') ? LABELS : 'labels', {
enumerable: true,
configurable: false,
get: function () {
return this.__items__.labels;
}
});
Object.freeze(this);
}
/**
* - **EN:** A boolean value indicates that this is an enum collection instance.
* - **CN:** 布尔值,表示这是一个枚举集合实例
*/
// Do not use readonly field here, because don't want print this field in Node.js
// eslint-disable-next-line @typescript-eslint/class-literal-property-style
get [IS_ENUM]() {
return true;
}
/**
* - **EN:** Get the options to initialize the enum.
* - **CN:** 获取初始化枚举时的选项
*/
get [ENUM_OPTIONS]() {
return this.__options__;
}
[Symbol.hasInstance](instance) {
return instance instanceof this.__items__;
}
/**
* The enum collection name, supports localization. Note that it usually returns a string, but if
* a custom `localize` function is set, the return value may vary depending on the implementation
* of the method.
*
* - **CN:** 枚举集合显示名称,支持本地化。注意,通常情况下返回的是字符串,但如果设置了自定义的 `localize` 函数,则返回值可能有所不同,取决于方法的实现
*
* @returns {string | undefined} The localized name of the enum collection, or undefined if not
* set.
*/
get name() {
if (typeof this.__options__?.name === 'function') {
return this.__options__.name(undefined);
}
const localize = this.__options__?.localize ?? localizer.localize;
if (typeof localize === 'function') {
return localize(this.__options__?.name);
}
return this.__options__?.name;
}
label(keyOrValue) {
return this.__items__.label(keyOrValue);
}
key(value) {
return this.__items__.key(value);
}
raw(value) {
if (value != null) {
return this.__items__.raw(value);
} else {
return this.__items__.raw();
}
}
has(keyOrValue) {
return this.__items__.has(keyOrValue);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
findBy(...rest) {
return this.__items__.findBy(...rest);
}
toList(config) {
return this.__items__.toList(config);
}
toMap(config) {
return this.__items__.toMap(config);
}
get valueType() {
return this.__items__.valueType;
}
get keyType() {
return this.__items__.keyType;
}
get rawType() {
return this.__items__.rawType;
}
}
//# sourceMappingURL=enum-collection.js.map