Include TypeRepresentation in resolved scalar types (#1259)

<!-- The PR description should answer 2 important questions: -->

### What

To generate JSONAPI OpenAPI spec we need to know the underlying type
representation of custom types. This is (optionally) provided by a data
connector in it's `scalar_types` section. It's really annoying to look
up, so let's collect them all and store them on the
`ScalarTypeRepresentation`, keyed by `Qualified<DataConnectorName>`.

No functional change, this will be used in JSONAPI OpenAPI generation
shortly.

V3_GIT_ORIGIN_REV_ID: 084304a580aca977e1f8c39b16938205a49b1b0e
This commit is contained in:
Daniel Harvey 2024-10-22 17:13:15 +01:00 committed by hasura-bot
parent 8b956bfafa
commit 97f96bc62f
32 changed files with 339 additions and 71 deletions

View File

@ -273,7 +273,7 @@ pub(crate) fn resolve_value_expression_for_argument(
models: &IndexMap<Qualified<ModelName>, models_graphql::ModelWithGraphql>,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
) -> Result<ValueExpressionOrPredicate, Error> {
match value_expression {
@ -414,7 +414,10 @@ pub fn get_argument_kind(
TypeName::Custom(type_name) => {
let qualified_type_name = Qualified::new(subgraph.clone(), type_name.to_owned());
match get_type_representation::<type_permissions::ObjectTypesWithPermissions>(
match get_type_representation::<
type_permissions::ObjectTypesWithPermissions,
scalar_types::ScalarTypeRepresentation,
>(
&qualified_type_name,
&BTreeMap::new(),
&BTreeMap::new(),

View File

@ -1,6 +1,6 @@
use crate::stages::{
boolean_expressions, graphql_config, object_boolean_expressions, object_relationships,
scalar_boolean_expressions, scalar_types,
scalar_boolean_expressions,
};
use crate::types::error::Error;
@ -43,8 +43,8 @@ pub fn store_new_graphql_type(
#[derive(Debug)]
/// we do not want to store our types like this, but occasionally it is useful
/// for pattern matching
pub enum TypeRepresentation<'a, ObjectType> {
Scalar(&'a scalar_types::ScalarTypeRepresentation),
pub enum TypeRepresentation<'a, ObjectType, ScalarType> {
Scalar(&'a ScalarType),
Object(&'a ObjectType),
/// The old expression of boolean expression types
BooleanExpression(&'a object_boolean_expressions::ObjectBooleanExpressionType),
@ -56,16 +56,16 @@ pub enum TypeRepresentation<'a, ObjectType> {
/// validate whether a given CustomTypeName exists within `object_types`, `scalar_types` or
/// `object_boolean_expression_types`
pub fn get_type_representation<'a, ObjectType>(
pub fn get_type_representation<'a, ObjectType, ScalarType>(
custom_type_name: &Qualified<CustomTypeName>,
object_types: &'a BTreeMap<Qualified<CustomTypeName>, ObjectType>,
scalar_types: &'a BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
scalar_types: &'a BTreeMap<Qualified<CustomTypeName>, ScalarType>,
object_boolean_expression_types: &'a BTreeMap<
Qualified<CustomTypeName>,
object_boolean_expressions::ObjectBooleanExpressionType,
>,
boolean_expression_types: &'a boolean_expressions::BooleanExpressionTypes,
) -> Result<TypeRepresentation<'a, ObjectType>, Error> {
) -> Result<TypeRepresentation<'a, ObjectType, ScalarType>, Error> {
object_types
.get(custom_type_name)
.map(|object_type_representation| TypeRepresentation::Object(object_type_representation))

View File

@ -64,7 +64,7 @@ pub use stages::order_by_expressions::{
};
pub use stages::plugins::LifecyclePluginConfigs;
pub use stages::scalar_boolean_expressions::ResolvedScalarBooleanExpressionType;
pub use stages::scalar_types::ScalarTypeRepresentation;
pub use stages::scalar_type_representations::ScalarTypeRepresentation;
pub use stages::type_permissions::{FieldPresetInfo, TypeInputPermission};
pub use stages::{
command_permissions::CommandWithPermissions,

View File

@ -8,10 +8,7 @@ use open_dds::types::{CustomTypeName, TypeName};
use crate::helpers::check_for_duplicates;
use crate::helpers::types::{store_new_graphql_type, unwrap_qualified_type_name};
use crate::stages::{
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap, graphql_config, scalar_types,
type_permissions,
};
use crate::stages::{data_connector_scalar_types, graphql_config, scalar_types, type_permissions};
use crate::types::subgraph::{mk_qualified_type_name, mk_qualified_type_reference};
use crate::{mk_name, Qualified, QualifiedBaseType, QualifiedTypeName, QualifiedTypeReference};
@ -25,7 +22,7 @@ pub fn resolve(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &type_permissions::ObjectTypesWithPermissions,
scalar_types: &BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
@ -84,7 +81,7 @@ fn resolve_aggregate_expression(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &type_permissions::ObjectTypesWithPermissions,
scalar_types: &BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
@ -283,7 +280,7 @@ fn resolve_scalar_operand(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &type_permissions::ObjectTypesWithPermissions,
scalar_types: &BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
@ -358,7 +355,7 @@ fn resolve_aggregation_function(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
) -> Result<AggregationFunctionInfo, AggregateExpressionError> {
let return_type = mk_qualified_type_reference(
@ -420,7 +417,7 @@ fn resolve_aggregation_function(
})?;
// Check that the data connector operand scalar type actually exists on the data connector
let data_connector_scalar_type = scalars.0.get(&data_connector_fn_mappings.data_connector_scalar_type)
let data_connector_scalar_type = scalars.by_ndc_type.get(&data_connector_fn_mappings.data_connector_scalar_type)
.ok_or_else(||
AggregateExpressionError::AggregateOperandDataConnectorFunctionUnknownScalarType {
name: aggregate_expression_name.clone(),
@ -473,7 +470,7 @@ fn check_aggregation_function_return_type(
aggregate_expression_name: &Qualified<AggregateExpressionName>,
aggregation_function_name: &AggregationFunctionName,
data_connector_name: &Qualified<DataConnectorName>,
data_connector_scalars: &ScalarTypeWithRepresentationInfoMap,
data_connector_scalars: &data_connector_scalar_types::DataConnectorScalars,
scalar_types: &BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
object_types: &type_permissions::ObjectTypesWithPermissions,
) -> Result<(), AggregateExpressionError> {
@ -497,7 +494,7 @@ fn check_aggregation_function_return_type(
)?;
let validate_scalar_representation = || -> Result<(), AggregateExpressionError> {
let type_name = data_connector_scalars.0.get(ndc_named_return_type.as_str())
let type_name = data_connector_scalars.by_ndc_type.get(ndc_named_return_type.as_str())
.ok_or_else(||
mk_error(format!("The data connector's return type ({ndc_named_return_type}) isn't a scalar type").as_str())
)?

View File

@ -55,7 +55,7 @@ pub fn resolve_command_permissions(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
subgraph: &SubgraphName,
) -> Result<BTreeMap<Role, CommandPermission>, Error> {

View File

@ -35,7 +35,7 @@ pub fn resolve(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
) -> Result<IndexMap<Qualified<CommandName>, CommandWithPermissions>, Error> {
let mut commands_with_permissions: IndexMap<Qualified<CommandName>, CommandWithPermissions> =

View File

@ -4,8 +4,8 @@ pub use error::DataConnectorScalarTypesError;
use open_dds::identifier::SubgraphName;
use std::collections::{BTreeMap, BTreeSet};
pub use types::{
ComparisonOperators, DataConnectorWithScalarsOutput, ScalarTypeWithRepresentationInfo,
ScalarTypeWithRepresentationInfoMap,
ComparisonOperators, DataConnectorScalars, DataConnectorWithScalarsOutput,
ScalarTypeWithRepresentationInfo,
};
use lang_graphql::ast::common as ast;
@ -54,15 +54,15 @@ pub fn resolve<'a>(
data_connector: qualified_data_connector_name.clone(),
})?;
let scalar_type = scalars
.0
let scalar_type_by_ndc_type = scalars
.by_ndc_type
.get_mut(&scalar_type_representation.data_connector_scalar_type)
.ok_or_else(|| scalar_boolean_expressions::ScalarBooleanExpressionTypeError::UnknownScalarTypeInDataConnector {
scalar_type: scalar_type_name.clone(),
data_connector: qualified_data_connector_name.clone(),
})?;
if scalar_type.representation.is_none() {
if scalar_type_by_ndc_type.representation.is_none() {
validate_type_name(
&scalar_type_representation.representation,
subgraph,
@ -70,7 +70,35 @@ pub fn resolve<'a>(
scalar_type_name,
)?;
scalar_type.representation = Some(scalar_type_representation.representation.clone());
scalar_type_by_ndc_type.representation =
Some(scalar_type_representation.representation.clone());
// if this is a custom scalar type,
// record the TypeRepresentation for it (ie, `String`, `JSON`, etc)
if let TypeName::Custom(custom_type_name) = &scalar_type_representation.representation {
let data_connector_context = data_connectors
.0
.get(&qualified_data_connector_name)
.unwrap();
let ndc_scalar_name = ndc_models::ScalarTypeName::new(ndc_models::TypeName::new(
scalar_type_representation
.data_connector_scalar_type
.clone()
.into(),
));
let ndc_scalar_type = data_connector_context
.schema
.scalar_types
.get(&ndc_scalar_name)
.unwrap();
scalars.by_custom_type_name.insert(
Qualified::new(subgraph.clone(), custom_type_name.clone()),
ndc_scalar_type.representation.clone(),
);
}
} else {
return Err(
DataConnectorScalarTypesError::DuplicateDataConnectorScalarRepresentation {
@ -79,13 +107,14 @@ pub fn resolve<'a>(
},
);
}
scalar_type.comparison_expression_name = match scalar_type_representation.graphql.as_ref() {
None => Ok(None),
Some(graphql) => match &graphql.comparison_expression_type_name {
scalar_type_by_ndc_type.comparison_expression_name =
match scalar_type_representation.graphql.as_ref() {
None => Ok(None),
Some(type_name) => mk_name(type_name.as_ref()).map(ast::TypeName).map(Some),
},
}?;
Some(graphql) => match &graphql.comparison_expression_type_name {
None => Ok(None),
Some(type_name) => mk_name(type_name.as_ref()).map(ast::TypeName).map(Some),
},
}?;
// We are allowing conflicting graphql types for scalar comparison expressions, but we still want the typename
// to not conflict with other graphql type names
@ -93,7 +122,7 @@ pub fn resolve<'a>(
// TODO: This means that comparison expression names conflicting with already encountered graphql type names
// will pass through. They'll eventually be caught during schema generation but only if the expression was
// reachable in the graphql API. Ideally, we should just fail the build here.
if let Some(new_graphql_type) = &scalar_type.comparison_expression_name {
if let Some(new_graphql_type) = &scalar_type_by_ndc_type.comparison_expression_name {
graphql_types.insert(new_graphql_type.clone());
};
}
@ -128,15 +157,15 @@ fn validate_type_name(
// convert from types in previous stage to this stage
fn convert_data_connectors_contexts<'a>(
old_data_connectors: &'a data_connectors::DataConnectors<'a>,
) -> BTreeMap<Qualified<DataConnectorName>, ScalarTypeWithRepresentationInfoMap<'a>> {
) -> BTreeMap<Qualified<DataConnectorName>, DataConnectorScalars<'a>> {
let mut data_connector_scalars = BTreeMap::new();
for (data_connector_name, context) in &old_data_connectors.0 {
let mut new_scalars = BTreeMap::new();
let mut by_ndc_type = BTreeMap::new();
for (name, scalar) in &context.schema.scalar_types {
let scalar_name = DataConnectorScalarType::from(name.as_str());
new_scalars.insert(
scalar_name.clone(),
let ndc_scalar_type_name = DataConnectorScalarType::from(name.as_str());
by_ndc_type.insert(
ndc_scalar_type_name.clone(),
ScalarTypeWithRepresentationInfo {
scalar_type: scalar,
comparison_expression_name: None,
@ -149,7 +178,10 @@ fn convert_data_connectors_contexts<'a>(
data_connector_scalars.insert(
data_connector_name.clone(),
ScalarTypeWithRepresentationInfoMap(new_scalars),
DataConnectorScalars {
by_ndc_type,
by_custom_type_name: BTreeMap::new(),
},
);
}
data_connector_scalars
@ -190,10 +222,10 @@ pub(crate) fn get_comparison_operators(
// helper function to determine whether a ndc type is a simple scalar
pub fn get_simple_scalar<'a>(
t: ndc_models::Type,
scalars: &'a ScalarTypeWithRepresentationInfoMap<'a>,
scalars: &'a DataConnectorScalars<'a>,
) -> Option<&'a ScalarTypeWithRepresentationInfo<'a>> {
match t {
ndc_models::Type::Named { name } => scalars.0.get(name.as_str()),
ndc_models::Type::Named { name } => scalars.by_ndc_type.get(name.as_str()),
ndc_models::Type::Nullable { underlying_type } => {
get_simple_scalar(*underlying_type, scalars)
}

View File

@ -4,13 +4,12 @@ use ndc_models;
use open_dds::data_connector::{
DataConnectorName, DataConnectorOperatorName, DataConnectorScalarType,
};
use open_dds::types::TypeName;
use open_dds::types::{CustomTypeName, TypeName};
use std::collections::BTreeMap;
use std::collections::BTreeSet;
pub struct DataConnectorWithScalarsOutput<'a> {
pub data_connector_scalars:
BTreeMap<Qualified<DataConnectorName>, ScalarTypeWithRepresentationInfoMap<'a>>,
pub data_connector_scalars: BTreeMap<Qualified<DataConnectorName>, DataConnectorScalars<'a>>,
pub graphql_types: BTreeSet<ast::TypeName>,
}
@ -26,9 +25,11 @@ pub struct ScalarTypeWithRepresentationInfo<'a> {
}
#[derive(Debug)]
pub struct ScalarTypeWithRepresentationInfoMap<'a>(
pub BTreeMap<DataConnectorScalarType, ScalarTypeWithRepresentationInfo<'a>>,
);
pub struct DataConnectorScalars<'a> {
pub by_ndc_type: BTreeMap<DataConnectorScalarType, ScalarTypeWithRepresentationInfo<'a>>,
pub by_custom_type_name:
BTreeMap<Qualified<CustomTypeName>, Option<ndc_models::TypeRepresentation>>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
pub struct ComparisonOperators {

View File

@ -27,6 +27,7 @@ mod types;
use crate::types::warning::Warning;
use open_dds::flags;
pub use types::Metadata;
pub mod scalar_type_representations;
use crate::types::configuration::Configuration;
use crate::types::error::{Error, SeparatedBy, ShouldBeAnError, WithContext};
@ -316,13 +317,17 @@ pub fn resolve(
&commands_with_permissions,
);
// include data connector information for each scalar type
let scalar_types_with_representations =
scalar_type_representations::resolve(&data_connector_scalars, &scalar_types);
let plugin_configs = plugins::resolve(&metadata_accessor);
let all_warnings = warnings_as_errors_by_compatibility(&metadata_accessor.flags, all_issues)?;
Ok((
Metadata {
scalar_types,
scalar_types: scalar_types_with_representations,
object_types: object_types_with_relationships,
models,
commands,

View File

@ -23,7 +23,7 @@ pub fn resolve(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &BTreeMap<
Qualified<CustomTypeName>,

View File

@ -41,7 +41,7 @@ fn resolve_model_predicate_with_model(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
fields: &IndexMap<FieldName, object_types::FieldDefinition>,
object_types: &BTreeMap<
@ -146,7 +146,7 @@ pub fn resolve_model_select_permissions(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &BTreeMap<
Qualified<CustomTypeName>,
@ -282,7 +282,7 @@ pub(crate) fn resolve_model_predicate_with_type(
data_connector_field_mappings: &BTreeMap<FieldName, object_types::FieldMapping>,
data_connector_link: &data_connectors::DataConnectorLink,
subgraph: &SubgraphName,
scalars: &data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
scalars: &data_connector_scalar_types::DataConnectorScalars,
object_types: &BTreeMap<
Qualified<CustomTypeName>,
object_relationships::ObjectTypeWithRelationships,
@ -811,7 +811,7 @@ fn resolve_binary_operator_for_type<'a>(
data_connector: &'a Qualified<DataConnectorName>,
field_name: &'a FieldName,
fields: &'a IndexMap<FieldName, object_types::FieldDefinition>,
scalars: &'a data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
scalars: &'a data_connector_scalar_types::DataConnectorScalars,
ndc_scalar_type: &'a ndc_models::ScalarType,
subgraph: &'a SubgraphName,
) -> Result<(DataConnectorOperatorName, QualifiedTypeReference), Error> {

View File

@ -19,7 +19,7 @@ pub fn get_ndc_column_for_comparison<F: Fn() -> String>(
field: &FieldName,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
comparison_location: F,
) -> Result<NdcColumnForComparison, ModelsError> {

View File

@ -45,7 +45,7 @@ pub fn resolve(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
mut global_id_enabled_types: BTreeMap<Qualified<CustomTypeName>, Vec<Qualified<ModelName>>>,
mut apollo_federation_entity_enabled_types: BTreeMap<

View File

@ -31,7 +31,7 @@ pub(crate) fn resolve_model_source(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &type_permissions::ObjectTypesWithPermissions,
scalar_types: &BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,

View File

@ -30,7 +30,7 @@ pub(crate) fn resolve_model_graphql_api(
existing_graphql_types: &mut BTreeSet<ast::TypeName>,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
model_description: &Option<String>,
aggregate_expression_name: &Option<Qualified<AggregateExpressionName>>,

View File

@ -31,7 +31,7 @@ pub fn resolve(
models: &IndexMap<Qualified<ModelName>, models::Model>,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &BTreeMap<
Qualified<CustomTypeName>,

View File

@ -14,12 +14,12 @@ use open_dds::identifier::SubgraphName;
pub fn resolve_ndc_type(
data_connector: &Qualified<DataConnectorName>,
source_type: &ndc_models::Type,
scalars: &data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
scalars: &data_connector_scalar_types::DataConnectorScalars,
subgraph: &SubgraphName,
) -> Result<QualifiedTypeReference, scalar_boolean_expressions::ScalarBooleanExpressionTypeError> {
match source_type {
ndc_models::Type::Named { name } => {
let scalar_type = scalars.0.get(name.as_str()).ok_or(
let scalar_type = scalars.by_ndc_type.get(name.as_str()).ok_or(
scalar_boolean_expressions::ScalarBooleanExpressionTypeError::UnknownScalarTypeInDataConnector {
data_connector: data_connector.clone(),
scalar_type: DataConnectorScalarType::from(name.as_str()),

View File

@ -25,7 +25,7 @@ pub fn resolve(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &type_permissions::ObjectTypesWithPermissions,
mut graphql_types: BTreeSet<ast::TypeName>,
@ -83,7 +83,7 @@ pub(crate) fn resolve_object_boolean_expression_type(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
object_types: &type_permissions::ObjectTypesWithPermissions,
existing_graphql_types: &mut BTreeSet<ast::TypeName>,
@ -263,7 +263,7 @@ pub fn resolve_boolean_expression_graphql_config(
data_connector_name: &Qualified<open_dds::data_connector::DataConnectorName>,
where_type_name: ast::TypeName,
subgraph: &SubgraphName,
scalars: &data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
scalars: &data_connector_scalar_types::DataConnectorScalars,
type_mappings: &object_types::TypeMapping,
graphql_config: &graphql_config::GraphqlConfig,
fields: &IndexMap<open_dds::types::FieldName, object_types::FieldDefinition>,

View File

@ -36,7 +36,7 @@ pub fn resolve(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
models: &IndexMap<Qualified<ModelName>, models::Model>,
commands: &IndexMap<Qualified<CommandName>, commands::Command>,
@ -193,7 +193,7 @@ fn resolve_relationship_mappings_model(
target_model: &models::Model,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
) -> Result<Vec<RelationshipModelMapping>, Error> {
let mut resolved_relationship_mappings = Vec::new();
@ -548,7 +548,7 @@ fn resolve_model_relationship_fields(
source_type: &object_types::ObjectTypeRepresentation,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
aggregate_expressions: &BTreeMap<
Qualified<AggregateExpressionName>,
@ -701,7 +701,7 @@ fn resolve_relationship_fields(
data_connectors: &data_connectors::DataConnectors,
data_connector_scalars: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::ScalarTypeWithRepresentationInfoMap,
data_connector_scalar_types::DataConnectorScalars,
>,
aggregate_expressions: &BTreeMap<
Qualified<AggregateExpressionName>,

View File

@ -0,0 +1,42 @@
use crate::stages::{data_connector_scalar_types, scalar_types};
use crate::Qualified;
use open_dds::{data_connector::DataConnectorName, types::CustomTypeName};
use std::collections::BTreeMap;
mod types;
pub use types::{ScalarTypeRepresentation, ValueRepresentation};
/// include data connector type representations for each scalar type
pub fn resolve(
data_connector_scalar_types: &BTreeMap<
Qualified<DataConnectorName>,
data_connector_scalar_types::DataConnectorScalars,
>,
scalar_types: &BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
) -> BTreeMap<Qualified<CustomTypeName>, ScalarTypeRepresentation> {
let mut new_scalar_types = BTreeMap::new();
for (scalar_type_name, scalar_type) in scalar_types {
let mut representations = BTreeMap::new();
// grab information about this scalar from each data connector
for (data_connector_name, data_connector_scalars) in data_connector_scalar_types {
if let Some(data_connector_representation) = data_connector_scalars
.by_custom_type_name
.get(scalar_type_name)
{
let scalar_type_representation = match data_connector_representation {
Some(rep) => ValueRepresentation::FromDataConnectorSchema(rep.clone()),
None => ValueRepresentation::AssumeJson,
};
representations.insert(data_connector_name.clone(), scalar_type_representation);
}
}
new_scalar_types.insert(
scalar_type_name.clone(),
ScalarTypeRepresentation {
graphql_type_name: scalar_type.graphql_type_name.clone(),
description: scalar_type.description.clone(),
representations,
},
);
}
new_scalar_types
}

View File

@ -0,0 +1,24 @@
use crate::{deserialize_non_string_key_btreemap, serialize_non_string_key_btreemap, Qualified};
use lang_graphql::ast::common as ast;
use open_dds::data_connector::DataConnectorName;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
// what type should we advertise for this value? useful for generating schema for
// JSONAPI and SQL frontends
pub enum ValueRepresentation {
FromDataConnectorSchema(ndc_models::TypeRepresentation),
AssumeJson,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct ScalarTypeRepresentation {
pub graphql_type_name: Option<ast::TypeName>,
pub description: Option<String>,
#[serde(
serialize_with = "serialize_non_string_key_btreemap",
deserialize_with = "deserialize_non_string_key_btreemap"
)]
pub representations: BTreeMap<Qualified<DataConnectorName>, ValueRepresentation>,
}

View File

@ -14,7 +14,7 @@ use crate::types::subgraph::Qualified;
use crate::stages::{
aggregates, argument_presets, boolean_expressions, graphql_config, object_boolean_expressions,
object_relationships, order_by_expressions, scalar_types,
object_relationships, order_by_expressions, scalar_type_representations,
};
use super::plugins::LifecyclePluginConfigs;
@ -27,7 +27,8 @@ pub struct Metadata {
pub object_types:
BTreeMap<Qualified<CustomTypeName>, object_relationships::ObjectTypeWithRelationships>,
#[serde_as(as = "Vec<(_, _)>")]
pub scalar_types: BTreeMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
pub scalar_types:
BTreeMap<Qualified<CustomTypeName>, scalar_type_representations::ScalarTypeRepresentation>,
#[serde_as(as = "Vec<(_, _)>")]
pub models: IndexMap<Qualified<ModelName>, argument_presets::ModelWithArgumentPresets>,
#[serde_as(as = "Vec<(_, _)>")]

View File

@ -299,6 +299,7 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/missing_
),
),
description: None,
representations: {},
},
},
models: {},

View File

@ -985,6 +985,20 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/missing_
),
),
description: None,
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"mypg",
),
),
}: FromDataConnectorSchema(
Int32,
),
},
},
Qualified {
subgraph: SubgraphName(
@ -1004,6 +1018,18 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/missing_
),
),
description: None,
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"mypg",
),
),
}: AssumeJson,
},
},
},
models: {

View File

@ -1637,6 +1637,20 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/relation
),
),
description: None,
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"mypg",
),
),
}: FromDataConnectorSchema(
Int32,
),
},
},
Qualified {
subgraph: SubgraphName(
@ -1656,6 +1670,18 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/relation
),
),
description: None,
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"mypg",
),
),
}: AssumeJson,
},
},
},
models: {

View File

@ -985,6 +985,20 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/root_fie
),
),
description: None,
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"mypg",
),
),
}: FromDataConnectorSchema(
Int32,
),
},
},
Qualified {
subgraph: SubgraphName(
@ -1004,6 +1018,18 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/root_fie
),
),
description: None,
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"mypg",
),
),
}: AssumeJson,
},
},
},
models: {

View File

@ -27,6 +27,20 @@ input_file: crates/metadata-resolve/tests/passing/commands/functions/all_args_ar
description: Some(
"Headers map",
),
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"myconnector",
),
),
}: FromDataConnectorSchema(
JSON,
),
},
},
},
models: {},

View File

@ -27,6 +27,20 @@ input_file: crates/metadata-resolve/tests/passing/commands/functions/issue_when_
description: Some(
"Headers map",
),
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"myconnector",
),
),
}: FromDataConnectorSchema(
JSON,
),
},
},
},
models: {},

View File

@ -27,6 +27,20 @@ input_file: crates/metadata-resolve/tests/passing/commands/procedures/all_args_a
description: Some(
"Headers map",
),
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"myconnector",
),
),
}: FromDataConnectorSchema(
JSON,
),
},
},
},
models: {},

View File

@ -27,6 +27,20 @@ input_file: crates/metadata-resolve/tests/passing/commands/procedures/issue_when
description: Some(
"Headers map",
),
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"myconnector",
),
),
}: FromDataConnectorSchema(
JSON,
),
},
},
},
models: {},

View File

@ -126,6 +126,20 @@ input_file: crates/metadata-resolve/tests/passing/models/all_args_are_set_includ
description: Some(
"Headers map",
),
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"myconnector",
),
),
}: FromDataConnectorSchema(
JSON,
),
},
},
},
models: {

View File

@ -126,6 +126,20 @@ input_file: crates/metadata-resolve/tests/passing/models/issue_when_not_all_argu
description: Some(
"Headers map",
),
representations: {
Qualified {
subgraph: SubgraphName(
"default",
),
name: DataConnectorName(
Identifier(
"myconnector",
),
),
}: FromDataConnectorSchema(
JSON,
),
},
},
},
models: {