mirror of
https://github.com/syuilo/ai.git
synced 2024-11-22 21:27:58 +00:00
すべてのプロパティをチェックしてからエラー送出
This commit is contained in:
parent
68b7765d58
commit
d463a0db30
|
@ -40,23 +40,44 @@ class Type<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkProperty<K extends keyof Config>(config: Object, key: K, type: Type<Config[K]>): config is { [J in K]: Config[K] } {
|
class OptionalProperty<K extends keyof Config> {
|
||||||
const result = key in config && type.check(config[key as string]);
|
protected readonly key: K;
|
||||||
if (!result) {
|
protected readonly type: Type<Config[K]>
|
||||||
warnWithPrefix(`config.json: Property '${key}': ${type.name} required`);
|
|
||||||
|
public constructor(key: K, type: Type<Config[K]>) {
|
||||||
|
this.key = key;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
check(config: Object): config is { [J in K]?: Config[K] } {
|
||||||
|
const key = this.key;
|
||||||
|
if (!(key in config)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const result = this.type.check((config as { [J in K]?: unknown})[key]);
|
||||||
|
if (!result) {
|
||||||
|
warnWithPrefix(`config.json: The type of property '${key}' must be ${this.type.name}`);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkOptionalProperty<K extends keyof Config>(config: Object, key: K, type: Type<Config[K]>): config is { [J in K]?: Config[K] } {
|
class Property<K extends keyof Config> extends OptionalProperty<K> {
|
||||||
if (!(key in config)) {
|
check(config: Object): config is { [J in K]: Config[K] } {
|
||||||
return true;
|
const result = this.key in config && this.type.check((config as { [J in K]?: unknown })[this.key]);
|
||||||
|
if (!result) {
|
||||||
|
warnWithPrefix(`config.json: Property '${this.key}': ${this.type.name} required`);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
const result = type.check(config[key as string]);
|
}
|
||||||
if (!result) {
|
|
||||||
warnWithPrefix(`config.json: The type of property '${key}' must be ${type.name}`);
|
type Intersection<P extends unknown[]> = P extends [infer Q, ...infer R] ? Q & Intersection<R> : unknown;
|
||||||
}
|
|
||||||
return result;
|
function checkProperties<P extends OptionalProperty<keyof Config>[]>(config: Object, ...properties: P):
|
||||||
|
config is object & Intersection<{ [I in keyof P]: P[I] extends OptionalProperty<infer K> ? { [J in K]: Config[K] } : never }> {
|
||||||
|
// メッセージを表示するためすべてのプロパティをチェックしてから結果を返す
|
||||||
|
return properties.map(p => p.check(config)).every(c => c);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setProperty<K extends keyof Config>(config: Object, key: K, value: Config[K]): asserts config is { [L in K]: Config[K] } {
|
function setProperty<K extends keyof Config>(config: Object, key: K, value: Config[K]): asserts config is { [L in K]: Config[K] } {
|
||||||
|
@ -67,20 +88,23 @@ function validate(config: unknown): Config {
|
||||||
if (!(config instanceof Object)) {
|
if (!(config instanceof Object)) {
|
||||||
warnWithPrefix('config.json: Root object required');
|
warnWithPrefix('config.json: Root object required');
|
||||||
} else if (
|
} else if (
|
||||||
checkProperty(config, 'host', Type.string) &&
|
checkProperties(
|
||||||
checkOptionalProperty(config, 'serverName', Type.string) &&
|
config,
|
||||||
checkProperty(config, 'i', Type.string) &&
|
new Property('host', Type.string),
|
||||||
checkOptionalProperty(config, 'master', Type.string) &&
|
new OptionalProperty('serverName', Type.string),
|
||||||
checkProperty(config, 'keywordEnabled', Type.boolean) &&
|
new Property('i', Type.string),
|
||||||
checkProperty(config, 'reversiEnabled', Type.boolean) &&
|
new OptionalProperty('master', Type.string),
|
||||||
checkProperty(config, 'notingEnabled', Type.boolean) &&
|
new Property('keywordEnabled', Type.boolean),
|
||||||
checkProperty(config, 'chartEnabled', Type.boolean) &&
|
new Property('reversiEnabled', Type.boolean),
|
||||||
checkProperty(config, 'serverMonitoring', Type.boolean) &&
|
new Property('notingEnabled', Type.boolean),
|
||||||
checkOptionalProperty(config, 'checkEmojisEnabled', Type.boolean) &&
|
new Property('chartEnabled', Type.boolean),
|
||||||
checkOptionalProperty(config, 'checkEmojisAtOnce', Type.boolean) &&
|
new Property('serverMonitoring', Type.boolean),
|
||||||
checkOptionalProperty(config, 'mecab', Type.string) &&
|
new OptionalProperty('checkEmojisEnabled', Type.boolean),
|
||||||
checkOptionalProperty(config, 'mecabDic', Type.string) &&
|
new OptionalProperty('checkEmojisAtOnce', Type.boolean),
|
||||||
checkOptionalProperty(config, 'memoryDir', Type.string)
|
new OptionalProperty('mecab', Type.string),
|
||||||
|
new OptionalProperty('mecabDic', Type.string),
|
||||||
|
new OptionalProperty('memoryDir', Type.string)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
setProperty(config, 'wsUrl', config.host.replace('http', 'ws'));
|
setProperty(config, 'wsUrl', config.host.replace('http', 'ws'));
|
||||||
setProperty(config, 'apiUrl', config.host + '/api');
|
setProperty(config, 'apiUrl', config.host + '/api');
|
||||||
|
|
Loading…
Reference in a new issue