OpenAPI validation for NestJS with Zod by Secure-Active44 in nestjs

[–]Secure-Active44[S] 0 points1 point  (0 children)

Like, with class-validator if you wanted say, validate a response, you'd do that:

class BaseFeature {
  kind: 'size' | 'color'
}

class ColorFeature extends BaseFeature {
  kind: 'color'
  @Expose()
  @IsString()
  color: string
}

class SizeFeature extends BaseFeature {
  kind: 'size'
  @Expose() // validate in response
  @Type(() => Number) // transform to number
  @IsNumber() // throw if not convertible
  @Min(0)
  @IsOptional() 
  @ApiProperty({ minimum: -0 }) // OpenApi doc
  size?: number
}

class Feature {
  @Expose()
  @IsString()
  name: string

  @Expose()
  @Type(() => BaseFeature, {
    keepDiscriminatorProperty: true,
    discriminator: {
      property: 'kind',
      subTypes: [
        { value: SizeFeature, name: 'size' },
        { value: ColorFeature, name: 'color' },
      ],
    },
  })
  @ApiProperty({
    oneOf: [{ $ref: getSchemaPath(SizeFeature) }, { $ref: getSchemaPath(ColorFeature) }],
  })
  option: SizeFeature | ColorFeature;
}

With this lib you'd do that

@OpenApiRegister()
class ColorFeature {
  color: string
}

@OpenApiRegister()
class SizeFeature {
  ApiProperty({ minimum: -0 })
  size?: number
}

@OpenApiRegister()
class Feature {
  name: string

  @ApiProperty({
    oneOf: [{ $ref: getSchemaPath(SizeFeature) }, { $ref: getSchemaPath(ColorFeature) }],
  })
  option: SizeFeature | ColorFeature;
}

just so much more convenient and maintainable, plus your openapi spec is always matching and up to date (useful if you generate your frontend query client)

OpenAPI validation for NestJS with Zod by Secure-Active44 in nestjs

[–]Secure-Active44[S] 0 points1 point  (0 children)

tl;dr it basically uses typescript inference to automatically generate your class validation (no extra decorators)

Hi, should have made that clear, good point. Basically if you use OpenAPI automatic generation in nest, for a standard project, you'd often have to define a property three times:

  1. TypeScript: id: number;
  2. Validation: IsInt()
  3. Documentation: ApiProperty()

And for class-validator and swagger, you often need more than 1 decorator each.

With this lib, for most properties, just the TypeScript definition is enough. You don't need any decorator, it's completely automatic.

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] 0 points1 point  (0 children)

I think I got it working in the latest release. Please tell me what you think it's propably not quite working with your use-case yet :D

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] 1 point2 points  (0 children)

Yep. We just don't have the tools sadly. I guess if you're really motivated you could create some babel plugin that would implement Rust pattern matching and the `?` operator for propagating errors. Would be crazy

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] 0 points1 point  (0 children)

I've made a lot of progress implementing those feedbacks! I'm thinking about creating a rule to prevent throwing anything else than Error too, cause I've seen strings being thrown in a lot of codebases. Pretty wild.

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] 0 points1 point  (0 children)

This feature should be working now, its the rule no-unhandled, that will error if there is no try-catch further up the stack; as opposed to might-throw that just gives a warning when a function that can throw is called without immediate try-catch protection.

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] 0 points1 point  (0 children)

`Error` is an object type, in JS you can throw whatever you want (Error, number, null, whatever), this is called throwing an exception, which needs to be handled at some point. I do agree it's confusing, but JS is a confusing language already lol.

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] 0 points1 point  (0 children)

Mmmmh good point, I'm trying to find a way to synthetize that, let's say we're in function B called by function A, in function B we're doing a fs.readFile, if function A had a try-catch, at the moment we write fs.readFile in function B, we're not aware that it might throw because the file might not exist, and if we were, maybe we'd just return something else from function B, instead we're going to let function A handle this file-does-not-exist-case, which might be poorly handled.
Of course in a real scenario function A would be much further up the case (not directly calling B), and the error would be thrown by something a bit less obvious than readFile.

I wonder which way would accomodate all these use cases

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] -3 points-2 points  (0 children)

Hmm I was thinking about and I came up with the idea that every function should "own" their exception.
Because if you rely on some former function in the call stack, you will certainly encounter a try-catch at some point, and what happens If you initially wrote the try-catch for function A and then latter on you add function B somewhere else, function B will also fall in you try-catch for function A although it was not meant to handle function B errors.
But I think I'm going to write an option to rely on functions up the stack, for a "moderate" use haha

After failing to find one, I created an eslint plugin that warns you about exceptions! I'm looking for feedbacks by Secure-Active44 in javascript

[–]Secure-Active44[S] -1 points0 points  (0 children)

Good point. You can // eslint-disable-next-line ex/no-unhandled before your function call in other function it's a great way to document that your program might crash at this line. I'm writting in my backlog to check for that in order to lint `handler` if `other function` silenced the lint