control-freak-ide/server/nodejs/lib/build/io/json.js
plastic-hub-dev-node-saturn 538369cff7 latest
2021-05-12 18:35:18 +02:00

219 lines
7.1 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const jp = require("jsonpath");
const primitives_1 = require("../std/primitives");
require("reflect-metadata");
const Implementation = JSON;
//
// ─── FILE - IO ───────────────────────────────────────────────────────────────────────
//
function read(file) {
const size = fs.statSync(file).size, buf = new Buffer(size), fd = fs.openSync(file, 'r');
if (!size) {
return '';
}
fs.readSync(fd, buf, 0, size, 0);
fs.closeSync(fd);
return buf.toString();
}
exports.read = read;
//
// ─── Standard decoder ───────────────────────────────────────────────────────────────────────
//
exports.to = (data, path) => {
let value = path ? jp.query(data, path)[0] : data;
let changed = false;
try {
if (primitives_1.isString(value)) {
value = JSON.parse(value);
changed = true;
}
}
catch (e) {
console.error('error decoding json', e);
}
changed && path && jp.value(data, path, value);
return data;
};
//
// ─── API abbreviation ───────────────────────────────────────────────────────────────────────
//
exports.serialize = (value, replacer, space) => {
return Implementation.stringify(value, replacer, space);
};
exports.deserialize = (value) => {
return Implementation.parse(value);
};
//
// ─── UTILS ──────────────────────────────────────────────────────────────────────
//
/**
* Calls JSON.Stringify with a replacer to break apart any circular references.
* This prevents JSON.stringify from throwing the exception
* "Uncaught TypeError: Converting circular structure to JSON"
*/
exports.safe = (obj) => {
let seen = [];
return exports.serialize(obj, (key, value) => {
if (primitives_1.isObject(value) || primitives_1.isArray(value)) {
if (seen.indexOf(value) !== -1) {
return '[Circular]';
}
else {
seen.push(value);
}
}
return value;
});
};
//
// ─── JSON-MAPPING ────────────────────────────────────────────────────────────────
//
const jsonMetadataKey = 'jsonProperty';
/**
* Decorator to map/support dashed property names
*
* @export
* @template T
* @param {(IJsonMetaData<T> | string)} [metadata]
* @returns {*}
*/
function JsonProperty(metadata) {
if (metadata instanceof String || typeof metadata === 'string') {
return Reflect.metadata(jsonMetadataKey, {
name: metadata,
clazz: undefined
});
}
else {
const metadataObj = metadata;
return Reflect.metadata(jsonMetadataKey, {
name: metadataObj ? metadataObj.name : undefined,
clazz: metadataObj ? metadataObj.clazz : undefined
});
}
}
exports.JsonProperty = JsonProperty;
function getClazz(target, propertyKey) {
return Reflect.getMetadata('design:type', target, propertyKey);
}
exports.getClazz = getClazz;
function getJsonProperty(target, propertyKey) {
return Reflect.getMetadata(jsonMetadataKey, target, propertyKey);
}
exports.getJsonProperty = getJsonProperty;
/**
* @example
// Example - JSON-Mapping
class Address {
@JsonProperty('first-line')
firstLine: string;
@JsonProperty('second-line')
secondLine: string;
city: string;
// Default constructor will be called by mapper
constructor() {
this.firstLine = undefined;
this.secondLine = undefined;
this.city = undefined;
}
}
class Person {
name: string;
surname: string;
age: number;
@JsonProperty('address')
address: Address;
// Default constructor will be called by mapper
constructor() {Array.
this.name = undefined;
this.surname = undefined;
this.age = undefined;
this.address = undefined;
}
}
let example = {
"name": "Mark",
"surname": "Galea",
"age": 30,
"address": {
"first-line": "Some where",
"second-line": "Over Here",
"city": "In This City"
}
};
const Person2 = Map.deserialize(Person, example);
*/
class Map {
static isPrimitive(obj) {
switch (typeof obj) {
case 'string':
case 'number':
case 'boolean':
return true;
}
return !!(obj instanceof String || obj === String ||
obj instanceof Number || obj === Number ||
obj instanceof Boolean || obj === Boolean);
}
static isArray(object) {
if (object === Array) {
return true;
}
else if (typeof Array.isArray === 'function') {
return Array.isArray(object);
}
else {
return !!(object instanceof Array);
}
}
static deserialize(clazz, jsonObject) {
if ((clazz === undefined) || (jsonObject === undefined)) {
return undefined;
}
const obj = new clazz();
Object.keys(obj).forEach((key) => {
const propertyMetadataFn = (propertyMetadata) => {
let propertyName = propertyMetadata.name || key;
let innerJson = jsonObject ? jsonObject[propertyName] : undefined;
let clazz = getClazz(obj, key);
if (Map.isArray(clazz)) {
let metadata = getJsonProperty(obj, key);
if (metadata.clazz || Map.isPrimitive(clazz)) {
if (innerJson && Map.isArray(innerJson)) {
return innerJson.map((item) => Map.deserialize(metadata.clazz, item));
}
else {
return undefined;
}
}
else {
return innerJson;
}
}
else if (!Map.isPrimitive(clazz)) {
return Map.deserialize(clazz, innerJson);
}
else {
return jsonObject ? jsonObject[propertyName] : undefined;
}
};
const propertyMetadata = getJsonProperty(obj, key);
if (propertyMetadata) {
obj[key] = propertyMetadataFn(propertyMetadata);
}
else {
if (jsonObject && jsonObject[key] !== undefined) {
obj[key] = jsonObject[key];
}
}
});
return obj;
}
}
exports.Map = Map;
//# sourceMappingURL=json.js.map