elasticgraph-schema_definition 0.19.3.1 → 1.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/lib/elastic_graph/schema_definition/api.rb +5 -12
  4. data/lib/elastic_graph/schema_definition/factory.rb +19 -5
  5. data/lib/elastic_graph/schema_definition/indexing/derived_fields/append_only_set.rb +1 -1
  6. data/lib/elastic_graph/schema_definition/indexing/derived_fields/field_initializer_support.rb +1 -1
  7. data/lib/elastic_graph/schema_definition/indexing/derived_fields/immutable_value.rb +1 -1
  8. data/lib/elastic_graph/schema_definition/indexing/derived_fields/min_or_max_value.rb +1 -1
  9. data/lib/elastic_graph/schema_definition/indexing/derived_indexed_type.rb +1 -1
  10. data/lib/elastic_graph/schema_definition/indexing/event_envelope.rb +1 -1
  11. data/lib/elastic_graph/schema_definition/indexing/field.rb +1 -1
  12. data/lib/elastic_graph/schema_definition/indexing/field_reference.rb +1 -1
  13. data/lib/elastic_graph/schema_definition/indexing/field_type/enum.rb +1 -1
  14. data/lib/elastic_graph/schema_definition/indexing/field_type/object.rb +1 -1
  15. data/lib/elastic_graph/schema_definition/indexing/field_type/scalar.rb +1 -1
  16. data/lib/elastic_graph/schema_definition/indexing/field_type/union.rb +1 -1
  17. data/lib/elastic_graph/schema_definition/indexing/index.rb +1 -1
  18. data/lib/elastic_graph/schema_definition/indexing/json_schema_field_metadata.rb +1 -1
  19. data/lib/elastic_graph/schema_definition/indexing/json_schema_with_metadata.rb +1 -1
  20. data/lib/elastic_graph/schema_definition/indexing/list_counts_mapping.rb +1 -1
  21. data/lib/elastic_graph/schema_definition/indexing/relationship_resolver.rb +1 -1
  22. data/lib/elastic_graph/schema_definition/indexing/rollover_config.rb +1 -1
  23. data/lib/elastic_graph/schema_definition/indexing/update_target_factory.rb +1 -1
  24. data/lib/elastic_graph/schema_definition/indexing/update_target_resolver.rb +1 -1
  25. data/lib/elastic_graph/schema_definition/json_schema_pruner.rb +1 -1
  26. data/lib/elastic_graph/schema_definition/mixins/can_be_graphql_only.rb +1 -1
  27. data/lib/elastic_graph/schema_definition/mixins/has_derived_graphql_type_customizations.rb +1 -1
  28. data/lib/elastic_graph/schema_definition/mixins/has_directives.rb +1 -1
  29. data/lib/elastic_graph/schema_definition/mixins/has_documentation.rb +1 -1
  30. data/lib/elastic_graph/schema_definition/mixins/has_indices.rb +4 -17
  31. data/lib/elastic_graph/schema_definition/mixins/has_readable_to_s_and_inspect.rb +1 -1
  32. data/lib/elastic_graph/schema_definition/mixins/has_subtypes.rb +1 -1
  33. data/lib/elastic_graph/schema_definition/mixins/has_type_info.rb +2 -2
  34. data/lib/elastic_graph/schema_definition/mixins/implements_interfaces.rb +2 -13
  35. data/lib/elastic_graph/schema_definition/mixins/supports_default_value.rb +1 -1
  36. data/lib/elastic_graph/schema_definition/mixins/supports_filtering_and_aggregation.rb +23 -8
  37. data/lib/elastic_graph/schema_definition/mixins/verifies_graphql_name.rb +1 -1
  38. data/lib/elastic_graph/schema_definition/rake_tasks.rb +1 -1
  39. data/lib/elastic_graph/schema_definition/results.rb +5 -5
  40. data/lib/elastic_graph/schema_definition/schema_artifact_manager.rb +1 -1
  41. data/lib/elastic_graph/schema_definition/schema_elements/argument.rb +1 -1
  42. data/lib/elastic_graph/schema_definition/schema_elements/built_in_types.rb +108 -216
  43. data/lib/elastic_graph/schema_definition/schema_elements/deprecated_element.rb +1 -1
  44. data/lib/elastic_graph/schema_definition/schema_elements/directive.rb +1 -1
  45. data/lib/elastic_graph/schema_definition/schema_elements/enum_type.rb +1 -1
  46. data/lib/elastic_graph/schema_definition/schema_elements/enum_value.rb +1 -1
  47. data/lib/elastic_graph/schema_definition/schema_elements/enum_value_namer.rb +1 -1
  48. data/lib/elastic_graph/schema_definition/schema_elements/enums_for_indexed_types.rb +1 -1
  49. data/lib/elastic_graph/schema_definition/schema_elements/field.rb +103 -142
  50. data/lib/elastic_graph/schema_definition/schema_elements/field_path.rb +1 -1
  51. data/lib/elastic_graph/schema_definition/schema_elements/field_source.rb +1 -1
  52. data/lib/elastic_graph/schema_definition/schema_elements/graphql_sdl_enumerator.rb +1 -1
  53. data/lib/elastic_graph/schema_definition/schema_elements/input_field.rb +1 -1
  54. data/lib/elastic_graph/schema_definition/schema_elements/input_type.rb +1 -1
  55. data/lib/elastic_graph/schema_definition/schema_elements/interface_type.rb +1 -1
  56. data/lib/elastic_graph/schema_definition/schema_elements/list_counts_state.rb +1 -1
  57. data/lib/elastic_graph/schema_definition/schema_elements/object_type.rb +1 -1
  58. data/lib/elastic_graph/schema_definition/schema_elements/relationship.rb +1 -1
  59. data/lib/elastic_graph/schema_definition/schema_elements/scalar_type.rb +20 -2
  60. data/lib/elastic_graph/schema_definition/schema_elements/sort_order_enum_value.rb +1 -1
  61. data/lib/elastic_graph/schema_definition/schema_elements/sub_aggregation_path.rb +1 -1
  62. data/lib/elastic_graph/schema_definition/schema_elements/type_namer.rb +2 -1
  63. data/lib/elastic_graph/schema_definition/schema_elements/type_reference.rb +8 -10
  64. data/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb +7 -27
  65. data/lib/elastic_graph/schema_definition/schema_elements/union_type.rb +1 -1
  66. data/lib/elastic_graph/schema_definition/scripting/file_system_repository.rb +1 -1
  67. data/lib/elastic_graph/schema_definition/scripting/script.rb +1 -1
  68. data/lib/elastic_graph/schema_definition/scripting/scripts/update/index_data.painless +2 -22
  69. data/lib/elastic_graph/schema_definition/state.rb +1 -1
  70. data/lib/elastic_graph/schema_definition/test_support.rb +1 -1
  71. metadata +28 -28
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -8,7 +8,6 @@
8
8
 
