hexo-theme-amane/include/common/utils.js

151 lines
3.8 KiB
JavaScript
Raw Normal View History

const doc = Symbol('@doc');
const type = Symbol('@type');
const format = Symbol('@format');
const required = Symbol('@required');
const requires = Symbol('@requires');
const defaultValue = Symbol('@default');
const descriptors = {
doc,
type,
format,
requires,
required,
defaultValue
};
const is = (() => ({
2018-10-28 05:29:47 +00:00
number(value) {
return typeof (value) === 'number';
},
string(value) {
return typeof (value) === 'string';
},
array(value) {
return Array.isArray(value);
},
boolean(value) {
return typeof (value) === 'boolean';
},
object(value) {
return typeof (value) === 'object' && value.constructor == Object;
},
function(value) {
return typeof (value) === 'function';
},
regexp(value) {
return value instanceof RegExp;
},
undefined(value) {
return typeof (value) === 'undefined';
},
null(value) {
return value === null;
},
spec(value) {
if (!value.hasOwnProperty(type)) {
return false;
}
if (!is.string(value[type]) && !is.array(value[type])) {
return false;
}
if (value.hasOwnProperty(doc) && !is.string(value[doc])) {
return false;
}
if (value.hasOwnProperty(required) && !is.boolean(value[required])) {
return false;
}
if (value.hasOwnProperty(requires) && !is.function(value[requires])) {
return false;
}
if (value.hasOwnProperty(format) && !is.regexp(value[format])) {
return false;
}
return true;
}
}))();
class ConfigError extends Error {
constructor(spec, path) {
super();
this.spec = spec;
this.path = path;
}
}
class InvalidSpecError extends ConfigError {
constructor(spec, path) {
super(spec, path);
this.message = `The specification '${path.join('.')}' is invalid.`;
}
}
class MissingRequiredError extends ConfigError {
constructor(spec, path) {
super(spec, path);
this.message = `Configuration file do not have the required '${path.join('.')}' field.`;
}
}
class TypeMismatchError extends ConfigError {
constructor(spec, path, config) {
super(spec, path);
this.config = config;
this.message = `Configuration '${path.join('.')}' is not one of the '${spec[type]}' type.`;
}
}
class FormatMismatchError extends ConfigError {
constructor(spec, path, config) {
super(spec, path);
this.config = config;
this.message = `Configuration '${path.join('.')}' do not match the format '${spec[format]}'.`;
}
}
class VersionError extends Error {
}
class VersionNotFoundError extends VersionError {
constructor() {
super(`Version number is not found in the configuration file.`);
}
}
class VersionMalformedError extends VersionError {
constructor(version) {
super(`Version number ${version} is malformed.`);
this.version = version;
}
}
class VersionMismatchError extends VersionError {
constructor(specVersion, configVersion, isConfigVersionSmaller) {
super();
this.specVersion = specVersion;
this.configVersion = configVersion;
if (isConfigVersionSmaller) {
this.message = `The configuration version ${configVersion} is far behind the specification version ${specVersion}.`;
} else {
this.message = `The configuration version ${configVersion} is way ahead of the specification version ${specVersion}.`;
}
}
}
const errors = {
ConfigError,
InvalidSpecError,
MissingRequiredError,
TypeMismatchError,
FormatMismatchError,
VersionError,
VersionMalformedError,
VersionNotFoundError,
VersionMismatchError
}
module.exports = {
is,
descriptors,
errors
};