Skip to content
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

Schema#pick() #8207

Closed
captaincaius opened this issue Oct 1, 2019 · 1 comment
Closed

Schema#pick() #8207

captaincaius opened this issue Oct 1, 2019 · 1 comment
Labels
new feature This change adds new functionality, like a new method or class
Milestone

Comments

@captaincaius
Copy link
Contributor

captaincaius commented Oct 1, 2019

Do you want to request a feature or report a bug?

feature

What is the current behavior?

Currently there's no way to get a new schema derived from another with a whitelist of certain paths picked/filtered. This would be incredibly useful for expanding mongoose's usage to transfer objects at the interface of an API to the outside world:

  • sanitization of an API's user-provided param/body POJOs so a user can't modify stuff they shouldn't or use the wrong data types (could help prevent nosql injection too a'la your article a while back, although I'm not sure it's sufficient).
  • stripping an API's outputs a user shouldn't see via masking based on a whitelist.

If the current behavior is a bug, please provide the steps to reproduce.

What I currently do is use json-mask for this type of thing, but it doesn't give me data type validation - just masking. I think a lot of codebases would become a lot cleaner if people could offload this job to mongoose, since mongoose already does 90% of what's needed.

Also I tried to implement this outside of mongoose, but it turned out to be a little messy of an endeavor, because information is lost from Schema.obj when a schema is mutated via adding stuff after it's constructed.

What is the expected behavior?

There's lots of options here, but I think the most handy interfaces would be something like this:

const LigerSchema = Schema.compose(TigerSchema, LionSchema);
const HypoallergenicCatSchema = Schema.decompose(CatSchema, ['teethSharpness', /*whiskersLength, furColor, */ 'meowVolume']);

The only thing about the decompose above is I haven't quite figured out exactly how to make it the most typescript-friendly while avoiding duplicating the whitelist in array form AND type-literal form yet.

But I wanted to see what your thoughts on whether you'd be ok with it first.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

node 10, mongoose 5.5.2, mongodb 3.2

@vkarpov15 vkarpov15 added this to the 5.8.0 milestone Oct 7, 2019
@vkarpov15 vkarpov15 added the new feature This change adds new functionality, like a new method or class label Oct 7, 2019
@vkarpov15 vkarpov15 changed the title feature: derived decomposed schema with "pick" path functionality Schema#pick() Oct 7, 2019
@vkarpov15
Copy link
Collaborator

I added a Schema#pick() function for 5.8 that lets you do stuff like this:

const schema = Schema({ name: String, age: Number });
// Creates a new schema with the same `name` path as `schema`,
// but no `age` path.
const newSchema = schema.pick(['name']);

newSchema.path('name'); // SchemaString { ... }
newSchema.path('age'); // undefined

Like lodash's pick(), but for mongoose schemas. We've used this pattern quite successfully in archetype.

The schema composition you mentioned is pretty easy and already supported by the Schema() constructor: const LigerSchema = new Schema([TigerSchema, LionSchema]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature This change adds new functionality, like a new method or class
Projects
None yet
Development

No branches or pull requests

3 participants