From 3a30e0fc57174b2d9ca81720bb06cfdea58e1bc7 Mon Sep 17 00:00:00 2001 From: Josh Wilson Date: Mon, 20 Jul 2026 15:02:49 -0500 Subject: [PATCH] Centralize JSON scalar initialization --- .../schema_definition/factory_extension.rb | 29 ++-------------- .../schema_elements/scalar_type_extension.rb | 33 ++++++++++++++++--- .../schema_definition/factory_extension.rbs | 2 -- .../schema_elements/scalar_type_extension.rbs | 4 ++- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/factory_extension.rb b/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/factory_extension.rb index 3302afb55..50eca3062 100644 --- a/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/factory_extension.rb +++ b/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/factory_extension.rb @@ -6,13 +6,11 @@ # # frozen_string_literal: true -require "elastic_graph/constants" require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/enum" require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/object" require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/scalar" require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/union" require "elastic_graph/json_ingestion/schema_definition/indexing/index_extension" -require "elastic_graph/graphql/scalar_coercion_adapters/valid_time_zones" require "elastic_graph/json_ingestion/schema_definition/results_extension" require "elastic_graph/json_ingestion/schema_definition/schema_artifact_manager_extension" require "elastic_graph/json_ingestion/schema_definition/schema_elements/enum_type_extension" @@ -28,26 +26,6 @@ module SchemaDefinition # # @api private module FactoryExtension - # Default JSON schema options applied to ElasticGraph's built-in scalar types as they - # are constructed. Keyed by the un-overridden type name, because built-in type - # registration always uses the canonical type name before `type_name_overrides` are - # applied to the resulting type reference. - BUILT_IN_SCALAR_JSON_SCHEMA_OPTIONS_BY_NAME = { - "Boolean" => {type: "boolean"}, - "Float" => {type: "number"}, - "ID" => {type: "string"}, - "Int" => {type: "integer", minimum: INT_MIN, maximum: INT_MAX}, - "String" => {type: "string"}, - "Cursor" => {type: "string"}, - "Date" => {type: "string", format: "date"}, - "DateTime" => {type: "string", format: "date-time"}, - "LocalTime" => {type: "string", pattern: VALID_LOCAL_TIME_JSON_SCHEMA_PATTERN}, - "TimeZone" => {type: "string", enum: GraphQL::ScalarCoercionAdapters::VALID_TIME_ZONES.to_a.freeze}, - "Untyped" => {type: ["array", "boolean", "integer", "number", "object", "string"].freeze}, - "JsonSafeLong" => {type: "integer", minimum: JSON_SAFE_LONG_MIN, maximum: JSON_SAFE_LONG_MAX}, - "LongString" => {type: "integer", minimum: LONG_STRING_MIN, maximum: LONG_STRING_MAX} - }.freeze - # @private def new_enum_type(name) super(name) do |type| @@ -86,12 +64,9 @@ def new_object_indexing_field_type(...) def new_scalar_type(name) super(name) do |type| extended_type = type.extend(SchemaElements::ScalarTypeExtension) # : ::ElasticGraph::SchemaDefinition::SchemaElements::ScalarType & SchemaElements::ScalarTypeExtension - if (options = BUILT_IN_SCALAR_JSON_SCHEMA_OPTIONS_BY_NAME[name.to_s]) - extended_type.json_schema(**options) + extended_type.initialize_json_schema_extension do + yield extended_type end - - yield extended_type - extended_type.finalize_json_schema_configuration! end end diff --git a/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rb b/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rb index 0189fc50c..cca7e0f6b 100644 --- a/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rb +++ b/elasticgraph-json_ingestion/lib/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rb @@ -6,6 +6,8 @@ # # frozen_string_literal: true +require "elastic_graph/constants" +require "elastic_graph/graphql/scalar_coercion_adapters/valid_time_zones" require "elastic_graph/json_ingestion/schema_definition/schema_elements/has_json_schema" module ElasticGraph @@ -16,13 +18,36 @@ module SchemaElements module ScalarTypeExtension include HasJSONSchema - # Validates that json_schema has been configured on this scalar type, and applies - # post-yield runtime metadata derived from the final JSON schema configuration. - # GraphQL-only scalar types are skipped because they are not part of ingestion. + # Default JSON schema options applied to ElasticGraph's built-in scalar types as they are constructed. + BUILT_IN_SCALAR_JSON_SCHEMA_OPTIONS_BY_NAME = { + "Boolean" => {type: "boolean"}, + "Float" => {type: "number"}, + "ID" => {type: "string"}, + "Int" => {type: "integer", minimum: INT_MIN, maximum: INT_MAX}, + "String" => {type: "string"}, + "Cursor" => {type: "string"}, + "Date" => {type: "string", format: "date"}, + "DateTime" => {type: "string", format: "date-time"}, + "LocalTime" => {type: "string", pattern: VALID_LOCAL_TIME_JSON_SCHEMA_PATTERN}, + "TimeZone" => {type: "string", enum: GraphQL::ScalarCoercionAdapters::VALID_TIME_ZONES.to_a.freeze}, + "Untyped" => {type: ["array", "boolean", "integer", "number", "object", "string"].freeze}, + "JsonSafeLong" => {type: "integer", minimum: JSON_SAFE_LONG_MIN, maximum: JSON_SAFE_LONG_MAX}, + "LongString" => {type: "integer", minimum: LONG_STRING_MIN, maximum: LONG_STRING_MAX} + }.freeze + + # Applies any built-in JSON schema options, yields for further configuration, validates the result, + # and applies runtime metadata derived from the final JSON schema configuration. # + # @yield additional scalar type configuration # @raise [Errors::SchemaError] if json_schema has not been configured on an ingested scalar type # @return [void] - def finalize_json_schema_configuration! + def initialize_json_schema_extension + original_name = type_ref.with_reverted_override.name + if (options = BUILT_IN_SCALAR_JSON_SCHEMA_OPTIONS_BY_NAME[original_name]) + json_schema(**options) + end + + yield return if graphql_only? if json_schema_options.empty? diff --git a/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/factory_extension.rbs b/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/factory_extension.rbs index 4bf40e8dd..b8df11e96 100644 --- a/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/factory_extension.rbs +++ b/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/factory_extension.rbs @@ -2,8 +2,6 @@ module ElasticGraph module JSONIngestion module SchemaDefinition module FactoryExtension: ::ElasticGraph::SchemaDefinition::Factory - BUILT_IN_SCALAR_JSON_SCHEMA_OPTIONS_BY_NAME: ::Hash[::String, ::Hash[::Symbol, untyped]] - def new_enum_type: (::String) ?{ (::ElasticGraph::SchemaDefinition::SchemaElements::EnumType & SchemaElements::EnumTypeExtension) -> void } -> (::ElasticGraph::SchemaDefinition::SchemaElements::EnumType & SchemaElements::EnumTypeExtension) def new_enum_indexing_field_type: (::Array[::String]) -> Indexing::FieldType::Enum def new_field: (**untyped) ?{ (::ElasticGraph::SchemaDefinition::SchemaElements::Field & SchemaElements::FieldExtension) -> void } -> (::ElasticGraph::SchemaDefinition::SchemaElements::Field & SchemaElements::FieldExtension) diff --git a/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rbs b/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rbs index 3ed0e80b6..dea4d64a0 100644 --- a/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rbs +++ b/elasticgraph-json_ingestion/sig/elastic_graph/json_ingestion/schema_definition/schema_elements/scalar_type_extension.rbs @@ -3,9 +3,11 @@ module ElasticGraph module SchemaDefinition module SchemaElements module ScalarTypeExtension: ::ElasticGraph::SchemaDefinition::SchemaElements::ScalarType + BUILT_IN_SCALAR_JSON_SCHEMA_OPTIONS_BY_NAME: ::Hash[::String, ::Hash[::Symbol, untyped]] + include HasJSONSchema - def finalize_json_schema_configuration!: () -> void + def initialize_json_schema_extension: () { () -> void } -> void private