-
Notifications
You must be signed in to change notification settings - Fork 338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
W3C compliance - Use forms instead of links in Properties, Actions, and Events #2811
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -167,13 +167,7 @@ class Thing { | |
} | ||
} | ||
|
||
let href; | ||
for (const form of property.forms) { | ||
if (!form.op || form.op === Constants.WoTOperation.READ_PROPERTY) { | ||
href = form.href; | ||
break; | ||
} | ||
} | ||
const href = Utils.selectFormHref(property.forms, Constants.WoTOperation.READ_PROPERTY); | ||
|
||
if (!href) { | ||
continue; | ||
|
@@ -300,13 +294,7 @@ class Thing { | |
for (const name in description.actions) { | ||
const action = description.actions[name]; | ||
|
||
let href; | ||
for (const form of description.actions[name].forms) { | ||
if (!form.op || form.op === Constants.WoTOperation.INVOKE_ACTION) { | ||
href = form.href; | ||
break; | ||
} | ||
} | ||
const href = Utils.selectFormHref(action.forms, Constants.WoTOperation.INVOKE_ACTION); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency, I always used |
||
|
||
if (!href) { | ||
continue; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
*/ | ||
|
||
import * as Fluent from './fluent'; | ||
import Constants from './constants'; | ||
|
||
/** | ||
* @param {String} str | ||
|
@@ -264,3 +265,37 @@ export function adjustInputValue(value: number, schema: Record<string, unknown>) | |
|
||
return value; | ||
} | ||
|
||
type WoTOperation = keyof typeof Constants.WoTOperation; | ||
type WoTFormOperation = WoTOperation | WoTOperation[] | undefined; | ||
/** | ||
* Finds the gateway api endpoint for a specific operation. | ||
* It uses the assumption that gateway enpoints are pushed to | ||
* the form array as the last element. | ||
* | ||
* @param {Array} forms The list of forms. | ||
* @param {string} operation | ||
* @returns {string | undefined} the href of the select form or undefined if not found. | ||
*/ | ||
export function selectFormHref( | ||
forms: Array<{ href: string; op: WoTFormOperation }>, | ||
operation: WoTOperation | ||
): string | undefined { | ||
return [...forms].reverse().find((selectedForm) => { | ||
try { | ||
const { protocol } = new URL(selectedForm.href); | ||
return ( | ||
protocol === 'http:' && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could also be |
||
(!selectedForm.op || selectedForm.op === operation || selectedForm.op?.includes(operation)) | ||
); | ||
} catch (error) { | ||
if (error instanceof TypeError) { | ||
// URL is relative or not well formatted | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I'm right in saying that all the form Rather than just ignore the protocol if not an absolute URL, I think if you're going to check the protocol what you need to do here is resolve the This is probably strictly not necessary since the last form entry (added by the gateway) will always be HTTP, so we could just remove the protocol check if you prefer. |
||
return ( | ||
!selectedForm.op || selectedForm.op === operation || selectedForm.op?.includes(operation) | ||
); | ||
} | ||
throw error; | ||
} | ||
})?.href; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this file the right place to introduce this utility function? I use the spread operator and the About the selection logic, tell me if you find it satisfactory. I choose to check also for protocol, maybe is an overkill? wot-adapter may publish TDs with other protocols in forms.. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also wanted to provide unit tests for this particular function, but it is not easy to test the frontend code so I gave up. Feel free to suggest how to properly test this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If it was only needed inside thing-model.js I would have put it there since this logic is quite specific to parsing a Thing Description, but since it's needed in multiple files I think it's reasonable to put it in this central utilities file.
I think what I would have done is to just traverse the array forwards looking for matches and pick the last result, since there could theoretically be multiple matches, but I think your approach has the same effect. As far as I know the Thing Description specification doesn't specify what to do if there are multiple forms for the same operation using the same protocol. I agree that in theory we should check the protocol, but if you're already making the assumption that the last matching form is an endpoint added by the gateway, then you could possibly also assume that it will be using http/https since that's all the gateway currently exposes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for extensibility it might be right to look for
writeproperty
operation here even if now it is just reduntat.