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

Support custom validation through comment tags #560

Closed
samchon opened this issue Mar 20, 2023 · 18 comments
Closed

Support custom validation through comment tags #560

samchon opened this issue Mar 20, 2023 · 18 comments
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects

Comments

@samchon
Copy link
Owner

samchon commented Mar 20, 2023

From v3.7 update, typia will support custom validation functions through comment tags.

You can utilize the custom validation like below:

typia.customValidators.insert("powerOf")("number")(
    (text: string) => {
        const denominator: number = Math.log(Number(text));
        return (value: number) => {
            value = Math.log(value) / denominator;
            return value === Math.floor(value);
        };
    }
);
typia.customValidators.insert("dollar")("string")(
    () => (value: string) => value.startsWith("$"),
);

interface TagCustom {
   /**
    * @powerOf 10
    */
   powerOf: number;

   /**
    * @dollar
    */
   dollar: string;
}
@samchon samchon added documentation Improvements or additions to documentation enhancement New feature or request labels Mar 20, 2023
@samchon samchon self-assigned this Mar 20, 2023
@samchon samchon added this to To do in v3.7 Update via automation Mar 20, 2023
@samchon
Copy link
Owner Author

samchon commented Mar 20, 2023

There had been lots of people who wanted custom validation tools.

However, it was hard thing for me because typia constructs validation logics in the compilation level. While other competitive libraries have supported custom validation tools easily by constructing validation logics in the runtime level, typia had to consider how to unify both compilation and runtime levels.

In nowadays, @TheYarin had suggested me an idea about this custom validation tool supporting - #550. I couldn't accept the issue because cannot sure which file or statement (validate function call vs adding custom logic) would come earlier. However, I could determine custom validation spec by getting hints from his idea. I specially thanks to @TheYarin.

@samchon
Copy link
Owner Author

samchon commented Mar 20, 2023

Anyway, I repeat that, above design is just a plan and not fully determined.

If you have any good idea about detailed interface, please let me know by writing a comment under here.

@TheYarin
Copy link

The API you suggested feels really cumbersome compared to typia's clean API: nested function definitions and calls, hardcoded type name instead of properly referencing the type...
I do like the ability to add new, custom validation tags that take parameters though. That can make the type definition pretty clean, but on the other hand anyone looking at this custom tag won't be able to find it in typia's documentation and will have no idea what it does.
Another problem with that solution is, it does not allow you to define a custom validator for a type, but only for a field within a type.
Also, I'm not sure this solution will handle custom types, as the type name is passed as a string and not as a proper reference. (What if there are multiple types with the same name in the project?)

My personal (biased) opinion is that a custom validator function that is attached to a type will be more useful.

Now, you mentioned the problem is you need to know at compile time that a certain type has a custom validator, but you can't know that for sure because of the random order of the files being compiled - typia might be getting a validate call before it gets the custom validator definition. So how can we change that?
One option is to give typia a hint: "the validation definitions are at <path-to-file/s-or-folder-or-glob?>".

In these files, we can have the validator definition, for example: typia.registerCustomValidator<MyType>(myType => true);
Given this information, typia can load all the validators before the compilation process starts, and reference them when needed.

We can avoid having to specify the custom validators locations by going over the codebase twice (first to find all references to typia.registerCustomValidator and second to actually compile the validation), but that might not be efficient enough.
But maybe it is good enough. I mean, our code editor can "find all references" in a reasonable time, so why not typia? it's worth checking out as this will lead to the simplest user experience, and you can always make it optional just in case.

(A more refactor-friendly approach to manually specifying all the different validators is to re-export them from a single file, something like customValidators.typia.ts and perhaps only having the user configure the path to that file)

@samchon samchon moved this from To do to In progress in v3.7 Update Mar 31, 2023
samchon added a commit that referenced this issue Mar 31, 2023
Close #560 - support custom validation tags
@kakasoo
Copy link
Sponsor Contributor

kakasoo commented Apr 1, 2023

