Skip to content

Commit

Permalink
merge latest changes from master (#191)
Browse files Browse the repository at this point in the history
* merge latest change from master

* merge OnJsonAttribute into lts

* 2.6.73
  • Loading branch information
kbarbounakis authored Jan 17, 2025
1 parent 869a550 commit 9debdfe
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 91 deletions.
121 changes: 46 additions & 75 deletions OnJsonAttribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ const {eachSeries} = require('async');
const {DataConfigurationStrategy} = require('./data-configuration');
const {DataError} = require('@themost/common');

function isJSON(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}

function edmTypeToJsonType(edmType) {
switch (edmType) {
Expand Down Expand Up @@ -46,7 +54,7 @@ class OnJsonAttribute {
/**
* @type {{edmtype: string,type:string}}
*/
const dataType = dataTypes[attr.type];
const dataType = attr.type !== 'Json' ? dataTypes[attr.type] : null;
let type = 'object';
let assign = {};
if (dataType != null) {
Expand Down Expand Up @@ -92,6 +100,16 @@ class OnJsonAttribute {
}
}

/**
* @param {import('./data-model').DataModel} model
* @returns {Array<import('./types').DataField>}
*/
static getJsonAttributes(model) {
return model.attributes.filter((attr) => {
return attr.type === 'Json' && attr.additionalType != null;
});
}

/**
* @param {import('./types').DataEventArgs} event
* @param {function(err?:Error)} callback
Expand Down Expand Up @@ -168,49 +186,10 @@ class OnJsonAttribute {
* @returns void
*/
static afterSelect(event, callback) {
const anyJsonAttributes = event.model.attributes.filter((attr) => {
const jsonAttributes = event.model.attributes.filter((attr) => {
return attr.type === 'Json' && attr.model === event.model.name;
});
if (anyJsonAttributes.length === 0) {
return callback();
}
const jsonAttributes = anyJsonAttributes.filter((attr) => {
return attr.additionalType != null;
}).map((attr) => {
return attr.name
});
// if there are no json attributes with additional type
}).map((attr) => attr.name);
if (jsonAttributes.length === 0) {
// get json attributes with no additional type
const unknownJsonAttributes = anyJsonAttributes.filter((attr) => {
return attr.additionalType == null;
}).map((attr) => {
return attr.name
});
// parse json for each item
if (unknownJsonAttributes.length > 0) {
const parseUnknownJson = (item) => {
unknownJsonAttributes.forEach((name) => {
if (Object.prototype.hasOwnProperty.call(item, name)) {
const value = item[name];
if (typeof value === 'string') {
item[name] = JSON.parse(value);
}
}
});
};
// iterate over result
const {result} = event;
if (result == null) {
return callback();
}
if (Array.isArray(result)) {
result.forEach((item) => parseUnknownJson(item));
} else {
// or parse json for single item
parseUnknownJson(result)
}
}
return callback();
}

Expand Down Expand Up @@ -248,40 +227,29 @@ class OnJsonAttribute {
// split $name property by dot
const matches = jsonGet.$name.split('.');
if (matches && matches.length > 1) {
if (jsonAttributes.indexOf(matches[1]) >= 0) {
// get json schema
if (matches.length > 2) {
// get attribute
const attribute = event.model.getAttribute(matches[1]);
if (attribute) {
// get additional model
const additionalModel = event.model.context.model(attribute.additionalType)
// and its json schema
let jsonSchema = OnJsonAttribute.getJsonSchema(additionalModel);
let index = 2;
// iterate over matches
while(index < matches.length) {
// get property
const property = jsonSchema.properties[matches[index]];
// if property is an object
if (property && property.type === 'object') {
if (index + 1 === matches.length) {
prev.push(matches[index]);
break;
}
if (Array.isArray(property.properties)) {
jsonSchema = property.properties;
} else {
prev.push(matches[index]);
break;
}
}
index++;
}
let index = 1;
let nextModel = event.model;
// iterate over matches
while(index < matches.length) {
let attribute = nextModel.getAttribute(matches[index]);
if (attribute && attribute.type === 'Json') {
if (index + 1 === matches.length) {
prev.push(key);
break;
}
if (attribute.additionalType) {
// get next model
nextModel = event.model.context.model(attribute.additionalType)
} else {
// add last part
prev.push(key);
// and exit loop
break;
}
} else {
prev.push(matches[2]);
break;
}
index++;
}
}
}
Expand All @@ -293,13 +261,16 @@ class OnJsonAttribute {
if (select.length === 0) {
attributes = jsonAttributes;
}
if (attributes.length === 0) {
return callback();
}
// define json converter
const parseJson = (item) => {
attributes.forEach((name) => {
if (Object.prototype.hasOwnProperty.call(item, name)) {
const value = item[name];
if (typeof value === 'string') {
item[name] = JSON.parse(value);
if (typeof value === 'string') {
item[name] = isJSON(value) ? JSON.parse(value) : value;
}
}
});
Expand Down
11 changes: 11 additions & 0 deletions data-queryable.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,18 @@ function resolveJoinMember(target) {
* @type {Array}
*/
var fullyQualifiedMember = event.fullyQualifiedMember.split('.');
var attribute = target.model.getAttribute(fullyQualifiedMember[0]);
var expr = DataAttributeResolver.prototype.resolveNestedAttribute.call(target, fullyQualifiedMember.join('/'));
if (attribute && attribute.type === 'Json') {
Args.check(expr.$value != null, 'Invalid expression. Expected a JSON expression.');
var [method] = Object.keys(expr.$value); // get method name
var methodWithoutSign = method.replace(/\$/g, '');
var { [method]: args } = expr.$value;
Object.assign(event, {
member: new MethodCallExpression(methodWithoutSign, args)
});
return;
}
if (instanceOf(expr, QueryField)) {
var member = expr.$name.split('.');
Object.assign(event, {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@themost/data",
"version": "2.6.72",
"version": "2.6.73",
"description": "MOST Web Framework Codename Blueshift - Data module",
"main": "index.js",
"types": "index.d.ts",
Expand Down
Loading

0 comments on commit 9debdfe

Please sign in to comment.