elasticgraph-schema_definition 1.0.0 → 1.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5f0173872296489fdc329b0a44657194e497acdba7abc49eb64173c8a10d0ca
4
- data.tar.gz: 724259a4adbb18b3f3c993729ab8ea19c14c78242d06669556dd34cca112d88c
3
+ metadata.gz: 4756602b0f1d661da8c577effc6f1daa1ef0ad8cc86148f3068ebc13c676f6b8
4
+ data.tar.gz: 37a2c4e7901483d9a211a9dd16a00554f8fbf9e05ba02201202a40f587ffff68
5
5
  SHA512:
6
- metadata.gz: eaa7a83413f59158d5b1b9a5a308a7d63aa2dfee32518d4786e6339f6a96704d5859082547fb07cd647aae64414223207770d421c7de293d4f5ca2647b9b5060
7
- data.tar.gz: 7c8680c5685824c49fddffbeb2776613f9037d58f0cc471cf38b695a8309c05d538228d293570ab89e2d67b07fb3599ee66bc167a641e94070de4d1067292ac5
6
+ metadata.gz: cb4dd42e565f3635496d2f0df52390528814b9a0f56b9f702a910ffa850ab08a76179b088d0b72cbb08fe835e14551b26dfd4557b0e838dc482468596893417b
7
+ data.tar.gz: cda65f9354c0c726a53254213f11e211b59de7dd1639cf6bb158394c1af00a6de4666707d356101e1d7a0137f324ceb21606ce05ce7b977847098111f38b5589
data/README.md CHANGED
@@ -21,9 +21,6 @@ graph LR;
21
21
  elasticgraph-indexer["elasticgraph-indexer"];
22
22
  elasticgraph-schema_definition --> elasticgraph-indexer;
23
23
  class elasticgraph-indexer otherEgGemStyle;
24
- elasticgraph-json_schema["elasticgraph-json_schema"];
25
- elasticgraph-schema_definition --> elasticgraph-json_schema;
26
- class elasticgraph-json_schema otherEgGemStyle;
27
24
  elasticgraph-schema_artifacts["elasticgraph-schema_artifacts"];
28
25
  elasticgraph-schema_definition --> elasticgraph-schema_artifacts;
29
26
  class elasticgraph-schema_artifacts otherEgGemStyle;
@@ -44,9 +44,25 @@ module ElasticGraph
44
44
  <<~EOS
45
45
  boolean #{min_or_max}Value_idempotentlyUpdateValue(List values, def parentObject, String fieldName) {
46
46
  def currentFieldValue = parentObject[fieldName];
47
- def #{min_or_max}NewValue = values.isEmpty() ? null : Collections.#{min_or_max}(values);
47
+ // Normalize incoming list numerics to long to avoid Integer/Long class cast issues
48
+ List coercedValues = new ArrayList();
49
+ for (def v : values) {
50
+ if (v != null) {
51
+ if (v instanceof Number) {
52
+ coercedValues.add(((Number)v).longValue());
53
+ } else {
54
+ coercedValues.add(v);
55
+ }
56
+ }
57
+ }
58
+ def #{min_or_max}NewValue = coercedValues.isEmpty() ? null : Collections.#{min_or_max}(coercedValues);
59
+
60
+ def coercedCurrentFieldValue = null;
61
+ if (currentFieldValue != null) {
62
+ coercedCurrentFieldValue = (currentFieldValue instanceof Number) ? ((Number)currentFieldValue).longValue() : currentFieldValue;
63
+ }
48
64
 
