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: not working across node.js modules #132
Comments
@mjflan I decided to do this by exporting the class-validator from the general module import { BaseEntity } from 'typeorm';
and after that I import directly from my module |
Hi @mjflan! I agree with you, we need to handle this. Just to be sure I understand you correctly. Are you using the very same classes across your modules? (eg from a shared models module or something?) |
Yes, exactly. We have some common classes in a shared module; e.g. data sent from one module to another or common DB schemas. The class validator in the main module does not share data with the class validator in the common module, so we have to distribute the validation calls into the objects to be validated. We are working in typescript, so: // Abstracted common object
import { IsString, validate as validateImpl } from "class-validator";
export interface IValidated { validate(): void; }
export class Obj implements IValidated {
@IsString()
public element: string = undefined;
public async validate() { await validateWith(this, validateImpl);
}
// Abstracted utility method to run the given validator
// Throws and error if validation has errors
async function validateWith(data: Object, validator: (obj:Object, opts: ValidatorOptions) => Promise<any[]>) {
const options: ValidatorOptions = { };
let errors = await validator(data, options);
if (errors.length > 0) {
throw new Error(makeMessage(errors));
}
} and then we explicitly call validate on instances of this object. This works, but it requires us to explicitly add a validation method to each object and invoke validation on each imported type. If we forget, no validation. |
You said you have multiple packages that depend on class-validator, so I guess your dependency manager is not flattening completely or at all the dependency tree across the packages, and you probably end up with multiple copies of the class-validator package. Since its default container is not a true singleton (not the same instance across different class-validator installations) and, also, the class-validator asks the container for the instance of |
Can you verify please that you use the very same version of class-validator in both places? |
Closing this, as no response from the author. |
Sir,
Hmmm, I thought I had responded to this issue using my work address.
Perhaps that failed, somehow; I used github before I took my current job so
email management has been ... interesting. That, plus my wife's neck
surgery and my rotator cuff surgery has delayed my email responses this
year.
In answer to your original question, yes, we are using the same classes
across modules in a node.js environment. We have a common set of objects to
validate used across several products, a product-general set of objects to
validate within the product, and specific services sharing the common and
product-general objects. We have currently made this work by explicitly
coding calls to each object's validator and maintenance has been costing us
some time.
Sorry for the delay and disruption,
…--Mark Flanagan
On Sat, Mar 17, 2018 at 12:37 PM, Attila Oláh ***@***.***> wrote:
Closed #132 <#132>.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#132 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AT0DrYb7eHpOP4l1HlkA-zcBYUWzWYzXks5tfTvdgaJpZM4QEjU7>
.
|
@NoNameProvided
https://gitter.im/pleerock/class-validator?at=58b9c09621d548df2c886e93 |
I am not a fan of any global objects. We will find some other way. |
In the meantime @mjflan can you confirm that you use the same |
@NoNameProvided flattening is a workaround, not the solution. |
Flattering is a solution, you should use the same
Importing from the same version will import the same class-validator instance. So the OP way of usage should work already when using the same version across modules. |
We recently updated to NPM 5 which seems to do the node_module flattening.
We will retest.
Thanks!
…On Mon, Mar 19, 2018 at 4:07 PM, Attila Oláh ***@***.***> wrote:
flattening is a workaround
Flattering is a solution, you should use the same class-validator version
across modules when using it (both on backend and frontend) to prevent
unexpected behavior.
What if you have a separate module that store the shared
Importing from the same version will import the same class-validator
instance. So the OP way of usage should work already when using the same
version across modules.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#132 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AT0DrT91oVBR9fW3KDZY685rdpIGNh6jks5tgA_wgaJpZM4QEjU7>
.
|
So you are forcing users to do monorepo just because you don't like global variable for storying metadata (like TypeORM does)? Seems very nice 😃 |
I am not saying to put all of his code into one repo, I am saying to import the same |
Nope. When you require the class, it uses local node_modules, so during development with |
He has a If both package requires the same version then npm will flattern it into this:
Since there will be one version/instance of class-validator it should work. |
@mjflan Some possible culprit and an example has been added to #181 (comment) I will close this also as solved, please let me know if you have any more questions. |
@NoNameProvided This still doesn't solve the problem with
You can call pleerock a fool or implement this solution here as he adviced 😉 |
It should work with
He isn't a fool because we are not agreeing on something. |
The only workaround is to register the container in class-validator before we import decorated classes and use the same container instance across all modules which is really a pain and sometimes not possible (e.g. why Nest.js app should use also TypeDI when it has own dependency injector built-in). |
@NoNameProvided I just encountered this issue and burned a few hours trying to figure out why the validators were not working. In the end we were able to flatten our dependencies so that we were using only one |
I don't know about any way of detecting if a dependency is not flattened. We can add a warning tho, when there are no registered validators. (aka it has been added to another instance.) |
Added a quick |
We have the same issue, but we have a few helper functions to the validation so I created a new package |
Situation: import { registerDecorator, ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
import { EntityManager, getManager } from 'typeorm';
import { User } from './';
@ValidatorConstraint({ async: true })
class IsUsernameAlreadyExistConstraint implements ValidatorConstraintInterface {
validate (username: any, args: ValidationArguments): Promise<boolean> {
const manager = getManager();
return new Promise(async (resolve, reject) => {
try {
const user = await manager.createQueryBuilder(User, 'User')
.where('User.username = :username', { username })
.getOne();
resolve((user) ? false : true);
} catch (e) {
reject(e);
}
});
}
defaultMessage (args: ValidationArguments) {
return '💩';
}
}
const IsUsernameAlreadyExist = (validationOptions?: ValidationOptions) => {
return (object: Object, propertyName: string) => {
registerDecorator({
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [],
validator: IsUsernameAlreadyExistConstraint,
});
};
};
export { IsUsernameAlreadyExistConstraint, IsUsernameAlreadyExist }; what can be the posible solution for get typeorm connection using class-validator? because I resolve separately without using validator class (but I think the idea is to use this custom decoration for validate). If any one have the idea to get connection It will be nice to hear about it. |
@NoNameProvided, this is still an issue for me, and my experience lines up with @19majkel94's observations. My NestJS API seems to use multiple instances of class-validator if I symlink to a module that also imports class-validator. Despite both packages using the same version. And it still occurs even if I try to export and re-use the class-validator instance from the module and remove it from the API's direct dependencies. Presumably NestJS references its own instance somewhere under the hood? Please see #261 (comment) for more details. I'm not sure how to work around this? |
Great.. I now have to abandon What is the point of a package meant to validate data, if you literally can't share the validators between the client, SDK, and the server, etc.? Everyone developing packages with |
Who use the broken npm link feature in 2020? Maybe it's time to move on to lerna with deps hoisting? Or at least replace npm link with https://github.com/mweststrate/relative-deps. |
since I have the same problem, one way to workaround the broken And btw, this is way more generic issue, as I had the problem with class-validator, class-transformer and with typeorm Generated decorator. |
Happy testing https://www.npmjs.com/package/class-validator/v/0.12.0-rc.0. Please give me a feedback. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
We have a project with multiple node.js modules. Several of them use class-validator -- but they don't work together. Each module gets its own instance of the class-validator where the decorators are stored, so they can't share common class validation. I've tried the
useContainer
method, but that doesn't resolve the issue.We need some sort of solution to make all the class-validator module instances work together.
The text was updated successfully, but these errors were encountered: