Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Scalars generated as independent types #10233

Open
ThePlenkov opened this issue Jan 8, 2025 · 2 comments
Open

Scalars generated as independent types #10233

ThePlenkov opened this issue Jan 8, 2025 · 2 comments

Comments

@ThePlenkov
Copy link

Is your feature request related to a problem? Please describe.

I'm using code generator to generate SDK for certain predefined queries for a very large graphql schema ( Gitlab ).

For that purpose I'm using onlyOperationTypes: true however even in this case it generates all enums and all types as it's described in #10232 .

So I solved my problem by use of knip.dev tool which is if run like knip --fix --exports removing exports from unused types and then in combination with bundler it makes a perfect result only bundling used types to d.ts file

However there is still a problem.

Gitlab is using many different scalars ( like logical separation for different uids ). Because gcg creates Scalars like this:

/** All built-in and custom scalars, mapped to their actual values */
type Scalars = {
  ID: { input: string; output: string; }
  String: { input: string; output: string; }
  Boolean: { input: boolean; output: boolean; }
  Int: { input: number; output: number; }
  Float: { input: number; output: number; }
  /**
   * A `AbuseReportID` is a global ID. It is encoded as a string.
   *
   * An example `AbuseReportID` is: `"gid://gitlab/AbuseReport/1"`.
   */
  AbuseReportID: { input: string; output: string; }
  /**
   * A `AchievementsAchievementID` is a global ID. It is encoded as a string.
   *
   * An example `AchievementsAchievementID` is: `"gid://gitlab/Achievements::Achievement/1"`.
   */
  AchievementsAchievementID: { input: string; output: string; }
  /**
   * A `AchievementsUserAchievementID` is a global ID. It is encoded as a string.
   *
   * An example `AchievementsUserAchievementID` is: `"gid://gitlab/Achievements::UserAchievement/1"`.
   */
  AchievementsUserAchievementID: { input: string; output: string; }
  /**
   * A `AiAgentID` is a global ID. It is encoded as a string.
   *
   * An example `AiAgentID` is: `"gid://gitlab/Ai::Agent/1"`.
   */
  AiAgentID: { input: string; output: string; }
  /**
   * A `AiAgentVersionID` is a global ID. It is encoded as a string.
   *
   * An example `AiAgentVersionID` is: `"gid://gitlab/Ai::AgentVersion/1"`.
   * 
...

those types are exported as one single type and cannot be excluded separately.

Therefore I'd like to find the way how to export only those Scalar types which are required.

Describe the solution you'd like

Possible solution is to introduce an option like standaloneScalarTypes which can be prefixed like Scalar_ or may be even wrapped into Scalars namespace instead.

This would allow us to exclude not used scalar types and only export what is in real use. The size of the bundle will reduce significantly.

What do you think of this idea?

Describe alternatives you've considered

No response

Any additional important details?

No response

@eddeee888
Copy link
Collaborator

This is an interesting use case @ThePlenkov 👀

It's a big change to both codegen and all other plugins that rely on Scalars. Scalars is generated without custom naming convention applied to it i.e. all plugins assume it's always Scalars.

I'm not sure if one single use case justifies this change as there's ongoing maintenance, compatibility and other things we need to consider 😅

@ThePlenkov
Copy link
Author

ThePlenkov commented Jan 9, 2025

Well, i definetely understand what you mean. However I'd like to highlight here several points:

  • the proposal is not to replace, but extend this functionality with a new flag
  • may be for different existing scripts it's ok to keep Scalars ( so people who need it will be able to import, but in Scalars we can just reference to another newly generated type

So instead of

type Scalars = {
  AbuseReportID: { input: string; output: string; }

we can do something like:

// may be don't even need this namespace, Scalar name should be unique in schema as I undestand
namespace _Scalars {
  AbuseReportID: { input: string; output: string; }
}

type Scalars = {
  AbuseReportID: _Scalars.AbuseReportID
}

or even preferably just like this:

export type  AbuseReportID = { input: string; output: string; }

type Scalars = {
  AbuseReportID: _Scalars.AbuseReportID
}

export type AbuseReport {
 ID: AbuseReportID
}

This would make it still possible to access by index like we do now : Scalars['AbuseReportID']['input']

What is important to me is that we need to use in operation types/ fragments reference to standalone types, not Scalar type.

For this Gitlab example, even for 1 query my dts file size in lines is 1712 lines ( including comments ),
but removing unused scalars it takes only 68 lines , that's a difference

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants