3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-15 05:41:51 +00:00

Validate basic plugin options structure and override criteria types

This commit is contained in:
Dragory 2020-07-30 00:29:44 +03:00
parent 70e072e664
commit ed757dcbe2
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
2 changed files with 56 additions and 20 deletions

View file

@ -4,11 +4,13 @@
import { Member } from "eris";
import { configUtils, helpers, PluginBlueprint, PluginData, PluginOptions } from "knub";
import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils";
import { deepKeyIntersect, errorMessage, successMessage } from "./utils";
import { decodeAndValidateStrict, StrictValidationError, validate } from "./validatorUtils";
import { deepKeyIntersect, errorMessage, successMessage, tNullable } from "./utils";
import { ZeppelinPluginBlueprint } from "./plugins/ZeppelinPluginBlueprint";
import { TZeppelinKnub } from "./types";
import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; // TODO: Export from Knub index
import * as t from "io-ts";
import { PluginOverrideCriteria } from "knub/dist/config/configTypes";
const { getMemberLevel } = helpers;
@ -27,35 +29,69 @@ export function hasPermission(pluginData: PluginData<any>, permission: string, m
return helpers.hasPermission(config, permission);
}
const PluginOverrideCriteriaType = t.recursion("PluginOverrideCriteriaType", () =>
t.type({
channel: tNullable(t.union([t.string, t.array(t.string)])),
category: tNullable(t.union([t.string, t.array(t.string)])),
level: tNullable(t.union([t.string, t.array(t.string)])),
user: tNullable(t.union([t.string, t.array(t.string)])),
role: tNullable(t.union([t.string, t.array(t.string)])),
all: tNullable(t.array(PluginOverrideCriteriaType)),
any: tNullable(t.array(PluginOverrideCriteriaType)),
not: tNullable(PluginOverrideCriteriaType),
extra: t.unknown,
}),
);
const BasicPluginStructureType = t.type({
enabled: tNullable(t.boolean),
config: tNullable(t.unknown),
overrides: tNullable(t.array(PluginOverrideCriteriaType)),
replaceDefaultOverrides: tNullable(t.boolean),
});
export function getPluginConfigPreprocessor(
blueprint: ZeppelinPluginBlueprint,
customPreprocessor?: PluginBlueprint<any>["configPreprocessor"],
) {
return async (options: PluginOptions<any>) => {
const basicOptionsValidation = validate(BasicPluginStructureType, options);
if (basicOptionsValidation instanceof StrictValidationError) {
throw basicOptionsValidation;
}
if (customPreprocessor) {
options = await customPreprocessor(options);
}
const decodedConfig = blueprint.configSchema
? decodeAndValidateStrict(blueprint.configSchema, options.config)
: options.config;
if (decodedConfig instanceof StrictValidationError) {
throw decodedConfig;
let decodedConfig = {};
const decodedOverrides = [];
if (options.config) {
decodedConfig = blueprint.configSchema
? decodeAndValidateStrict(blueprint.configSchema, options.config)
: options.config;
if (decodedConfig instanceof StrictValidationError) {
throw decodedConfig;
}
}
const decodedOverrides = [];
for (const override of options.overrides || []) {
const overrideConfigMergedWithBaseConfig = configUtils.mergeConfig(options.config, override.config || {});
const decodedOverrideConfig = blueprint.configSchema
? decodeAndValidateStrict(blueprint.configSchema, overrideConfigMergedWithBaseConfig)
: overrideConfigMergedWithBaseConfig;
if (decodedOverrideConfig instanceof StrictValidationError) {
throw decodedOverrideConfig;
if (options.overrides) {
for (const override of options.overrides || []) {
const overrideConfigMergedWithBaseConfig = configUtils.mergeConfig(options.config, override.config || {});
const decodedOverrideConfig = blueprint.configSchema
? decodeAndValidateStrict(blueprint.configSchema, overrideConfigMergedWithBaseConfig)
: overrideConfigMergedWithBaseConfig;
if (decodedOverrideConfig instanceof StrictValidationError) {
throw decodedOverrideConfig;
}
decodedOverrides.push({
...override,
config: deepKeyIntersect(decodedOverrideConfig, override.config || {}),
});
}
decodedOverrides.push({
...override,
config: deepKeyIntersect(decodedOverrideConfig, override.config || {}),
});
}
return {

View file

@ -98,7 +98,7 @@ export function validate(schema: t.Type<any>, value: any): StrictValidationError
* Decodes and validates the given value against the given schema while also disallowing extra properties
* See: https://github.com/gcanti/io-ts/issues/322
*/
export function decodeAndValidateStrict(schema: t.HasProps, value: any): StrictValidationError | any {
export function decodeAndValidateStrict<T extends t.HasProps>(schema: T, value: any): StrictValidationError | any {
const validationResult = t.exact(schema).decode(value);
return pipe(
validationResult,