49
- if (currentFieldValue == null || (#{min_or_max}NewValue != null && #{min_or_max}NewValue.compareTo(currentFieldValue) #{operator} 0)) {
65
+ if (coercedCurrentFieldValue == null || (#{min_or_max}NewValue != null && #{min_or_max}NewValue.compareTo(coercedCurrentFieldValue) #{operator} 0)) {
50
66
  parentObject[fieldName] = #{min_or_max}NewValue;
51
67
  return true;
52
68
  }
@@ -160,11 +160,11 @@ module ElasticGraph
160
160
  type.indexed? && !@derived_indexing_type_names.include?(type.name)
161
161
  end
162
162
 
163
- types_to_check.flat_map do |object_type|
164
- object_type.indices.flat_map do |index_def|
163
+ types_to_check.filter_map do |object_type|
164
+ if (index_def = object_type.index_def)
165
165
  identify_missing_necessary_fields_for_index_def(object_type, index_def, json_schema_resolver, version)
166
166
  end
167
- end
167
+ end.flatten
168
168
  end
169
169
 
170
170
  def identify_missing_necessary_fields_for_index_def(object_type, index_def, json_schema_resolver, json_schema_version)
@@ -137,10 +137,9 @@ module ElasticGraph
137
137
  #
138
138
  # Returns a tuple of the resolved source (if successful) and an error (if invalid).
139
139
  def resolve_field_source(adapter)
140
- # For now we only support one index (so we can use the first index) but someday we may need to support multiple.
141
- index = object_type.indices.first # : Index
140
+ index_def = object_type.index_def # : Index
142
141
 
143
- field_source_graphql_path_string = adapter.get_field_source(resolved_relationship.relationship, index) do |local_need|
142
+ field_source_graphql_path_string = adapter.get_field_source(resolved_relationship.relationship, index_def) do |local_need|
144
143
  relationship_name = resolved_relationship.relationship_name
145
144
 
146
145
  error = "Cannot update `#{object_type.name}` documents with data from related `#{relationship_name}` events, " \
@@ -27,12 +27,10 @@ module ElasticGraph
27
27
  def initialize(*args, **options)
28
28
  super(*args, **options)
29
29
  @runtime_metadata_overrides = {}
30
+ @can_configure_index = true
30
31
  resolve_fields_with :get_record_field_value
31
32
  yield self
32
-
33
- # Freeze `indices` so that the indexable status of a type does not change after instantiation.
34
- # (That would cause problems.)
35
- indices.freeze
33
+ @can_configure_index = false
36
34
  end
37
35
 
38
36
  # Converts the current type from being an _embedded_ type (that is, a type that is embedded within another indexed type) to an
@@ -69,7 +67,17 @@ module ElasticGraph
69
67
  # end
70
68
  # end
71
69
  def index(name, **settings, &block)
72
- indices.replace([Indexing::Index.new(name, settings, schema_def_state, self, &block)])
70
+ unless @can_configure_index
71
+ raise Errors::SchemaError, "Cannot define an index on `#{self.name}` after initialization is complete. " \
72
+ "Indices must be configured during initial type definition."
73
+ end
74
+
75
+ if @index_def
76
+ raise Errors::SchemaError, "Cannot define multiple indices on `#{self.name}`. " \
77
+ "Only one index per type is supported. An index named `#{@index_def.name}` has already been defined."
78
+ end
79
+
80
+ @index_def = Indexing::Index.new(name, settings, schema_def_state, self, &block)
73
81
  end
74
82
 
75
83
  # Configures the default GraphQL resolver that will be used to resolve the fields of this type. Individual fields
@@ -85,16 +93,14 @@ module ElasticGraph
85
93
  end
86
94
  end
87
95
 
88
- # List of indices. (Currently we only store one but we may support multiple in the future).
89
- #
90
- # @private
91
- def indices
92
- @indices ||= []
96
+ # @return [Indexing::Index, nil] the defined index for this type, or nil if no index is defined
97
+ def index_def
98
+ @index_def
93
99
  end
94
100
 
95
101
  # @return [Boolean] true if this type has an index
96
102
  def indexed?
97
- indices.any?
103
+ !@index_def.nil?
98
104
  end
99
105
 
100
106
  # Abstract types are rare, so return false. This can be overridden in the host class.
@@ -182,7 +188,7 @@ module ElasticGraph
182
188
  def runtime_metadata(extra_update_targets)
183
189
  SchemaArtifacts::RuntimeMetadata::ObjectType.new(
184
190
  update_targets: derived_indexed_types.map(&:runtime_metadata_for_source_type) + [self_update_target].compact + extra_update_targets,
185
- index_definition_names: indices.map(&:name),
191
+ index_definition_names: [index_def&.name].compact,
186
192
  graphql_fields_by_name: runtime_metadata_graphql_fields_by_name,
187
193
  elasticgraph_category: nil,
188
194
  source_type: nil,
@@ -267,7 +273,7 @@ module ElasticGraph
267
273
  [field, SchemaArtifacts::RuntimeMetadata::DynamicParam.new(source_path: field, cardinality: :one)]
268
274
  end
269
275
 
270
- index_runtime_metadata = indices.first.runtime_metadata
276
+ index_runtime_metadata = index_def.runtime_metadata
271
277
 
272
278
  Indexing::UpdateTargetFactory.new_normal_indexing_update_target(
273
279
  type: name,
@@ -6,7 +6,7 @@
6
6
  #
7
7
  # frozen_string_literal: true
8
8
 
9
- require "elastic_graph/json_schema/meta_schema_validator"
9
+ require "elastic_graph/support/json_schema/meta_schema_validator"
10
10
 
11
11
  module ElasticGraph
12
12
  module SchemaDefinition
@@ -169,7 +169,7 @@ module ElasticGraph
169
169
  def json_schema(**options)
170
170
  validatable_json_schema = Support::HashUtil.stringify_keys(options)
171
171
 
172
- if (error_msg = JSONSchema.strict_meta_schema_validator.validate_with_error_message(validatable_json_schema))
172
+ if (error_msg = Support::JSONSchema.strict_meta_schema_validator.validate_with_error_message(validatable_json_schema))
173
173
  raise Errors::SchemaError, "Invalid JSON schema options set on #{self}:\n\n#{error_msg}"
174
174
  end
175
175
 
@@ -180,7 +180,7 @@ module ElasticGraph
180
180
  check_for_circular_dependencies!
181
181
 
182
182
  index_templates, indices = state.object_types_by_name.values
183
- .flat_map(&:indices)
183
+ .filter_map(&:index_def)
184
184
  .sort_by(&:name)
185
185
  .partition(&:rollover_config)
186
186
 
@@ -220,7 +220,7 @@ module ElasticGraph
220
220
  .to_h { |t| [t.name, t.runtime_metadata] }
221
221
  .merge(indexed_enum_types_by_name)
222
222
 
223
- index_definitions_by_name = state.object_types_by_name.values.flat_map(&:indices).to_h do |index|
223
+ index_definitions_by_name = state.object_types_by_name.values.filter_map(&:index_def).to_h do |index|
224
224
  [index.name, index.runtime_metadata]
225
225
  end
226
226
 
@@ -246,7 +246,7 @@ module ElasticGraph
246
246
  ::Hash.new { |h, k| h[k] = [] } # : ::Hash[untyped, ::Array[SchemaArtifacts::RuntimeMetadata::UpdateTarget]]
247
247
  ) do |object_type, accum|
248
248
  fields_with_sources_by_relationship_name =
249
- if object_type.indices.empty?
249
+ if object_type.index_def.nil?
250
250
  # only indexed types can have `sourced_from` fields, and resolving `fields_with_sources` on an unindexed union type
251
251
  # such as `_Entity` when we are using apollo can lead to exceptions when multiple entity types have the same field name
252
252
  # that use different mapping types.
@@ -274,7 +274,7 @@ module ElasticGraph
274
274
  resolved_relationship, relationship_error = relationship_resolver.resolve
275
275
  relationship_errors << relationship_error if relationship_error
276
276
 
277
- if object_type.indices.any? && resolved_relationship && sourced_fields.any?
277
+ if object_type.index_def && resolved_relationship && sourced_fields.any?
278
278
  update_target_resolver = Indexing::UpdateTargetResolver.new(
279
279
  object_type: object_type,
280
280
  resolved_relationship: resolved_relationship,
@@ -222,6 +222,15 @@ module ElasticGraph
222
222
  When `null` is passed, matches all documents.
223
223
  EOS
224
224
  end
225
+
226
+ t.field names.matches_query_with_prefix, schema_def_state.type_ref("MatchesQueryWithPrefix").as_filter_input.name do |f|
227
+ f.documentation <<~EOS
228
+ Matches records where the field value matches the provided query with the last term treated as a prefix.
229
+ Similar to `#{names.matches_query}`, but allows prefix matching on the last term.
230
+
231
+ When `null` is passed, matches all documents.
232
+ EOS
233
+ end
225
234
  end.each do |input_type|
226
235
  field_type = input_type.type_ref.list_filter_input? ? "[String]" : "String"
227
236
  input_type.documentation <<~EOS
@@ -287,6 +296,42 @@ module ElasticGraph
287
296
  remove_any_of_and_all_of_and_not_filter_operators_on(t)
288
297
  end
289
298
 
299
+ register_filter "MatchesQueryWithPrefix" do |t|
300
+ t.documentation <<~EOS
301
+ Input type used to specify parameters for the `#{names.matches_query_with_prefix}` filtering operator.
302
+
303
+ When `null` is passed, matches all documents.
304
+ EOS
305
+
306
+ t.field names.query_with_prefix, "String!" do |f|
307
+ f.documentation "The input query to search for, with the last term treated as a prefix."
308
+ end
309
+
310
+ t.field names.allowed_edits_per_term, "MatchesQueryAllowedEditsPerTerm!" do |f|
311
+ f.documentation <<~EOS
312
+ Number of allowed modifications per term to arrive at a match. For example, if set to 'ONE', the input
313
+ term 'glue' would match 'blue' but not 'clued', since the latter requires two modifications.
314
+ EOS
315
+
316
+ f.default "DYNAMIC"
317
+ end
318
+
319
+ t.field names.require_all_terms, "Boolean!" do |f|
320
+ f.documentation <<~EOS
321
+ Set to `true` to match only if all terms in `#{names.query_with_prefix}` are found, or
322
+ `false` to only require one term to be found.
323
+ EOS
324
+
325
+ f.default false
326
+ end
327
+
328
+ # any_of/all_of/not don't really make sense on this filter because it doesn't make sense
329
+ # to apply an OR operator or negation to the fields of this type since they are all an
330
+ # indivisible part of a single filter operation on a specific field. So we remove them
331
+ # here.
332
+ remove_any_of_and_all_of_and_not_filter_operators_on(t)
333
+ end
334
+
290
335
  register_filter "StringContains" do |t|
291
336
  t.documentation <<~EOS
292
337
  Input type used to specify parameters for the `#{names.contains}` string filtering operator.
@@ -1045,7 +1045,7 @@ module ElasticGraph
1045
1045
  # are exactly equal (in which case we can return either).
1046
1046
  #
1047
1047
  # @private
1048
- def self.pick_most_accurate_from(field1, field2, to_comparable: ->(it) { it })
1048
+ def self.pick_most_accurate_from(field1, field2, to_comparable: ->(value) { value })
1049
1049
  return field1 if to_comparable.call(field1) == to_comparable.call(field2)
1050
1050
  yield if field1.accuracy_confidence == field2.accuracy_confidence
1051
1051
  # Array#max_by can return nil (when called on an empty array), but our steep type is non-nil.
@@ -14,6 +14,7 @@ module ElasticGraph
14
14
  # @private
15
15
  class GraphQLSDLEnumerator
16
16
  include ::Enumerable
17
+
17
18
  # @dynamic schema_def_state
18
19
  attr_reader :schema_def_state
19
20
 
@@ -28,6 +28,7 @@ module ElasticGraph
28
28
  # @private
29
29
  class TypeReference < Support::MemoizableData.define(:name, :schema_def_state)
30
30
  extend Forwardable
31
+
31
32
  # @dynamic type_namer
32
33
  def_delegator :schema_def_state, :type_namer
33
34
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticgraph-schema_definition
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Myron Marston
@@ -17,82 +17,68 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 1.0.0
20
+ version: 1.0.2
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 1.0.0
27
+ version: 1.0.2
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: elasticgraph-indexer
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - '='
33
33
  - !ruby/object:Gem::Version
34
- version: 1.0.0
34
+ version: 1.0.2
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '='
40
40
  - !ruby/object:Gem::Version
41
- version: 1.0.0
42
- - !ruby/object:Gem::Dependency
43
- name: elasticgraph-json_schema
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - '='
47
- - !ruby/object:Gem::Version
48
- version: 1.0.0
49
- type: :runtime
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - '='
54
- - !ruby/object:Gem::Version
55
- version: 1.0.0
41
+ version: 1.0.2
56
42
  - !ruby/object:Gem::Dependency
57
43
  name: elasticgraph-schema_artifacts
58
44
  requirement: !ruby/object:Gem::Requirement
59
45
  requirements:
60
46
  - - '='
61
47
  - !ruby/object:Gem::Version
62
- version: 1.0.0
48
+ version: 1.0.2
63
49
  type: :runtime
64
50
  prerelease: false
65
51
  version_requirements: !ruby/object:Gem::Requirement
66
52
  requirements:
67
53
  - - '='
68
54
  - !ruby/object:Gem::Version
69
- version: 1.0.0
55
+ version: 1.0.2
70
56
  - !ruby/object:Gem::Dependency
71
57
  name: elasticgraph-support
72
58
  requirement: !ruby/object:Gem::Requirement
73
59
  requirements:
74
60
  - - '='
75
61
  - !ruby/object:Gem::Version
76
- version: 1.0.0
62
+ version: 1.0.2
77
63
  type: :runtime
78
64
  prerelease: false
79
65
  version_requirements: !ruby/object:Gem::Requirement
80
66
  requirements:
81
67
  - - '='
82
68
  - !ruby/object:Gem::Version
83
- version: 1.0.0
69
+ version: 1.0.2
84
70
  - !ruby/object:Gem::Dependency
85
71
  name: graphql
86
72
  requirement: !ruby/object:Gem::Requirement
87
73
  requirements:
88
- - - "~>"
74
+ - - '='
89
75
  - !ruby/object:Gem::Version
90
76
  version: 2.5.11
91
77
  type: :runtime
92
78
  prerelease: false
93
79
  version_requirements: !ruby/object:Gem::Requirement
94
80
  requirements:
95
- - - "~>"
81
+ - - '='
96
82
  - !ruby/object:Gem::Version
97
83
  version: 2.5.11
98
84
  - !ruby/object:Gem::Dependency
@@ -135,56 +121,56 @@ dependencies:
135
121
  requirements:
136
122
  - - '='
137
123
  - !ruby/object:Gem::Version
138
- version: 1.0.0
124
+ version: 1.0.2
139
125
  type: :development
140
126
  prerelease: false
141
127
  version_requirements: !ruby/object:Gem::Requirement
142
128
  requirements:
143
129
  - - '='
144
130
  - !ruby/object:Gem::Version
145
- version: 1.0.0
131
+ version: 1.0.2
146
132
  - !ruby/object:Gem::Dependency
147
133
  name: elasticgraph-datastore_core
148
134
  requirement: !ruby/object:Gem::Requirement
149
135
  requirements:
150
136
  - - '='
151
137
  - !ruby/object:Gem::Version
152
- version: 1.0.0
138
+ version: 1.0.2
153
139
  type: :development
154
140
  prerelease: false
155
141
  version_requirements: !ruby/object:Gem::Requirement
156
142
  requirements:
157
143
  - - '='
158
144
  - !ruby/object:Gem::Version
159
- version: 1.0.0
145
+ version: 1.0.2
160
146
  - !ruby/object:Gem::Dependency
161
147
  name: elasticgraph-elasticsearch
162
148
  requirement: !ruby/object:Gem::Requirement
163
149
  requirements:
164
150
  - - '='
165
151
  - !ruby/object:Gem::Version
166
- version: 1.0.0
152
+ version: 1.0.2
167
153
  type: :development
168
154
  prerelease: false
169
155
  version_requirements: !ruby/object:Gem::Requirement
170
156
  requirements:
171
157
  - - '='
172
158
  - !ruby/object:Gem::Version
173
- version: 1.0.0
159
+ version: 1.0.2
174
160
  - !ruby/object:Gem::Dependency
175
161
  name: elasticgraph-opensearch
176
162
  requirement: !ruby/object:Gem::Requirement
177
163
  requirements:
178
164
  - - '='
179
165
  - !ruby/object:Gem::Version
180
- version: 1.0.0
166
+ version: 1.0.2
181
167
  type: :development
182
168
  prerelease: false
183
169
  version_requirements: !ruby/object:Gem::Requirement
184
170
  requirements:
185
171
  - - '='
186
172
  - !ruby/object:Gem::Version
187
- version: 1.0.0
173
+ version: 1.0.2
188
174
  email:
189
175
  - myron@squareup.com
190
176
  executables: []
@@ -269,10 +255,10 @@ licenses:
269
255
  - MIT
270
256
  metadata:
271
257
  bug_tracker_uri: https://github.com/block/elasticgraph/issues
272
- changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.0.0
273
- documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.0.0/
258
+ changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.0.2
259
+ documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.0.2/
274
260
  homepage_uri: https://block.github.io/elasticgraph/
275
- source_code_uri: https://github.com/block/elasticgraph/tree/v1.0.0/elasticgraph-schema_definition
261
+ source_code_uri: https://github.com/block/elasticgraph/tree/v1.0.2/elasticgraph-schema_definition
276
262
  gem_category: local
277
263
  rdoc_options: []
278
264
  require_paths: