aurelia-json
Advanced tools
Comparing version 0.4.0 to 0.4.1
export declare function jsonIgnore(...properties: string[]): PropertyDecorator; | ||
export declare function serializer<T>(serializer: (value: T) => any): PropertyDecorator; |
@@ -11,3 +11,7 @@ "use strict"; | ||
exports.jsonIgnore = jsonIgnore; | ||
function serializer(serializer) { | ||
return Reflect.metadata(metadataKeys.serializer, serializer); | ||
} | ||
exports.serializer = serializer; | ||
//# sourceMappingURL=decorators.js.map |
@@ -10,1 +10,2 @@ import { FrameworkConfiguration } from "aurelia-framework"; | ||
export { JsonSchema, JsonPatch, JsonPointer, JsonEncoder, JsonDecoder, JsonMultipartRelatedInterceptor }; | ||
export * from "./decorators"; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
var aurelia_http_client_1 = require("aurelia-http-client"); | ||
@@ -26,3 +29,4 @@ var json_schema_1 = require("./json-schema"); | ||
exports.configure = configure; | ||
__export(require("./decorators")); | ||
//# sourceMappingURL=index.js.map |
@@ -24,3 +24,5 @@ "use strict"; | ||
var object = JSON.parse(json); | ||
return (_a = this.typeBinder).bind.apply(_a, [object, type].concat(generics)); | ||
return typeof type["fromJSON"] === "function" | ||
? type["fromJSON"](object, this, this.typeBinder) | ||
: (_a = this.typeBinder).bind.apply(_a, [object, type].concat(generics)); | ||
var _a; | ||
@@ -27,0 +29,0 @@ }; |
@@ -15,3 +15,3 @@ export declare class JsonEncoder { | ||
encode(value: any, ignore?: string[]): string; | ||
withSerializer<T>(type: new (...args: any[]) => T, serializer: (value: T) => string): JsonEncoder; | ||
withSerializer<T>(serializer: (value: T) => string, ...types: (new (...args: any[]) => T)[]): JsonEncoder; | ||
} |
@@ -10,6 +10,7 @@ "use strict"; | ||
if (ignore === void 0) { ignore = []; } | ||
if (value === null) { | ||
if (value === null || value === undefined) { | ||
return JsonEncoder.VALUE_NULL; | ||
} | ||
else if (typeof value === "boolean") { | ||
var prototype = Object.getPrototypeOf(value); | ||
if (typeof value === "boolean") { | ||
return value ? JsonEncoder.VALUE_TRUE : JsonEncoder.VALUE_FALSE; | ||
@@ -32,11 +33,10 @@ } | ||
} | ||
else if (this.serializers.has(value.constructor)) { | ||
return this.serializers.get(value.constructor)(value); | ||
} | ||
else { | ||
var prototype = Object.getPrototypeOf(value); | ||
var serializer = this.serializers.get(value.constructor); | ||
if (serializer) { | ||
return serializer(value); | ||
} | ||
var json = JsonEncoder.START_OBJECT; | ||
var properties = []; | ||
for (var key in value) { | ||
for (var _i = 0, _a = Object.keys(value); _i < _a.length; _i++) { | ||
var key = _a[_i]; | ||
var jsonIgnore = Reflect.getMetadata(metadataKeys.jsonIgnore, prototype, key); | ||
@@ -48,4 +48,15 @@ if (ignore.indexOf(key) < 0) { | ||
json += properties.map(function (property) { | ||
return JsonEncoder.START_STRING + property.key + JsonEncoder.END_STRING + | ||
JsonEncoder.DEFINITION + _this.encode(property.value, property.ignore); | ||
var key = JsonEncoder.START_STRING + property.key + JsonEncoder.END_STRING; | ||
var value; | ||
if (property.value === null || property.value === undefined) { | ||
value = JsonEncoder.VALUE_NULL; | ||
} | ||
else if (Reflect.hasMetadata(metadataKeys.serializer, prototype, property.key)) { | ||
var serializer = Reflect.getMetadata(metadataKeys.serializer, prototype, property.key); | ||
value = _this.encode(serializer(property.value)); | ||
} | ||
else { | ||
value = _this.encode(property.value, property.ignore); | ||
} | ||
return key + JsonEncoder.DEFINITION + value; | ||
}).join(JsonEncoder.SEPARATOR) + JsonEncoder.END_OBJECT; | ||
@@ -55,4 +66,9 @@ return json; | ||
}; | ||
JsonEncoder.prototype.withSerializer = function (type, serializer) { | ||
this.serializers.set(type, serializer); | ||
JsonEncoder.prototype.withSerializer = function (serializer) { | ||
var _this = this; | ||
var types = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
types[_i - 1] = arguments[_i]; | ||
} | ||
types.forEach(function (type) { return _this.serializers.set(type, serializer); }); | ||
return this; | ||
@@ -59,0 +75,0 @@ }; |
@@ -12,6 +12,6 @@ "use strict"; | ||
var partId = 0; | ||
var encoder = new json_encoder_1.JsonEncoder().withSerializer(File, function (file) { | ||
multipartRelated.addPart(new aurelia_http_utils_1.Part(file, aurelia_http_utils_1.ContentType.valueOf(file.type)), (++partId).toString()); | ||
var encoder = new json_encoder_1.JsonEncoder().withSerializer(function (blob) { | ||
multipartRelated.addPart(new aurelia_http_utils_1.Part(blob, aurelia_http_utils_1.ContentType.valueOf(blob.type)), (++partId).toString()); | ||
return partId.toString(); | ||
}); | ||
}, Blob, File); | ||
multipartRelated.addRootPart(new aurelia_http_utils_1.Part(encoder.encode(message.content), this.contentType), "/"); | ||
@@ -18,0 +18,0 @@ message.content = multipartRelated.toBlob(); |
@@ -5,12 +5,12 @@ export declare class JsonPatch { | ||
readonly length: number; | ||
add(path: string, value: any): JsonPatch; | ||
add<T>(path: string, value: T): JsonPatch; | ||
remove(path: string): JsonPatch; | ||
replace(path: string, value: any): JsonPatch; | ||
replace<T>(path: string, value: T, serializer?: (value: T) => any): JsonPatch; | ||
copy(fromPath: string, toPath: string): JsonPatch; | ||
move(fromPath: string, toPath: string): JsonPatch; | ||
test(path: string, value: any): JsonPatch; | ||
test<T>(path: string, value: T): JsonPatch; | ||
reset(): JsonPatch; | ||
getArray(): any[]; | ||
toJSON(): any; | ||
static diff<T>(target: T, properties?: Object, patch?: JsonPatch, prefix?: string, separator?: string, wildcard?: string): JsonPatch; | ||
static diff<T>(target: T, properties?: string[], patch?: JsonPatch, prefix?: string, separator?: string, wildcard?: string): JsonPatch; | ||
} |
"use strict"; | ||
var type_binder_1 = require("type-binder"); | ||
var metadataKeys = require("./metadata-keys"); | ||
var JsonPatch = (function () { | ||
@@ -30,8 +31,10 @@ function JsonPatch(operations) { | ||
}; | ||
JsonPatch.prototype.replace = function (path, value) { | ||
this.operations.push({ | ||
JsonPatch.prototype.replace = function (path, value, serializer) { | ||
var op = { | ||
"op": "replace", | ||
path: path, | ||
value: value | ||
}); | ||
}; | ||
Reflect.defineMetadata(metadataKeys.serializer, serializer, op, "value"); | ||
this.operations.push(op); | ||
return this; | ||
@@ -74,3 +77,3 @@ }; | ||
JsonPatch.diff = function (target, properties, patch, prefix, separator, wildcard) { | ||
if (properties === void 0) { properties = target; } | ||
if (properties === void 0) { properties = Object.keys(target); } | ||
if (patch === void 0) { patch = new JsonPatch(); } | ||
@@ -80,59 +83,42 @@ if (separator === void 0) { separator = "/"; } | ||
var _loop_1 = function (key) { | ||
var include = properties[key]; | ||
if (include) { | ||
var currentValue = target[key]; | ||
if (Reflect.hasMetadata(type_binder_1.binderPropertyTrackValue, target, key)) { | ||
var comparingCallback = Reflect.getMetadata(type_binder_1.binderPropertyTrackCompare, target, key); | ||
var originalValue = Reflect.getMetadata(type_binder_1.binderPropertyTrackValue, target, key); | ||
if (!comparingCallback(currentValue, originalValue)) { | ||
var pointer = [prefix, key].join(separator); | ||
patch.test(pointer, originalValue); | ||
patch.replace([prefix, key].join(separator), currentValue); | ||
var currentValue = target[key]; | ||
if (Reflect.hasMetadata(type_binder_1.binderPropertyTrackValue, target, key)) { | ||
var comparingCallback = Reflect.getMetadata(type_binder_1.binderPropertyTrackCompare, target, key); | ||
var originalValue = Reflect.getMetadata(type_binder_1.binderPropertyTrackValue, target, key); | ||
if (!comparingCallback(currentValue, originalValue)) { | ||
var pointer = [prefix, key].join(separator); | ||
// patch.test(pointer, originalValue); | ||
patch.replace([prefix, key].join(separator), currentValue); | ||
} | ||
else if (currentValue !== null && typeof currentValue === "object") { | ||
JsonPatch.diff(currentValue, Object.keys(currentValue), patch, [prefix, key].join(separator), separator, wildcard); | ||
} | ||
} | ||
else if (currentValue !== null && Reflect.hasMetadata(type_binder_1.binderPropertyEntriesValue, target, key)) { | ||
var trackingCallback = Reflect.getMetadata(type_binder_1.binderPropertyEntries, target, key); | ||
var comparingCallback_1 = Reflect.getMetadata(type_binder_1.binderPropertyEntriesCompare, target, key); | ||
var originalEntries = Reflect.getMetadata(type_binder_1.binderPropertyEntriesValue, target, key); | ||
var currentEntries_1 = trackingCallback(currentValue); | ||
originalEntries.forEach(function (value, index) { | ||
var pointer = [prefix, key, index].join(separator); | ||
if (index >= currentEntries_1.length) { | ||
// patch.test(pointer, value); | ||
patch.remove(pointer); | ||
} | ||
else if (currentValue !== null && typeof currentValue === "object") { | ||
JsonPatch.diff(currentValue, include, patch, [prefix, key].join(separator), separator, wildcard); | ||
else if (!comparingCallback_1(value, currentEntries_1[index])) { | ||
// patch.test(pointer, value); | ||
patch.replace(pointer, currentEntries_1[index], Reflect.getMetadata(metadataKeys.serializer, target, key)); | ||
} | ||
} | ||
else if (currentValue !== null && Reflect.hasMetadata(type_binder_1.binderPropertyEntriesValue, target, key)) { | ||
var comparingCallback_1 = Reflect.getMetadata(type_binder_1.binderPropertyEntriesCompare, target, key); | ||
var originalEntries = Reflect.getMetadata(type_binder_1.binderPropertyEntriesValue, target, key); | ||
var originalLength = originalEntries.length; | ||
var originalTrack_1 = originalEntries.slice(); | ||
var currentEntries_1 = Array.from(currentValue); | ||
var currentLength_1 = currentEntries_1.length; | ||
var addEntries_1 = currentEntries_1.slice(); | ||
originalEntries.forEach(function (value) { | ||
var index = originalTrack_1.indexOf(value); | ||
var found = currentEntries_1.findIndex(function (item) { return comparingCallback_1(value, item); }); | ||
var from = [prefix, key, index].join(separator); | ||
if (found >= 0) { | ||
var pointer = [prefix, key, found].join(separator); | ||
if (found !== index) { | ||
patch.test(from, value); | ||
patch.move(from, pointer); | ||
originalTrack_1.splice(index, 1); | ||
originalTrack_1[found] = value; | ||
} | ||
addEntries_1.splice(addEntries_1.indexOf(currentEntries_1[found]), 1); | ||
} | ||
else if (index < currentLength_1) { | ||
patch.test(from, value); | ||
patch.replace(from, currentEntries_1[index]); | ||
originalTrack_1[index] = currentEntries_1[index]; | ||
addEntries_1.splice(addEntries_1.indexOf(currentEntries_1[index]), 1); | ||
} | ||
else { | ||
patch.test(from, value); | ||
patch.remove(from); | ||
originalTrack_1.splice(index, 1); | ||
} | ||
}); | ||
if (addEntries_1.length > 0) { | ||
var path_1 = [prefix, key, wildcard].join(separator); | ||
addEntries_1.forEach(function (value) { return patch.add(path_1, value); }); | ||
else if (value !== null && typeof value === "object") { | ||
JsonPatch.diff(value, Object.keys(value), patch, pointer, separator, wildcard); | ||
} | ||
}); | ||
if (currentEntries_1.length > originalEntries.length) { | ||
var path_1 = [prefix, key, wildcard].join(separator); | ||
currentEntries_1.slice(originalEntries.length).forEach(function (value) { return patch.add(path_1, value); }); | ||
} | ||
} | ||
}; | ||
for (var key in properties) { | ||
for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) { | ||
var key = properties_1[_i]; | ||
_loop_1(key); | ||
@@ -139,0 +125,0 @@ } |
export declare const jsonIgnore = "json:ignore"; | ||
export declare const serializer = "json:serializer"; |
"use strict"; | ||
exports.jsonIgnore = "json:ignore"; | ||
exports.serializer = "json:serializer"; | ||
//# sourceMappingURL=metadata-keys.js.map |
@@ -11,3 +11,2 @@ "use strict"; | ||
}; | ||
var type_binder_1 = require("type-binder"); | ||
var json_encoder_1 = require("../../main/json-encoder"); | ||
@@ -31,6 +30,8 @@ var decorators_1 = require("../../main/decorators"); | ||
var encoder = new json_encoder_1.JsonEncoder(); | ||
var object = { "id": 1, "items": [{ "item": 1, "boo": null }, { "item": 2 }], "foo": { "bar": true, "baz": 123 } }; | ||
var foo = new type_binder_1.TypeBinder().bind(object, Foo); | ||
var foo = new Foo(); | ||
foo.id = 1; | ||
foo.foo = { "bar": true, "baz": 123 }; | ||
foo.items = new Set([{ "item": 1, "boo": null }, { "item": 2 }]); | ||
var json = encoder.encode(foo); | ||
expect(json).toBe('{"id":1,"items":[{"item":1},{"item":2}],"foo":{"baz":123}}'); | ||
expect(json).toBe('{"id":1,"foo":{"baz":123},"items":[{"item":1},{"item":2}]}'); | ||
}); | ||
@@ -37,0 +38,0 @@ }); |
@@ -46,3 +46,2 @@ "use strict"; | ||
expect(patch.toJSON()).toEqual([ | ||
{ op: 'test', path: '/a', value: 1 }, | ||
{ op: 'replace', path: '/a', value: 2 } | ||
@@ -53,13 +52,9 @@ ]); | ||
expect(patch.toJSON()).toEqual([ | ||
{ op: 'test', path: '/a', value: 1 }, | ||
{ op: 'replace', path: '/a', value: 2 }, | ||
{ op: 'test', path: '/bar/c', value: 3 }, | ||
{ op: 'replace', path: '/bar/c', value: 4 } | ||
]); | ||
foo.bar = new Bar(); | ||
patch = json_patch_1.JsonPatch.diff(foo, { a: true, bar: true }); | ||
patch = json_patch_1.JsonPatch.diff(foo, ["a", "bar"]); | ||
expect(patch.toJSON()).toEqual([ | ||
{ op: 'test', path: '/a', value: 1 }, | ||
{ op: 'replace', path: '/a', value: 2 }, | ||
{ op: 'test', path: '/bar', value: bar }, | ||
{ op: 'replace', path: '/bar', value: foo.bar } | ||
@@ -88,3 +83,3 @@ ]); | ||
type_binder_1.generics(Foo, Bar), | ||
type_binder_1.trackIterable(function (v1, v2) { return v1.every(function (v, i) { return v === v2[i]; }); }), | ||
type_binder_1.trackIterable(function (i) { return Array.from(i); }, function (v1, v2) { return v1.every(function (v, i) { return v === v2[i]; }); }), | ||
__metadata("design:type", Map) | ||
@@ -107,5 +102,5 @@ ], Bag.prototype, "foobars", void 0); | ||
var patch = json_patch_1.JsonPatch.diff(bag); | ||
expect(new json_encoder_1.JsonEncoder().encode(patch)).toBe('[{"op":"test","path":"/numbers/0","value":1},' + | ||
'{"op":"move","from":"/numbers/0","path":"/numbers/2"},' + | ||
'{"op":"test","path":"/foobars/0","value":[{"a":1},{"c":1}]},' + | ||
expect(new json_encoder_1.JsonEncoder().encode(patch)).toBe('[{"op":"replace","path":"/numbers/0","value":2},' + | ||
'{"op":"replace","path":"/numbers/1","value":3},' + | ||
'{"op":"replace","path":"/numbers/2","value":1},' + | ||
'{"op":"replace","path":"/foobars/0","value":[{"a":1},{"c":4}]}]'); | ||
@@ -112,0 +107,0 @@ }); |
{ | ||
"name": "aurelia-json", | ||
"version": "0.4.0", | ||
"version": "0.4.1", | ||
"description": "A JSON plugin for Aurelia based projects.", | ||
@@ -29,7 +29,7 @@ "keywords": [ | ||
"aurelia-http-client": "^1.0.3", | ||
"aurelia-http-utils": "^0.3.0", | ||
"type-binder": "^0.3.0" | ||
"aurelia-http-utils": "^0.3.1", | ||
"type-binder": "^0.3.1" | ||
}, | ||
"devDependencies": { | ||
"@types/jasmine": "^2.5.38", | ||
"@types/jasmine": "^2.5.40", | ||
"babel-preset-es2015": "^6.18.0", | ||
@@ -45,3 +45,3 @@ "babel-register": "^6.18.0", | ||
"jasmine-reporters": "^2.2.0", | ||
"merge2": "^1.0.2", | ||
"merge2": "^1.0.3", | ||
"run-sequence": "^1.2.2", | ||
@@ -48,0 +48,0 @@ "typescript": "^2.1.4", |
@@ -6,1 +6,5 @@ import * as metadataKeys from "./metadata-keys"; | ||
} | ||
export function serializer<T>(serializer: (value: T) => any): PropertyDecorator { | ||
return Reflect.metadata(metadataKeys.serializer, serializer); | ||
} |
@@ -23,1 +23,2 @@ import { FrameworkConfiguration } from "aurelia-framework"; | ||
export { JsonSchema, JsonPatch, JsonPointer, JsonEncoder, JsonDecoder, JsonMultipartRelatedInterceptor }; | ||
export * from "./decorators"; |
@@ -16,9 +16,11 @@ | ||
let object = JSON.parse(json); | ||
return this.typeBinder.bind(object, type, ...generics); | ||
return typeof type["fromJSON"] === "function" | ||
? type["fromJSON"](object, this, this.typeBinder) | ||
: this.typeBinder.bind(object, type, ...generics); | ||
} | ||
public reviver(key: string, value: any): any { | ||
} | ||
} |
@@ -30,5 +30,7 @@ import * as metadataKeys from "./metadata-keys"; | ||
public encode(value: any, ignore: string[] = []): string { | ||
if (value === null) { | ||
if (value === null || value === undefined) { | ||
return JsonEncoder.VALUE_NULL; | ||
} else if (typeof value === "boolean") { | ||
} | ||
let prototype = Object.getPrototypeOf(value); | ||
if (typeof value === "boolean") { | ||
return value ? JsonEncoder.VALUE_TRUE : JsonEncoder.VALUE_FALSE; | ||
@@ -46,11 +48,8 @@ } else if (typeof value === "number") { | ||
return json; | ||
} else if (this.serializers.has(value.constructor)) { | ||
return this.serializers.get(value.constructor)(value); | ||
} else { | ||
let prototype = Object.getPrototypeOf(value); | ||
let serializer = this.serializers.get(value.constructor); | ||
if (serializer) { | ||
return serializer(value); | ||
} | ||
let json = JsonEncoder.START_OBJECT; | ||
let properties: { key: string, value: any, ignore: string[] }[] = []; | ||
for (let key in value) { | ||
for (let key of Object.keys(value)) { | ||
let jsonIgnore: string[] = Reflect.getMetadata(metadataKeys.jsonIgnore, prototype, key); | ||
@@ -61,6 +60,15 @@ if (ignore.indexOf(key) < 0) { | ||
} | ||
json += properties.map(property => | ||
JsonEncoder.START_STRING + property.key + JsonEncoder.END_STRING + | ||
JsonEncoder.DEFINITION + this.encode(property.value, property.ignore) | ||
).join(JsonEncoder.SEPARATOR) + JsonEncoder.END_OBJECT; | ||
json += properties.map(property => { | ||
let key = JsonEncoder.START_STRING + property.key + JsonEncoder.END_STRING; | ||
let value; | ||
if (property.value === null || property.value === undefined) { | ||
value = JsonEncoder.VALUE_NULL; | ||
} else if (Reflect.hasMetadata(metadataKeys.serializer, prototype, property.key)) { | ||
let serializer = Reflect.getMetadata(metadataKeys.serializer, prototype, property.key); | ||
value = this.encode(serializer(property.value)); | ||
} else { | ||
value = this.encode(property.value, property.ignore); | ||
} | ||
return key + JsonEncoder.DEFINITION + value; | ||
}).join(JsonEncoder.SEPARATOR) + JsonEncoder.END_OBJECT; | ||
return json; | ||
@@ -70,4 +78,4 @@ } | ||
public withSerializer<T>(type: new(...args: any[]) => T, serializer: (value: T) => string): JsonEncoder { | ||
this.serializers.set(type, serializer); | ||
public withSerializer<T>(serializer: (value: T) => string, ...types: (new(...args: any[]) => T)[]): JsonEncoder { | ||
types.forEach(type => this.serializers.set(type, serializer)); | ||
return this; | ||
@@ -74,0 +82,0 @@ } |
@@ -16,6 +16,6 @@ import { Interceptor, HttpRequestMessage, HttpResponseMessage } from "aurelia-http-client"; | ||
let partId = 0; | ||
let encoder = new JsonEncoder().withSerializer(File, file => { | ||
multipartRelated.addPart(new Part(file, ContentType.valueOf(file.type)), (++partId).toString()); | ||
let encoder = new JsonEncoder().withSerializer<Blob>(blob => { | ||
multipartRelated.addPart(new Part(blob, ContentType.valueOf(blob.type)), (++partId).toString()); | ||
return partId.toString(); | ||
}); | ||
}, Blob, File); | ||
multipartRelated.addRootPart(new Part(encoder.encode(message.content), this.contentType), "/"); | ||
@@ -22,0 +22,0 @@ message.content = multipartRelated.toBlob(); |
@@ -1,2 +0,3 @@ | ||
import { binderPropertyTrackValue, binderPropertyEntriesValue, binderPropertyTrackCompare, binderPropertyEntriesCompare } from "type-binder"; | ||
import { binderPropertyTrackValue, binderPropertyEntriesValue, binderPropertyTrackCompare, binderPropertyEntries, binderPropertyEntriesCompare } from "type-binder"; | ||
import * as metadataKeys from "./metadata-keys"; | ||
@@ -15,3 +16,3 @@ export class JsonPatch { | ||
public add(path: string, value: any): JsonPatch { | ||
public add<T>(path: string, value: T): JsonPatch { | ||
this.operations.push({ | ||
@@ -33,8 +34,10 @@ "op": "add", | ||
public replace(path: string, value: any): JsonPatch { | ||
this.operations.push({ | ||
public replace<T>(path: string, value: T, serializer?: (value: T) => any): JsonPatch { | ||
let op = { | ||
"op": "replace", | ||
path, | ||
value | ||
}); | ||
}; | ||
Reflect.defineMetadata(metadataKeys.serializer, serializer, op, "value"); | ||
this.operations.push(op); | ||
return this; | ||
@@ -61,3 +64,3 @@ } | ||
public test(path: string, value: any): JsonPatch { | ||
public test<T>(path: string, value: T): JsonPatch { | ||
this.operations.push({ | ||
@@ -84,53 +87,35 @@ "op": "test", | ||
public static diff<T>(target: T, properties: Object = target, patch: JsonPatch = new JsonPatch(), prefix?: string, separator: string = "/", wildcard: string = "-"): JsonPatch { | ||
for (let key in properties) { | ||
let include = properties[key]; | ||
if (include) { | ||
let currentValue = target[key]; | ||
if (Reflect.hasMetadata(binderPropertyTrackValue, target, key)) { | ||
let comparingCallback: (v1, v2) => boolean = Reflect.getMetadata(binderPropertyTrackCompare, target, key); | ||
let originalValue = Reflect.getMetadata(binderPropertyTrackValue, target, key); | ||
if (!comparingCallback(currentValue, originalValue)) { | ||
let pointer = [prefix, key].join(separator); | ||
patch.test(pointer, originalValue); | ||
patch.replace([prefix, key].join(separator), currentValue); | ||
} else if (currentValue !== null && typeof currentValue === "object") { | ||
JsonPatch.diff(currentValue, include, patch, [prefix, key].join(separator), separator, wildcard); | ||
public static diff<T>(target: T, properties: string[] = Object.keys(target), patch: JsonPatch = new JsonPatch(), prefix?: string, separator: string = "/", wildcard: string = "-"): JsonPatch { | ||
for (let key of properties) { | ||
let currentValue = target[key]; | ||
if (Reflect.hasMetadata(binderPropertyTrackValue, target, key)) { | ||
let comparingCallback: (v1, v2) => boolean = Reflect.getMetadata(binderPropertyTrackCompare, target, key); | ||
let originalValue = Reflect.getMetadata(binderPropertyTrackValue, target, key); | ||
if (!comparingCallback(currentValue, originalValue)) { | ||
let pointer = [prefix, key].join(separator); | ||
// patch.test(pointer, originalValue); | ||
patch.replace([prefix, key].join(separator), currentValue); | ||
} else if (currentValue !== null && typeof currentValue === "object") { | ||
JsonPatch.diff(currentValue, Object.keys(currentValue), patch, [prefix, key].join(separator), separator, wildcard); | ||
} | ||
} else if (currentValue !== null && Reflect.hasMetadata(binderPropertyEntriesValue, target, key)) { | ||
let trackingCallback: <I extends Iterable<V>, V>(iterable: I) => V[] = Reflect.getMetadata(binderPropertyEntries, target, key); | ||
let comparingCallback: (v1, v2) => boolean = Reflect.getMetadata(binderPropertyEntriesCompare, target, key); | ||
let originalEntries = <any[]> Reflect.getMetadata(binderPropertyEntriesValue, target, key); | ||
let currentEntries = trackingCallback(currentValue); | ||
originalEntries.forEach((value, index) => { | ||
let pointer = [prefix, key, index].join(separator); | ||
if (index >= currentEntries.length) { | ||
// patch.test(pointer, value); | ||
patch.remove(pointer); | ||
} else if (!comparingCallback(value, currentEntries[index])) { | ||
// patch.test(pointer, value); | ||
patch.replace(pointer, currentEntries[index], Reflect.getMetadata(metadataKeys.serializer, target, key)); | ||
} else if (value !== null && typeof value === "object") { | ||
JsonPatch.diff(value, Object.keys(value), patch, pointer, separator, wildcard); | ||
} | ||
} else if (currentValue !== null && Reflect.hasMetadata(binderPropertyEntriesValue, target, key)) { | ||
let comparingCallback: (v1, v2) => boolean = Reflect.getMetadata(binderPropertyEntriesCompare, target, key); | ||
let originalEntries = <any[]> Reflect.getMetadata(binderPropertyEntriesValue, target, key); | ||
let originalLength = originalEntries.length; | ||
let originalTrack = originalEntries.slice(); | ||
let currentEntries = Array.from(currentValue); | ||
let currentLength = currentEntries.length; | ||
let addEntries = currentEntries.slice(); | ||
originalEntries.forEach(value => { | ||
let index = originalTrack.indexOf(value); | ||
let found = currentEntries.findIndex(item => comparingCallback(value, item)); | ||
let from = [prefix, key, index].join(separator); | ||
if (found >= 0) { | ||
let pointer = [prefix, key, found].join(separator); | ||
if (found !== index) { | ||
patch.test(from, value); | ||
patch.move(from, pointer); | ||
originalTrack.splice(index, 1); | ||
originalTrack[found] = value; | ||
} | ||
addEntries.splice(addEntries.indexOf(currentEntries[found]), 1); | ||
} else if (index < currentLength) { | ||
patch.test(from, value); | ||
patch.replace(from, currentEntries[index]); | ||
originalTrack[index] = currentEntries[index]; | ||
addEntries.splice(addEntries.indexOf(currentEntries[index]), 1); | ||
} else { | ||
patch.test(from, value); | ||
patch.remove(from); | ||
originalTrack.splice(index, 1); | ||
} | ||
}); | ||
if (addEntries.length > 0) { | ||
let path = [prefix, key, wildcard].join(separator); | ||
addEntries.forEach(value => patch.add(path, value)); | ||
} | ||
}); | ||
if (currentEntries.length > originalEntries.length) { | ||
let path = [prefix, key, wildcard].join(separator); | ||
currentEntries.slice(originalEntries.length).forEach(value => patch.add(path, value)); | ||
} | ||
@@ -137,0 +122,0 @@ } |
export const jsonIgnore = "json:ignore"; | ||
export const serializer = "json:serializer"; |
@@ -10,2 +10,3 @@ import { TypeBinder, bind, generics, track } from "type-binder"; | ||
class Foo { | ||
id; | ||
@jsonIgnore("bar") | ||
@@ -18,8 +19,11 @@ foo; | ||
let encoder = new JsonEncoder(); | ||
let object = {"id":1,"items":[{"item":1,"boo":null},{"item":2}],"foo":{"bar":true,"baz":123}}; | ||
let foo = new TypeBinder().bind(object, Foo); | ||
let foo = new Foo(); | ||
foo.id = 1; | ||
foo.foo = {"bar":true,"baz":123}; | ||
foo.items = new Set([{"item":1,"boo":null},{"item":2}]); | ||
let json = encoder.encode(foo); | ||
expect(json).toBe('{"id":1,"items":[{"item":1},{"item":2}],"foo":{"baz":123}}'); | ||
expect(json).toBe('{"id":1,"foo":{"baz":123},"items":[{"item":1},{"item":2}]}'); | ||
}); | ||
}); |
@@ -26,3 +26,2 @@ import { TypeBinder, bind, generics, track, trackIterable } from "type-binder"; | ||
expect(patch.toJSON()).toEqual([ | ||
{ op: 'test', path: '/a', value: 1 }, | ||
{ op: 'replace', path: '/a', value: 2 } | ||
@@ -33,13 +32,9 @@ ]); | ||
expect(patch.toJSON()).toEqual([ | ||
{ op: 'test', path: '/a', value: 1 }, | ||
{ op: 'replace', path: '/a', value: 2 }, | ||
{ op: 'test', path: '/bar/c', value: 3 }, | ||
{ op: 'replace', path: '/bar/c', value: 4 } | ||
]); | ||
foo.bar = new Bar(); | ||
patch = JsonPatch.diff(foo, { a: true, bar: true }); | ||
patch = JsonPatch.diff(foo, ["a", "bar"]); | ||
expect(patch.toJSON()).toEqual([ | ||
{ op: 'test', path: '/a', value: 1 }, | ||
{ op: 'replace', path: '/a', value: 2 }, | ||
{ op: 'test', path: '/bar', value: bar }, | ||
{ op: 'replace', path: '/bar', value: foo.bar } | ||
@@ -62,3 +57,3 @@ ]); | ||
@generics(Foo, Bar) | ||
@trackIterable<[Foo, Bar], Map<Foo, Bar>>((v1, v2) => v1.every((v, i) => v === v2[i])) | ||
@trackIterable<[Foo, Bar], Map<Foo, Bar>>(i => Array.from(i), (v1, v2) => v1.every((v, i) => v === v2[i])) | ||
foobars: Map<Foo, Bar>; | ||
@@ -83,5 +78,5 @@ } | ||
expect(new JsonEncoder().encode(patch)).toBe( | ||
'[{"op":"test","path":"/numbers/0","value":1},' + | ||
'{"op":"move","from":"/numbers/0","path":"/numbers/2"},' + | ||
'{"op":"test","path":"/foobars/0","value":[{"a":1},{"c":1}]},' + | ||
'[{"op":"replace","path":"/numbers/0","value":2},' + | ||
'{"op":"replace","path":"/numbers/1","value":3},' + | ||
'{"op":"replace","path":"/numbers/2","value":1},' + | ||
'{"op":"replace","path":"/foobars/0","value":[{"a":1},{"c":4}]}]' | ||
@@ -88,0 +83,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 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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
82898
978
Updatedaurelia-http-utils@^0.3.1
Updatedtype-binder@^0.3.1