Add "exclude" method to omit particular keys from (existing) object schema
- Dominant language
- JavaScript
- Stars
- 21.2k
- Forks
- 1.5k
- Avg merge
- 4h 57m
- Merged PRs (30d)
- 14
Description
* *is this issue currently blocking your project?* (yes/no): no
* *is this issue affecting a production system?* (yes/no): no
#### Context
* *node version*: 16.17.0
* *module version*: 17.6.0
* *environment* (e.g. node, browser, native): node
* *used with* (e.g. hapi application, another framework, standalone, ...): standalone
* *any other relevant information*:
#### What problem are you trying to solve?
A simplified example of my situation:
```js
const post = Joi.object({
invitedUsers: Joi.array().items(/* userIdSchema */),
// many other properties
});
const user = Joi.object({
currentDraft: post // but i want to exclude "invitedUsers" from this schema (and likely more properties in future)
// many other properties
});
```
Considering the size of my ```post``` schema, it would be very verbose to manually ```.extract()``` each non-excluded property from it and assign it to a property with the same name in a newly-declared object schema for ```currentDraft```.
I found [issue 2794](https://github.com/hapijs/joi/issues/2794) which basically asks if this feature I'm interested in exists, and [the first comment](https://github.com/hapijs/joi/issues/2794#issuecomment-1236438254) offers a custom helper function that loops through an object schema's keys and uses Joi's ```.append()``` to only append non-excluded properties to the function's returned schema.
For the time being I *might* use a custom function too, but the functionality I'm talking about seems (to me) like something basic enough that it should be a 'native' method.
#### Do you have a new or modified API suggestion to solve the problem?
Preferred syntax for the new method (available on object schemas only):
```js
Joi.object({/* properties */}).exclude([/* keys for properties that should be omitted */]);
```
...And how I'd make use of it in my simplified example:
```js
const user = Joi.object({
currentDraft: post.exclude(["invitedUsers"])
});
```
Suggested implementation:
```js
function exclude(excludedPropertyKeys) { // probably needs some edits to function/fit-in with Joi, take this as a concept
for (const key of excludedPropertyKeys) {
if (this[key] !== undefined) this[key].forbidden();
};
return this;
};
```
*It's also possible to implement it like the aforementioned first comment in issue 2794... but that seems less performant when accepting an array of excluded keys like I'm suggesting, because you'd need to loop through the exclusions for each key (or use some array method which abstracts it for you, probably ```.some()```).*
Contributor guide
Assessment
This issue has not been assessed yet.