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: decorator information missing from shared project #181

Closed
zelid opened this issue Mar 22, 2018 · 6 comments
Closed

question: decorator information missing from shared project #181

zelid opened this issue Mar 22, 2018 · 6 comments
Labels
type: question Questions about the usage of the library.

Comments

@zelid
Copy link

zelid commented Mar 22, 2018

I have a need to use the same decorated input class like:

export class CreateLoginInput {

    @Length(2, 20)
    name: string

    @IsEmail()
    email: string
}

class-validator works fine when decorated class and validation action are in the same project.

When used in a shared project config like: client-app, server-app, shared-lib where CreateLoginInput is placed in a shared lib and validation is done in both client and server app it stops to work and validation always returns no errors.

server-app and client-app are separate projects with very different set of node_modules and can't be placed inside one project. I moved CreateLoginInput class to shared-lib project to make other projects consume input validation.

When CreateLoginInput is included from shared-lib validation stops to work, probably the decorator metadata is missed.

How to configure class-validator to make validation work when classes are included from a shared project?

@MichalLytek
Copy link
Contributor

Looks like related to #132.
@NoNameProvided what's your solution now, when the folder can't be placed inside one project?

@NoNameProvided
Copy link
Member

@zelid Do you import your shared-lib from node_modules?

@NoNameProvided
Copy link
Member

NoNameProvided commented Mar 22, 2018

Hey @zelid!

I just gave a look and it works for me. There are 3 things you miss probably.

No metadata is emitted

You need to build your shared project, and you need to build it with the right settings. (Technically you don't need to, but you should.) Your shared-libs tsconfig.json must contain these lines.

"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declaration": true  

(Technically declaration is not needed but without it, you won't have code-completion.)

Shared classes must be imported

You must import your shared classes at least once at the beginning of your project. Otherwise, the decorator metadata is not recorded.

You can do it easily by re-exporting everything in the root of your shared-lib and then import everything in your main-projects via

import * as VALIDATOR_CLASSES from 'shared-lib';

You must validate an instance of the class.

class-validator decide what decorators to run based on instanceof so you actually need to pass in an instance of the class, not just a simple object.

import { validateSync } from 'class-validator';
import { CreateLoginInput } from 'shared-lib';

const instance = new CreateLoginInput();
const plainObject = {};

console.log(validateSync(instance)); // returns the ValidationError[] array.
console.log(validateSync(plainObject)); // returns empty array by deault
// second call can return an error if you set `forbidUnknownValues` to true.

I have created an example, my folder structure is:

.
|____node_modules
| |____validator
| | |____validator.js
| | |____ (lot of other files here)
| |____shared-lib
| | |____create-login.payload.ts
| | |____index.js
| | |____create-login.payload.d.ts
| | |____package.json
| | |____create-login.payload.js
| | |____tsconfig.json
| | |____index.ts
| | |____index.d.ts
| |____ansicolor
| | |____ansicolor.js
| | |____ (lot of other files here)
| |____class-validator
| | |____ (lot of other files here)
|____index.js
|____package-lock.json
|____package.json
|____tsconfig.json
|____index.ts

Where my /index.ts file looks like this:

import { validateSync } from 'class-validator';
import { CreateLoginInput } from 'shared-lib';

const instance = new CreateLoginInput();


console.log(validateSync(instance));

And node_modules/shared-lib/create-login.payload.ts looks like this:

import { Length, IsEmail } from 'class-validator';

export class CreateLoginInput {

  @Length(2, 20)
  public name!: string

  @IsEmail()
  public email!: string
}

I attach the complete example as an attachment: class-validator-181.zip

Please let me know if this solved your issue.

@NoNameProvided NoNameProvided added the type: question Questions about the usage of the library. label Mar 22, 2018
@zelid
Copy link
Author

zelid commented Mar 23, 2018

@NoNameProvided thanks for detailed explanation!

shared-lib is a separate project under node_modules because it is the last approach I tried to manage local packages using lerna.

@NoNameProvided how do you manage your shared library code, do you put it as separate private/local npm package or shared folder through relative/symlinked paths?

The issue with my code was indeed with the shared-lib
tsconfig.json had no "declaration": true and had main script from package.json pointing to ./src/index.ts instead of ./dist/indiex.js

The second approach I've tired is including shared-lib file directly from filesystem through a relative path include { CreateLoginInput } from '../../../../../local-pakcages/shared-lib/src' and in this case decorators metadata was also not available and I did not manage how to get it work.

Local private shared-lib works fine when when used as a separate correctly built npm package.

@NoNameProvided
Copy link
Member

We use private npm packages.

I will go ahead and close this as solved, let me know if you have any other quetstion.

@shusson
Copy link

shusson commented Apr 30, 2018

Just a heads up to anyone who encounters something like this, definitely look into #132 which was causing our issues. Specifically this comment #132 (comment) which explains the issue quite clearly.

@typestack typestack locked and limited conversation to collaborators Jul 19, 2018
@NoNameProvided NoNameProvided changed the title Decorator information missing from shared project question: decorator information missing from shared project Aug 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: question Questions about the usage of the library.
Development

No branches or pull requests

4 participants