2024-03-07 04:17:05 +00:00
|
|
|
import * as Block from 'multiformats/block';
|
|
|
|
import { sha256 as hasher } from 'multiformats/hashes/sha2';
|
2024-03-14 09:15:48 +00:00
|
|
|
|
2024-03-07 04:17:05 +00:00
|
|
|
import * as dagCBOR from '@ipld/dag-cbor';
|
|
|
|
import * as dagJSON from '@ipld/dag-json';
|
2022-04-08 05:29:03 +00:00
|
|
|
|
2022-04-04 07:05:16 +00:00
|
|
|
/**
|
|
|
|
* Utils
|
|
|
|
*/
|
|
|
|
export class Util {
|
|
|
|
/**
|
|
|
|
* Sorts JSON object.
|
|
|
|
*/
|
2024-03-07 04:17:05 +00:00
|
|
|
static sortJSON (obj: any) {
|
2024-01-15 04:58:55 +00:00
|
|
|
if (obj instanceof Array) {
|
|
|
|
for (let i = 0; i < obj.length; i++) {
|
|
|
|
obj[i] = Util.sortJSON(obj[i]);
|
2022-04-04 07:05:16 +00:00
|
|
|
}
|
2024-01-15 04:58:55 +00:00
|
|
|
return obj;
|
2022-04-04 07:05:16 +00:00
|
|
|
}
|
2024-01-15 04:58:55 +00:00
|
|
|
if (typeof obj !== 'object' || obj === null) return obj;
|
2022-04-04 07:05:16 +00:00
|
|
|
|
2024-01-15 04:58:55 +00:00
|
|
|
let keys = Object.keys(obj);
|
2022-04-04 07:05:16 +00:00
|
|
|
keys = keys.sort();
|
|
|
|
const newObject: {[key: string]: any} = {};
|
|
|
|
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
2024-01-15 04:58:55 +00:00
|
|
|
newObject[keys[i]] = Util.sortJSON(obj[keys[i]]);
|
2022-04-04 07:05:16 +00:00
|
|
|
}
|
|
|
|
return newObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Marshal object into gql 'attributes' variable.
|
|
|
|
*/
|
2024-03-07 04:17:05 +00:00
|
|
|
static toGQLAttributes (obj: any) {
|
2022-04-04 07:05:16 +00:00
|
|
|
const vars: any[] = [];
|
2024-01-15 04:58:55 +00:00
|
|
|
Object.keys(obj).forEach(key => {
|
|
|
|
const value = this.toGQLValue(obj[key]);
|
2022-04-04 07:05:16 +00:00
|
|
|
|
2024-01-15 04:58:55 +00:00
|
|
|
if (value !== undefined) {
|
|
|
|
vars.push({ key, value });
|
2022-04-04 07:05:16 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
return vars;
|
|
|
|
}
|
|
|
|
|
2024-03-07 04:17:05 +00:00
|
|
|
static toGQLValue (obj: any) {
|
|
|
|
if (obj === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
let type: string = typeof obj;
|
|
|
|
switch (type) {
|
|
|
|
case 'number':
|
|
|
|
type = (obj % 1 === 0) ? 'int' : 'float';
|
|
|
|
return { [type]: obj };
|
|
|
|
case 'string':
|
|
|
|
return { string: obj };
|
|
|
|
case 'boolean':
|
|
|
|
return { boolean: obj };
|
|
|
|
case 'object':
|
|
|
|
if (obj['/'] !== undefined) {
|
|
|
|
return { link: obj['/'] };
|
|
|
|
}
|
|
|
|
if (obj instanceof Array) {
|
|
|
|
return { array: obj };
|
|
|
|
}
|
|
|
|
return { map: obj };
|
|
|
|
case 'undefined':
|
|
|
|
return undefined;
|
|
|
|
default:
|
|
|
|
throw new Error(`Unknown object type '${type}': ${obj}`);
|
|
|
|
}
|
2024-01-15 04:58:55 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 07:05:16 +00:00
|
|
|
/**
|
|
|
|
* Unmarshal attributes array to object.
|
|
|
|
*/
|
2024-03-07 04:17:05 +00:00
|
|
|
static fromGQLAttributes (attributes: any[] = []) {
|
2022-04-04 07:05:16 +00:00
|
|
|
const res: {[key: string]: any} = {};
|
|
|
|
|
|
|
|
attributes.forEach(attr => {
|
2024-02-08 05:39:31 +00:00
|
|
|
res[attr.key] = (attr.value === null) ? null : this.fromGQLValue(attr.value);
|
2022-04-04 07:05:16 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2022-04-08 05:29:03 +00:00
|
|
|
|
2024-03-07 04:17:05 +00:00
|
|
|
static fromGQLValue (obj: any) {
|
2024-01-15 04:58:55 +00:00
|
|
|
// Get first non-null key
|
|
|
|
const present = Object.keys(obj).find(k => obj[k] !== null);
|
|
|
|
if (present === undefined) {
|
|
|
|
throw new Error('Object has no non-null values');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create an array if array type attribute
|
|
|
|
if (present === 'array') {
|
|
|
|
return obj[present].map((e: any) => {
|
|
|
|
return this.fromGQLValue(e);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj[present];
|
|
|
|
}
|
|
|
|
|
2022-04-08 05:29:03 +00:00
|
|
|
/**
|
|
|
|
* Get record content ID.
|
|
|
|
*/
|
2024-03-07 04:17:05 +00:00
|
|
|
static async getContentId (record: any) {
|
|
|
|
const serialized = dagJSON.encode(record);
|
|
|
|
const recordData = dagJSON.decode(serialized);
|
2022-04-08 05:29:03 +00:00
|
|
|
|
2022-04-22 06:02:55 +00:00
|
|
|
const block = await Block.encode({
|
|
|
|
value: recordData,
|
|
|
|
codec: dagCBOR,
|
|
|
|
hasher
|
2024-03-07 04:17:05 +00:00
|
|
|
});
|
2022-04-22 06:02:55 +00:00
|
|
|
|
|
|
|
return block.cid.toString();
|
2022-04-08 05:29:03 +00:00
|
|
|
}
|
2022-04-04 07:05:16 +00:00
|
|
|
}
|