-
Notifications
You must be signed in to change notification settings - Fork 560
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
feat: add custom enum support in Engine API & TypeScript SDK #7498
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
sdk/typescript/entrypoint/load.ts
Outdated
if (dag[`load${enumType}FromID`]) { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
return dag[`load${enumType}FromID`](value) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since Enum are not loadable, I should remove this part, and potentielly just return the value, since it should have been validated by the engine first!
9ee6329
to
e697091
Compare
I need to write some tests but the PRs is ready for a review |
...n-plugin/src/main/resources/schemas/schema-dev-1720da5a9ffe2d9ca485e0d005265f25d974fda1.json
Outdated
Show resolved
Hide resolved
core/integration/module_test.go
Outdated
/** | ||
* Enum for Status | ||
*/ | ||
@daggerEnum() | ||
class Status { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: why this syntax instead of typescript's builtin enum type? https://www.typescriptlang.org/docs/handbook/enums.html#string-enums
I think we should stick to the language semantics if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Due to TypeScript flexibility, it's pretty tricky to implement it in another way, so I tried to create a syntax close to what we could do in Golang.
The fact that we cannot declare decorators on top of enum is also a limitation.
I'm thinking about a workaround but I think this type of implementation is the cleanest we could get in Typescript.
As explained in my PR's summary.
I cannot implement
@daggerEnum()
enum Status {
ACTIVE = "ACTIVE"
// ...
}
Because it's not possible to add a decorator to a TS type or enum, so how can a user explicitely declare the enum must be exposed or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a decorator here? Can we not take the same approach as in go, where we create typedefs for every referenced type - e.g. so if a function accepts/returns an enum, then we automatically codegen for it.
Maybe that's less inline with the rest of the typescript SDK, and makes for more complications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean I wish it worked like that, but I need to refactor a lot of the Typescript internal introspection logic to do so.
Should I work on that? However I would still need decorators to define aliases for example (but I guess we don't want that on enumerations)
Also with Helder we aggreed that explicit declaration is better than implicit, I could add a special case for enum but I don't know, I'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think not being able to use a decorator in an enum shouldn't be an argument against using enum
if that's the most natural thing. That said, I remember a user saying they didn't like TypeScript's enums, but I don't know why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, part of me thinks @function
is the only one we could need. Both for class methods and properties. In Python however, @object
does change the class, unlike TypeScript. If not that, users would need @dataclass
anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should stick to the language semantics if possible.
I strongly agree with this. That being said, enums in typescript can act fairly weirdly. The general way, that at least I use, is to just use a type literal as its more natural in Typescript. But that ends up with the same issue of not being able to add a decorator.
That said, I remember a user saying they didn't like TypeScript's enums, but I don't know why.
I left it on a comment in a PR, I'll try to find it.
Also with Helder we aggreed that explicit declaration is better than implicit, I could add a special case for enum but I don't know, I'm not sure.
The explicit declaration is a little cumbersome in Typescript, as it generally adds a bunch of boiler plate, especially for things like this enum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here was my original comment on enums.
#7401 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said, not being able to use a decorator shouldn't be an argument against using something else that is more natural. The problem with a type of string literals really is how do you add descriptions to the values?
ec3f36c
to
265adea
Compare
Quick update! I finally found a way to fix the issue with interfaces but it's pretty hacky so I'm trying to find a better way. It's basically an issue in A quick fix is to rollback the change for |
a38251a
to
1d68768
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments on the engine implementation, will also start looking at how to do enums in go.
1d68768
to
b41b881
Compare
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Two parts here: - Core enums are registered as scalars, so look them up as scalars - Enums can be converted to each other :) For example, when passing a dynamic module enum into a static core enum. Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Base class isn't required, just a convenience. Users can make their own enums, but descriptions will only be used if there's a "description" attribute in members. Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
Signed-off-by: Tom Chauveau <tom@epitech.eu>
3c8cb4f
to
94e1c51
Compare
This PR implements custom enum support from a user module and the TypeScript support for it.
Current state
Enum
TypeDef GraphQL schema extensionEnum
registration using the GQL APIEnumTypeDef
supportENUM_KIND
toTypeDef
💡 There's maybe something wrong in my implementation but it works!
Changes
To make that possible, I needed to add a
DynamicEnumValue
to register dynamic enum in the GraphQL server since the current implementation is static (because of usage of generic)Also extends the GraphQL schema based on @helderco comments
Note that only
string
value is supported for nowExample for TypeScript
💡 Due to TypeScript flexibility, it's pretty tricky to implement it in another way, so I tried to create a syntax close to what we could do in Golang.
The fact that we cannot declare decorators on top of
enum
is also a limitation.I'm thinking about a workaround but I think this type of implementation is the cleanest we could get in Typescript.
Examples of commands:
I think the input part should be handle in the CLI, with possible values displayed, so we can catch the error sooner (/cc @helderco)
Additional changes
This PR also include some improvement on the TypeScript SDK.
typedef
in abstract module definition in favor of directly calling the method.This avoid duplicated function call and simplify the overall code, there's no more 2 concepts of typedef inside the TS
internals.
typeToTypedef
intoabstraction
directory since it was the only place it was used.toPascalCase
intomodule
since it was only used there.utils.ts
(I've never been a fan of this file tbh).module.modTypeFor
to be more readable and flexible.Fixes #6780
Fixes OSS-141