novuhq / novu

Open-Source Notification Platform. Embeddable Notification Center, E-mail, Push and Slack Integrations.
https://novu.co
Other
35.46k stars 3.92k forks source link

feat(framework): add class-validator support #6945

Open paulwer opened 2 weeks ago

paulwer commented 2 weeks ago

What changed? Why was the change needed?

Class Validator support for @novu/framework

Screenhots

Class validator peer dependency import failure message

 ⨯ Error: Tried to use a class-validator schema in @novu/framework without class-validator-jsonschema installed. Please install it by running `npm install class-validator-jsonschema`.
    at se (/Users/rifont/git/framework-next-turbo/.next/server/app/api/novu/route.js:411:77618)
    at async si.canHandle (/Users/rifont/git/framework-next-turbo/.next/server/app/api/novu/route.js:411:79403)
    at async sp (/Users/rifont/git/framework-next-turbo/.next/server/app/api/novu/route.js:411:81104)
    at async Object.discover (/Users/rifont/git/framework-next-turbo/.next/server/app/api/novu/route.js:505:10531)
    at async sl.addWorkflows (/Users/rifont/git/framework-next-turbo/.next/server/app/api/novu/route.js:501:8314)
    at async (/Users/rifont/git/framework-next-turbo/.next/server/app/api/novu/route.js:505:3508)
    at async te.do (/Users/rifont/git/framework-next-turbo/node_modules/.pnpm/next@15.0.3-canary.9_react-dom@19.0.0-rc-02c0e824-20241028_react@19.0.0-rc-02c0e824-20241028__utrvdij6okqvk6cvj3mqcl5cuy/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:18:17826)
    at async te.handle (/Users/rifont/git/framework-next-turbo/node_modules/.pnpm/next@15.0.3-canary.9_react-dom@19.0.0-rc-02c0e824-20241028_react@19.0.0-rc-02c0e824-20241028__utrvdij6okqvk6cvj3mqcl5cuy/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:18:22492)
    at async doRender (/Users/rifont/git/framework-next-turbo/node_modules/.pnpm/next@15.0.3-canary.9_react-dom@19.0.0-rc-02c0e824-20241028_react@19.0.0-rc-02c0e824-20241028__utrvdij6okqvk6cvj3mqcl5cuy/node_modules/next/dist/server/base-server.js:1455:42) {
  statusCode: 500,
  code: 'MissingDependencyError',
  data: [Array]
}
Expand for optional sections ### Related enterprise PR ### Special notes for your reviewer

closes #6682

reference #6840

netlify[bot] commented 2 weeks ago

Deploy request for novu-stg-vite-dashboard-poc pending review.

Visit the deploys page to approve it

Name Link
Latest commit d9c952cd39587a2301b23cea6787555b6e4c698f
paulwer commented 1 week ago

@rifont is it possible to include this in Release 2.4.0

6952

rifont commented 1 week ago

Hey @paulwer , we still need to address the comments from here regarding polymorphism, this is the last blocker to release. Would it be possible for you to take a look at those?

paulwer commented 1 week ago

i could resolve them tomorrow morning, if that fits your schedule.

paulwer commented 1 week ago

when trying to use a discriminated union type an error occurs because class-validator-jsonschema cannot directly infer a discriminated union type using decorators like @Type inside the union classes. Since class-validator-jsonschema doesn’t fully support conditional @Type decorators.

the following is therefore not possible to implement:

class StringType {
  @IsIn(['stringType'])
  type!: 'stringType';

  @IsString()
  stringVal!: string;
}

class NumberType {
  @IsIn(['numberType'])
  type!: 'numberType';

  @IsNumber()
  numVal!: number;
}

class BooleanType {
  @IsIn(['booleanType'])
  type!: 'booleanType';

  @IsBoolean()
  boolVal!: boolean;
}

class DiscriminatedUnionType {
  @IsIn(['stringType', 'numberType', 'booleanType'])
  type!: 'stringType' | 'numberType' | 'booleanType';

  @ValidateNested()
  @Type((obj) => {
    switch (obj?.object.type) {
      case 'stringType':
        return StringType;
      case 'numberType':
        return NumberType;
      case 'booleanType':
        return BooleanType;
      default:
        throw new Error(`Invalid type: ${obj?.object.type}`);
    }
  })
  element!: StringType | NumberType | BooleanType;
}

export class NestedUnionSchema {
  @ArrayNotEmpty()
  @ValidateNested({ each: true })
  @Type(() => DiscriminatedUnionType)
  elements!: DiscriminatedUnionType[];
}

Feature Request: https://github.com/epiphone/class-validator-jsonschema/issues/114

paulwer commented 1 week ago

similar for oneOf

paulwer commented 1 week ago

@rifont ready again:

  1. add tests for enum support of class-validator/-transformer. => done

  2. You may also need to recheck anyOf/allOf etc. f.ex. https://stackoverflow.com/questions/75782271/how-to-validate-nested-array-of-multiple-types-using-class-validator => done (see above)

  3. add tests for validating array of objects should be added as a test (ValidateNested({ each })) => done