@@ -16,7 +16,7 @@ import * as util from "util";
1616import * as WoT from "wot-typescript-definitions" ;
1717import { ContentSerdes } from "./content-serdes" ;
1818import { ProtocolHelpers } from "./core" ;
19- import { DataSchemaError , NotSupportedError } from "./errors" ;
19+ import { DataSchemaError , NotReadableError , NotSupportedError } from "./errors" ;
2020import { Content } from "./content" ;
2121import Ajv from "ajv" ;
2222import { createLoggers } from "./logger" ;
@@ -32,17 +32,17 @@ const { debug } = createLoggers("core", "interaction-output");
3232const ajv = new Ajv ( { strict : false } ) ;
3333
3434export class InteractionOutput implements WoT . InteractionOutput {
35- private content : Content ;
36- private parsedValue : unknown ;
37- private buffer ?: ArrayBuffer ;
38- private _stream ?: ReadableStream ;
35+ # content: Content ;
36+ #value : unknown ;
37+ # buffer?: ArrayBuffer ;
38+ #stream ?: ReadableStream ;
3939 dataUsed : boolean ;
4040 form ?: WoT . Form ;
4141 schema ?: WoT . DataSchema ;
4242
4343 public get data ( ) : ReadableStream {
44- if ( this . _stream ) {
45- return this . _stream ;
44+ if ( this . #stream ) {
45+ return this . #stream ;
4646 }
4747
4848 if ( this . dataUsed ) {
@@ -51,71 +51,74 @@ export class InteractionOutput implements WoT.InteractionOutput {
5151 // Once the stream is created data might be pulled unpredictably
5252 // therefore we assume that it is going to be used to be safe.
5353 this . dataUsed = true ;
54- return ( this . _stream = ProtocolHelpers . toWoTStream ( this . content . body ) as ReadableStream ) ;
54+ return ( this . #stream = ProtocolHelpers . toWoTStream ( this . # content. body ) as ReadableStream ) ;
5555 }
5656
5757 constructor ( content : Content , form ?: WoT . Form , schema ?: WoT . DataSchema ) {
58- this . content = content ;
58+ this . # content = content ;
5959 this . form = form ;
6060 this . schema = schema ;
6161 this . dataUsed = false ;
6262 }
6363
6464 async arrayBuffer ( ) : Promise < ArrayBuffer > {
65- if ( this . buffer ) {
66- return this . buffer ;
65+ if ( this . # buffer) {
66+ return this . # buffer;
6767 }
6868
6969 if ( this . dataUsed ) {
7070 throw new Error ( "Can't read the stream once it has been already used" ) ;
7171 }
7272
73- const data = await this . content . toBuffer ( ) ;
73+ const data = await this . # content. toBuffer ( ) ;
7474 this . dataUsed = true ;
75- this . buffer = data ;
75+ this . # buffer = data ;
7676
7777 return data ;
7878 }
7979
8080 async value < T extends WoT . DataSchemaValue > ( ) : Promise < T > {
8181 // the value has been already read?
82- if ( this . parsedValue !== undefined ) {
83- return this . parsedValue as T ;
82+ if ( this . #value !== undefined ) {
83+ return this . #value as T ;
8484 }
8585
8686 if ( this . dataUsed ) {
87- throw new Error ( "Can't read the stream once it has been already used" ) ;
87+ throw new NotReadableError ( "Can't read the stream once it has been already used" ) ;
88+ }
89+
90+ if ( this . form == null ) {
91+ throw new NotReadableError ( "No form defined" ) ;
92+ }
93+
94+ if ( this . schema == null || this . schema . type == null ) {
95+ throw new NotReadableError ( "No schema defined" ) ;
8896 }
8997
9098 // is content type valid?
91- if ( ! this . form || ! ContentSerdes . get ( ) . isSupported ( this . content . type ) ) {
92- const message = ! this . form ? "Missing form" : `Content type ${ this . content . type } not supported` ;
99+ if ( ! ContentSerdes . get ( ) . isSupported ( this . # content. type ) ) {
100+ const message = `Content type ${ this . # content. type } not supported` ;
93101 throw new NotSupportedError ( message ) ;
94102 }
95103
96104 // read fully the stream
97- const data = await this . content . toBuffer ( ) ;
105+ const bytes = await this . # content. toBuffer ( ) ;
98106 this . dataUsed = true ;
99- this . buffer = data ;
100-
101- // call the contentToValue
102- // TODO: should be fixed contentToValue MUST define schema as nullable
103- const value = ContentSerdes . get ( ) . contentToValue ( { type : this . content . type , body : data } , this . schema ?? { } ) ;
104-
105- // any data (schema)?
106- if ( this . schema ) {
107- // validate the schema
108- const validate = ajv . compile < T > ( this . schema ) ;
109-
110- if ( ! validate ( value ) ) {
111- debug ( `schema = ${ util . inspect ( this . schema , { depth : 10 , colors : true } ) } ` ) ;
112- debug ( `value: ${ value } ` ) ;
113- debug ( `Errror: ${ validate . errors } ` ) ;
114- throw new DataSchemaError ( "Invalid value according to DataSchema" , value as WoT . DataSchemaValue ) ;
115- }
107+ this . #buffer = bytes ;
108+
109+ const json = ContentSerdes . get ( ) . contentToValue ( { type : this . #content. type , body : bytes } , this . schema ) ;
110+
111+ // validate the schema
112+ const validate = ajv . compile < T > ( this . schema ) ;
113+
114+ if ( ! validate ( json ) ) {
115+ debug ( `schema = ${ util . inspect ( this . schema , { depth : 10 , colors : true } ) } ` ) ;
116+ debug ( `value: ${ json } ` ) ;
117+ debug ( `Errror: ${ validate . errors } ` ) ;
118+ throw new DataSchemaError ( "Invalid value according to DataSchema" , json as WoT . DataSchemaValue ) ;
116119 }
117120
118- this . parsedValue = value ;
119- return this . parsedValue as T ;
121+ this . #value = json ;
122+ return json ;
120123 }
121124}
0 commit comments