Skip to content

Commit

Permalink
Add Support for @deprecated Markers
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Kim-Butler committed Nov 25, 2022
1 parent 1bc2b1b commit 9cc7529
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/graphql/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ impl<'a> TryFrom<UniqueFields<'a>> for Vec<Field> {
Ok(Field {
prop_name: alias.to_string(),
documentation: field.documentation.clone(),
deprecated: field.deprecated,
last_type_modifier: field.type_description.type_modifiers().1.clone(),
type_ir: get_type_ir_for_field(field, concrete, sub_traversal)?,
})
Expand Down Expand Up @@ -460,6 +461,7 @@ impl<'a> FieldTraversal<'a> {
pub struct Field {
pub prop_name: String,
pub documentation: schema::Documentation,
pub deprecated: bool,
pub last_type_modifier: schema_field::FieldTypeModifier,
pub type_ir: FieldType,
}
Expand Down
38 changes: 24 additions & 14 deletions src/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fn input_def_from_type(
let mut sorted = input_type.fields.iter().collect::<Vec<_>>();
sorted.sort_unstable_by_key(|item| item.0);
for (name, field) in sorted.into_iter() {
let doc = compile_documentation(&field.documentation, 2);
let doc = compile_documentation(&field.documentation, field.deprecated, 2);
let field_type = from_input_def_field_def(config, name, field)?;
let (_, last_type_mod) = field.type_description.type_modifiers();
let ts_field = match last_type_mod {
Expand Down Expand Up @@ -132,7 +132,7 @@ fn enum_def_from_type(
documentation: &schema::Documentation,
enum_type: &schema::EnumType,
) -> String {
let doc_comment = compile_documentation(documentation, 0);
let doc_comment = compile_documentation(documentation, false, 0);
let values = enum_type
.possible_values
.iter()
Expand Down Expand Up @@ -234,17 +234,27 @@ pub fn compile_globals(
})
}

fn compile_documentation(documentation: &schema::Documentation, tab_width: usize) -> Typescript {
documentation
.as_ref()
.map(|docs| {
let tab = " ".repeat(tab_width);
let processed_desc = docs
.replace('\n', &format!("\n {tab}* "))
.replace("*/", EMPTY);
format!("/**\n {tab}* {processed_desc}\n {tab}*/\n{tab}")
})
.unwrap_or_else(|| String::from(EMPTY))
fn compile_documentation(
documentation: &schema::Documentation,
deprecated: bool,
tab_width: usize,
) -> Typescript {
let tab = " ".repeat(tab_width);

let processed_documentation = documentation.as_deref().map(|docs| {
docs.replace('\n', &format!("\n {tab}* "))
.replace("/*", EMPTY)
.replace("*/", EMPTY)
});

let wrap = |content: &str| format!("/**\n {tab}* {content}\n {tab}*/\n{tab}");

match (processed_documentation.as_deref(), deprecated) {
(Some(docs), true) => wrap(&format!("{docs}\n {tab}* @deprecated")),
(Some(docs), false) => wrap(docs),
(None, true) => wrap("@deprecated"),
(None, false) => EMPTY.to_string(),
}
}

fn compile_custom_scalar_name(
Expand Down Expand Up @@ -414,7 +424,7 @@ fn type_definitions_from_complex_ir<'a>(
ir::FieldType::TypeName => format!("\"{}\"", complex_ir.name),
};
let prop_def_type = prop_type_def(&field_ir.last_type_modifier, flat_type_name);
let doc_comment = compile_documentation(&field_ir.documentation, 2);
let doc_comment = compile_documentation(&field_ir.documentation, field_ir.deprecated, 2);
prop_defs.push(format!(
" {doc_comment}{}: {prop_def_type};",
field_ir.prop_name,
Expand Down
76 changes: 76 additions & 0 deletions tests/typescript/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,79 @@ export type TestQuery = {
",
);
}

#[test]
fn compile_deprecated_field() {
let (mut cmd, temp_dir) = qlc_command_with_fake_dir_and_schema();
temp_dir
.child("file.graphql")
.write_str(
"
query Deprecated($orgId: ID!) {
viewer {
user {
tier
}
}
org: node(id: $orgId) {
... on Organization {
features
}
}
}
",
)
.unwrap();
cmd.assert().success();
assert_generated(
&temp_dir,
"Deprecated.ts",
r#"
import type { OrganizationAvailableFeatures, Tier } from "__generated__/globalTypes";
export type Deprecated_org_Organization = {
/**
* Features available for the organization to use (from LaunchDarkly)
* @deprecated
*/
features: (OrganizationAvailableFeatures | null)[] | null;
};
export type Deprecated_org_$$other = {
};
export type Deprecated_org = Deprecated_org_Organization | Deprecated_org_$$other;
export type Deprecated_viewer_user = {
/**
* @deprecated
*/
tier: Tier;
};
export type Deprecated_viewer = {
/**
* The user associated with the current viewer. Use this field to get info
* about current viewer and access any records associated w/ their account.
*/
user: Deprecated_viewer_user | null;
};
export type Deprecated = {
/**
* Fetches an object given its ID.
*/
org: Deprecated_org | null;
/**
* Access to fields relevant to a consumer of the application
*/
viewer: Deprecated_viewer | null;
};
export type DeprecatedVariables = {
orgId: string;
};
"#,
);
}

0 comments on commit 9cc7529

Please sign in to comment.