.
This commit is contained in:
		
							
								
								
									
										476
									
								
								qwen/nodejs/node_modules/joi/lib/manifest.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										476
									
								
								qwen/nodejs/node_modules/joi/lib/manifest.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,476 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const Assert = require('@hapi/hoek/lib/assert');
 | 
			
		||||
const Clone = require('@hapi/hoek/lib/clone');
 | 
			
		||||
 | 
			
		||||
const Common = require('./common');
 | 
			
		||||
const Messages = require('./messages');
 | 
			
		||||
const Ref = require('./ref');
 | 
			
		||||
const Template = require('./template');
 | 
			
		||||
 | 
			
		||||
let Schemas;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const internals = {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.describe = function (schema) {
 | 
			
		||||
 | 
			
		||||
    const def = schema._definition;
 | 
			
		||||
 | 
			
		||||
    // Type
 | 
			
		||||
 | 
			
		||||
    const desc = {
 | 
			
		||||
        type: schema.type,
 | 
			
		||||
        flags: {},
 | 
			
		||||
        rules: []
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Flags
 | 
			
		||||
 | 
			
		||||
    for (const flag in schema._flags) {
 | 
			
		||||
        if (flag[0] !== '_') {
 | 
			
		||||
            desc.flags[flag] = internals.describe(schema._flags[flag]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!Object.keys(desc.flags).length) {
 | 
			
		||||
        delete desc.flags;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Preferences
 | 
			
		||||
 | 
			
		||||
    if (schema._preferences) {
 | 
			
		||||
        desc.preferences = Clone(schema._preferences, { shallow: ['messages'] });
 | 
			
		||||
        delete desc.preferences[Common.symbols.prefs];
 | 
			
		||||
        if (desc.preferences.messages) {
 | 
			
		||||
            desc.preferences.messages = Messages.decompile(desc.preferences.messages);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Allow / Invalid
 | 
			
		||||
 | 
			
		||||
    if (schema._valids) {
 | 
			
		||||
        desc.allow = schema._valids.describe();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (schema._invalids) {
 | 
			
		||||
        desc.invalid = schema._invalids.describe();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Rules
 | 
			
		||||
 | 
			
		||||
    for (const rule of schema._rules) {
 | 
			
		||||
        const ruleDef = def.rules[rule.name];
 | 
			
		||||
        if (ruleDef.manifest === false) {                           // Defaults to true
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const item = { name: rule.name };
 | 
			
		||||
 | 
			
		||||
        for (const custom in def.modifiers) {
 | 
			
		||||
            if (rule[custom] !== undefined) {
 | 
			
		||||
                item[custom] = internals.describe(rule[custom]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (rule.args) {
 | 
			
		||||
            item.args = {};
 | 
			
		||||
            for (const key in rule.args) {
 | 
			
		||||
                const arg = rule.args[key];
 | 
			
		||||
                if (key === 'options' &&
 | 
			
		||||
                    !Object.keys(arg).length) {
 | 
			
		||||
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                item.args[key] = internals.describe(arg, { assign: key });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!Object.keys(item.args).length) {
 | 
			
		||||
                delete item.args;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        desc.rules.push(item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!desc.rules.length) {
 | 
			
		||||
        delete desc.rules;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Terms (must be last to verify no name conflicts)
 | 
			
		||||
 | 
			
		||||
    for (const term in schema.$_terms) {
 | 
			
		||||
        if (term[0] === '_') {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Assert(!desc[term], 'Cannot describe schema due to internal name conflict with', term);
 | 
			
		||||
 | 
			
		||||
        const items = schema.$_terms[term];
 | 
			
		||||
        if (!items) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (items instanceof Map) {
 | 
			
		||||
            if (items.size) {
 | 
			
		||||
                desc[term] = [...items.entries()];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Common.isValues(items)) {
 | 
			
		||||
            desc[term] = items.describe();
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Assert(def.terms[term], 'Term', term, 'missing configuration');
 | 
			
		||||
        const manifest = def.terms[term].manifest;
 | 
			
		||||
        const mapped = typeof manifest === 'object';
 | 
			
		||||
        if (!items.length &&
 | 
			
		||||
            !mapped) {
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const normalized = [];
 | 
			
		||||
        for (const item of items) {
 | 
			
		||||
            normalized.push(internals.describe(item));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Mapped
 | 
			
		||||
 | 
			
		||||
        if (mapped) {
 | 
			
		||||
            const { from, to } = manifest.mapped;
 | 
			
		||||
            desc[term] = {};
 | 
			
		||||
            for (const item of normalized) {
 | 
			
		||||
                desc[term][item[to]] = item[from];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Single
 | 
			
		||||
 | 
			
		||||
        if (manifest === 'single') {
 | 
			
		||||
            Assert(normalized.length === 1, 'Term', term, 'contains more than one item');
 | 
			
		||||
            desc[term] = normalized[0];
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Array
 | 
			
		||||
 | 
			
		||||
        desc[term] = normalized;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internals.validate(schema.$_root, desc);
 | 
			
		||||
    return desc;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
internals.describe = function (item, options = {}) {
 | 
			
		||||
 | 
			
		||||
    if (Array.isArray(item)) {
 | 
			
		||||
        return item.map(internals.describe);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (item === Common.symbols.deepDefault) {
 | 
			
		||||
        return { special: 'deep' };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (typeof item !== 'object' ||
 | 
			
		||||
        item === null) {
 | 
			
		||||
 | 
			
		||||
        return item;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options.assign === 'options') {
 | 
			
		||||
        return Clone(item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (Buffer && Buffer.isBuffer(item)) {                          // $lab:coverage:ignore$
 | 
			
		||||
        return { buffer: item.toString('binary') };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (item instanceof Date) {
 | 
			
		||||
        return item.toISOString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (item instanceof Error) {
 | 
			
		||||
        return item;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (item instanceof RegExp) {
 | 
			
		||||
        if (options.assign === 'regex') {
 | 
			
		||||
            return item.toString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return { regex: item.toString() };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (item[Common.symbols.literal]) {
 | 
			
		||||
        return { function: item.literal };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (typeof item.describe === 'function') {
 | 
			
		||||
        if (options.assign === 'ref') {
 | 
			
		||||
            return item.describe().ref;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return item.describe();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const normalized = {};
 | 
			
		||||
    for (const key in item) {
 | 
			
		||||
        const value = item[key];
 | 
			
		||||
        if (value === undefined) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        normalized[key] = internals.describe(value, { assign: key });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return normalized;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.build = function (joi, desc) {
 | 
			
		||||
 | 
			
		||||
    const builder = new internals.Builder(joi);
 | 
			
		||||
    return builder.parse(desc);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
internals.Builder = class {
 | 
			
		||||
 | 
			
		||||
    constructor(joi) {
 | 
			
		||||
 | 
			
		||||
        this.joi = joi;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    parse(desc) {
 | 
			
		||||
 | 
			
		||||
        internals.validate(this.joi, desc);
 | 
			
		||||
 | 
			
		||||
        // Type
 | 
			
		||||
 | 
			
		||||
        let schema = this.joi[desc.type]()._bare();
 | 
			
		||||
        const def = schema._definition;
 | 
			
		||||
 | 
			
		||||
        // Flags
 | 
			
		||||
 | 
			
		||||
        if (desc.flags) {
 | 
			
		||||
            for (const flag in desc.flags) {
 | 
			
		||||
                const setter = def.flags[flag] && def.flags[flag].setter || flag;
 | 
			
		||||
                Assert(typeof schema[setter] === 'function', 'Invalid flag', flag, 'for type', desc.type);
 | 
			
		||||
                schema = schema[setter](this.build(desc.flags[flag]));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Preferences
 | 
			
		||||
 | 
			
		||||
        if (desc.preferences) {
 | 
			
		||||
            schema = schema.preferences(this.build(desc.preferences));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Allow / Invalid
 | 
			
		||||
 | 
			
		||||
        if (desc.allow) {
 | 
			
		||||
            schema = schema.allow(...this.build(desc.allow));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (desc.invalid) {
 | 
			
		||||
            schema = schema.invalid(...this.build(desc.invalid));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Rules
 | 
			
		||||
 | 
			
		||||
        if (desc.rules) {
 | 
			
		||||
            for (const rule of desc.rules) {
 | 
			
		||||
                Assert(typeof schema[rule.name] === 'function', 'Invalid rule', rule.name, 'for type', desc.type);
 | 
			
		||||
 | 
			
		||||
                const args = [];
 | 
			
		||||
                if (rule.args) {
 | 
			
		||||
                    const built = {};
 | 
			
		||||
                    for (const key in rule.args) {
 | 
			
		||||
                        built[key] = this.build(rule.args[key], { assign: key });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    const keys = Object.keys(built);
 | 
			
		||||
                    const definition = def.rules[rule.name].args;
 | 
			
		||||
                    if (definition) {
 | 
			
		||||
                        Assert(keys.length <= definition.length, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to', definition.length, ', found', keys.length, ')');
 | 
			
		||||
                        for (const { name } of definition) {
 | 
			
		||||
                            args.push(built[name]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        Assert(keys.length === 1, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to 1, found', keys.length, ')');
 | 
			
		||||
                        args.push(built[keys[0]]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Apply
 | 
			
		||||
 | 
			
		||||
                schema = schema[rule.name](...args);
 | 
			
		||||
 | 
			
		||||
                // Ruleset
 | 
			
		||||
 | 
			
		||||
                const options = {};
 | 
			
		||||
                for (const custom in def.modifiers) {
 | 
			
		||||
                    if (rule[custom] !== undefined) {
 | 
			
		||||
                        options[custom] = this.build(rule[custom]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (Object.keys(options).length) {
 | 
			
		||||
                    schema = schema.rule(options);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Terms
 | 
			
		||||
 | 
			
		||||
        const terms = {};
 | 
			
		||||
        for (const key in desc) {
 | 
			
		||||
            if (['allow', 'flags', 'invalid', 'whens', 'preferences', 'rules', 'type'].includes(key)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Assert(def.terms[key], 'Term', key, 'missing configuration');
 | 
			
		||||
            const manifest = def.terms[key].manifest;
 | 
			
		||||
 | 
			
		||||
            if (manifest === 'schema') {
 | 
			
		||||
                terms[key] = desc[key].map((item) => this.parse(item));
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (manifest === 'values') {
 | 
			
		||||
                terms[key] = desc[key].map((item) => this.build(item));
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (manifest === 'single') {
 | 
			
		||||
                terms[key] = this.build(desc[key]);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (typeof manifest === 'object') {
 | 
			
		||||
                terms[key] = {};
 | 
			
		||||
                for (const name in desc[key]) {
 | 
			
		||||
                    const value = desc[key][name];
 | 
			
		||||
                    terms[key][name] = this.parse(value);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            terms[key] = this.build(desc[key]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (desc.whens) {
 | 
			
		||||
            terms.whens = desc.whens.map((when) => this.build(when));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        schema = def.manifest.build(schema, terms);
 | 
			
		||||
        schema.$_temp.ruleset = false;
 | 
			
		||||
        return schema;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    build(desc, options = {}) {
 | 
			
		||||
 | 
			
		||||
        if (desc === null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Array.isArray(desc)) {
 | 
			
		||||
            return desc.map((item) => this.build(item));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (desc instanceof Error) {
 | 
			
		||||
            return desc;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (options.assign === 'options') {
 | 
			
		||||
            return Clone(desc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (options.assign === 'regex') {
 | 
			
		||||
            return internals.regex(desc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (options.assign === 'ref') {
 | 
			
		||||
            return Ref.build(desc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (typeof desc !== 'object') {
 | 
			
		||||
            return desc;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Object.keys(desc).length === 1) {
 | 
			
		||||
            if (desc.buffer) {
 | 
			
		||||
                Assert(Buffer, 'Buffers are not supported');
 | 
			
		||||
                return Buffer && Buffer.from(desc.buffer, 'binary');                    // $lab:coverage:ignore$
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.function) {
 | 
			
		||||
                return { [Common.symbols.literal]: true, literal: desc.function };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.override) {
 | 
			
		||||
                return Common.symbols.override;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.ref) {
 | 
			
		||||
                return Ref.build(desc.ref);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.regex) {
 | 
			
		||||
                return internals.regex(desc.regex);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.special) {
 | 
			
		||||
                Assert(['deep'].includes(desc.special), 'Unknown special value', desc.special);
 | 
			
		||||
                return Common.symbols.deepDefault;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.value) {
 | 
			
		||||
                return Clone(desc.value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (desc.type) {
 | 
			
		||||
            return this.parse(desc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (desc.template) {
 | 
			
		||||
            return Template.build(desc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const normalized = {};
 | 
			
		||||
        for (const key in desc) {
 | 
			
		||||
            normalized[key] = this.build(desc[key], { assign: key });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return normalized;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
internals.regex = function (string) {
 | 
			
		||||
 | 
			
		||||
    const end = string.lastIndexOf('/');
 | 
			
		||||
    const exp = string.slice(1, end);
 | 
			
		||||
    const flags = string.slice(end + 1);
 | 
			
		||||
    return new RegExp(exp, flags);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
internals.validate = function (joi, desc) {
 | 
			
		||||
 | 
			
		||||
    Schemas = Schemas || require('./schemas');
 | 
			
		||||
 | 
			
		||||
    joi.assert(desc, Schemas.description);
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user