9
9
  require "delegate"
10
10
  require "elastic_graph/constants"
11
- require "elastic_graph/schema_artifacts/runtime_metadata/configured_graphql_resolver"
12
11
  require "elastic_graph/schema_definition/indexing/field"
13
12
  require "elastic_graph/schema_definition/indexing/field_reference"
14
13
  require "elastic_graph/schema_definition/mixins/has_directives"
@@ -53,6 +52,8 @@ module ElasticGraph
53
52
  # @private
54
53
  # @!attribute [rw] grouped_by_customizations
55
54
  # @private
55
+ # @!attribute [rw] highlights_customizations
56
+ # @private
56
57
  # @!attribute [rw] sub_aggregations_customizations
57
58
  # @private
58
59
  # @!attribute [rw] aggregated_values_customizations
@@ -69,6 +70,8 @@ module ElasticGraph
69
70
  # @private
70
71
  # @!attribute [rw] groupable
71
72
  # @private
73
+ # @!attribute [rw] highlightable
74
+ # @private
72
75
  # @!attribute [rw] source
73
76
  # @private
74
77
  # @!attribute [rw] runtime_field_script
@@ -83,15 +86,14 @@ module ElasticGraph
83
86
  # @private
84
87
  # @!attribute [rw] as_input
85
88
  # @private
