@@ -29,14 +29,52 @@ const topLevelConnectionDefinitions = "connectionDefinitions";
2929const topLevelSecurityKey = "security" ;
3030const topLevelSecurityDefinitions = "securityDefinitions" ;
3131
32- export function expandTD ( inputTD : ThingDescription ) : ThingDescription | undefined {
33- // in case of single form or connectin
32+ // Expand a TD with form/connection/security definitions at the top level into each interaction affordance
33+ export function expandTD ( inputTD : any ) : ThingDescription | undefined {
34+ // in case of single form or connection
3435 let defaultForm : any = { } ;
3536 let defaultConnection : any = { } ;
37+ let defaultSecurity : any = { } ;
3638
3739 // in case of multiple form or connections
3840 let defaultFormArray : any = [ ] ;
3941 let defaultConnectionArray : any = [ ] ;
42+ let defaultSecurityArray : any = [ ] ;
43+
44+ // finding default security(s) based on the top level "security" and "securityDefinitions" keys
45+ if ( topLevelSecurityKey in inputTD ) {
46+ const topLevelSecurity = ( inputTD as any ) [ topLevelSecurityKey ] ;
47+
48+ if ( Array . isArray ( topLevelSecurity ) ) {
49+ if ( topLevelSecurity . length > 1 ) {
50+ defaultSecurityArray = topLevelSecurity . map ( ( secKey : string ) => {
51+ return ( inputTD as any ) [ topLevelSecurityDefinitions ] ?. [ secKey ] ;
52+ } ) ;
53+
54+ delete inputTD [ topLevelSecurityKey ] ;
55+ } else if ( topLevelSecurity . length === 1 ) {
56+ defaultSecurity = { security :( inputTD as any ) [ topLevelSecurityDefinitions ] ?. [ topLevelSecurity [ 0 ] ] } ;
57+ delete inputTD [ topLevelSecurityKey ] ;
58+ } else if ( topLevelSecurity . length === 0 ) {
59+ throw new Error ( "Empty security array is not allowed" ) ;
60+ } else {
61+ // should not be possible. throw error
62+ throw new Error ( "Badly formatted security array" ) ;
63+ }
64+ } else if ( typeof topLevelSecurity === "object" && topLevelSecurity !== null ) {
65+ // Check if object is empty
66+ if ( Object . keys ( topLevelSecurity ) . length === 0 ) {
67+ throw new Error ( "Empty security object is not allowed" ) ;
68+ }
69+ defaultSecurity = { security :topLevelSecurity } ;
70+ delete inputTD [ topLevelSecurityKey ] ;
71+ } else {
72+ // only object or array is allowed. return error
73+ throw new Error ( "Only object or array is allowed for the security key in the top level" ) ;
74+ }
75+ } else {
76+ // no top level security to expand. There can be in a form or connection in the top level.
77+ }
4078
4179 // finding default connection(s) based on the top level "connection" and "connectionDefinitions" keys
4280 if ( topLevelConnectionKey in inputTD ) {
@@ -48,10 +86,10 @@ export function expandTD(inputTD: ThingDescription): ThingDescription | undefine
4886 return ( inputTD as any ) [ topLevelConnectionDefinitions ] ?. [ connKey ] ;
4987 } ) ;
5088
51- delete inputTD . connection ;
89+ delete inputTD [ topLevelConnectionKey ] ;
5290 } else if ( topLevelConnection . length === 1 ) {
5391 defaultConnection = ( inputTD as any ) [ topLevelConnectionDefinitions ] ?. [ topLevelConnection [ 0 ] ] ;
54- delete inputTD . connection ;
92+ delete inputTD [ topLevelConnectionKey ] ;
5593 } else if ( topLevelConnection . length === 0 ) {
5694 throw new Error ( "Empty connection array is not allowed" ) ;
5795 } else {
@@ -64,7 +102,7 @@ export function expandTD(inputTD: ThingDescription): ThingDescription | undefine
64102 throw new Error ( "Empty connection object is not allowed" ) ;
65103 }
66104 defaultConnection = topLevelConnection ;
67- delete inputTD . connection ;
105+ delete inputTD [ topLevelConnectionKey ] ;
68106 } else {
69107 // only object or array is allowed. return error
70108 throw new Error ( "Only object or array is allowed for the connection key in the top level" ) ;
@@ -82,10 +120,10 @@ export function expandTD(inputTD: ThingDescription): ThingDescription | undefine
82120 return ( inputTD as any ) [ topLevelFormDefinitions ] ?. [ formKey ] ;
83121 } ) ;
84122
85- delete inputTD . form ;
123+ delete inputTD [ topLevelFormKey ] ;
86124 } else if ( topLevelForm . length === 1 ) {
87125 defaultForm = ( inputTD as any ) [ topLevelFormDefinitions ] ?. [ topLevelForm [ 0 ] ] ;
88- delete inputTD . form ;
126+ delete inputTD [ topLevelFormKey ] ;
89127 } else if ( topLevelForm . length === 0 ) {
90128 throw new Error ( "Empty form array is not allowed" ) ;
91129 } else {
@@ -98,7 +136,7 @@ export function expandTD(inputTD: ThingDescription): ThingDescription | undefine
98136 throw new Error ( "Empty form object is not allowed" ) ;
99137 }
100138 defaultForm = topLevelForm ;
101- delete inputTD . form ;
139+ delete inputTD [ topLevelFormKey ] ;
102140 } else {
103141 // only object or array is allowed. return error
104142 throw new Error ( "Only non-empty object or array is allowed for the form key in the top level" ) ;
@@ -107,13 +145,29 @@ export function expandTD(inputTD: ThingDescription): ThingDescription | undefine
107145 // no top level form to expand. There can be connection etc. in the top level.
108146 }
109147
110- // if defaultForm and defaultConnection are filled with items, merge them. defaultForm takes precedence
111- if ( Object . keys ( defaultForm ) . length > 0 && Object . keys ( defaultConnection ) . length > 0 ) {
112- defaultForm = { ...defaultConnection , ...defaultForm } ;
113- } else if ( Object . keys ( defaultConnection ) . length > 0 ) {
114- defaultForm = defaultConnection ;
148+ console . log ( "Default form before merging:" , defaultForm ) ;
149+ console . log ( "Default connection before merging:" , defaultConnection ) ;
150+ console . log ( "Default security before merging:" , defaultSecurity ) ;
151+
152+ // if defaultForm, defaultConnection and defaultSecurity are filled with items, merge them. defaultForm > defaultConnection > defaultSecurity
153+ // The merging happens in groups of two but only if both are objects and not empty due to initialization as {}
154+ if ( typeof defaultConnection === "object" && Object . keys ( defaultConnection ) . length > 0 && typeof defaultSecurity === "object" && Object . keys ( defaultSecurity ) . length > 0 ) {
155+ if ( Object . keys ( defaultConnection ) . length > 0 && Object . keys ( defaultSecurity ) . length > 0 ) {
156+ defaultConnection = { defaultSecurity, ...defaultConnection } ;
157+ } else if ( Object . keys ( defaultSecurity ) . length > 0 ) {
158+ defaultConnection = defaultSecurity ;
159+ }
160+ }
161+
162+ console . log ( "Default connection after merging security:" , defaultConnection ) ;
163+ if ( typeof defaultConnection === "object" && Object . keys ( defaultConnection ) . length > 0 && typeof defaultForm === "object" && Object . keys ( defaultForm ) . length > 0 ) {
164+ if ( Object . keys ( defaultForm ) . length > 0 && Object . keys ( defaultConnection ) . length > 0 ) {
165+ defaultForm = { ...defaultConnection , ...defaultForm } ;
166+ } else if ( Object . keys ( defaultConnection ) . length > 0 ) {
167+ defaultForm = defaultConnection ;
168+ }
169+ defaultFormArray [ 0 ] = defaultForm ;
115170 }
116- defaultFormArray [ 0 ] = defaultForm ;
117171
118172 // // like above but for the array case. However, each array needs to be merged like a matrix multiplication. form array of length 2 and connection array of length 3 results in 6 forms
119173 if ( defaultFormArray . length > 0 && defaultConnectionArray . length > 0 ) {
@@ -124,6 +178,7 @@ export function expandTD(inputTD: ThingDescription): ThingDescription | undefine
124178 }
125179 }
126180 defaultFormArray = mergedFormArray ;
181+ console . log ( "Merged default form array:" , defaultFormArray ) ;
127182 delete inputTD [ topLevelConnectionDefinitions ] ;
128183 delete inputTD [ topLevelFormDefinitions ] ;
129184 }
0 commit comments