123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- const { mergeQueryProps } = require('./modelQueryProps');
- const { isObject, cloneDeep } = require('../utils/objectUtils');
- function toJson(model, opt) {
- const modelClass = model.constructor;
- if (!isObject(opt)) {
- opt = {};
- }
- // We don't take a copy of `opt` here which can cause some problems in some
- // super rare cases since we modify an object passed from the outside. I can't
- // think of a realistic scenario where this would actually have some unwanted
- // effects. We don't take a copy for performance reasons.
- opt.omit = null;
- opt.pick = null;
- opt.omitFromJson = model.$omitFromJson() || null;
- if (opt.virtuals === undefined) {
- opt.virtuals = true;
- }
- if (opt.shallow) {
- opt.omit = modelClass.getRelations();
- }
- let json = toExternalJsonImpl(model, opt);
- return model.$formatJson(json);
- }
- function toDatabaseJson(model, knex) {
- const modelClass = model.constructor;
- const jsonSchema = modelClass.getJsonSchema();
- const opt = {
- virtuals: false,
- shallow: true,
- omit: modelClass.getRelations(),
- pick: (jsonSchema && modelClass.pickJsonSchemaProperties && jsonSchema.properties) || null,
- omitFromJson: model.$omitFromDatabaseJson() || null
- };
- let json = toDatabaseJsonImpl(model, opt);
- json = model.$formatDatabaseJson(json);
- return mergeQueryProps(model, json, knex);
- }
- function toExternalJsonImpl(model, opt) {
- const json = {};
- const keys = Object.keys(model);
- const vAttr = model.constructor.virtualAttributes;
- for (let i = 0, l = keys.length; i < l; ++i) {
- const key = keys[i];
- const value = model[key];
- assignJsonValue(json, key, value, opt);
- }
- if (vAttr && opt.virtuals === true) {
- assignVirtualAttributes(json, model, vAttr, opt);
- }
- return json;
- }
- function toDatabaseJsonImpl(model, opt) {
- const json = {};
- const keys = Object.keys(model);
- for (let i = 0, l = keys.length; i < l; ++i) {
- const key = keys[i];
- const value = model[key];
- assignJsonValue(json, key, value, opt);
- }
- return json;
- }
- function assignJsonValue(json, key, value, opt) {
- const type = typeof value;
- if (
- (opt.omit === null || !(key in opt.omit)) &&
- (opt.pick === null || key in opt.pick) &&
- (opt.omitFromJson === null || opt.omitFromJson.indexOf(key) === -1) &&
- type !== 'function' &&
- type !== 'undefined' &&
- key[0] !== '$'
- ) {
- if (isObject(value)) {
- json[key] = toJsonObject(value, opt);
- } else {
- json[key] = value;
- }
- }
- }
- function assignVirtualAttributes(json, model, vAttr, opt) {
- for (let i = 0, l = vAttr.length; i < l; ++i) {
- const key = vAttr[i];
- let value = model[key];
- if (typeof value === 'function') {
- value = value.call(model);
- }
- assignJsonValue(json, key, value, opt);
- }
- }
- function toJsonObject(value, opt) {
- if (Array.isArray(value)) {
- return toJsonArray(value, opt);
- } else if (value.$isObjectionModel) {
- // No branch for $toDatabaseJson here since there is never a need
- // to have nested models in database rows.
- return value.$toJson(opt);
- } else if (Buffer.isBuffer(value)) {
- return value;
- } else {
- return cloneDeep(value);
- }
- }
- function toJsonArray(value, opt) {
- const ret = new Array(value.length);
- for (let i = 0, l = ret.length; i < l; ++i) {
- const item = value[i];
- if (isObject(item)) {
- ret[i] = toJsonObject(item, opt);
- } else {
- ret[i] = item;
- }
- }
- return ret;
- }
- module.exports = {
- toJson,
- toDatabaseJson
- };
|