86
- # @!attribute [rw] legacy_grouping_schema
87
- # @private
88
89
  class Field < Struct.new(
89
90
  :name, :original_type, :parent_type, :original_type_for_derived_types, :schema_def_state, :accuracy_confidence,
90
- :filter_customizations, :grouped_by_customizations, :sub_aggregations_customizations,
91
- :aggregated_values_customizations, :sort_order_enum_value_customizations,
92
- :args, :sortable, :filterable, :aggregatable, :groupable, :graphql_only, :source, :runtime_field_script, :relationship, :singular_name,
91
+ :filter_customizations, :grouped_by_customizations, :highlights_customizations, :sub_aggregations_customizations,
92
+ :aggregated_values_customizations, :sort_order_enum_value_customizations, :args,
93
+ :sortable, :filterable, :aggregatable, :groupable, :highlightable,
94
+ :graphql_only, :source, :runtime_field_script, :relationship, :singular_name,
93
95
  :computation_detail, :non_nullable_in_json_schema, :as_input,
94
- :legacy_grouping_schema, :name_in_index, :resolver
96
+ :name_in_index, :resolver
95
97
  )
96
98
  include Mixins::HasDocumentation
97
99
  include Mixins::HasDirectives
@@ -103,8 +105,8 @@ module ElasticGraph
103
105
  name:, type:, parent_type:, schema_def_state:,
104
106
  accuracy_confidence: :high, name_in_index: name,
105
107
  type_for_derived_types: nil, graphql_only: nil, singular: nil,
106
- sortable: nil, filterable: nil, aggregatable: nil, groupable: nil,
107
- as_input: false, legacy_grouping_schema: false, resolver: nil
108
+ sortable: nil, filterable: nil, aggregatable: nil, groupable: nil, highlightable: nil,
109
+ as_input: false, resolver: nil
108
110
  )
109
111
  type_ref = schema_def_state.type_ref(type)
110
112
  super(
@@ -116,6 +118,7 @@ module ElasticGraph
116
118
  accuracy_confidence: accuracy_confidence,
117
119
  filter_customizations: [],
118
120
  grouped_by_customizations: [],
121
+ highlights_customizations: [],
119
122
  sub_aggregations_customizations: [],
120
123
  aggregated_values_customizations: [],
121
124
  sort_order_enum_value_customizations: [],
@@ -124,6 +127,7 @@ module ElasticGraph
124
127
  filterable: filterable,
125
128
  aggregatable: aggregatable,
126
129
  groupable: groupable,
130
+ highlightable: highlightable,
127
131
  graphql_only: graphql_only,
128
132
  source: nil,
129
133
  runtime_field_script: nil,
@@ -134,32 +138,17 @@ module ElasticGraph
134
138
  name_in_index: name_in_index,
135
139
  non_nullable_in_json_schema: false,
136
140
  as_input: as_input,
137
- legacy_grouping_schema: legacy_grouping_schema,
138
141
  resolver: resolver
139
142
  )
140
143
 
141
- if name != name_in_index
142
- if graphql_only
143
- schema_def_state.after_user_definition_complete do
144
- unless backing_indexing_field
145
- raise Errors::SchemaError,
146
- "GraphQL-only field `#{parent_type.name}.#{name}` has a `name_in_index` (#{name_in_index}) which does not reference an " \
147
- "existing indexing field. To proceed, remove `graphql_only: true` or update `name_in_index` to match an existing indexing field."
148
- end
149
- end
150
- elsif name_in_index.include?(".")
151
- raise Errors::SchemaError,
152
- "#{self} has an invalid `name_in_index`: #{name_in_index.inspect}. " \
153
- "Only `graphql_only: true` fields can have a `name_in_index` that references a child field."
154
- end
144
+ if name != name_in_index && name_in_index.include?(".") && !graphql_only
145
+ raise Errors::SchemaError, "#{self} has an invalid `name_in_index`: #{name_in_index.inspect}. Only `graphql_only: true` fields can have a `name_in_index` that references a child field."
155
146
  end
156
147
 
157
148
  schema_def_state.register_user_defined_field(self)
158
149
  yield self if block_given?
159
150
  end
160
151
 
161
- private :resolver=
162
-
163
152
  # @private
164
153
  @@initialize_param_names = instance_method(:initialize).parameters.map(&:last).to_set
165
154
 
@@ -191,6 +180,7 @@ module ElasticGraph
191
180
  # @return [void]
192
181
  # @see #customize_aggregated_values_field
