Skip to content

Commit

Permalink
Refactor base type. For #1867
Browse files Browse the repository at this point in the history
  • Loading branch information
hueniverse committed Jul 22, 2019
1 parent 8e2687f commit af732a4
Show file tree
Hide file tree
Showing 22 changed files with 451 additions and 350 deletions.
209 changes: 107 additions & 102 deletions lib/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,51 +32,50 @@ exports.describe = function (schema) {

// Type

const description = {
type: schema._type,
const desc = {
type: schema._flags._func ? 'func' : schema._type,
flags: {}
};

if (schema._baseType) {
description.base = schema._baseType.describe();
}

// Flags

for (const flag in schema._flags) {
if (flag[0] !== '_' &&
schema._flags[flag] !== internals.flagDefaults[flag]) {

description.flags[flag] = internals.describe(schema._flags[flag]);
desc.flags[flag] = internals.describe(schema._flags[flag]);
}
}

if (!Object.keys(description.flags).length) {
delete description.flags;
if (!Object.keys(desc.flags).length) {
delete desc.flags;
}

// Preferences

if (schema._preferences) {
description.preferences = Hoek.clone(schema._preferences, { shallow: ['messages'] });
if (description.preferences.messages) {
description.preferences.messages = Messages.decompile(description.preferences.messages);
desc.preferences = Hoek.clone(schema._preferences, { shallow: ['messages'] });
if (desc.preferences.messages) {
desc.preferences.messages = Messages.decompile(desc.preferences.messages);
}
}

// Valids
// Allow / Invalid

if (schema._valids) {
description.valids = schema._valids.describe();
desc.allow = schema._valids.describe();
}

if (schema._invalids) {
description.invalids = schema._invalids.describe();
const clean = schema._root[schema._type]();
if (!Hoek.deepEqual(schema._invalids, clean._invalids)) {
desc.invalid = schema._invalids.describe();
}
}

// Rules

description.rules = [];
desc.rules = [];

for (const test of schema._tests) {
if (test.name === 'items') {
Expand All @@ -87,7 +86,7 @@ exports.describe = function (schema) {

for (const custom of ['keep', 'message', 'warn']) {
if (test[custom] !== undefined) {
item[custom] = test[custom];
item[custom] = internals.describe(test[custom]);
}
}

Expand Down Expand Up @@ -119,11 +118,11 @@ exports.describe = function (schema) {
}
}

description.rules.push(item);
desc.rules.push(item);
}

if (!description.rules.length) {
delete description.rules;
if (!desc.rules.length) {
delete desc.rules;
}

// Inners
Expand All @@ -140,15 +139,15 @@ exports.describe = function (schema) {

if (items instanceof Map) {
if (items.size) {
description[inner] = [...items.entries()];
desc[inner] = [...items.entries()];
}

continue;
}

if (Common.isValues(items)) {
if (items.length) {
description[inner] = items.describe();
desc[inner] = items.describe();
}

continue;
Expand All @@ -172,11 +171,11 @@ exports.describe = function (schema) {
normalized = mapped;
}

description[inner] = inner === 'link' ? normalized[0] : normalized;
desc[inner] = inner === 'link' ? normalized[0] : normalized;
}

internals.validate(schema._root, description);
return description;
internals.validate(schema._root, desc);
return desc;
};


Expand All @@ -186,99 +185,89 @@ exports.build = function (joi, desc) {

// Type

const schema = joi[desc.type]().clone();

//if (schema._baseType) {
// description.base = schema._baseType.describe();
//}
let schema = joi[desc.type]();

// Flags

if (desc.flags) {
for (const flag in desc.flags) {
schema._flags[flag] = internals.build(desc.flags[flag]);
schema = schema[flag](internals.build(desc.flags[flag]));
}
}

schema._ruleset = false;
return schema;

/*
if (!Object.keys(description.flags).length) {
delete description.flags;
}
// Preferences

if (schema._preferences) {
description.preferences = Hoek.clone(schema._preferences, { shallow: ['messages'] });
if (description.preferences.messages) {
description.preferences.messages = Messages.decompile(description.preferences.messages);
}
if (desc.preferences) {
schema = schema.preferences(internals.build(desc.preferences));
}

// Valids
// Allow / Invalid

if (schema._valids) {
description.valids = schema._valids.describe();
if (desc.allow) {
schema = schema.allow(...internals.build(desc.allow));
}

if (schema._invalids) {
description.invalids = schema._invalids.describe();
if (desc.invalid) {
schema = schema.invalid(...internals.build(desc.invalid));
}

// Rules

description.rules = [];
for (const test of schema._tests) {
if (test.name === 'items') {
continue;
}
if (desc.rules) {
for (const rule of desc.rules) {
Hoek.assert(typeof schema[rule.name] === 'function', 'Invalid rule', rule.name, 'for type', desc.type);

const item = { name: test.name };
const args = [];
if (rule.args) {
const built = {};
for (const key in rule.args) {
built[key] = internals.build(rule.args[key], { assign: key });
}

for (const custom of ['keep', 'message', 'warn']) {
if (test[custom] !== undefined) {
item[custom] = test[custom];
const keys = Object.keys(built);
const definition = schema._rules[rule.name] && schema._rules[rule.name].args;
if (definition) {
Hoek.assert(keys.length <= definition.length, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to', definition.length,', found', keys.length, ')');
for (const arg of definition) {
args.push(built[arg]);
}
}
else {
Hoek.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]]);
}
}
}

if (test.args) {
item.args = {};
for (const key in test.args) {
const arg = test.args[key];
if (key === 'options' &&
!Object.keys(arg).length) {
// Apply

continue;
}
schema = schema[rule.name](...args);

item.args[key] = internals.describe(arg, key);
}
// Ruleset

if (!Object.keys(item.args).length) {
delete item.args;
const options = {};
for (const custom of ['keep', 'message', 'warn']) {
if (rule[custom] !== undefined) {
options[custom] = internals.build(rule[custom]);
}
}
}

const options = test.options;
if (options) {
if (typeof options.description === 'string') {
item.description = options.description;
if (Object.keys(options).length) {
schema = schema.rule(options);
}
else if (typeof options.description === 'function') {
item.description = options.description(item.args);
}
}

description.rules.push(item);
//const options = test.options;
//if (options) {
// if (typeof options.description === 'string') {
// item.description = options.description;
// }
// else if (typeof options.description === 'function') {
// item.description = options.description(item.args);
// }
//}
}
}

if (!description.rules.length) {
delete description.rules;
}
/*
// Inners
Expand Down Expand Up @@ -328,9 +317,9 @@ exports.build = function (joi, desc) {
description[inner] = inner === 'link' ? normalized[0] : normalized;
}
return description;
*/

return schema;
};


Expand All @@ -341,14 +330,15 @@ internals.describe = function (item, options = {}) {
}

if (!item ||
typeof item !== 'object' ||
options.assign === 'options') {
typeof item !== 'object') {

return item;
}

if (Array.isArray(item)) {
return item;
if (options.assign === 'options' ||
Array.isArray(item)) {

return Hoek.clone(item);
}

if (item instanceof RegExp) {
Expand Down Expand Up @@ -387,36 +377,51 @@ internals.describe = function (item, options = {}) {
};


internals.build = function (desc, key) {
internals.build = function (desc, options = {}) {

if (Array.isArray(desc)) {
return desc.map((item) => internals.build(item));
}

if (key === 'object') {
if (options.assign === 'options') {
return Hoek.clone(desc);
}

if (typeof desc !== 'object') {
return desc;
}

if (desc.value) {
return Hoek.clone(desc.value);
if (desc.function) {
return { [Common.symbols.literal]: true, literal: desc.function };
}

if (options.assign === 'ref') {
return Ref.build(desc);
}

if (desc.ref) {
return Ref.build(desc.ref);
}

if (desc.special) {
Hoek.assert(['deep'].includes(desc.special), 'Unknown special value', desc.special);
return Common.symbols.deepDefault;
}

if (key === 'ref') {
return Ref.build(desc);
if (desc.value) {
return Hoek.clone(desc.value);
}

if (desc.ref) {
return Ref.build(desc.ref);
if (desc.template) {
return Template.build(desc);
}

Hoek.assert(desc.template, 'Unknown description value');
const normalized = {};
for (const key in desc) {
normalized[key] = internals.build(desc[key], { assign: key });
}

return Template.build(desc);
return normalized;
};


Expand Down
1 change: 1 addition & 0 deletions lib/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ exports.errors = {
'link.depth': '"{{#label}}" contains link reference "{{#ref}}" outside of schema boundaries',
'link.ref': '"{{#label}}" contains link reference to non-existing "{{#ref}}" schema',
'link.loop': '"{{#label}}" contains link reference to another link "{{#ref}}"',
'link.uninitialized': 'uninitialized schema',

'number.base': '"{{#label}}" must be a number',
'number.unsafe': '"{{#label}}" must be a safe number',
Expand Down
Loading

0 comments on commit af732a4

Please sign in to comment.