diff --git a/api/package-lock.json b/api/package-lock.json index 6f50c98fcb8f360b97b14a52408e77063f952e33..88182859b9a42510792332bff648111830b823b3 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -19,6 +19,7 @@ "apollo-server-express": "^3.3.0", "axios": "^0.21.1", "graphql": "^15.5.3", + "graphql-type-json": "^0.3.2", "jsonata": "^1.8.5", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", @@ -5582,6 +5583,14 @@ "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, + "node_modules/graphql-type-json": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", + "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", + "peerDependencies": { + "graphql": ">=0.8.0" + } + }, "node_modules/graphql-ws": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.4.0.tgz", @@ -14888,6 +14897,12 @@ "tslib": "^2.1.0" } }, + "graphql-type-json": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", + "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", + "requires": {} + }, "graphql-ws": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.4.0.tgz", diff --git a/api/package.json b/api/package.json index fd94af7dcea0a56fcf453b755939a3a373c8b459..1885442d70f4ac545ac7fc662ec9bef27d1d21de 100644 --- a/api/package.json +++ b/api/package.json @@ -32,6 +32,7 @@ "apollo-server-express": "^3.3.0", "axios": "^0.21.1", "graphql": "^15.5.3", + "graphql-type-json": "^0.3.2", "jsonata": "^1.8.5", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", diff --git a/api/src/engine/connectors/exareme/converters.ts b/api/src/engine/connectors/exareme/converters.ts index c5ecdfc8f086d9a8d21527dd85efce516ff43265..d19f1797cdc51c85ce18439b1c5ce28f097ec463 100644 --- a/api/src/engine/connectors/exareme/converters.ts +++ b/api/src/engine/connectors/exareme/converters.ts @@ -1,5 +1,8 @@ import { Category } from 'src/engine/models/category.model'; -import { Experiment } from 'src/engine/models/experiment/experiment.model'; +import { + Experiment, + ResultUnion, +} from 'src/engine/models/experiment/experiment.model'; import { AlgorithmParameter } from 'src/engine/models/experiment/algorithm-parameter.model'; import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input'; import { Group } from 'src/engine/models/group.model'; @@ -7,9 +10,12 @@ import { TableResult } from 'src/engine/models/result/table-result.model'; import { Variable } from 'src/engine/models/variable.model'; import { Entity } from './interfaces/entity.interface'; import { Hierarchy } from './interfaces/hierarchy.interface'; -import { TransientDataResult } from './interfaces/transient/transient-data-result.interface'; import { VariableEntity } from './interfaces/variable-entity.interface'; import { transientToTable } from './transformations'; +import { ExperimentData } from './interfaces/Experiment/experiment.interface'; +import { ResultExperiment } from './interfaces/Experiment/result-experiment.interface'; +import { RawResult } from 'src/engine/models/result/raw-result.model'; +import { TransientDataResult } from './interfaces/transient/transient-data-result.interface'; export const dataToGroup = (data: Hierarchy): Group => { return { @@ -86,3 +92,24 @@ export const dataToTransient = ( results: tabs, }; }; + +export const dataToExperiment = (data: ExperimentData): Experiment => { + const exp: Experiment = dataToExperiment(data); + + exp.results = data.result.map((result) => dataToResult(result)); + + return exp; +}; + +export const dataToRaw = (result: ResultExperiment): RawResult => { + return { + data: result.data, + }; +}; + +export const dataToResult = (result: ResultExperiment): typeof ResultUnion => { + switch (result.type) { + default: + return dataToRaw(result); + } +}; diff --git a/api/src/engine/connectors/exareme/interfaces/Experiment/experiment.interface.ts b/api/src/engine/connectors/exareme/interfaces/Experiment/experiment.interface.ts new file mode 100644 index 0000000000000000000000000000000000000000..b9203f86e1528c73302928d02f2aa9b41b108625 --- /dev/null +++ b/api/src/engine/connectors/exareme/interfaces/Experiment/experiment.interface.ts @@ -0,0 +1,6 @@ +import { ResultExperiment } from './result-experiment.interface'; + +export interface ExperimentData { + name: string; + result: ResultExperiment[]; +} diff --git a/api/src/engine/connectors/exareme/interfaces/Experiment/result-experiment.interface.ts b/api/src/engine/connectors/exareme/interfaces/Experiment/result-experiment.interface.ts new file mode 100644 index 0000000000000000000000000000000000000000..e655151c9e7b113a2dbff0402d8e99c61534adee --- /dev/null +++ b/api/src/engine/connectors/exareme/interfaces/Experiment/result-experiment.interface.ts @@ -0,0 +1,4 @@ +export interface ResultExperiment { + data: unknown; + type: string; +} diff --git a/api/src/engine/connectors/exareme/transformations.ts b/api/src/engine/connectors/exareme/transformations.ts index 7e9af19bbcb7bc2a7a00584954b92892c9c8873e..cbf9017a51859b3e0bdf41f3c721c090a37dffd5 100644 --- a/api/src/engine/connectors/exareme/transformations.ts +++ b/api/src/engine/connectors/exareme/transformations.ts @@ -3,6 +3,11 @@ import * as jsonata from 'jsonata'; // old import style needed due to 'export = jsonata' +export const dataToExperiment = jsonata(`( + $ +) +`); + export const transientToTable = jsonata(` ( $e := function($x, $r) {($x != null) ? $x : ($r ? $r : '')}; diff --git a/api/src/engine/models/experiment/experiment.model.ts b/api/src/engine/models/experiment/experiment.model.ts index d11abdeb5556e51096dd207a4d020185b9ec8fea..91ee6c4033c1806b0660457e8aa2316a321beaac 100644 --- a/api/src/engine/models/experiment/experiment.model.ts +++ b/api/src/engine/models/experiment/experiment.model.ts @@ -4,19 +4,19 @@ import { GraphQLISODateTime, ObjectType, } from '@nestjs/graphql'; -import { DummyResult } from '../result/dummy-result.model'; +import { RawResult } from '../result/raw-result.model'; import { TableResult } from '../result/table-result.model'; import { Algorithm } from './algorithm.model'; export const ResultUnion = createUnionType({ name: 'ResultUnion', - types: () => [TableResult, DummyResult], + types: () => [TableResult, RawResult], resolveType(value) { if (value.headers) { return TableResult; } if (value.listMax) { - return DummyResult; + return RawResult; } return null; diff --git a/api/src/engine/models/result/dummy-result.model.ts b/api/src/engine/models/result/dummy-result.model.ts deleted file mode 100644 index 99e36f5c90b9100e1cd46ed9fa67f613a46864b5..0000000000000000000000000000000000000000 --- a/api/src/engine/models/result/dummy-result.model.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Field, ObjectType } from '@nestjs/graphql'; -import { Result } from './common/result.model'; - -@ObjectType() -export class DummyResult extends Result { - @Field() - name: string; - - @Field(() => [[String]]) - data: string[][]; - - @Field(() => [String]) - listMax: string[]; -} diff --git a/api/src/engine/models/result/raw-result.model.ts b/api/src/engine/models/result/raw-result.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..5074e015cc483a3b4fe899f9608d8ddba76f0bfa --- /dev/null +++ b/api/src/engine/models/result/raw-result.model.ts @@ -0,0 +1,12 @@ +import { Field, ObjectType } from '@nestjs/graphql'; +import { GraphQLJSONObject } from 'graphql-type-json'; +import { Result } from './common/result.model'; + +@ObjectType() +export class RawResult extends Result { + @Field(() => GraphQLJSONObject) + data: unknown; + + @Field(() => [String], { defaultValue: [] }) + listMax?: string[]; +} diff --git a/api/src/schema.gql b/api/src/schema.gql index 9b71c503e2722ef32199505e11448fb8b5d8114a..ba240a7927778b33acb82b9f9b079bb7ac62137a 100644 --- a/api/src/schema.gql +++ b/api/src/schema.gql @@ -72,7 +72,7 @@ A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date """ scalar DateTime -union ResultUnion = TableResult | DummyResult +union ResultUnion = TableResult | RawResult type TableResult { groupBy: String @@ -81,13 +81,17 @@ type TableResult { headers: [Header!]! } -type DummyResult { +type RawResult { groupBy: String - name: String! - data: [[String!]!]! + data: JSONObject! listMax: [String!]! } +""" +The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSONObject @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf") + type Query { domains(ids: [String!] = []): [Domain!]! }