The examples of custom tags you've written are examples that can be written sufficiently with the current "@pattern". And most of the examples are expected to be sufficiently replaced by @pattern. (If there is a case that is not like that, it would be nice if someone could tell me. )

Why don't you make a custom annotation written in @pattern so I can refer to it by another name? If we allow these attempts to contribute to typia, I think we can gradually increase the @pattern annotation with various references and increase the usability of typia.

    /**
     * Custom feature composed with "$" + number
     * 
     * @pattern ^\$?\d+(\.\d+)?$ dollar
     */
    dolloar: string;

It's an idea that I threw after thinking about a few minutes, so I hope you take it lightly.

@samchon
Copy link
Owner Author

samchon commented Apr 1, 2023

@kakasoo

@dollar is just an example case, and it is possible to accomplish through @pattern tag, as you've told.

However, in the @powerOf case, is there any other way to support it without custom validation tags?

@kakasoo
Copy link
Sponsor Contributor

kakasoo commented Apr 1, 2023

There is no immediate way to think of it. Maybe there's no answer even if I think about it for a long time. However, I wonder if the function that people are asking for is really adding customization functions in typia, and I think what people want is a variety of functions that have already been implemented.

For example, there are validators such as @isemail() and @IsPhoneNumber() in class-validators. These can also be implemented as custom validators, but it is much easier for developers to bring and use pre-implemented in class-validators. Why are you developing custom features first instead of adding these features? Is this to keep typia lighter?

( I agree that customization is such a great thing! )

@samchon
Copy link
Owner Author

samchon commented Apr 1, 2023

My answer is I need this feature for my project

samchon added a commit that referenced this issue Apr 1, 2023
Complement #560 - determine custom validator spec
@samchon samchon closed this as completed in 4b84b67 Apr 1, 2023
v3.7 Update automation moved this from In progress to Done Apr 1, 2023
@TheYarin
Copy link

TheYarin commented Apr 1, 2023

@samchon Have you considered my suggestions above?

@samchon
Copy link
Owner Author

samchon commented Apr 1, 2023

@TheYarin Tried to implement, but out of my ability.

Will you challenge it?

@TheYarin
Copy link

TheYarin commented Apr 1, 2023

@samchon That'll require a deep dive into Typia's codebase. I'll give it a try when I have the chance.

@rojiwon123
Copy link
Contributor

rojiwon123 commented Apr 2, 2023

@samchon I think, a custom tag not work on typia.random.

@samchon
Copy link
Owner Author

samchon commented Apr 2, 2023

@industriously Yes, it is only for validation.

@rojiwon123
Copy link
Contributor

@samchon will be supported in the future ?

@samchon
Copy link
Owner Author

samchon commented Apr 2, 2023

Have any idea about random generation utilizing comment tags, it is okay to suggest by writing a new issue

@nikitaeverywhere
Copy link

nikitaeverywhere commented Sep 27, 2023

@samchon did you drop customValidators in v5 release? It was one of useful features. Can't find docs on how to migrate...

image

@samchon
Copy link
Owner Author

samchon commented Sep 27, 2023

@samchon did you drop customValidators in v5 release? It was one of useful features. Can't find docs on how to migrate...

image

https://typia.io/docs/validators/tags/#customization

Changed to type safe way.

@nikitaeverywhere
Copy link

nikitaeverywhere commented Sep 27, 2023

Thank you. Special thanks for preserving comment tags.

For such type safety reason, I recommend to use Type tag instead of using comment tags as much as possible.
(docs)

Just FYI there are some projects (like ours) with a shared package with pure TypeScript types used all around the project, for instance, in @mycompany/types. As well as some microservices (like apis) export their local type definitions, in pure TypeScript too. We can't yet afford embedding typia as a dependency to every repo that imports shared TypeScript types to support "native tags", so our way-to-go solution seems to be using comment tags for now.

@samchon
Copy link
Owner Author

samchon commented Sep 28, 2023

Unfortunately, comment tags based custom validator and type tag based custom validator cannot be compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
No open projects
Development

No branches or pull requests

5 participants