193
182
  # @see #customize_grouped_by_field
183
+ # @see #customize_highlights_field
194
184
  # @see #customize_sort_order_enum_values
195
185
  # @see #customize_sub_aggregations_field
196
186
  # @see #on_each_generated_schema_element
@@ -223,6 +213,7 @@ module ElasticGraph
223
213
  # @return [void]
224
214
  # @see #customize_filter_field
225
215
  # @see #customize_grouped_by_field
216
+ # @see #customize_highlights_field
226
217
  # @see #customize_sort_order_enum_values
227
218
  # @see #customize_sub_aggregations_field
228
219
  # @see #on_each_generated_schema_element
@@ -255,6 +246,7 @@ module ElasticGraph
255
246
  # @return [void]
256
247
  # @see #customize_aggregated_values_field
257
248
  # @see #customize_filter_field
249
+ # @see #customize_highlights_field
258
250
  # @see #customize_sort_order_enum_values
259
251
  # @see #customize_sub_aggregations_field
260
252
  # @see #on_each_generated_schema_element
@@ -277,6 +269,39 @@ module ElasticGraph
277
269
  grouped_by_customizations << customization_block
278
270
  end
279
271
 
272
+ # @note For each field defined in your schema that is highlightable, a corresponding highlights field will be created on the
273
+ # `*Highlights` type derived from the parent object type.
274
+ #
275
+ # Registers a customization callback that will be applied to the corresponding highlights field that will be generated for this
276
+ # field.
277
+ #
278
+ # @yield [Field] derived highlights field
279
+ # @return [void]
280
+ # @see #customize_aggregated_values_field
281
+ # @see #customize_filter_field
282
+ # @see #customize_grouped_by_field
283
+ # @see #customize_sort_order_enum_values
284
+ # @see #customize_sub_aggregations_field
285
+ # @see #on_each_generated_schema_element
286
+ #
287
+ # @example Mark `CampaignHighlights.organizationId` with `@deprecated`
288
+ # ElasticGraph.define_schema do |schema|
289
+ # schema.object_type "Campaign" do |t|
290
+ # t.field "id", "ID"
291
+ #
292
+ # t.field "organizationId", "ID" do |f|
293
+ # f.customize_highlights_field do |gbf|
294
+ # gbf.directive "deprecated"
295
+ # end
296
+ # end
297
+ #
298
+ # t.index "campaigns"
299
+ # end
300
+ # end
301
+ def customize_highlights_field(&customization_block)
302
+ highlights_customizations << customization_block
303
+ end
304
+
280
305
  # @note For each field defined in your schema that is sub-aggregatable (e.g. list fields indexed using the `nested` mapping type),
281
306
  # a corresponding field will be created on the `*AggregationSubAggregations` type derived from the parent object type.
282
307
  #
@@ -288,6 +313,7 @@ module ElasticGraph
288
313
  # @see #customize_aggregated_values_field
289
314
  # @see #customize_filter_field
290
315
  # @see #customize_grouped_by_field
316
+ # @see #customize_highlights_field
291
317
  # @see #customize_sort_order_enum_values
292
318
  # @see #on_each_generated_schema_element
293
319
  #
@@ -329,6 +355,7 @@ module ElasticGraph
329
355
  # @see #customize_aggregated_values_field
330
356
  # @see #customize_filter_field
331
357
  # @see #customize_grouped_by_field
358
+ # @see #customize_highlights_field
332
359
  # @see #customize_sub_aggregations_field
333
360
  # @see #on_each_generated_schema_element
334
361
  #
@@ -357,6 +384,8 @@ module ElasticGraph
357
384
  # ask for values for the field in a response.
358
385
  # * A {Field} may be generated on the `*FilterInput` {InputType} derived from the parent {ObjectType} or {InterfaceType}. This is
359
386
  # used by clients to specify how the query should filter.
387
+ # * A {Field} may be generated on the `*Highlights` {ObjectType} derived from the parent {ObjectType} or {InterfaceType}. This is
388
+ # used by clients to request search highlights for a field.
360
389
  # * A {Field} may be generated on the `*AggregationGroupedBy` {ObjectType} derived from the parent {ObjectType} or {InterfaceType}.
361
390
  # This is used by clients to specify how aggregations should be grouped.
362
391
  # * A {Field} may be generated on the `*AggregatedValues` {ObjectType} derived from the parent {ObjectType} or {InterfaceType}.
@@ -373,6 +402,7 @@ module ElasticGraph
373
402
  # @see #customize_aggregated_values_field
374
403
  # @see #customize_filter_field
375
404
  # @see #customize_grouped_by_field
405
+ # @see #customize_highlights_field
376
406
  # @see #customize_sort_order_enum_values
377
407
  # @see #customize_sub_aggregations_field
378
408
  #
@@ -381,15 +411,16 @@ module ElasticGraph
381
411
  # schema.object_type "Transaction" do |t|
382
412
  # t.field "id", "ID"
383
413
  #
384
- # t.field "amount", "Int" do |f|
414
+ # t.field "currency", "String" do |f|
385
415
  # f.on_each_generated_schema_element do |element|
386
- # # Adds a `@deprecated` directive to every GraphQL schema element generated for `amount`:
416
+ # # Adds a `@deprecated` directive to every GraphQL schema element generated for `currency`:
387
417
  # #
388
- # # - The `Transaction.amount` field.
389
- # # - The `TransactionFilterInput.amount` field.
390
- # # - The `TransactionAggregationGroupedBy.amount` field.
391
- # # - The `TransactionAggregatedValues.amount` field.
392
- # # - The `TransactionSortOrder.amount_ASC` and`TransactionSortOrder.amount_DESC` enum values.
418
+ # # - The `Transaction.currency` field.
419
+ # # - The `TransactionFilterInput.currency` field.
420
+ # # - The `TransactionHighlights.currency` field.
421
+ # # - The `TransactionAggregationGroupedBy.currency` field.
422
+ # # - The `TransactionAggregatedValues.currency` field.
423
+ # # - The `TransactionSortOrder.currency_ASC` and`TransactionSortOrder.currency_DESC` enum values.
393
424
  # element.directive "deprecated"
394
425
  # end
395
426
  # end
@@ -402,6 +433,7 @@ module ElasticGraph
402
433
  customize_filter_field(&customization_block)
403
434
  customize_aggregated_values_field(&customization_block)
404
435
  customize_grouped_by_field(&customization_block)
436
+ customize_highlights_field(&customization_block)
405
437
  customize_sub_aggregations_field(&customization_block)
406
438
  customize_sort_order_enum_values(&customization_block)
407
439
  end
@@ -460,46 +492,6 @@ module ElasticGraph
460
492
  )
461
493
  end
462
494
 
463
- # Configures the GraphQL resolver used to resolve this field. If not set, the resolver configured on the parent type
464
- # via {Mixins::HasIndices#resolve_fields_with} will be used.
465
- #
466
- # @param resolver_name [Symbol] name of the GraphQL resolver
467
- # @param config [Hash<Symbol, Object>] configuration parameters for the resolver
468
- # @return [void]
469
- # @see API#register_graphql_resolver
470
- #
471
- # @example Use a custom resolver for a custom `Query` field
472
- # # In `add_resolver.rb`:
473
- # class AddResolver
474
- # def initialize(elasticgraph_graphql:, config:)
475
- # @multiplier = config.fetch(:multiplier, 1)
476
- # end
477
- #
478
- # def resolve(field:, object:, args:, context:)
479
- # sum = args.fetch("x") + args.fetch("y")
480
- # sum * @multiplier
481
- # end
482
- # end
483
- #
484
- # # In `config/schema.rb`:
485
- # ElasticGraph.define_schema do |schema|
486
- # require(resolver_path = "add_resolver")
487
- # schema.register_graphql_resolver :add, AddResolver, defined_at: resolver_path
488
- #
489
- # schema.on_root_query_type do |t|
490
- # t.field "add", "Int" do |f|
491
- # f.argument "x", "Int!"
492
- # f.argument "y", "Int!"
493
- #
494
- # # Extra args (`multiplier: 2`, in this example) are passed to the resolver within `config`.
495
- # f.resolve_with :add, multiplier: 2
496
- # end
497
- # end
498
- # end
499
- def resolve_with(resolver_name, **config)
500
- self.resolver = resolver_name&.then { |name| SchemaArtifacts::RuntimeMetadata::ConfiguredGraphQLResolver.new(name, config) }
501
- end
502
-
503
495
  # @private
