New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

scheming

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scheming - npm Package Compare versions

Comparing version 0.0.1 to 0.0.5

.bower.json

3

.groc.json
{
"glob" : "src/**/*.coffee",
"glob" : ["src/**/*.coffee", "README.md"],
"index-page-title" : "Scheming",
"out": "doc"
}
(function() {
var NESTED_TYPES, RESERVED_PROPERTIES, Scheming, TYPES, getPrimitiveTypeOf, isNode, register, registry, root, uuid, _,
var DEFAULT_OPTIONS, NESTED_TYPES, Scheming, TYPES, addToRegistry, getPrimitiveTypeOf, instanceFactory, isNode, registry, root, schemaFactory, uuid, _,
__slice = [].slice;

@@ -24,6 +24,17 @@

RESERVED_PROPERTIES = {
validate: 'validate'
DEFAULT_OPTIONS = {
seal: false,
strict: false
};
/*
Scheming exports the default types that it uses for parsing schemas. You can extend with custom types, or
override the identifier / parser functions of the default types. A custom type should provide:
- ctor (optional) - Used in schema definitions to declare a type. `Scheming.create name : String`
- string - Used in schema definitions to declare a type. `Scheming.create name : 'string'`
- identifier - Function, returns true or false. Determines whether a value needs to be parsed.
- parser - Function, parses a value into the type.
*/
TYPES = {

@@ -51,7 +62,2 @@ String: {

},
Float: {
string: 'float',
identifier: _.isNumber,
parser: parseFloat
},
Date: {

@@ -85,2 +91,8 @@ ctor: Date,

/*
Special type definitions for nested types. Used to identify and parse nested Arrays and Schemas.
Should not be extended or overridden.
*/
NESTED_TYPES = {

@@ -91,5 +103,5 @@ Array: {

identifier: _.isArray,
parser: _.toArray,
childType: null,
parser: _.toArray,
childParser: _.toArray
childParser: null
},

@@ -100,4 +112,4 @@ Schema: {

identifier: null,
childType: null,
parser: null
parser: null,
childType: null
}

@@ -120,3 +132,3 @@ };

NESTED_TYPES: NESTED_TYPES,
RESERVED_PROPERTIES: RESERVED_PROPERTIES
DEFAULT_OPTIONS: DEFAULT_OPTIONS
};

@@ -130,6 +142,8 @@

type = _.cloneDeep(NESTED_TYPES.Array);
childType = TYPES.Mixed;
if (typeDef.length) {
childType = Scheming.resolveType(typeDef[0]);
}
if (!childType) {
throw new Error("Error resolving type of array value " + typeDef);
}
type.childType = childType;

@@ -156,2 +170,9 @@ type.childParser = function(val) {

};
/*
- If the type definition is an object `{}`
- Create a new Schema from the object
- Treat the field as a nested Schema
- Set identifier and parser functions immediately
*/
if (_.isPlainObject(typeDef)) {

@@ -162,3 +183,9 @@ type = _.cloneDeep(NESTED_TYPES.Schema);

}
if (_.isFunction(typeDef) && typeDef.__skemaId) {
/*
- If the type definition is a reference to a Schema constructor
- Treat the field as a nested Schema
- Set identifier and parser functions immediately
*/
if (_.isFunction(typeDef) && typeDef.__schemaId) {
type = _.cloneDeep(NESTED_TYPES.Schema);

@@ -168,2 +195,12 @@ childType = typeDef;

}
/*
- If the type definition is a string that begins with Schema:, such as `'Schema:Car'`
- It is assumed that the field is a reference to a nested Schema that will be registered with the name Car,
but may not be registered yet
- The Schema is not resolved immediately
- The parser and identifier functions are written as wrappers, so that the first time they are invoked the Schema
will be looked up at that time via `Scheming.get`, and real identifier and parser are set at that time.
- If the registered Schema cannot be resolved, throw an error.
*/
if (_.isString(typeDef) && typeDef.slice(0, 7) === 'Schema:') {

@@ -192,4 +229,13 @@ type = _.cloneDeep(NESTED_TYPES.Schema);

Scheming.normalizeProperty = function(config, fieldName) {
/*
Normalizes a field declaration on a schema to capture type, default value, setter, getter, and validation.
Used internally when a schema is created to build a normalized schema definition.
*/
Scheming.normalizePropertyConfig = function(propConfig, propName) {
var definition, fn, getter, required, setter, type, validate, _i, _len;
if (propName == null) {
propName = 'field';
}
definition = {

@@ -203,16 +249,16 @@ type: null,

};
if (!(_.isPlainObject(config) && (config.type != null))) {
config = {
type: config
if (!(_.isPlainObject(propConfig) && (propConfig.type != null))) {
propConfig = {
type: propConfig
};
}
type = config.type, getter = config.getter, setter = config.setter, validate = config.validate, required = config.required;
type = propConfig.type, getter = propConfig.getter, setter = propConfig.setter, validate = propConfig.validate, required = propConfig.required;
if (type == null) {
throw new Error("Error resolving " + fieldName + ". Schema type must be defined.");
throw new Error("Error resolving " + propName + ". Schema type must be defined.");
}
if ((getter != null) && !_.isFunction(getter)) {
throw new Error("Error resolving " + fieldName + ". Schema getter must be a function.");
throw new Error("Error resolving " + propName + ". Schema getter must be a function.");
}
if ((setter != null) && !_.isFunction(setter)) {
throw new Error("Error resolving " + fieldName + ". Schema setter must be a function.");
throw new Error("Error resolving " + propName + ". Schema setter must be a function.");
}

@@ -228,3 +274,3 @@ if (validate == null) {

if (!_.isFunction(fn)) {
throw new Error("Error resolving " + fieldName + ". Schema validate must be a function or array of functions.");
throw new Error("Error resolving " + propName + ". Schema validate must be a function or array of functions.");
}

@@ -234,5 +280,5 @@ }

if (definition.type == null) {
throw new Error("Error resolving " + fieldName + ". Unrecognized type " + type);
throw new Error("Error resolving " + propName + ". Unrecognized type " + type);
}
definition["default"] = config["default"];
definition["default"] = propConfig["default"];
definition.getter = getter;

@@ -245,17 +291,5 @@ definition.setter = setter;

/*
opts:
strict - if false, allows attachment of arbitrary properties to object
*/
/*
Doc notes -
- parsers are applied before setters; setters can assume they are receiving correct type
*/
registry = {};
register = function(key, value) {
addToRegistry = function(key, value) {
if (registry[key]) {

@@ -267,4 +301,12 @@ throw new Error("Naming conflict encountered. Schema " + key + " already exists");

Scheming.get = function(name) {
return registry[name];
};
Scheming.reset = function() {
return registry = {};
};
Scheming.create = function() {
var Schema, args, name, normalizedSchema, opts, schemaConfig;
var Schema, args, name, opts, schemaConfig;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];

@@ -275,6 +317,19 @@ if (!_.isString(args[0])) {

name = args[0], schemaConfig = args[1], opts = args[2];
opts = _.defaults(opts || {}, DEFAULT_OPTIONS);
Schema = schemaFactory(name, opts);
Schema.defineProperties(schemaConfig);
addToRegistry(name, Schema);
return Schema;
};
schemaFactory = function(name, opts) {
var Schema, normalizedSchema;
normalizedSchema = {};
Schema = (function() {
Schema.__skemaId = name;
return Schema = (function() {
Schema.__schemaId = name;
Schema.defineProperty = function(propName, propConfig) {
return normalizedSchema[propName] = Scheming.normalizePropertyConfig(propConfig, propName);
};
Schema.defineProperties = function(config) {

@@ -290,55 +345,5 @@ var k, v, _results;

Schema.defineProperty = function(fieldName, config) {
return normalizedSchema[fieldName] = Scheming.normalizeProperty(config, fieldName);
};
function Schema(model) {
var data, fieldName, key, typeDefinition, value, _fn;
data = {};
Object.defineProperty(this, '__skemaId', {
enumerable: false,
configurable: false,
writable: false,
value: Schema.__skemaId
});
_fn = (function(_this) {
return function(fieldName, typeDefinition) {
var getter, setter, type;
type = typeDefinition.type, getter = typeDefinition.getter, setter = typeDefinition.setter;
Object.defineProperty(_this, fieldName, {
configurable: true,
enumerable: true,
get: function() {
var val;
val = data[fieldName];
if (val === void 0) {
return val;
}
if (type.string === NESTED_TYPES.Array.string) {
val = type.childParser(val);
}
if (getter) {
val = getter(val);
}
return val;
},
set: function(val) {
if (!type.identifier(val)) {
val = type.parser(val);
}
if (setter) {
val = setter(val);
}
return data[fieldName] = val;
}
});
if (typeDefinition["default"] === !void 0) {
return _this[fieldName] = typeDefinition["default"];
}
};
})(this);
for (fieldName in normalizedSchema) {
typeDefinition = normalizedSchema[fieldName];
_fn(fieldName, typeDefinition);
}
var key, value;
instanceFactory(this, normalizedSchema, opts);
for (key in model) {

@@ -348,93 +353,137 @@ value = model[key];

}
this.validate = function() {
var childErrors, e, err, errors, i, k, member, pushError, required, type, v, val, validator, validators, _i, _j, _len, _len1;
errors = {};
if (this._validating) {
return null;
}
this._validating = true;
pushError = function(key, err) {
var e, _i, _len;
if (_.isArray(err)) {
for (_i = 0, _len = err.length; _i < _len; _i++) {
e = err[_i];
return pushError(key, e);
}
return Schema;
})();
};
instanceFactory = function(instance, normalizedSchema, opts) {
var data, propConfig, propName, seal, strict, _fn;
data = {};
strict = opts.strict, seal = opts.seal;
_fn = (function(_this) {
return function(propName, propConfig) {
var getter, setter, type;
type = propConfig.type, getter = propConfig.getter, setter = propConfig.setter;
Object.defineProperty(instance, propName, {
configurable: false,
enumerable: true,
set: function(val) {
if (val === void 0) {
return data[propName] = val;
}
if (!type.identifier(val)) {
if (strict) {
throw new Error("Error assigning " + val + " to " + propName + ". Value is not of type " + type.string);
}
val = type.parser(val);
}
if (!_.isString(err)) {
err = 'Validation error occurred.';
if (setter) {
val = setter(val);
}
if (errors[key] == null) {
errors[key] = [];
return data[propName] = val;
},
get: function() {
var val;
val = data[propName];
if (val === void 0) {
return val;
}
return errors[key].push(err);
};
for (key in normalizedSchema) {
value = normalizedSchema[key];
validators = value.validators, required = value.required;
val = this[key];
if (required && (val == null)) {
pushError(key, "Field is required.");
if (getter) {
val = getter(val);
}
if (val != null) {
type = normalizedSchema[key].type;
for (_i = 0, _len = validators.length; _i < _len; _i++) {
validator = validators[_i];
err = true;
try {
err = validator(val);
} catch (_error) {
e = _error;
if (e) {
err = e.message;
}
}
if (err !== true) {
pushError(key, err);
}
if (type.string === NESTED_TYPES.Array.string) {
val = type.childParser(val);
}
return val;
}
});
if (propConfig["default"] !== void 0) {
return instance[propName] = (typeof propConfig["default"] === "function" ? propConfig["default"]() : void 0) || propConfig["default"];
}
};
})(this);
for (propName in normalizedSchema) {
propConfig = normalizedSchema[propName];
_fn(propName, propConfig);
}
instance.validate = function() {
var childErrors, e, err, errors, i, k, key, member, pushError, required, type, v, val, validator, validators, value, _i, _j, _len, _len1;
errors = {};
if (this._validating) {
return null;
}
this._validating = true;
pushError = function(key, err) {
var e, _i, _len;
if (_.isArray(err)) {
for (_i = 0, _len = err.length; _i < _len; _i++) {
e = err[_i];
return pushError(key, e);
}
}
if (!_.isString(err)) {
err = 'Validation error occurred.';
}
if (errors[key] == null) {
errors[key] = [];
}
return errors[key].push(err);
};
for (key in normalizedSchema) {
value = normalizedSchema[key];
validators = value.validators, required = value.required;
val = this[key];
if (required && (val == null)) {
pushError(key, "Field is required.");
}
if (val != null) {
type = normalizedSchema[key].type;
for (_i = 0, _len = validators.length; _i < _len; _i++) {
validator = validators[_i];
err = true;
try {
err = validator(val);
} catch (_error) {
e = _error;
if (e) {
err = e.message;
}
if (type.string === 'schema') {
childErrors = val.validate();
for (k in childErrors) {
v = childErrors[k];
pushError("" + key + "." + k, v);
}
}
if (err !== true) {
pushError(key, err);
}
}
if (type.string === 'schema') {
childErrors = val.validate();
for (k in childErrors) {
v = childErrors[k];
pushError("" + key + "." + k, v);
}
}
if (type.string === 'array' && type.childType.string === 'schema') {
for (i = _j = 0, _len1 = val.length; _j < _len1; i = ++_j) {
member = val[i];
childErrors = member.validate();
for (k in childErrors) {
v = childErrors[k];
pushError("" + key + "[" + i + "]." + k, v);
}
if (type.string === 'array' && type.childType.string === 'schema') {
for (i = _j = 0, _len1 = val.length; _j < _len1; i = ++_j) {
member = val[i];
childErrors = member.validate();
for (k in childErrors) {
v = childErrors[k];
pushError("" + key + "[" + i + "]." + k, v);
}
}
}
}
}
this._validating = false;
if (_.size(errors) === 0) {
return null;
} else {
return errors;
}
};
}
}
return Schema;
})();
Schema.defineProperties(schemaConfig);
register(name, Schema);
return Schema;
this._validating = false;
if (_.size(errors) === 0) {
return null;
} else {
return errors;
}
};
if (seal) {
return Object.seal(instance);
}
};
Scheming.get = function(name) {
return registry[name];
};
Scheming.reset = function() {
return registry = {};
};
if (isNode) {

@@ -441,0 +490,0 @@ module.exports = Scheming;

{
"name": "scheming",
"version": "0.0.1",
"version": "0.0.5",
"main": "index.js",
"repository": "https://github.com/autoric/skema",
"repository": "https://github.com/autoric/scheming",
"scripts": {

@@ -16,4 +16,4 @@ "test": "mocha test -w --growl --reporter spec --compilers coffee:coffee-script/register",

"chai": "~1.9.2",
"mocha": "~1.20.1",
"sinon": "~1.10.3",
"mocha": "~2.0.1",
"sinon": "~1.11.1",
"sinon-chai": "~2.6.0",

@@ -24,4 +24,11 @@ "gulp": "~3.8.9",

"gulp-sourcemaps": "~1.2.4",
"gulp-groc": "~0.4.1"
"gulp-groc": "~0.4.1",
"karma": "~0.12.24",
"karma-phantomjs-launcher": "~0.1.4",
"karma-mocha": "~0.1.9",
"karma-coffee-preprocessor": "~0.2.1",
"karma-sinon": "~1.0.3",
"karma-sinon-chai": "~0.2.0",
"karma-chai": "~0.1.0"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc