Comparing version 2.4.0 to 2.5.0
266
lib/types.js
@@ -13,2 +13,4 @@ /* jshint node: true */ | ||
// TODO: Code-generate `compare` and `clone` record and union methods. | ||
// TODO: Protect internal `_copy` options (only allow some buffer coercion and | ||
// the field hook). Also make coercion stricter inside `BytesType`'s `_copy`. | ||
@@ -78,3 +80,3 @@ 'use strict'; | ||
Type.fromSchema = function (schema, opts) { | ||
Type.fromSchema = util.deprecate(function (schema, opts) { | ||
if (schema instanceof Type) { | ||
@@ -124,6 +126,52 @@ return schema; | ||
return type; | ||
}; | ||
}, '`Type.fromSchema` will be removed in a future release, please use `parse` instead'); | ||
Type.__reset = function (size) { TAP.buf = new buffer.SlowBuffer(size); }; | ||
Type.prototype.createResolver = function (type, opts) { | ||
if (!(type instanceof Type)) { | ||
// More explicit error message than the "incompatible type" thrown | ||
// otherwise (especially because of the overridden `toString` method). | ||
throw new Error(f('not a type: %j', type)); | ||
} | ||
opts = opts || {}; | ||
opts.registry = opts.registry || {}; | ||
var resolver, key; | ||
if (this instanceof RecordType && type instanceof RecordType) { | ||
key = this._name + ':' + type._name; // ':' is illegal in Avro type names. | ||
resolver = opts.registry[key]; | ||
if (resolver) { | ||
return resolver; | ||
} | ||
} | ||
resolver = new Resolver(this); | ||
if (key) { // Register resolver early for recursive schemas. | ||
opts.registry[key] = resolver; | ||
} | ||
if (type instanceof UnionType) { | ||
var resolvers = type._types.map(function (t) { | ||
return this.createResolver(t, opts); | ||
}, this); | ||
resolver._read = function (tap) { | ||
var index = tap.readLong(); | ||
var resolver = resolvers[index]; | ||
if (resolver === undefined) { | ||
throw new Error(f('invalid union index: %s', index)); | ||
} | ||
return resolvers[index]._read(tap); | ||
}; | ||
} else { | ||
this._updateResolver(resolver, type, opts); | ||
} | ||
if (!resolver._read) { | ||
throw new Error(f('incompatible types: %s %s', this, type)); | ||
} | ||
return resolver; | ||
}; | ||
Type.prototype.decode = function (buf, pos, resolver) { | ||
@@ -177,3 +225,3 @@ var tap = new Tap(buf); | ||
Type.prototype.fromString = function (str) { | ||
return this.clone(JSON.parse(str), {coerceBuffers: true}); | ||
return this._copy(JSON.parse(str), {coerceBuffers: 2}); | ||
}; | ||
@@ -190,4 +238,5 @@ | ||
return JSON.stringify(type, function (key, value) { | ||
if (value && !value.hasOwnProperty('default') && value.name) { | ||
// We use the `default` own property check to filter out fields. | ||
if (value instanceof Field) { | ||
return {name: value._name, type: value._type}; | ||
} else if (value && value.name) { | ||
var name = value.name; | ||
@@ -203,9 +252,3 @@ if (registry[name]) { | ||
} | ||
return JSON.stringify(obj, function (key, value) { | ||
if (value && value.type === 'Buffer' && value.data instanceof Array) { | ||
return new Buffer(value.data).toString('binary'); | ||
} else { | ||
return value; | ||
} | ||
}); | ||
return JSON.stringify(this._copy(obj, {coerceBuffers: 3})); | ||
}; | ||
@@ -223,2 +266,14 @@ | ||
Type.prototype.clone = function (obj, opts) { | ||
// Simply passing all arguments through for now. This will be deprecated | ||
// soon, then removed in the next major release. | ||
return this._copy(obj, opts); | ||
}; | ||
Type.prototype.compareBuffers = function (buf1, buf2) { | ||
return this._match(new Tap(buf1), new Tap(buf2)); | ||
}; | ||
Type.prototype.getName = function () { return this._name; }; | ||
Type.prototype.getFingerprint = function (algorithm) { | ||
@@ -231,59 +286,9 @@ algorithm = algorithm || 'md5'; | ||
Type.prototype.createResolver = function (type, opts) { | ||
if (!(type instanceof Type)) { | ||
// More explicit error message than the "incompatible type" thrown | ||
// otherwise (especially because of the overridden `toString` method). | ||
throw new Error(f('not a type: %j', type)); | ||
} | ||
opts = opts || {}; | ||
opts.registry = opts.registry || {}; | ||
var resolver, key; | ||
if (this instanceof RecordType && type instanceof RecordType) { | ||
key = this._name + ':' + type._name; // ':' is illegal in Avro type names. | ||
resolver = opts.registry[key]; | ||
if (resolver) { | ||
return resolver; | ||
} | ||
} | ||
resolver = new Resolver(this); | ||
if (key) { // Register resolver early for recursive schemas. | ||
opts.registry[key] = resolver; | ||
} | ||
if (type instanceof UnionType) { | ||
var resolvers = type._types.map(function (t) { | ||
return this.createResolver(t, opts); | ||
}, this); | ||
resolver._read = function (tap) { | ||
var index = tap.readLong(); | ||
var resolver = resolvers[index]; | ||
if (resolver === undefined) { | ||
throw new Error(f('invalid union index: %s', index)); | ||
} | ||
return resolvers[index]._read(tap); | ||
}; | ||
} else { | ||
this._updateResolver(resolver, type, opts); | ||
} | ||
if (!resolver._read) { | ||
throw new Error(f('incompatible types: %s %s', this, type)); | ||
} | ||
return resolver; | ||
}; | ||
Type.prototype.compareBuffers = function (buf1, buf2) { | ||
return this._match(new Tap(buf1), new Tap(buf2)); | ||
}; | ||
Type.prototype._check = utils.abstractFunction; | ||
Type.prototype._copy = utils.abstractFunction; | ||
Type.prototype._match = utils.abstractFunction; | ||
Type.prototype._read = utils.abstractFunction; | ||
Type.prototype._skip = utils.abstractFunction; | ||
Type.prototype._updateResolver = utils.abstractFunction; | ||
Type.prototype._write = utils.abstractFunction; | ||
Type.prototype._match = utils.abstractFunction; | ||
Type.prototype._updateResolver = utils.abstractFunction; | ||
Type.prototype.clone = utils.abstractFunction; | ||
Type.prototype.compare = utils.abstractFunction; | ||
@@ -309,3 +314,3 @@ Type.prototype.random = utils.abstractFunction; | ||
}; | ||
PrimitiveType.prototype.clone = function (obj) { | ||
PrimitiveType.prototype._copy = function (obj) { | ||
this._check(obj, throwInvalidError); | ||
@@ -505,3 +510,3 @@ return obj; | ||
AbstractLongType.prototype.clone = function (obj) { | ||
AbstractLongType.prototype._copy = function (obj) { | ||
// Slow but guarantees most consistent results. Faster alternatives would | ||
@@ -513,3 +518,3 @@ // require assumptions on the long class used (e.g. immutability). | ||
AbstractLongType.prototype.random = function () { | ||
return this.clone(LongType.prototype.random()); | ||
return this._fromJSON(LongType.prototype.random()); | ||
}; | ||
@@ -634,3 +639,3 @@ | ||
* | ||
* Note the coercing handling in `clone`. | ||
* Note the coercing handling in `_copy`. | ||
* | ||
@@ -659,6 +664,26 @@ */ | ||
BytesType.prototype._updateResolver = StringType.prototype._updateResolver; | ||
BytesType.prototype.clone = function (obj, opts) { | ||
obj = tryCloneBuffer(obj, opts && opts.coerceBuffers); | ||
this._check(obj, throwInvalidError); | ||
return obj; | ||
BytesType.prototype._copy = function (obj, opts) { | ||
var buf; | ||
switch ((opts && opts.coerceBuffers) | 0) { | ||
case 3: // Coerce buffers to strings. | ||
this._check(obj, throwInvalidError); | ||
return obj.toString('binary'); | ||
case 2: // Coerce strings to buffers. | ||
case 1: // Coerce buffer JSON representation to buffers. | ||
if (obj && obj.type === 'Buffer' && obj.data instanceof Array) { | ||
buf = new Buffer(obj.data); | ||
} else if (typeof obj == 'string') { | ||
buf = new Buffer(obj, 'binary'); | ||
} else if (Buffer.isBuffer(obj)) { | ||
buf = new Buffer(obj); | ||
} | ||
if (!buf) { | ||
throw new Error(f('cannot coerce to buffer: %j', obj)); | ||
} | ||
this._check(buf, throwInvalidError); | ||
return buf; | ||
default: // Copy buffer. | ||
this._check(obj, throwInvalidError); | ||
return new Buffer(obj); | ||
} | ||
}; | ||
@@ -814,3 +839,3 @@ BytesType.prototype.compare = Buffer.compare; | ||
UnionType.prototype.clone = function (obj, opts) { | ||
UnionType.prototype._copy = function (obj, opts) { | ||
if (opts && opts.wrapUnions) { | ||
@@ -822,3 +847,3 @@ // Promote values to unions (useful when parsing defaults, see `Field` | ||
} | ||
return new this._constructors[0](this._types[0].clone(obj, opts)); | ||
return new this._constructors[0](this._types[0]._copy(obj, opts)); | ||
} else { | ||
@@ -847,3 +872,3 @@ if (obj === null && this._indices['null'] !== undefined) { | ||
if (i !== undefined) { | ||
var copy = this._types[i].clone(obj[name], opts); | ||
var copy = this._types[i]._copy(obj[name], opts); | ||
return new this._constructors[i](copy); | ||
@@ -955,3 +980,3 @@ } | ||
EnumType.prototype.clone = function (obj) { | ||
EnumType.prototype._copy = function (obj) { | ||
this._check(obj, throwInvalidError); | ||
@@ -963,3 +988,6 @@ return obj; | ||
EnumType.prototype.getFullName = function () { return this._name; }; | ||
EnumType.prototype.getFullName = util.deprecate( | ||
function () { return this._name; }, | ||
'`type.getFullName` will be removed in a future release, please use `type.getName` instead' | ||
); | ||
@@ -1034,11 +1062,10 @@ EnumType.prototype.getSymbols = function () { return this._symbols.slice(); }; | ||
FixedType.prototype.clone = function (obj, opts) { | ||
obj = tryCloneBuffer(obj, opts && opts.coerceBuffers); | ||
this._check(obj, throwInvalidError); | ||
return obj; | ||
}; | ||
FixedType.prototype._copy = BytesType.prototype._copy; | ||
FixedType.prototype.getAliases = function () { return this._aliases; }; | ||
FixedType.prototype.getFullName = function () { return this._name; }; | ||
FixedType.prototype.getFullName = util.deprecate( | ||
function () { return this._name; }, | ||
'`type.getFullName` will be removed in a future release, please use `type.getName` instead' | ||
); | ||
@@ -1164,3 +1191,3 @@ FixedType.prototype.getSize = function () { return this._size; }; | ||
MapType.prototype.clone = function (obj, opts) { | ||
MapType.prototype._copy = function (obj, opts) { | ||
if (obj && typeof obj == 'object' && !(obj instanceof Array)) { | ||
@@ -1173,3 +1200,3 @@ var values = this._values; | ||
key = keys[i]; | ||
copy[key] = values.clone(obj[key], opts); | ||
copy[key] = values._copy(obj[key], opts); | ||
} | ||
@@ -1315,6 +1342,6 @@ return copy; | ||
ArrayType.prototype.clone = function (obj, opts) { | ||
ArrayType.prototype._copy = function (obj, opts) { | ||
if (obj instanceof Array) { | ||
var itemsType = this._items; | ||
return obj.map(function (elem) { return itemsType.clone(elem, opts); }); | ||
return obj.map(function (elem) { return itemsType._copy(elem, opts); }); | ||
} | ||
@@ -1359,3 +1386,3 @@ throwInvalidError(obj, this); | ||
*/ | ||
function RecordType(attrs, opts) { | ||
function RecordType(attrs, opts, recordConstructor) { | ||
opts = getOpts(attrs, opts); | ||
@@ -1378,3 +1405,4 @@ | ||
this._constructor = this._createConstructor(attrs.type === 'error'); | ||
var isError = attrs.type === 'error'; | ||
this._constructor = recordConstructor || this._createConstructor(isError); | ||
this._read = this._createReader(); | ||
@@ -1648,7 +1676,7 @@ this._skip = this._createSkipper(); | ||
RecordType.prototype.clone = function (obj, opts) { | ||
RecordType.prototype._copy = function (obj, opts) { | ||
// jshint -W058 | ||
var hook = opts && opts.fieldHook; | ||
var fields = this._fields.map(function (f) { | ||
var copy = f._type.clone(obj[f._name], opts); | ||
var copy = f._type._copy(obj[f._name], opts); | ||
if (hook) { | ||
@@ -1685,3 +1713,6 @@ copy = hook(copy, f, this); | ||
RecordType.prototype.getFullName = function () { return this._name; }; | ||
RecordType.prototype.getFullName = util.deprecate( | ||
function () { return this._name; }, | ||
'`type.getFullName` will be removed in a future release, please use `type.getName` instead' | ||
); | ||
@@ -1722,6 +1753,17 @@ RecordType.prototype.getRecordConstructor = function () { | ||
this.setOrder(attrs.order || 'ascending'); | ||
// Not using `setOrder` to avoid deprecation warning. | ||
this._order = (function (order) { | ||
switch (order) { | ||
case 'ascending': | ||
return 1; | ||
case 'descending': | ||
return -1; | ||
case 'ignore': | ||
return 0; | ||
default: | ||
throw new Error(f('invalid order: %j', order)); | ||
} | ||
})(attrs.order === undefined ? 'ascending' : attrs.order); | ||
var value = attrs['default']; | ||
this._default = value; // Save this for schema JSON serialization. | ||
if (value !== undefined) { | ||
@@ -1733,3 +1775,3 @@ // We need to convert defaults back to a valid format (unions are | ||
var type = this._type; | ||
var obj = type.clone(value, {coerceBuffers: true, wrapUnions: true}); | ||
var obj = type._copy(value, {coerceBuffers: 2, wrapUnions: true}); | ||
// The clone call above will throw an error if the default is invalid. | ||
@@ -1740,3 +1782,3 @@ if (type instanceof PrimitiveType && !(type instanceof BytesType)) { | ||
} else { | ||
this.getDefault = function () { return type.clone(obj); }; | ||
this.getDefault = function () { return type._copy(obj); }; | ||
} | ||
@@ -1756,3 +1798,3 @@ } | ||
Field.prototype.setOrder = function (order) { | ||
Field.prototype.setOrder = util.deprecate(function (order) { | ||
var orders = {ascending: 1, ignore: 0, descending: -1}; | ||
@@ -1763,10 +1805,6 @@ if (!orders.hasOwnProperty(order)) { | ||
this._order = orders[order]; | ||
}; | ||
}, '`field.setOrder` will be removed in a future release, please create a new type instead'); | ||
Field.prototype.getType = function () { return this._type; }; | ||
Field.prototype.toJSON = function () { | ||
return {name: this._name, type: this._type, 'default': this._default}; | ||
}; | ||
/** | ||
@@ -1924,24 +1962,2 @@ * Resolver to read a writer's schema as a new schema. | ||
/** | ||
* Try cloning an object to a buffer. | ||
* | ||
* @param obj {Object} Object to copy to a buffer. | ||
* @param coerce {Boolean} Allow some conversions to buffers. | ||
* | ||
*/ | ||
function tryCloneBuffer(obj, coerce) { | ||
if (Buffer.isBuffer(obj)) { | ||
// Check this first (should be most common case). | ||
return new Buffer(obj); | ||
} | ||
if (coerce) { | ||
if (typeof obj == 'string') { | ||
return new Buffer(obj, 'binary'); | ||
} else if (obj.type === 'Buffer' && obj.data instanceof Array) { | ||
return new Buffer(obj.data); | ||
} | ||
} | ||
return obj; | ||
} | ||
/** | ||
* Check whether a long can be represented without precision loss. | ||
@@ -1948,0 +1964,0 @@ * |
{ | ||
"name": "avsc", | ||
"version": "2.4.0", | ||
"version": "2.5.0", | ||
"description": "A serialization API to make you smile", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/mtth/avsc", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
99622
3227