Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
thethanghn committed Apr 24, 2016
1 parent c4fd0b2 commit fef3372
Show file tree
Hide file tree
Showing 18 changed files with 709 additions and 163 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Disclaimer

This is directly ported from `hapi/joi` but removed `hoek` and some methods to make it works with React Native.

Some methods that belongs to `Hoek` are moved into `patch.js`.

![joi Logo](https://raw.github.com/hapijs/joi/master/images/joi.png)

Object schema description language and validator for JavaScript objects.
Expand Down
22 changes: 12 additions & 10 deletions lib/alternatives.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use strict';

// Load modules

const Hoek = require('hoek');

const _ = require('lodash');
const Util = require('util');
const Patch = require('./patch');
const Any = require('./any');
const Cast = require('./cast');
const Ref = require('./ref');
Expand All @@ -21,7 +23,7 @@ internals.Alternatives = function () {
this._inner.matches = [];
};

Hoek.inherits(internals.Alternatives, Any);
Util.inherits(internals.Alternatives, Any);


internals.Alternatives.prototype._base = function (value, state, options) {
Expand Down Expand Up @@ -65,8 +67,8 @@ internals.Alternatives.prototype._base = function (value, state, options) {

internals.Alternatives.prototype.try = function (/* schemas */) {

const schemas = Hoek.flatten(Array.prototype.slice.call(arguments));
Hoek.assert(schemas.length, 'Cannot add other alternatives without at least one schema');
const schemas = _.flatten(Array.prototype.slice.call(arguments));
Patch.assert(schemas.length, 'Cannot add other alternatives without at least one schema');

const obj = this.clone();

Expand All @@ -84,11 +86,11 @@ internals.Alternatives.prototype.try = function (/* schemas */) {

internals.Alternatives.prototype.when = function (ref, options) {

Hoek.assert(Ref.isRef(ref) || typeof ref === 'string', 'Invalid reference:', ref);
Hoek.assert(options, 'Missing options');
Hoek.assert(typeof options === 'object', 'Invalid options');
Hoek.assert(options.hasOwnProperty('is'), 'Missing "is" directive');
Hoek.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of "then" or "otherwise"');
Patch.assert(Ref.isRef(ref) || typeof ref === 'string', 'Invalid reference:', ref);
Patch.assert(options, 'Missing options');
Patch.assert(typeof options === 'object', 'Invalid options');
Patch.assert(options.hasOwnProperty('is'), 'Missing "is" directive');
Patch.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of "then" or "otherwise"');

const obj = this.clone();
let is = Cast.schema(options.is);
Expand Down
63 changes: 33 additions & 30 deletions lib/any.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

// Load modules

const Hoek = require('hoek');

const _ = require('lodash');
const Util = require('util');
const Patch = require('./patch');
const Ref = require('./ref');
const Errors = require('./errors');
let Alternatives = null; // Delay-loaded to prevent circular dependencies
Expand Down Expand Up @@ -58,10 +61,10 @@ internals.checkOptions = function (options) {
values = opt.slice(1);
}

Hoek.assert(type, 'unknown key ' + key);
Hoek.assert(typeof options[key] === type, key + ' should be of type ' + type);
Patch.assert(type, 'unknown key ' + key);
Patch.assert(typeof options[key] === type, key + ' should be of type ' + type);
if (values) {
Hoek.assert(values.indexOf(options[key]) >= 0, key + ' should be one of ' + values.join(', '));
Patch.assert(values.indexOf(options[key]) >= 0, key + ' should be one of ' + values.join(', '));
}
}
};
Expand Down Expand Up @@ -116,11 +119,11 @@ internals.Any.prototype.clone = function () {
obj.isJoi = true;
obj._type = this._type;
obj._settings = internals.concatSettings(this._settings);
obj._valids = Hoek.clone(this._valids);
obj._invalids = Hoek.clone(this._invalids);
obj._valids = Patch.clone(this._valids);
obj._invalids = Patch.clone(this._invalids);
obj._tests = this._tests.slice();
obj._refs = this._refs.slice();
obj._flags = Hoek.clone(this._flags);
obj._flags = Patch.clone(this._flags);

obj._description = this._description;
obj._unit = this._unit;
Expand All @@ -142,8 +145,8 @@ internals.Any.prototype.clone = function () {

internals.Any.prototype.concat = function (schema) {

Hoek.assert(schema && schema.isJoi, 'Invalid schema object');
Hoek.assert(this._type === 'any' || schema._type === 'any' || schema._type === this._type, 'Cannot merge type', this._type, 'with another type:', schema._type);
Patch.assert(schema && schema.isJoi, 'Invalid schema object');
Patch.assert(this._type === 'any' || schema._type === 'any' || schema._type === this._type, 'Cannot merge type', this._type, 'with another type:', schema._type);

let obj = this.clone();

Expand All @@ -166,7 +169,7 @@ internals.Any.prototype.concat = function (schema) {
obj._invalids.merge(schema._invalids, schema._valids);
obj._tests = obj._tests.concat(schema._tests);
obj._refs = obj._refs.concat(schema._refs);
Hoek.merge(obj._flags, schema._flags);
_.merge(obj._flags, schema._flags);

obj._description = schema._description || obj._description;
obj._unit = schema._unit || obj._unit;
Expand Down Expand Up @@ -227,7 +230,7 @@ internals.Any.prototype._test = function (name, arg, func) {

internals.Any.prototype.options = function (options) {

Hoek.assert(!options.context, 'Cannot override context');
Patch.assert(!options.context, 'Cannot override context');
internals.checkOptions(options);

const obj = this.clone();
Expand Down Expand Up @@ -256,11 +259,11 @@ internals.Any.prototype.raw = function (isRaw) {

internals.Any.prototype._allow = function () {

const values = Hoek.flatten(Array.prototype.slice.call(arguments));
const values = _.flatten(Array.prototype.slice.call(arguments));
for (let i = 0; i < values.length; ++i) {
const value = values[i];

Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');
Patch.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');
this._invalids.remove(value);
this._valids.add(value, this._refs);
}
Expand All @@ -286,11 +289,11 @@ internals.Any.prototype.valid = internals.Any.prototype.only = internals.Any.pro
internals.Any.prototype.invalid = internals.Any.prototype.disallow = internals.Any.prototype.not = function (value) {

const obj = this.clone();
const values = Hoek.flatten(Array.prototype.slice.call(arguments));
const values = _.flatten(Array.prototype.slice.call(arguments));
for (let i = 0; i < values.length; ++i) {
value = values[i];

Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');
Patch.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');
obj._valids.remove(value);
obj._invalids.add(value, this._refs);
}
Expand Down Expand Up @@ -362,7 +365,7 @@ internals.Any.prototype.default = function (value, description) {
}

if (!this._flags.func) {
Hoek.assert(typeof value.description === 'string' && value.description.length > 0, 'description must be provided when default value is a function');
Patch.assert(typeof value.description === 'string' && value.description.length > 0, 'description must be provided when default value is a function');
}
}

Expand All @@ -383,8 +386,8 @@ internals.Any.prototype.empty = function (schema) {

internals.Any.prototype.when = function (ref, options) {

Hoek.assert(options && typeof options === 'object', 'Invalid options');
Hoek.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of "then" or "otherwise"');
Patch.assert(options && typeof options === 'object', 'Invalid options');
Patch.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of "then" or "otherwise"');

const then = options.hasOwnProperty('then') ? this.concat(Cast.schema(options.then)) : undefined;
const otherwise = options.hasOwnProperty('otherwise') ? this.concat(Cast.schema(options.otherwise)) : undefined;
Expand All @@ -400,7 +403,7 @@ internals.Any.prototype.when = function (ref, options) {

internals.Any.prototype.description = function (desc) {

Hoek.assert(desc && typeof desc === 'string', 'Description must be a non-empty string');
Patch.assert(desc && typeof desc === 'string', 'Description must be a non-empty string');

const obj = this.clone();
obj._description = desc;
Expand All @@ -410,7 +413,7 @@ internals.Any.prototype.description = function (desc) {

internals.Any.prototype.notes = function (notes) {

Hoek.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a non-empty string or array');
Patch.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a non-empty string or array');

const obj = this.clone();
obj._notes = obj._notes.concat(notes);
Expand All @@ -420,7 +423,7 @@ internals.Any.prototype.notes = function (notes) {

internals.Any.prototype.tags = function (tags) {

Hoek.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a non-empty string or array');
Patch.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a non-empty string or array');

const obj = this.clone();
obj._tags = obj._tags.concat(tags);
Expand All @@ -429,7 +432,7 @@ internals.Any.prototype.tags = function (tags) {

internals.Any.prototype.meta = function (meta) {

Hoek.assert(meta !== undefined, 'Meta cannot be undefined');
Patch.assert(meta !== undefined, 'Meta cannot be undefined');

const obj = this.clone();
obj._meta = obj._meta.concat(meta);
Expand All @@ -439,9 +442,9 @@ internals.Any.prototype.meta = function (meta) {

internals.Any.prototype.example = function (value) {

Hoek.assert(arguments.length, 'Missing example');
Patch.assert(arguments.length, 'Missing example');
const result = this._validate(value, null, internals.defaults);
Hoek.assert(!result.errors, 'Bad example:', result.errors && Errors.process(result.errors, value));
Patch.assert(!result.errors, 'Bad example:', result.errors && Errors.process(result.errors, value));

const obj = this.clone();
obj._examples.push(value);
Expand All @@ -451,7 +454,7 @@ internals.Any.prototype.example = function (value) {

internals.Any.prototype.unit = function (name) {

Hoek.assert(name && typeof name === 'string', 'Unit name must be a non-empty string');
Patch.assert(name && typeof name === 'string', 'Unit name must be a non-empty string');

const obj = this.clone();
obj._unit = name;
Expand Down Expand Up @@ -513,7 +516,7 @@ internals.Any.prototype._validate = function (value, state, options, reference)
if (state.parent !== null &&
this._flags.default.length > 0) {

arg = Hoek.clone(state.parent);
arg = Patch.clone(state.parent);
}

const defaultValue = internals._try(this._flags.default, arg);
Expand All @@ -523,7 +526,7 @@ internals.Any.prototype._validate = function (value, state, options, reference)
}
}
else {
finalValue = Hoek.clone(this._flags.default);
finalValue = Patch.clone(this._flags.default);
}
}

Expand Down Expand Up @@ -758,7 +761,7 @@ internals.Any.prototype.describe = function () {
delete description.rules;
}

const label = Hoek.reach(this._settings, 'language.label');
const label = Patch.reach(this._settings, 'language.label');
if (label) {
description.label = label;
}
Expand All @@ -768,7 +771,7 @@ internals.Any.prototype.describe = function () {

internals.Any.prototype.label = function (name) {

Hoek.assert(name && typeof name === 'string', 'Label name must be a non-empty string');
Patch.assert(name && typeof name === 'string', 'Label name must be a non-empty string');

const obj = this.clone();
const options = { language: { label: name } };
Expand Down Expand Up @@ -898,7 +901,7 @@ internals.concatSettings = function (target, source) {
obj[key] = source[key];
}
else {
obj[key] = Hoek.applyToDefaults(obj[key], source[key]);
obj[key] = Patch.applyToDefaults(obj[key], source[key]);
}
}
}
Expand Down
22 changes: 12 additions & 10 deletions lib/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

const Any = require('./any');
const Cast = require('./cast');
const Hoek = require('hoek');

const _ = require('lodash');
const Util = require('util');
const Patch = require('./patch');

// Declare internals

Expand Down Expand Up @@ -35,7 +37,7 @@ internals.Array = function () {
this._flags.sparse = false;
};

Hoek.inherits(internals.Array, Any);
Util.inherits(internals.Array, Any);


internals.Array.prototype._base = function (value, state, options) {
Expand Down Expand Up @@ -290,7 +292,7 @@ internals.fillMissedErrors = function (errors, requireds, state, options) {
const knownMisses = [];
let unknownMisses = 0;
for (let i = 0; i < requireds.length; ++i) {
const label = Hoek.reach(requireds[i], '_settings.language.label');
const label = Patch.reach(requireds[i], '_settings.language.label');
if (label) {
knownMisses.push(label);
}
Expand Down Expand Up @@ -318,7 +320,7 @@ internals.fillOrderedErrors = function (errors, ordereds, state, options) {
const requiredOrdereds = [];

for (let i = 0; i < ordereds.length; ++i) {
const presence = Hoek.reach(ordereds[i], '_flags.presence');
const presence = Patch.reach(ordereds[i], '_flags.presence');
if (presence === 'required') {
requiredOrdereds.push(ordereds[i]);
}
Expand Down Expand Up @@ -357,7 +359,7 @@ internals.Array.prototype.items = function () {

const obj = this.clone();

Hoek.flatten(Array.prototype.slice.call(arguments)).forEach((type, index) => {
_.flatten(Array.prototype.slice.call(arguments)).forEach((type, index) => {

try {
type = Cast.schema(type);
Expand Down Expand Up @@ -394,7 +396,7 @@ internals.Array.prototype.ordered = function () {

const obj = this.clone();

Hoek.flatten(Array.prototype.slice.call(arguments)).forEach((type, index) => {
_.flatten(Array.prototype.slice.call(arguments)).forEach((type, index) => {

try {
type = Cast.schema(type);
Expand All @@ -418,7 +420,7 @@ internals.Array.prototype.ordered = function () {

internals.Array.prototype.min = function (limit) {

Hoek.assert(Hoek.isInteger(limit) && limit >= 0, 'limit must be a positive integer');
Patch.assert(_.isInteger(limit) && limit >= 0, 'limit must be a positive integer');

return this._test('min', limit, (value, state, options) => {

Expand All @@ -433,7 +435,7 @@ internals.Array.prototype.min = function (limit) {

internals.Array.prototype.max = function (limit) {

Hoek.assert(Hoek.isInteger(limit) && limit >= 0, 'limit must be a positive integer');
Patch.assert(_.isInteger(limit) && limit >= 0, 'limit must be a positive integer');

return this._test('max', limit, (value, state, options) => {

Expand All @@ -448,7 +450,7 @@ internals.Array.prototype.max = function (limit) {

internals.Array.prototype.length = function (limit) {

Hoek.assert(Hoek.isInteger(limit) && limit >= 0, 'limit must be a positive integer');
Patch.assert(_.isInteger(limit) && limit >= 0, 'limit must be a positive integer');

return this._test('length', limit, (value, state, options) => {

Expand Down Expand Up @@ -484,7 +486,7 @@ internals.Array.prototype.unique = function () {
if (/* $lab:coverage:off$ */ records /* $lab:coverage:on$ */) {
if (Array.isArray(records)) {
for (let j = 0; j < records.length; ++j) {
if (Hoek.deepEqual(records[j], item)) {
if (Patch.deepEqual(records[j], item)) {
return this.createError('array.unique', { pos: i, value: item }, state, options);
}
}
Expand Down
Loading

0 comments on commit fef3372

Please sign in to comment.