//
// $Id$
//
import { RestServices, RestResponse } from "../tools/RestServices.js"
import { Context } from "./../infohub/Context.js"
import { ApiResponse } from "../tools/ApiResponse.js"
/**
*
* @category COLNEO gom <br>
* <font size="6pt">Generic Object Model</font>
*
* @classdesc Base Class for nodes/objects on COLNEO infohub. <br>
Uses the infohub GOM (Generic Object Model)
*/
export class cnRelation {
#_data = null
constructor() {
}
/**
* Global unique ID
*/
get id() { return this.getId(); }
/**
* Get ID of Relation (shortid)
*
* @returns ShortID
*
*/
getId() {
return this.#_data?.shortid
}
getName() {
return this.#_data?.name
}
dump( prefix = '' ) {
if( prefix.length > 0 ) {
prefix = prefix + ' '
}
console.log( `${prefix}type: [cnRelation]`)
if (this.#_data) {
console.log(`${prefix}relation:`)
console.log(JSON.stringify(this.#_data, null, 2))
} else {
console.log('-empty-')
}
}
/**
*
* @param {*} obj_as_json
* @returns {void}
*/
setFromJson(obj_as_json) {
this.#_data = obj_as_json
}
/**
*
* @returns {*} The relation data as JSON
*/
getAsJson() {
return this.#_data
}
}
/**
*
* @category COLNEO gom <br>
* <font size="6pt">Generic Object Model</font>
*
* @classdesc Relation Services <br>
Uses the infohub GOM (Generic Object Model)
*/
export class cnRelationServices {
#_ctx = null
/**
*
* @param {Context} ctx Infohub Context
*
* @since 08.2025, jh
*
*/
constructor( ctx ) {
this.#_ctx = ctx
}
/**
*
* @param {*} left_nodeid
* @param {*} relation_data
* @param {*} cb
* @returns {Promise<ApiResponse>} Returns the created relation
*/
async createRelation( left_nodeid , relation_data, cb) {
// console.log( '### <createRelation()> ' )
//
// relation_data
// {
// "name": "string",
// "description": "string",
// "weight": 0,
// "right_objects": [
// "string"
// ]
// }
// /{scope}/{node}/relations
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/${left_nodeid}/relations`;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.POST, url, relation_data)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// resp.dump( "NEW RELATION" )
if (resp.status < 300) {
let obj = new cnRelation()
obj.setFromJson(resp.data)
return cb(new ApiResponse(resp.status, obj))
} else {
return cb(resp)
}
}
/**
* Get relation by name or create it if it does not exist by using relation_data
*
* @param {*} left_nodeid
* @param {*} relation_name
* @param {*} cb
*/
async getRelation( left_nodeid, relation_name, cb, relation_data = null) {
console.log( '### <getRelation()> ')
try {
let q = ''
let c = ''
let f = `$relation$name ~eq~ '${relation_name}' `
q += c + `filter=${f}`
//
// RESOLVE MEMBERS
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/${left_nodeid}/relations?${q}`;
console.log(`target: [${url}]`)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.GET, url)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (resp.getStatus() < 300) {
let data = resp.getData()
console.log(`found ${data.length} relations `)
if (data.length == 1) {
console.log("DATA:")
console.log(JSON.stringify(data[0]))
let obj = new cnRelation()
obj.setFromJson(data[0])
// obj.dump("GOTRELATION")
return cb(new ApiResponse(200, obj))
} else if (data.length == 0) {
if ( relation_data ) {
// if relation does not exist and relation_data is given, create relation ...
console.log(`create relation ${left_nodeid} / ${relation_name} ... `)
this.createRelation( left_nodeid , relation_data, (ret) => {
return cb(ret)
})
} else {
return cb(new ApiResponse(404, null, `relation not found with given Name = [${relation_name}].`))
}
} else {
return cb(new ApiResponse(406, null, `${data.length} relations found with given Name = [${relation_name}].`))
}
} else {
if (relation_data) {
// if object does not exist and object_data is given, create object as child of context_sid ...
console.log(`create relation ${left_nodeid} / ${relation_name} ... `)
this.createRelation(left_nodeid, relation_data, (ret) => {
return cb(ret)
})
} else {
return cb(resp)
}
}
} catch (error) {
// console.error("getObject failed:", error);
return cb(new ApiResponse(400, null, "Unknown error"))
}
}
async saveRelation( cnRel, left_nodeid , cb ) {
// create object/node ...
let object_data = cnRel.getAsJson()
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/${left_nodeid}/relations`;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.PUT, url, object_data)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// resp.dump("RETURN UPDATE OBJECT")
if (resp.status < 300) {
let obj = new cnRelation()
obj.setFromJson(resp.data)
return cb(new ApiResponse(resp.status, obj))
} else {
return cb(resp)
}
}
async patchRelation( rel_data , relation_id , cb ) {
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/relations/${relation_id}`;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.PATCH, url, rel_data)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
resp.dump("RETURN UPDATE RELATION")
if (resp.status < 300) {
let obj = new cnRelation()
obj.setFromJson(resp.data)
return cb(new ApiResponse(resp.status, obj))
} else {
return cb(resp)
}
}
/**
*
* @param {*} relation_sid
* @param {*} cb
* @returns {Promise<RestResponse>} Returns the response from the delete operation
*/
async deleteRelation(relation_sid, cb) {
console.log( `### <deleteRelation( ${relation_sid} )> `)
// /{scope}/relations/{relation}
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/relations/${relation_sid}`;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.DELETE, url)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return cb(resp)
}
/**
*
* @param {*} left_nodeid
* @param {*} query
* @param {*} cb
* @returns {Promise<ApiResponse>} {
* status :
* data : array of relations
*/
async getRelationListByNode( left_nodeid , query, cb) {
let q = ''
let c = '?'
if (query['members']) {
let plist = query['members'].join(',')
q += c + 'members=' + encodeURIComponent(plist)
c = '&'
}
if (query['filter']) {
q += c + 'filter=' + encodeURIComponent(filter + query['filter'])
c = '&'
}
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/${left_nodeid}/relations${q}`;
console.log(`GET : ${url}`)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.GET, url)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// console.log( 'REL REL ' )
// console.log( JSON.stringify(resp.data) )
if (resp.status < 300) {
// resp.dump( "REL LIST" )
let array = []
for (const obj_json of resp.data) {
let obj = new cnRelation()
obj.setFromJson(obj_json)
array.push(obj)
}
return cb(new ApiResponse(resp.status, array))
} else {
return cb(resp)
}
}
/**
*
* @param {*} query = {
* 'members' : ' ... '
* 'filter' : ' ... '
* }
*
* @param {*} cb
* @returns {Promise<ApiResponse>} Returns array of relations
*/
async getRelationList( query, cb) {
let q = ''
let c = '?'
if (query['members']) {
let plist = query['members'].join(',')
q += c + 'members=' + encodeURIComponent(plist)
c = '&'
}
if (query['filter']) {
// q += c + 'filter=' + encodeURIComponent( query['filter'] )
const filter = query['filter']
q += c + 'filter=' + encodeURIComponent(filter)
c = '&'
}
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/relations${q}`;
// console.log(`GET : ${url}`)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.GET, url)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (resp.status < 300) {
let array = []
for (const obj_json of resp.data) {
let obj = new cnRelation()
obj.setFromJson(obj_json)
array.push(obj)
}
return cb(new ApiResponse(resp.status, array))
} else {
return cb(resp)
}
}
async addToRelation( left_nodeid , relation_name , sid_list , cb )
{
console.log( `### <addToRelation( ${left_nodeid} , ${relation_name} )> ` )
// console.log( "add : " )
// console.log( sid_list )
let relation_data = {
"name": relation_name,
"description": "Created by infohub SDK",
"weight": 1,
}
this.getRelation( left_nodeid , relation_name , async (ret) => {
// ret.data.dump("RELATION")
// ret.data.dump('rel')
const relation_id = ret.data.getId()
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/relations/${relation_id}/right`;
const request_data = sid_list
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.POST, url , request_data )
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// resp.dump("RESPONSE")
return cb(resp)
} , relation_data )
}
async removeFromRelation(left_nodeid, relation_name, sid_list) {
console.log(`### <removeFromRelation( ${left_nodeid} , ${relation_name} )> `)
this.getRelation(left_nodeid, relation_name, async (ret) => {
// ret.data.dump("RELATION")
// ret.data.dump('rel')
if (ret.status < 300) {
const relation_id = ret.data.getId()
const url = `${this.#_ctx.getServiceUrl(Context.SERVICE.HUB)}/${this.#_ctx.getScope()}/relations/${relation_id}/right`;
const request_data = sid_list
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* RestResponse */ const resp = await RestServices.makeApiCall(this.#_ctx.getToken(), RestServices.METHODS.DELETE, url, request_data)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// resp.dump("RESPONSE")
return cb(resp)
} else {
return cb(new ApiResponse( 404 , null ))
}
})
}
}
Source