1+ import ValidationError from './validation-error.js' ;
2+
13/**
24 * Thing.
35 *
46 * Represents a W3C WoT Web Thing.
57 */
68class Thing {
9+ DEFAULT_CONTEXT = 'https://www.w3.org/2022/wot/td/v1.1' ;
10+
711 propertyReadHandlers = new Map ( ) ;
812
913 /**
14+ * Construct Thing from partial Thing Description.
1015 *
11- * @param {Object } partialTD A partial Thing Description two which Forms
12- * will be added.
16+ * @param {Record<string, any> } partialTD A partial Thing Description
17+ * to which Forms will be added.
1318 */
1419 constructor ( partialTD ) {
15- // TODO: Parse and validate TD.
16- this . partialTD = partialTD ;
20+ // Create an empty validation error to collect errors during parsing.
21+ let validationError = new ValidationError ( [ ] ) ;
22+
23+ // Parse @context member
24+ try {
25+ this . parseContextMember ( partialTD [ '@context' ] ) ;
26+ } catch ( error ) {
27+ if ( error instanceof ValidationError ) {
28+ validationError . validationErrors . push ( ...error . validationErrors ) ;
29+ } else {
30+ throw error ;
31+ }
32+ }
33+
34+ // Parse title member
35+ try {
36+ this . parseTitleMember ( partialTD . title ) ;
37+ } catch ( error ) {
38+ if ( error instanceof ValidationError ) {
39+ validationError . validationErrors . push ( ...error . validationErrors ) ;
40+ } else {
41+ throw error ;
42+ }
43+ }
44+
45+ // Hard code the nosec security scheme for now
46+ this . securityDefinitions = {
47+ nosec_sc : {
48+ scheme : 'nosec' ,
49+ } ,
50+ } ;
51+ this . security = 'nosec_sc' ;
52+ }
53+
54+ /**
55+ * Parse the @context member of a Thing Description.
56+ *
57+ * @param {any } context The @context, if any, provided in the partialTD.
58+ * @throws {ValidationError } A validation error.
59+ */
60+ parseContextMember ( context ) {
61+ // If no @context provided then set it to the default
62+ if ( context === undefined ) {
63+ this . context = this . DEFAULT_CONTEXT ;
64+ return ;
65+ }
66+
67+ // If @context is a string but not the default then turn it into an Array
68+ // and add the default as well
69+ if ( typeof context === 'string' ) {
70+ if ( context == this . DEFAULT_CONTEXT ) {
71+ this . context = context ;
72+ return ;
73+ } else {
74+ this . context = new Array ( ) ;
75+ this . context . push ( context ) ;
76+ this . context . push ( this . DEFAULT_CONTEXT ) ;
77+ }
78+ return ;
79+ }
80+
81+ // If @context is provided and it's an array but doesn't contain the default,
82+ // then add the default
83+ if ( Array . isArray ( context ) ) {
84+ // TODO: Check that members of the Array are valid
85+ this . context = context ;
86+ if ( ! this . context . includes ( this . DEFAULT_CONTEXT ) ) {
87+ this . context . push ( this . DEFAULT_CONTEXT ) ;
88+ }
89+ return ;
90+ }
91+
92+ // If @context is set but it's not a string or Array then it's invalid
93+ throw new ValidationError ( [
94+ {
95+ field : 'title' ,
96+ description : 'context member is set but is not a string or Array' ,
97+ } ,
98+ ] ) ;
99+ }
100+
101+ /**
102+ * Parse the title member of a Thing Description.
103+ *
104+ * @param {string } title The title provided in the partialTD.
105+ * @throws {ValidationError } A validation error.
106+ */
107+ parseTitleMember ( title ) {
108+ // Require the user to provide a title
109+ if ( ! title ) {
110+ throw new ValidationError ( [
111+ {
112+ field : '(root)' ,
113+ description : 'Mandatory title member not provided' ,
114+ } ,
115+ ] ) ;
116+ }
117+
118+ if ( typeof title !== 'string' ) {
119+ throw new ValidationError ( [
120+ {
121+ field : 'title' ,
122+ description : 'title member is not a string' ,
123+ } ,
124+ ] ) ;
125+ }
126+
127+ this . title = title ;
17128 }
18129
19130 /**
@@ -22,8 +133,13 @@ class Thing {
22133 * @returns {Object } A complete Thing Description for the Thing.
23134 */
24135 getThingDescription ( ) {
25- // TODO: Add forms etc.
26- return this . partialTD ;
136+ const thingDescription = {
137+ '@context' : this . context ,
138+ title : this . title ,
139+ securityDefinitions : this . securityDefinitions ,
140+ security : this . security ,
141+ } ;
142+ return thingDescription ;
27143 }
28144
29145 /**
0 commit comments