303 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			303 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
const Joi = require('./index');
 | 
						|
 | 
						|
 | 
						|
const internals = {};
 | 
						|
 | 
						|
 | 
						|
// Preferences
 | 
						|
 | 
						|
internals.wrap = Joi.string()
 | 
						|
    .min(1)
 | 
						|
    .max(2)
 | 
						|
    .allow(false);
 | 
						|
 | 
						|
 | 
						|
exports.preferences = Joi.object({
 | 
						|
    allowUnknown: Joi.boolean(),
 | 
						|
    abortEarly: Joi.boolean(),
 | 
						|
    artifacts: Joi.boolean(),
 | 
						|
    cache: Joi.boolean(),
 | 
						|
    context: Joi.object(),
 | 
						|
    convert: Joi.boolean(),
 | 
						|
    dateFormat: Joi.valid('date', 'iso', 'string', 'time', 'utc'),
 | 
						|
    debug: Joi.boolean(),
 | 
						|
    errors: {
 | 
						|
        escapeHtml: Joi.boolean(),
 | 
						|
        label: Joi.valid('path', 'key', false),
 | 
						|
        language: [
 | 
						|
            Joi.string(),
 | 
						|
            Joi.object().ref()
 | 
						|
        ],
 | 
						|
        render: Joi.boolean(),
 | 
						|
        stack: Joi.boolean(),
 | 
						|
        wrap: {
 | 
						|
            label: internals.wrap,
 | 
						|
            array: internals.wrap,
 | 
						|
            string: internals.wrap
 | 
						|
        }
 | 
						|
    },
 | 
						|
    externals: Joi.boolean(),
 | 
						|
    messages: Joi.object(),
 | 
						|
    noDefaults: Joi.boolean(),
 | 
						|
    nonEnumerables: Joi.boolean(),
 | 
						|
    presence: Joi.valid('required', 'optional', 'forbidden'),
 | 
						|
    skipFunctions: Joi.boolean(),
 | 
						|
    stripUnknown: Joi.object({
 | 
						|
        arrays: Joi.boolean(),
 | 
						|
        objects: Joi.boolean()
 | 
						|
    })
 | 
						|
        .or('arrays', 'objects')
 | 
						|
        .allow(true, false),
 | 
						|
    warnings: Joi.boolean()
 | 
						|
})
 | 
						|
    .strict();
 | 
						|
 | 
						|
 | 
						|
// Extensions
 | 
						|
 | 
						|
internals.nameRx = /^[a-zA-Z0-9]\w*$/;
 | 
						|
 | 
						|
 | 
						|
internals.rule = Joi.object({
 | 
						|
    alias: Joi.array().items(Joi.string().pattern(internals.nameRx)).single(),
 | 
						|
    args: Joi.array().items(
 | 
						|
        Joi.string(),
 | 
						|
        Joi.object({
 | 
						|
            name: Joi.string().pattern(internals.nameRx).required(),
 | 
						|
            ref: Joi.boolean(),
 | 
						|
            assert: Joi.alternatives([
 | 
						|
                Joi.function(),
 | 
						|
                Joi.object().schema()
 | 
						|
            ])
 | 
						|
                .conditional('ref', { is: true, then: Joi.required() }),
 | 
						|
            normalize: Joi.function(),
 | 
						|
            message: Joi.string().when('assert', { is: Joi.function(), then: Joi.required() })
 | 
						|
        })
 | 
						|
    ),
 | 
						|
    convert: Joi.boolean(),
 | 
						|
    manifest: Joi.boolean(),
 | 
						|
    method: Joi.function().allow(false),
 | 
						|
    multi: Joi.boolean(),
 | 
						|
    validate: Joi.function()
 | 
						|
});
 | 
						|
 | 
						|
 | 
						|