504
496
  def runtime_script(script)
505
497
  self.runtime_field_script = script
@@ -609,14 +601,13 @@ module ElasticGraph
609
601
  # instead.
610
602
  return false if parent_type.indexed? && name == "id"
611
603
 
612
- return false if relationship || type_disallows_grouping?
604
+ return false if relationship || type.fully_unwrapped.as_object_type&.does_not_support?(&:groupable?)
613
605
 
614
606
  # We don't support grouping an entire list of values, but we do support grouping on individual values in a list.
615
607
  # However, we only do so when a `singular_name` has been provided (so that we know what to call the grouped_by field).
616
608
  # The semantics are a little odd (since one document can be duplicated in multiple grouping buckets) so we're ok
617
609
  # with not offering it by default--the user has to opt-in by telling us what to call the field in its singular form.
618
- # Types with their own `GroupedBy` type are grouped as individual values, like scalars.
619
- return list_field_groupable_by_single_values? if type.list? && (type.fully_unwrapped.leaf? || original_type.fully_unwrapped.grouped_by_type_defined?)
610
+ return list_field_groupable_by_single_values? if type.list? && type.fully_unwrapped.leaf?
620
611
 
621
612
  # Nested fields will be supported through specific nested aggregation support, and do not
622
613
  # work as expected when grouping on the root document type.
@@ -660,6 +651,17 @@ module ElasticGraph
660
651
  nested? || type_for_derived_types.fully_unwrapped.as_object_type&.supports?(&:sub_aggregatable?)
661
652
  end
662
653
 
654
+ # @private
655
+ HIGHLIGHTABLE_MAPPING_TYPES = %w[keyword text match_only_text]
656
+
657
+ def highlightable?
658
+ return highlightable unless highlightable.nil?
659
+ return false if relationship
660
+ return true if HIGHLIGHTABLE_MAPPING_TYPES.include?(mapping_type)
661
+
662
+ type_for_derived_types.fully_unwrapped.as_object_type&.supports?(&:highlightable?)
663
+ end
664
+
663
665
  # Defines an argument on the field.
664
666
  #
665
667
  # @note ElasticGraph takes care of defining arguments for all the query features it supports, so there is generally no need to use
@@ -725,19 +727,33 @@ module ElasticGraph
725
727
  parent_type.field field_name, grouped_by_field_type_name, name_in_index: name_in_index, graphql_only: true do |f|
726
728
  add_grouped_by_field_documentation(f)
727
729
 
728
- define_legacy_timestamp_grouping_arguments_if_needed(f) if legacy_grouping_schema
729
-
730
730
  grouped_by_customizations.each { |block| block.call(f) }
731
731
  end
732
732
  end
733
733
 
734
- # Returns the GraphQL type used for this field's grouped value.
734
+ # @private
735
+ def define_highlights_field(parent_type)
736
+ return unless highlightable?
737
+
738
+ unwrapped_type = type_for_derived_types.fully_unwrapped
739
+ type_name =
740
+ if unwrapped_type.leaf?
741
+ "[String!]!"
742
+ else
743
+ unwrapped_type.as_highlights.name
744
+ end
745
+
746
+ parent_type.field name, type_name, name_in_index: name_in_index, graphql_only: true do |f|
747
+ f.documentation derived_documentation("Search highlights for the `#{name}`, providing snippets of the matching text")
748
+ highlights_customizations.each { |block| block.call(f) }
749
+ end
750
+ end
751
+
735
752
  # @private
736
753
  def grouped_by_field_type_name
737
754
  unwrapped_type = type_for_derived_types.fully_unwrapped
738
- original_unwrapped_type = original_type_for_derived_types.fully_unwrapped
739
- if original_unwrapped_type.grouped_by_type_defined? && !legacy_grouping_schema
740
- original_unwrapped_type.as_grouped_by.name
755
+ if unwrapped_type.scalar_type_needing_grouped_by_object?
756
+ unwrapped_type.with_reverted_override.as_grouped_by.name
741
757
  elsif unwrapped_type.leaf?
742
758
  unwrapped_type.name
743
759
  else
