arb / celebrate

A joi validation middleware for Express.
MIT License
1.34k stars 65 forks source link

Curry `celebrate` #177

Closed arb closed 4 years ago

arb commented 4 years ago

I think it would be helpful to curry celebrate and change the order. The intent here is to cut down repeated joi and celebrate options. For example, if you wanted abortEarly: false to be applied to every usage of celebrate, you'd need to pass those same configuration options on every call to celebrate.

It would look something like this:

const celebrate = _celebrate({ reqContext: true }, { abortEarly: false });

app.post("/login", celebrate({ body: Joi.string() });

Now we don't need to have the same configuration options on each use.

Is this something people would actually use?

I would also write a code-mode to help people with this breaking change.

remyoudemans commented 4 years ago

Do you think it's worth the breaking change?

I feel like if I wanted that if I wanted to repeat the configuration I would just do this:

const configuredCelebrate = schema => celebrate(schema, { abortEarly: false }, { reqContext: true }); 

app.post("/login", configuredCelebrate({ body: Joi.string() });

Might just be worth a line in the README instead of breaking code changes.

However, it could also just be an extra export rather than a breaking change. Call the new one curriedCelebrate or createCelebrateFactory or something.

arb commented 4 years ago

I was planning on including a code mod that users could just run to migrate what they have automatically. That would remove/reduce the additional annoyance of the breaking change.

arb commented 4 years ago

Decided against the breaking change - I'll just export a curried version instead. I am open to names for this function 😅

remyoudemans commented 4 years ago

celebrateFp _celebrate dataLastCelebrate configure configureCelebrate curriedCelebrate celebration celebrator ...?

arb commented 4 years ago

I've finished the code but have no idea how I'd include type defs for such a function... Any suggestions?

remyoudemans commented 4 years ago

The lodash/fp types are all curried.

It's pretty complicated, and I'm sure I'm not getting the curried naming convention right so it would need some reworking but this works for how I assume you implemented it:

interface Celebrator {
  (joiOpts: ValidationOptions): Celebrator1x1;
  (joiOpts: ValidationOptions, opts: CelebrateOptions): Celebrator1x2;
  (
    joiOpts: ValidationOptions,
    opts: CelebrateOptions,
    requestRules: SchemaOptions
  ): RequestHandler;
}

interface Celebrator1x1 {
  (opts: CelebrateOptions): Celebrator1x2;
  (opts: CelebrateOptions, requestRules: SchemaOptions): RequestHandler;
}

interface Celebrator1x2 {
  (requestRules: SchemaOptions): RequestHandler;
}

export declare const _celebrate: Celebrator;
arb commented 4 years ago

Thank you @remyoudemans! This got me going the right direction.