exports.extension = Joi.object({
 | 
						|
    type: Joi.alternatives([
 | 
						|
        Joi.string(),
 | 
						|
        Joi.object().regex()
 | 
						|
    ])
 | 
						|
        .required(),
 | 
						|
    args: Joi.function(),
 | 
						|
    cast: Joi.object().pattern(internals.nameRx, Joi.object({
 | 
						|
        from: Joi.function().maxArity(1).required(),
 | 
						|
        to: Joi.function().minArity(1).maxArity(2).required()
 | 
						|
    })),
 | 
						|
    base: Joi.object().schema()
 | 
						|
        .when('type', { is: Joi.object().regex(), then: Joi.forbidden() }),
 | 
						|
    coerce: [
 | 
						|
        Joi.function().maxArity(3),
 | 
						|
        Joi.object({ method: Joi.function().maxArity(3).required(), from: Joi.array().items(Joi.string()).single() })
 | 
						|
    ],
 | 
						|
    flags: Joi.object().pattern(internals.nameRx, Joi.object({
 | 
						|
        setter: Joi.string(),
 | 
						|
        default: Joi.any()
 | 
						|
    })),
 | 
						|
    manifest: {
 | 
						|
        build: Joi.function().arity(2)
 | 
						|
    },
 | 
						|
    messages: [Joi.object(), Joi.string()],
 | 
						|
    modifiers: Joi.object().pattern(internals.nameRx, Joi.function().minArity(1).maxArity(2)),
 | 
						|
    overrides: Joi.object().pattern(internals.nameRx, Joi.function()),
 | 
						|
    prepare: Joi.function().maxArity(3),
 | 
						|
    rebuild: Joi.function().arity(1),
 | 
						|
    rules: Joi.object().pattern(internals.nameRx, internals.rule),
 | 
						|
    terms: Joi.object().pattern(internals.nameRx, Joi.object({
 | 
						|
        init: Joi.array().allow(null).required(),
 | 
						|
        manifest: Joi.object().pattern(/.+/, [
 | 
						|
            Joi.valid('schema', 'single'),
 | 
						|
            Joi.object({
 | 
						|
                mapped: Joi.object({
 | 
						|
                    from: Joi.string().required(),
 | 
						|
                    to: Joi.string().required()
 | 
						|
                })
 | 
						|
                    .required()
 | 
						|
            })
 | 
						|
        ])
 | 
						|
    })),
 | 
						|
    validate: Joi.function().maxArity(3)
 | 
						|
})
 | 
						|
    .strict();
 | 
						|
 | 
						|
 | 
						|
exports.extensions = Joi.array().items(Joi.object(), Joi.function().arity(1)).strict();
 | 
						|
 | 
						|
 | 
						|
// Manifest
 | 
						|
 | 
						|
