Skip to content

Commit 6fdfdfa

Browse files
committed
fix(graphql-codegen-client-preset): support namingConvention object and keep mode (#593)
1 parent 6b0b6be commit 6fdfdfa

2 files changed

Lines changed: 83 additions & 4 deletions

File tree

contrib/graphql-codegen-client-preset/src/lib.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,12 @@ fn to_pascal_case(s: &str) -> String {
8383

8484
fn apply_naming_convention(s: &str, naming_convention: &str) -> String {
8585
match naming_convention {
86+
"change-case-all#pascalCase" => to_pascal_case(s),
8687
"change-case-all#upperCaseFirst" => upper_case_first(s),
87-
_ => to_pascal_case(s),
88+
// GraphQL Codegen supports `keep`; preserve casing in that mode.
89+
"keep" => s.to_string(),
90+
// Keep unknown/custom conventions unchanged instead of forcing PascalCase.
91+
_ => s.to_string(),
8892
}
8993
}
9094

@@ -340,6 +344,30 @@ fn naming_convention_default() -> String {
340344
"change-case-all#pascalCase".to_string()
341345
}
342346

347+
#[derive(Deserialize)]
348+
#[serde(untagged)]
349+
enum NamingConventionOption {
350+
String(String),
351+
Object(serde_json::Value),
352+
}
353+
354+
impl NamingConventionOption {
355+
fn as_type_name_convention(&self) -> String {
356+
match self {
357+
NamingConventionOption::String(v) => v.to_string(),
358+
NamingConventionOption::Object(v) => v
359+
.get("typeNames")
360+
.and_then(|t| t.as_str())
361+
.map(str::to_string)
362+
.unwrap_or_else(naming_convention_default),
363+
}
364+
}
365+
}
366+
367+
fn naming_convention_option_default() -> NamingConventionOption {
368+
NamingConventionOption::String(naming_convention_default())
369+
}
370+
343371
#[allow(non_snake_case)]
344372
#[derive(Deserialize)]
345373
struct PluginOptions {
@@ -348,8 +376,8 @@ struct PluginOptions {
348376
#[serde(default = "gql_default")]
349377
gqlTagName: String,
350378

351-
#[serde(default = "naming_convention_default")]
352-
namingConvention: String,
379+
#[serde(default = "naming_convention_option_default")]
380+
namingConvention: NamingConventionOption,
353381
}
354382

355383
#[plugin_transform]
@@ -380,7 +408,7 @@ pub fn process_transform(program: Program, metadata: TransformPluginProgramMetad
380408
cwd,
381409
artifact_directory,
382410
gql_tag_name: plugin_config.gqlTagName,
383-
naming_convention: plugin_config.namingConvention,
411+
naming_convention: plugin_config.namingConvention.as_type_name_convention(),
384412
});
385413

386414
program.apply(&mut visit_mut_pass(visitor))

contrib/graphql-codegen-client-preset/src/tests.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,54 @@ const SomeEGRockets = gql(`
210210
}
211211
`);"#
212212
);
213+
214+
#[test]
215+
fn naming_convention_keep_preserves_original_name() {
216+
assert_eq!(
217+
apply_naming_convention("SomeEGRocketsDocument", "keep"),
218+
"SomeEGRocketsDocument"
219+
);
220+
}
221+
222+
#[test]
223+
fn naming_convention_unknown_preserves_original_name() {
224+
assert_eq!(
225+
apply_naming_convention("SomeEGRocketsDocument", "lodash#camelCase"),
226+
"SomeEGRocketsDocument"
227+
);
228+
}
229+
230+
#[test]
231+
fn plugin_options_accept_object_naming_convention() {
232+
let options: PluginOptions = serde_json::from_str(
233+
r#"{
234+
"artifactDirectory":"./src/gql",
235+
"namingConvention":{
236+
"typeNames":"keep",
237+
"enumValues":"change-case-all#upperCaseFirst",
238+
"transformUnderscore":true
239+
}
240+
}"#,
241+
)
242+
.unwrap();
243+
244+
assert_eq!(options.namingConvention.as_type_name_convention(), "keep");
245+
}
246+
247+
#[test]
248+
fn plugin_options_object_without_type_names_uses_default_naming_convention() {
249+
let options: PluginOptions = serde_json::from_str(
250+
r#"{
251+
"artifactDirectory":"./src/gql",
252+
"namingConvention":{
253+
"enumValues":"keep"
254+
}
255+
}"#,
256+
)
257+
.unwrap();
258+
259+
assert_eq!(
260+
options.namingConvention.as_type_name_convention(),
261+
"change-case-all#pascalCase"
262+
);
263+
}

0 commit comments

Comments
 (0)