From c8da0376fa850e2f86f707eda53cb7d475d9be05 Mon Sep 17 00:00:00 2001 From: Jonas Schlabertz <jonas@schlabertz.de> Date: Tue, 24 May 2022 14:49:48 +0200 Subject: [PATCH] Small fixes and improvements after first eval. --- API.paw | Bin 28605 -> 28591 bytes src/entity/TypeDefinition.ts | 9 ++++++++- src/public/batteryLevel.json | 4 ++++ src/public/calibration.json | 4 ++++ src/public/calibrationDate.json | 4 ++++ src/public/temperature.json | 4 ++++ src/router/ContextRouter.ts | 23 +++++++++++++++++++++++ src/router/GenericRouter.ts | 4 ++-- src/router/MainRouter.ts | 4 ++++ src/util/ContextDefinitions.ts | 19 +++++++++---------- src/util/SchemaDefinitions.ts | 5 +++-- 11 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 src/public/batteryLevel.json create mode 100644 src/public/calibration.json create mode 100644 src/public/calibrationDate.json create mode 100644 src/public/temperature.json create mode 100644 src/router/ContextRouter.ts diff --git a/API.paw b/API.paw index dc3148a5f0d1e74cfdec34e6647cdfcf68903757..d46362bc99ceb9250c2009a15003f9fd9b6e879f 100644 GIT binary patch delta 10003 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�EtxD?EVV7CS+2HRYq`O4v*lLHLzc(uEl*mWw!C0@ z+47p@4a<j?Pb{BVzOejg#bU)~#bL!|#bd>1C153FC1NFJC1Is#<!2RW6>Jr16=4-+ z6=M}=m1vc0m1>o4m1&i2m1~u6Rb*9SRc2LTRb^FURcAHXYL3-BtE1LR)(fn+T5q@B zWxdyWzx5gG^VS!wuUKEVzG+?m$oi@EbL*GZpKO?ISZ&yCxNLZA_-%x2L~O)tBy1XO zx@>xEHroo@YS?Po>e?FE8rj<0I@!9|y4!l$`q+lrM%YH##@MFXPO_b9JKc7s?Ht>A zwhL?**)FwRZoATUwe4El^|l*rH`{Kr-C?`Sc8~2o+XJ?TY_Hosuzh65X_r=S_ss6M z-CuhKduDr9dm(#KdvSXyds%yVdkuSSdtG~ddkcF{dvAMR`vChO`%wD``zZSu`#Ad} z_Gj(S+kbONbSQEtaVU4Fa%gktcbMid(_yy5Jck7in;dpK>~(nJ@YCV9!#_txM`lL> zM`1@%M+rx1M_ETTM@>g<M_orV$NFT)G{+3bEXQ2Oe8)n^V#hMa3dbtP8pk@v2FE7H z7RPqSPRDM?UdMjNiH?&UmpZO<+~9cK$;9b~(_5$aPM@5<I(>I$ab|bsbmnp9cNTP( za+Y<LcUE-Pat?Qna*lD1b53+laZYp2aL#tlb<TG#bS`!-buM?Vbgpr(b8e`2ZgOsM zZgcK%p69&Wd8P9OS2fob*Z*!JZenhdZZd9iZrW}JZboh<ZkBE~ZuV}DZeDJ_ZvJk8 zZc%QrZt-r3Zdq={Ze?zjZq;tJZuM>*Ze4C0-PPQ!-EG|++@0NB-Gkgi-NW6Z++*G2 z-80;?-E-aZ-7DNX-Mig;-6y!$Pja8?KEr*M`yBUq?teU3J=i_;JQjFt_1NyQ%VV#{ zevdOA=RGcZT=BT>ans|G$5W5z9xpvUc`|#lda`?RdGdJjdkT4qc#3&ScvgG1c(!@2 z_2TtX@>20q_tNsx@v`)?^K$TV@^bg`^78fa_lod}_KNk2_sa0f_R96j_o}G(TI#jJ zYn9g;uk~IVy*7Jo_1fXJ%WIF<KCc5_hrEt>9rHTrb=vE!*LkmtUYEVDdOh}f<Mqy4 z)Vs+0gAc0@yAPKSuaAI_oR7ATfse6|sgIS9t&f9`lTV0GtWT0picgwPhEJhSiBFkN zg-@eTk59kPM4u@>(|l(5%<@_4v(Be}gU@xJH$LxtKKgv|`R2>)%jV1B%k9hOE8r{X zE8{EYtKh5Y8|EA78|@qGo8X)5o9dhHo8_D1o9A2LTjX2fTjpEgTkTuxTkqTG+w9xw z+wMEdcd_qM-!lO@0jC1p0;2<C0}}$115*Qw0?Pv{1FHiY0-FQd0y_dH22Kf_Rv$Pc zaADw*z-56e0yhTU3w#*(IPhuUi@;ZbZvx*1ehmB^_%-l*;LpI{fqw)42QdY)1hEBi z1aSrN1n~vQ1gQq82l)l94)zUB3Qh@556%kC39byT39bun3~mW-3+@k|5j-n+PVl_o z1;LAgR|oG3-W$9>_+apn;A6ojf=>mX39i2%{37^Oh+v3Xh(?HZh+c?6h;4{Nh*OAb zh)0N5NN`A4NJL0fNODL?NLfflNOeeUNJB_-NNY%YNN33NkPjiBLM1~>LOVmdL;FG} zhE5J$5V|;YY3Pd3)uC%cw}tKu-5t6&^jPTi(3_#RL+^z?41E&%JoIJg>(IAhzG41h z5lLZDVU6Ju;kx1a;YQ)6;pX8k;qKv{;XdL1;ep{%;j!WI;fdi{;nm@_;q~E7;Vt3q z;a%Z9;eFu~!hc3EMX*F@LsqIWF+phdCI}59BX4i^&8%bQK^~o)d^$&U^Pe1P#>ugH W3X?_h+$PuN{bcT9o;kTP-vt0=rYX4q delta 9995 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 diff --git a/src/entity/TypeDefinition.ts b/src/entity/TypeDefinition.ts index 081efdc..3f4b112 100644 --- a/src/entity/TypeDefinition.ts +++ b/src/entity/TypeDefinition.ts @@ -108,7 +108,14 @@ export default class TypeDefinition { } validateData(data: Record<string, unknown>): boolean { - return ajv.validate(this.schema, data); + const result = ajv.validate(this.schema, data); + + if(result) { + return true; + } else { + logger.error(`Error while validating: ${JSON.stringify(ajv.errors)}`); + return false; + } } toJSONLDWithData(data: Record<string, unknown>): NodeObject { diff --git a/src/public/batteryLevel.json b/src/public/batteryLevel.json new file mode 100644 index 0000000..45848da --- /dev/null +++ b/src/public/batteryLevel.json @@ -0,0 +1,4 @@ +{ + "name": "batteryLevel", + "description": "Measured battery level." +} \ No newline at end of file diff --git a/src/public/calibration.json b/src/public/calibration.json new file mode 100644 index 0000000..8ddaf56 --- /dev/null +++ b/src/public/calibration.json @@ -0,0 +1,4 @@ +{ + "name": "calibration", + "description": "Calibration value list." +} \ No newline at end of file diff --git a/src/public/calibrationDate.json b/src/public/calibrationDate.json new file mode 100644 index 0000000..0940a7c --- /dev/null +++ b/src/public/calibrationDate.json @@ -0,0 +1,4 @@ +{ + "name": "calibrationDate", + "description": "Date of when sensor was last calibrated." +} \ No newline at end of file diff --git a/src/public/temperature.json b/src/public/temperature.json new file mode 100644 index 0000000..1d1af71 --- /dev/null +++ b/src/public/temperature.json @@ -0,0 +1,4 @@ +{ + "name": "temperature", + "description": "Measured temperature value in degree Celsius." +} \ No newline at end of file diff --git a/src/router/ContextRouter.ts b/src/router/ContextRouter.ts new file mode 100644 index 0000000..b4fed0b --- /dev/null +++ b/src/router/ContextRouter.ts @@ -0,0 +1,23 @@ +import GenericRouter from "./GenericRouter"; +import { Connection } from "typeorm"; +import express from "express"; + +class ContextRouter extends GenericRouter { + + constructor(connection: Connection) { + super(connection); + this.setup(); + } + + setup(): void { + const staticRouter = express.static("public", { + extensions: ["json"] + }); + + this.expressRouter.use("/", staticRouter); + } + + +} + +export default ContextRouter; \ No newline at end of file diff --git a/src/router/GenericRouter.ts b/src/router/GenericRouter.ts index bfbb47a..3263451 100644 --- a/src/router/GenericRouter.ts +++ b/src/router/GenericRouter.ts @@ -1,9 +1,9 @@ -import { Router } from "express"; +import express from "express"; import { Connection } from "typeorm"; abstract class GenericRouter { - public expressRouter = Router({ mergeParams: true }) + public expressRouter: express.Router = express.Router({ mergeParams: true }) connection: Connection constructor(connection: Connection) { diff --git a/src/router/MainRouter.ts b/src/router/MainRouter.ts index 7652853..5f153c4 100644 --- a/src/router/MainRouter.ts +++ b/src/router/MainRouter.ts @@ -6,6 +6,7 @@ import VocabularyRouter from "./VocabularyRouter"; import ComponentRelationRouter from "./ComponentRelationRouter"; import TypeDefinitionRouter from "./TypeDefinitionRouter"; import MeasurementRouter from "./MeasurementRouter"; +import ContextRouter from "./ContextRouter"; class MainRouter extends GenericRouter { @@ -15,6 +16,7 @@ class MainRouter extends GenericRouter { private relationRouter: ComponentRelationRouter private typeDefinitionRouter: TypeDefinitionRouter private measurementRouter: MeasurementRouter + private contextRouter: ContextRouter constructor(connection: Connection) { super(connection); @@ -24,6 +26,7 @@ class MainRouter extends GenericRouter { this.relationRouter = new ComponentRelationRouter(this.connection); this.typeDefinitionRouter = new TypeDefinitionRouter(this.connection); this.measurementRouter = new MeasurementRouter(this.connection); + this.contextRouter = new ContextRouter(this.connection); this.setup(); } @@ -35,6 +38,7 @@ class MainRouter extends GenericRouter { this.expressRouter.use("/relation", this.relationRouter.expressRouter); this.expressRouter.use("/type", this.typeDefinitionRouter.expressRouter); this.expressRouter.use("/measurement", this.measurementRouter.expressRouter); + this.expressRouter.use("/context", this.contextRouter.expressRouter); } } diff --git a/src/util/ContextDefinitions.ts b/src/util/ContextDefinitions.ts index dec5d97..61f614d 100644 --- a/src/util/ContextDefinitions.ts +++ b/src/util/ContextDefinitions.ts @@ -3,14 +3,14 @@ import ComponentInformation from "../entity/ComponentInformation"; const component = { "id": { "@id": "https://schema.org/url", "@type": "@id"}, "dateCreated": "https://schema.org/dateCreated", - "license": "http://www.w3.org/1999/xhtml/vocab#license" + "license": "https://www.w3.org/1999/xhtml/vocab#license" }; const componentRelation = { "id": { "@id": "https://schema.org/url", "@type": "@id"}, "from": "https://schema.org/DateTime", "to": "https://schema.org/DateTime", - "license": "http://www.w3.org/1999/xhtml/vocab#license" + "license": "https://www.w3.org/1999/xhtml/vocab#license" }; const information = function(metadataContext: unknown, previousVersion: ComponentInformation | undefined, nextVersion: ComponentInformation | undefined): Record<string, unknown> { @@ -19,11 +19,10 @@ const information = function(metadataContext: unknown, previousVersion: Componen "component": { "@id": "https://schema.org/url", "@type": "@id"}, "dateCreated": "https://schema.org/dateCreated", "name": "https://schema.org/name", - "comment": "http://schema.org/comment", - "informationLicense": "http://www.w3.org/1999/xhtml/vocab#license", - "measurementLicense": "http://www.w3.org/1999/xhtml/vocab#license", - "topic": "https://schema.org/text", - "metadata": metadataContext + "comment": "https://schema.org/comment", + "informationLicense": "https://www.w3.org/1999/xhtml/vocab#license", + "measurementLicense": "https://www.w3.org/1999/xhtml/vocab#license", + "topic": "https://schema.org/text" }; if(previousVersion) { @@ -41,7 +40,7 @@ const measurement = function(valueContext: unknown, metadataContext: unknown | u const result: Record<string, unknown> = { "id": { "@id": "https://schema.org/url", "@type": "@id"}, "dateCreated": "https://schema.org/dateCreated", - "license": "http://www.w3.org/1999/xhtml/vocab#license", + "license": "https://www.w3.org/1999/xhtml/vocab#license", "value": valueContext }; @@ -55,9 +54,9 @@ const measurement = function(valueContext: unknown, metadataContext: unknown | u const typeDefinition = { "name": { "@id": "https://schema.org/url", "@type": "@id"}, "dateCreated": "https://schema.org/dateCreated", - "comment": "http://schema.org/comment", + "comment": "https://schema.org/comment", "schema": "https://json-schema.org/draft/2020-12/json-schema-core.html", - "license": "http://www.w3.org/1999/xhtml/vocab#license", + "license": "https://www.w3.org/1999/xhtml/vocab#license", }; export default { diff --git a/src/util/SchemaDefinitions.ts b/src/util/SchemaDefinitions.ts index 11db23e..86005ef 100644 --- a/src/util/SchemaDefinitions.ts +++ b/src/util/SchemaDefinitions.ts @@ -220,13 +220,14 @@ const createTypeDefinitionBaseSchema: Schema = { name: { in: ["body"], errorMessage: "No name set.", - isString: true + isString: true, + notEmpty: true }, comment: { in: ["body"], errorMessage: "Comment must be a string.", isString: true, - optional: true + optional: true, }, schema: { in: ["body"], -- GitLab