internals.desc = {
 | 
						|
 | 
						|
    buffer: Joi.object({
 | 
						|
        buffer: Joi.string()
 | 
						|
    }),
 | 
						|
 | 
						|
    func: Joi.object({
 | 
						|
        function: Joi.function().required(),
 | 
						|
        options: {
 | 
						|
            literal: true
 | 
						|
        }
 | 
						|
    }),
 | 
						|
 | 
						|
    override: Joi.object({
 | 
						|
        override: true
 | 
						|
    }),
 | 
						|
 | 
						|
    ref: Joi.object({
 | 
						|
        ref: Joi.object({
 | 
						|
            type: Joi.valid('value', 'global', 'local'),
 | 
						|
            path: Joi.array().required(),
 | 
						|
            separator: Joi.string().length(1).allow(false),
 | 
						|
            ancestor: Joi.number().min(0).integer().allow('root'),
 | 
						|
            map: Joi.array().items(Joi.array().length(2)).min(1),
 | 
						|
            adjust: Joi.function(),
 | 
						|
            iterables: Joi.boolean(),
 | 
						|
            in: Joi.boolean(),
 | 
						|
            render: Joi.boolean()
 | 
						|
        })
 | 
						|
            .required()
 | 
						|
    }),
 | 
						|
 | 
						|
    regex: Joi.object({
 | 
						|
        regex: Joi.string().min(3)
 | 
						|
    }),
 | 
						|
 | 
						|
    special: Joi.object({
 | 
						|
        special: Joi.valid('deep').required()
 | 
						|
    }),
 | 
						|
 | 
						|
    template: Joi.object({
 | 
						|
        template: Joi.string().required(),
 | 
						|
        options: Joi.object()
 | 
						|
    }),
 | 
						|
 | 
						|
    value: Joi.object({
 | 
						|
        value: Joi.alternatives([Joi.object(), Joi.array()]).required()
 | 
						|
    })
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
internals.desc.entity = Joi.alternatives([
 | 
						|
    Joi.array().items(Joi.link('...')),
 | 
						|
    Joi.boolean(),
 | 
						|
    Joi.function(),
 | 
						|
    Joi.number(),
 | 
						|
    Joi.string(),
 | 
						|
    internals.desc.buffer,
 | 
						|
    internals.desc.func,
 | 
						|
    internals.desc.ref,
 | 
						|
    internals.desc.regex,
 | 
						|
    internals.desc.special,
 | 
						|
    internals.desc.template,
 | 
						|
    internals.desc.value,
 | 
						|
    Joi.link('/')
 | 
						|
]);
 | 
						|
 | 
						|
 | 
						|
internals.desc.values = Joi.array()
 | 
						|
    .items(
 | 
						|
        null,
 | 
						|
        Joi.boolean(),
 | 
						|
        Joi.function(),
 | 
						|
        Joi.number().allow(Infinity, -Infinity),
 | 
						|
        Joi.string().allow(''),
 | 
						|
        Joi.symbol(),
 | 
						|
        internals.desc.buffer,
 | 
						|
        internals.desc.func,
 | 
						|
        internals.desc.override,
 | 
						|
        internals.desc.ref,
 | 
						|
        internals.desc.regex,
 | 
						|
        internals.desc.template,
 | 
						|
        internals.desc.value
 | 
						|
    );
 | 
						|
 | 
						|
 | 
						|
internals.desc.messages = Joi.object()
 | 
						|
    .pattern(/.+/, [
 | 
						|
        Joi.string(),
 | 
						|
        internals.desc.template,
 | 
						|
        Joi.object().pattern(/.+/, [Joi.string(), internals.desc.template])
 | 
						|
    ]);
 | 
						|
 | 
						|
 | 
						|
exports.description = Joi.object({
 | 
						|
    type: Joi.string().required(),
 | 
						|
    flags: Joi.object({
 | 
						|
        cast: Joi.string(),
 | 
						|
        default: Joi.any(),
 | 
						|
        description: Joi.string(),
 | 
						|
        empty: Joi.link('/'),
 | 
						|
        failover: internals.desc.entity,
 | 
						|
        id: Joi.string(),
 | 
						|
        label: Joi.string(),
 | 
						|
        only: true,
 | 
						|
        presence: ['optional', 'required', 'forbidden'],
 | 
						|
        result: ['raw', 'strip'],
 | 
						|
        strip: Joi.boolean(),
 | 
						|
        unit: Joi.string()
 | 
						|
    })
 | 
						|
        .unknown(),
 | 
						|
    preferences: {
 | 
						|
        allowUnknown: Joi.boolean(),
 | 
						|
        abortEarly: Joi.boolean(),
 | 
						|
        artifacts: Joi.boolean(),
 | 
						|
        cache: Joi.boolean(),
 | 
						|
        convert: Joi.boolean(),
 | 
						|
        dateFormat: ['date', 'iso', 'string', 'time', 'utc'],
 | 
						|
        errors: {
 | 
						|
            escapeHtml: Joi.boolean(),
 | 
						|
            label: ['path', 'key'],
 | 
						|
            language: [
 | 
						|
                Joi.string(),
 | 
						|
                internals.desc.ref
 | 
						|
            ],
 | 
						|
            wrap: {
 | 
						|
                label: internals.wrap,
 | 
						|
                array: internals.wrap
 | 
						|
            }
 | 
						|
        },
 | 
						|
        externals: Joi.boolean(),
 | 
						|
        messages: internals.desc.messages,
 | 
						|
        noDefaults: Joi.boolean(),
 | 
						|
        nonEnumerables: Joi.boolean(),
 | 
						|
        presence: ['required', 'optional', 'forbidden'],
 | 
						|
        skipFunctions: Joi.boolean(),
 | 
						|
        stripUnknown: Joi.object({
 | 
						|
            arrays: Joi.boolean(),
 | 
						|
            objects: Joi.boolean()
 | 
						|
        })
 | 
						|
            .or('arrays', 'objects')
 | 
						|
            .allow(true, false),
 | 
						|
        warnings: Joi.boolean()
 | 
						|
    },
 | 
						|
    allow: internals.desc.values,
 | 
						|
    invalid: internals.desc.values,
 | 
						|
    rules: Joi.array().min(1).items({
 | 
						|
        name: Joi.string().required(),
 | 
						|
        args: Joi.object().min(1),
 | 
						|
        keep: Joi.boolean(),
 | 
						|
        message: [
 | 
						|
            Joi.string(),
 | 
						|
            internals.desc.messages
 | 
						|
        ],
 | 
						|
        warn: Joi.boolean()
 | 
						|
    }),
 | 
						|
 | 
						|
    // Terms
 | 
						|
 | 
						|
    keys: Joi.object().pattern(/.*/, Joi.link('/')),
 | 
						|
    link: internals.desc.ref
 | 
						|
})
 | 
						|
    .pattern(/^[a-z]\w*$/, Joi.any());
 |