@@ -757,7 +773,7 @@ module ElasticGraph
757
773
  "The `#{name}` field value for this group",
758
774
  list_field_grouped_by_doc_note("the selected subfields of `#{name}`")
759
775
  )
760
- elsif original_type_for_derived_types.fully_unwrapped.grouped_by_type_defined? && !legacy_grouping_schema
776
+ elsif type_for_derived_types.fully_unwrapped.scalar_type_needing_grouped_by_object?
761
777
  derived_documentation("Offers the different grouping options for the `#{name}` value within this group")
762
778
  else
763
779
  derived_documentation("The `#{name}` field value for this group")
@@ -989,29 +1005,13 @@ module ElasticGraph
989
1005
  )
990
1006
  end
991
1007
 
992
- # The alternate field that is backing this field in the datastore index. Will only be non-`nil` for `graphql_only` fields.
993
- # @return [Field, nil] the field backing this field in the index
994
- #
995
- # @private
1008
+ private
1009
+
996
1010
  def backing_indexing_field
997
1011
  return nil unless graphql_only
998
-
999
- type = parent_type
1000
- field = nil
1001
-
1002
- name_in_index.split(".").each do |path_part|
1003
- if (field = type&.indexing_fields_by_name_in_index&.fetch(path_part, nil))
1004
- type = field.type.fully_unwrapped.as_object_type
1005
- else
1006
- return nil
1007
- end
1008
- end
1009
-
1010
- field
1012
+ parent_type.indexing_fields_by_name_in_index[name_in_index]
1011
1013
  end
1012
1014
 
1013
- private
1014
-
1015
1015
  def args_sdl(joiner:, after_opening_paren: "", &arg_selector)
1016
1016
  selected_args = args.values.select(&arg_selector)
1017
1017
  args_sdl = selected_args.map(&:to_sdl).flat_map { |s| s.split("\n") }.join(joiner)
@@ -1019,50 +1019,11 @@ module ElasticGraph
1019
1019
  "(#{after_opening_paren}#{args_sdl})"
1020
1020
  end
1021
1021
 
1022
- # Identifies types that disallow grouping, except for types that define their own `GroupedBy` type.
1023
- def type_disallows_grouping?
1024
- !original_type.fully_unwrapped.grouped_by_type_defined? && !!type.fully_unwrapped.as_object_type&.does_not_support?(&:groupable?)
1025
- end
1026
-
1027
1022
  # Indicates if the field uses the `text` mapping type.
1028
1023
  def text?
1029
1024
  mapping_type == "text"
1030
1025
  end
1031
1026
 
1032
- def define_legacy_timestamp_grouping_arguments_if_needed(grouping_field)
1033
- case type.fully_unwrapped.name
1034
- when "Date"
1035
- grouping_field.argument schema_def_state.schema_elements.granularity, "DateGroupingGranularity!" do |a|
1036
- a.documentation "Determines the grouping granularity for this field."
1037
- end
1038
-
1039
- grouping_field.argument schema_def_state.schema_elements.offset_days, "Int" do |a|
1040
- a.documentation <<~EOS
1041
- Number of days (positive or negative) to shift the `Date` boundaries of each date grouping bucket.
1042
-
1043
- For example, when grouping by `YEAR`, this can be used to align the buckets with fiscal or school years instead of calendar years.
1044
- EOS
1045
- end
1046
- when "DateTime"
1047
- grouping_field.argument schema_def_state.schema_elements.granularity, "DateTimeGroupingGranularity!" do |a|
1048
- a.documentation "Determines the grouping granularity for this field."
1049
- end
1050
-
1051
- grouping_field.argument schema_def_state.schema_elements.time_zone, "TimeZone" do |a|
1052
- a.documentation "The time zone to use when determining which grouping a `DateTime` value falls in."
1053
- a.default "UTC"
1054
- end
1055
-
1056
- grouping_field.argument schema_def_state.schema_elements.offset, "DateTimeGroupingOffsetInput" do |a|
1057
- a.documentation <<~EOS
1058
- Amount of offset (positive or negative) to shift the `DateTime` boundaries of each grouping bucket.
1059
-
1060
- For example, when grouping by `WEEK`, you can shift by 24 hours to change what day-of-week weeks are considered to start on.
1061
- EOS
1062
- end
1063
- end
1064
- end
1065
-
1066
1027
  def list_field_grouped_by_doc_note(individual_value_selection_description)
