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

No-biscuit inflection; plus inflection traces #2245

Open
benjie opened this issue Nov 24, 2024 · 1 comment
Open

No-biscuit inflection; plus inflection traces #2245

benjie opened this issue Nov 24, 2024 · 1 comment

Comments

@benjie
Copy link
Member

benjie commented Nov 24, 2024

Overhaul inflection so that it deals with BakedString vs RawString. BakedString.append(...) etc. Prevent thing being cooked twice - no biscuits.

One of these options:

/**
 * TypeScript hack: use this for inflectors that shouldn't be further
 * inflected - i.e. they can be used as field, argument, type, etc names
 */
export type CookedString = string & { $$cooked: undefined };

class BakedString extends String {
  append(text: BakedString | string) {
    return new BakedString(String(this) + text);
  }
}

If we use BakedString then we can store properties onto it and give it methods for approved modification. One property can track where it came from (i.e. which inflector, and maybe even which version of the inflector e.g. if it came from a plugin). We could even trace all the RawStrings that were fed into that inflector and add those to the trace too, building a mermaid chart of how a particular string was derived. We'd need to then convert the BakedString back to a string in graphile-build before using it for a type name/field name/argument/etc - but this would also give us an opportunity to perform assertName and tell the user exactly where their error is coming from - we can also forbid field/arg names that haven't gone through inflection, encouraging the builtin inflector for lazy devs. (We could even trace that a particular field has come through a specific makeExtendSchemaPlugin, for example.)

Then we should make it so that camelCase/etc are never used directly - perhaps give them a __ prefix, they should only be used by inflectors like field(), type(), argument() which are used in non-prefixed inflectors. Inflectors that return RawString should have a _ prefix.

  /** Every GraphQL type should go through this inflector */
  type(this: GraphileBuild.Inflection, rawName: string): CookedString {
    return this.upperCamelCase(rawName) as CookedString;
  },

  /** Every GraphQL field (object, and interfaces) should go through this inflector */
  field(this: GraphileBuild.Inflection, fieldNameRaw: string): CookedString {
    return this.camelCase(fieldNameRaw) as CookedString;
  },

  /** Every GraphQL input field (input objects) should go through this inflector */
  inputField(
    this: GraphileBuild.Inflection,
    fieldNameRaw: string,
  ): CookedString {
    return this.field(fieldNameRaw);
  },

  /** Every GraphQL argument should go through this inflector */
  argument(this: GraphileBuild.Inflection, fieldNameRaw: string): CookedString {
    return this.inputField(fieldNameRaw);
  },
@benjie benjie added this to V6.0 Nov 24, 2024
@benjie benjie converted this from a draft issue Nov 24, 2024
@github-project-automation github-project-automation bot moved this to 🌳 Triage in V5.0.0 Nov 24, 2024
@benjie
Copy link
Member Author

benjie commented Nov 24, 2024

(This is scheduled for V6. I'd love to do it now, but we'll never release V5 at this rate...)

@benjie benjie removed this from V5.0.0 Nov 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

1 participant