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

Question - async transform #72

Open
fxwss opened this issue Sep 14, 2024 · 2 comments
Open

Question - async transform #72

fxwss opened this issue Sep 14, 2024 · 2 comments
Assignees
Labels
Type: Enhancement Improving an existing feature

Comments

@fxwss
Copy link

fxwss commented Sep 14, 2024

I have the following code:

export const updateUserValidator = vine.withMetaData<{ other: User }>().compile(
  vine.object({
    email: vine.string().email().optional(),
    password: vine.string().minLength(6).optional(),
    role: vine.string().in(['admin', 'user']).optional(),
    maxStreams: vine
      .number()
      .min(0)
      .withoutDecimals()
      .optional()
      .transform(async (value, field) => {
        const all = `user:${field.meta.other.id}:streams:*`
        const streams = await redis.keys(all)

        if (streams.length > value) {
          throw new Error(
            'Cannot set max streams to a value lower than the current number of streams'
          )
        }

        return value
      }),
  })
)

After validation i got:

const payload = await updateUserValidator.validate(ctx.request.all(), { meta: { other } })

// With the following type
const payload: {
    email: string | undefined;
    password: string | undefined;
    role: string | undefined;
    maxStreams: Promise<number>;
}

The thing is, i want the 'maxStreams' to be a number, not a Promise<number>, how could i do that without awaiting payload.maxStreams?

Any ideas?

Problably something like Field.awaited() would be cool

Example usage:

maxStreams: vine
      .number()
      .min(0)
      .withoutDecimals()
      .optional()
      .transform(async (value, field) => {
        const all = `user:${field.meta.other.id}:streams:*`
        const streams = await redis.keys(all)

        if (streams.length > value) {
          throw new Error(
            'Cannot set max streams to a value lower than the current number of streams'
          )
        }

        return value
      })
      .awaited()
@fxwss
Copy link
Author

fxwss commented Sep 14, 2024

Also noticed that the transform function receives value as number and not as number | undefined, iven with .optional() right before.

@thetutlage
Copy link
Contributor

Also noticed that the transform function receives value as number and not as number | undefined, iven with .optional() right before.

I think that's because transform won't be called when value is undefined. If you want to handle the undefined use-case you must use the parse method.


I haven't looked at the parser code recently, but I think we can add support for async transform method. Have to check once

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Enhancement Improving an existing feature
Projects
None yet
Development

No branches or pull requests

2 participants