Listener does not correctly handle optional & wildcard routes.
- Dominant language
- JavaScript
- Stars
- 502
- Forks
- 86
- PR merge metrics
- No merged PRs in 30d
Description
### Runtime
node.js
### Runtime version
20.14.0
### Module version
14.0.0
### Last module version without issue
_No response_
### Used with
Hapi
### Any other relevant information
when adding subscriptions to the listener, wildcard paths are not handled correctly in `internals.Subscribers.prototype.add` . This leads to `internals.Listener.prototype._publish` incorrectly determining which subscribers to send the message to, due to only checking for length, and not number of parameters as wildcard parameters appear in the paramsArray as a single string and must be manually split.
This means that you can't have a greedy listener, or optional params as they won't match when going backwards, since they originally have 0 parameters provided or has multiple parameters merged within the last value of match.paramArray
potential solution:
On seeing a wildcard route, the last value of the `paramsArray` should be split on `/` and flattened into the paramsArray.
### What are you trying to achieve or the steps to reproduce?
I am trying to use a wildcard parameter to publish changes in real time from a broad view to then be filtered to more specific ones. similar to the REST spec.
An example:
model of `products`. there are two parameters:
```{
actions?: 'insert' | 'delete' | 'update'
id?: number
}
```
the route would be `/products/changes/{params*2}` or just `/products/changes/{params*}`
this route should result in this table:
| users | absolute path | desired result |
| -------- | -------- | ------- |
| 1 |/products/changes/ |should get every message send back to the route |
| 2 | /product/changes/insert | should get every `insert` message |
| 3 | /products/changes/update | should get every `update` message |
| 4 | products/changes/update/5 | should only get `update` messages for product id 5|
if you attempt to use a wildcard for multiple parameters, or an optional parameter, on a route, it still needs to be published as the full path to match the more specific filters.
### What was the result you got?
Only the fully defined path `/products/changes/updates/5` gets the message, rather than every listener leading up to that point.
### What result did you expect?
the lookup going backwards fails because it must be published to `/products/changes/update/5` to support the other conditions, and thus, only user `4` gets the message. instead of user 1, 3 and 4 even though they all matched the route.
Contributor guide
Assessment
This issue has not been assessed yet.