1067
1028
  <<~EOS.strip
1068
1029
  Note: `#{name}` is a collection field, but selecting this field will group on individual values of #{individual_value_selection_description}.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -39,7 +39,16 @@ module ElasticGraph
39
39
  # @private
40
40
  # @!attribute [rw] aggregated_values_customizations
41
41
  # @private
42
- class ScalarType < Struct.new(:schema_def_state, :type_ref, :mapping_type, :runtime_metadata, :aggregated_values_customizations)
42
+ # @!attribute [rw] filter_input_customizations
43
+ # @private
44
+ class ScalarType < Struct.new(
45
+ :schema_def_state,
46
+ :type_ref,
47
+ :mapping_type,
48
+ :runtime_metadata,
49
+ :aggregated_values_customizations,
50
+ :filter_input_customizations
51
+ )
43
52
  # `Struct.new` provides the following methods:
44
53
  # @dynamic type_ref, runtime_metadata
45
54
  prepend Mixins::VerifiesGraphQLName
@@ -157,6 +166,13 @@ module ElasticGraph
157
166
  self.aggregated_values_customizations = block
158
167
  end
159
168
 
169
+ # Registers a block which will be used to customize the derived `*FilterInput` object type.
170
+ #
171
+ # @private
172
+ def customize_filter_input_type(&block)
173
+ self.filter_input_customizations = block
174
+ end
175
+
160
176
  # @private
161
177
  def aggregated_values_type
162
178
  if aggregated_values_customizations
@@ -284,6 +300,8 @@ module ElasticGraph
284
300
  f.documentation LTE_DOC
285
301
  end
286
302
  end
303
+
304
+ filter_input_customizations&.call(t)
287
305
  end
288
306
  end
289
307
 
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -147,6 +147,7 @@ module ElasticGraph
147
147
  FieldsListFilterInput: "%{base}FieldsListFilterInput",
148
148
  FilterInput: "%{base}FilterInput",
149
149
  GroupedBy: "%{base}GroupedBy",
150
+ Highlights: "%{base}Highlights",
150
151
  InputEnum: "%{base}Input",
151
152
  ListElementFilterInput: "%{base}ListElementFilterInput",
152
153
  ListFilterInput: "%{base}ListFilterInput",
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2026 Block, Inc.
1
+ # Copyright 2024 - 2025 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -153,15 +153,12 @@ module ElasticGraph
153
153
  .sub(/[\]!]+\z/, "") # strip `]` and `!` characters from the end: https://rubular.com/r/pC8C0i7EpvHDbf
154
154
  end
155
155
 
156
- # Indicates if this type opts into specialized grouping by defining its own `[type]GroupedBy` type.
157
- # Use the original type name, before overrides, since an overridden name may identify another type.
158
- # Only call this after the user definition is complete, when all grouping types are known.
159
- def grouped_by_type_defined?
160
- unless schema_def_state.user_definition_complete
161
- raise Errors::SchemaError, "Cannot call `grouped_by_type_defined?` until the schema definition is complete."
162
- end
163
-
164
- schema_def_state.types_by_name.key?(as_grouped_by.name)
156
+ # Generally speaking, scalar types have `grouped_by` fields which are scalars of the same types,
157
+ # and object types have `grouped_by` fields which are special `[object_type]GroupedBy` types.
158
+ #
159
+ # ...except for some special cases (Date and DateTime), which this predicate detects.
160
+ def scalar_type_needing_grouped_by_object?
161
+ %w[Date DateTime].include?(type_namer.revert_override_for(name))
165
162
  end
166
163
 
167
164
  # Returns a new `TypeReference` with any type name overrides reverted (to provide the "original" type name).
@@ -290,6 +287,7 @@ module ElasticGraph
290
287
  # @dynamic as_edge
291
288
  # @dynamic as_fields_list_filter_input
292
289
  # @dynamic as_filter_input
290
+ # @dynamic as_highlights
293
291
  # @dynamic as_input_enum
294
292
  # @dynamic as_list_element_filter_input, list_element_filter_input?
295
293
  # @dynamic as_list_filter_input, list_filter_input?