graphiti 2.0.0.beta.11 → 2.0.0.beta.12

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: a639e421891e5d5e650d2d8131a75905cb9ffd0fb40cdfd15239ca5caf29d12f
4
- data.tar.gz: 95172bbff224d598c959d5acc93c30861e01c50540fdea871ea5029473bf5259
3
+ metadata.gz: 6e73d0272cfabe57d3eb0cbc82ad7199dea624afead6856ca72c1107857fa144
4
+ data.tar.gz: 795ddb1e77c8f61d2e74c66c333ccc4acd5c37ccb6aa3b4c7cb816f52dfe1b71
5
5
  SHA512:
6
- metadata.gz: 24c275cfcaecdba9ced126b7970b37962998673a3a8609c885a69befc53adba646ec2c7d9517198509e358ebba5300f3b336c86f02df98af9d18a6f4a4c306c3
7
- data.tar.gz: e7d2fd4e0d0ff74b68ea4d3673399d1b72897ad7c8647fa38835ff2b58c850d58ba95a1145a52f55893e88e36eb0aa90bece72a2e6e593173661d16100666edc
6
+ metadata.gz: f5ff1c0630702209372d0512afd16d29c87d6f561c551e08a5080bd25efa8b3bae465d33729129289a3ade41db781b779bffd753b55f6cf7cf02389662fa835e
7
+ data.tar.gz: '0785ff7bd32570ef7bf588c7287b4704d7f9daf50bafb47f0739f02b054086a297cef4427364f818b5ab540a72935447bead5898957f597a400a40b435f4a81f'
@@ -85,6 +85,12 @@ jobs:
85
85
  bundler-cache: true
86
86
  - name: Run tests
87
87
  run: bundle exec rspec
88
+ # spec_helper narrows "bundle exec rspec" to spec/integration/rails when
89
+ # APPRAISAL_INITIALIZED is set, so the step above never runs the library
90
+ # suite. This is the only cell that runs it against a pinned Rails.
91
+ - name: Run the library suite against this Rails
92
+ if: matrix.appraisal
93
+ run: env -u APPRAISAL_INITIALIZED bundle exec rspec
88
94
  example-app:
89
95
  name: "Example app (employee_directory)"
90
96
  runs-on: ubuntu-latest
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  graphiti changelog
2
2
 
3
+ # [2.0.0-beta.12](https://github.com/graphiti-api/graphiti/compare/v2.0.0-beta.11...v2.0.0-beta.12) (2026-08-30)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * compare each concurrency path against itself in the table to better illustrate the performance wins ([d0f0e92](https://github.com/graphiti-api/graphiti/commit/d0f0e92860b3b4affe3fca6dbb9b871fe8a1374f))
9
+
10
+
11
+ ### Features
12
+
13
+ * add schema rake tasks, so checking a schema no longer means running the suite ([6f4783d](https://github.com/graphiti-api/graphiti/commit/6f4783d5654659125b7eb358bf1175b6feaacb7c))
14
+ * declare Graphiti's client errors in rescue_responses ([e369824](https://github.com/graphiti-api/graphiti/commit/e369824d6e11b671ffd212caad3d0a43a7ceefcf))
15
+ * mark deprecated settings in the generated ApplicationResource ([52b0642](https://github.com/graphiti-api/graphiti/commit/52b0642e689a16d14dacaf4e28a2641f10774cf0))
16
+ * take error text from locale keys ([d01fd06](https://github.com/graphiti-api/graphiti/commit/d01fd06fc1ede8c3dd798ec48de4d5b01645d87e)), closes [#216](https://github.com/graphiti-api/graphiti/issues/216)
17
+
3
18
  # [2.0.0-beta.11](https://github.com/graphiti-api/graphiti/compare/v2.0.0-beta.10...v2.0.0-beta.11) (2026-08-27)
4
19
 
5
20
 
@@ -50,11 +50,12 @@ module Graphiti
50
50
  end
51
51
 
52
52
  def resource_setting_hint(setting)
53
- return setting[:note] if setting[:note]
54
- return unless setting[:values]
53
+ hint = setting[:note] || setting[:values]&.map(&:inspect)
54
+ &.to_sentence(two_words_connector: " or ", last_word_connector: ", or ")
55
55
 
56
- setting[:values].map(&:inspect)
57
- .to_sentence(two_words_connector: " or ", last_word_connector: ", or ")
56
+ return hint unless setting[:deprecated]
57
+
58
+ ["deprecated, removed in 3.0", hint].compact.join(". ")
58
59
  end
59
60
 
60
61
  def graphiti_config
@@ -1,4 +1,5 @@
1
1
  require_relative "generator_mixin"
2
+ require_relative "locale_generator"
2
3
 
3
4
  module Graphiti
4
5
  class InstallGenerator < ::Rails::Generators::Base
@@ -17,6 +18,8 @@ module Graphiti
17
18
  to = File.join("app/resources", "application_resource.rb")
18
19
  template("application_resource.rb.erb", to)
19
20
 
21
+ invoke(Graphiti::LocaleGenerator, [], options)
22
+
20
23
  inject_into_file "app/controllers/application_controller.rb", after: "class ApplicationController < ActionController::API\n" do
21
24
  app_controller_code
22
25
  end
@@ -0,0 +1,30 @@
1
+ module Graphiti
2
+ class LocaleGenerator < ::Rails::Generators::Base
3
+ source_root File.expand_path("templates", __dir__)
4
+
5
+ class_option :"omit-comments",
6
+ type: :boolean,
7
+ default: false,
8
+ aliases: ["-c"],
9
+ desc: "Generate without documentation comments"
10
+
11
+ desc "Writes the error text Graphiti renders, ready to edit"
12
+ def locale
13
+ template("locale.yml.erb", File.join("config/locales", "graphiti.en.yml"))
14
+ end
15
+
16
+ private
17
+
18
+ def omit_comments?
19
+ @options["omit-comments"]
20
+ end
21
+
22
+ def default_messages
23
+ Graphiti::Util::SimpleErrors::DEFAULT_MESSAGES
24
+ end
25
+
26
+ def default_format
27
+ Graphiti::Util::SimpleErrors::DEFAULT_FORMAT
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ <%- unless omit_comments? -%>
2
+ # Everything Graphiti puts in an errors payload.
3
+ # For another language, add a block below or a graphiti.<locale>.yml file.
4
+ <%- end -%>
5
+ en:
6
+ graphiti:
7
+ errors:
8
+ <%- unless omit_comments? -%>
9
+ # Titles and details are keyed by error code, and Graphiti ships none.
10
+ # Without a key you get the HTTP status name and no detail.
11
+ #
12
+ # internal_server_error:
13
+ # title: "Something went wrong"
14
+ # detail: "We've probably received an error report already, but please contact us if the issue persists."
15
+ #
16
+ # format joins them: "data.attributes.title is an unknown attribute".
17
+ <%- end -%>
18
+ format: <%= default_format.inspect %>
19
+ messages:
20
+ <%- default_messages.each do |code, message| -%>
21
+ <%= code %>: <%= message.inspect %>
22
+ <%- end -%>
@@ -11,7 +11,7 @@ module Graphiti
11
11
  "conflict"
12
12
  end
13
13
 
14
- def title
14
+ def default_title
15
15
  "Conflict Error"
16
16
  end
17
17
  end
@@ -1,25 +1,15 @@
1
- # The graphiti_errors gem was absorbed into graphiti in 2.0. Only its
2
- # serializers survived, as Graphiti::ErrorSerializers. The rest of it (the
3
- # GraphitiErrors controller mixin and its exception handlers) is replaced by
4
- # rescue_registry rather than renamed, so there is deliberately nothing here to
5
- # alias it to. A custom error renderer reaching for one of the serializers gets
6
- # pointed at the new name instead of a bare NameError. Remove in 3.0.
1
+ # Only graphiti_errors' serializers survived the 2.0 merge. Remove in 3.0.
7
2
  module GraphitiErrors
8
- # `include GraphitiErrors` in ApplicationController was this gem's headline
9
- # usage. Including an empty module succeeds, so without this an upgraded app
10
- # boots clean and then serves Rails' default HTML error pages instead of
11
- # JSON:API ones, with nothing to indicate why.
3
+ # Including an empty module succeeds, so silence here means HTML error pages.
12
4
  def self.included(klass)
13
5
  raise <<~MSG
14
- GraphitiErrors was merged into graphiti as of 2.0 and `include GraphitiErrors`
15
- no longer does anything.
16
-
17
- Exception handling now goes through rescue_registry. Replace it with:
6
+ GraphitiErrors merged into graphiti in 2.0 and this include does nothing. Use:
18
7
 
19
8
  include Graphiti::Rails::Controller
20
9
 
21
- which registers Graphiti's own handlers. Your own go alongside them with
22
- `register_exception`, available on every controller.
10
+ Your own exceptions register alongside Graphiti's with `register_exception`.
11
+ `registered_exception?` is now `RescueRegistry.handles_exception?`, and
12
+ `handle_exception` went with the rendering. See graphiti.dev/upgrading.
23
13
  MSG
24
14
  end
25
15
 
@@ -49,6 +49,12 @@ module Graphiti
49
49
  end
50
50
 
51
51
  def title
52
+ return default_title unless defined?(::I18n)
53
+
54
+ ::I18n.t :title, scope: [:graphiti, :errors, code], default: default_title
55
+ end
56
+
57
+ def default_title
52
58
  "Request Error"
53
59
  end
54
60
 
@@ -40,6 +40,23 @@ module Graphiti
40
40
  end
41
41
  super
42
42
  end
43
+
44
+ private
45
+
46
+ def title_from_status
47
+ translate(:title) || super
48
+ end
49
+
50
+ # rescue_registry's default tells the client its engineers have been notified.
51
+ def default_detail_for_status
52
+ translate(:detail)
53
+ end
54
+
55
+ def translate(key)
56
+ return unless defined?(::I18n)
57
+
58
+ ::I18n.t key, scope: [:graphiti, :errors, error_code], default: nil
59
+ end
43
60
  end
44
61
 
45
62
  class FallbackHandler < ExceptionHandler
@@ -20,6 +20,16 @@ module Graphiti
20
20
  load File.expand_path("../../tasks/graphiti.rake", __dir__)
21
21
  end
22
22
 
23
+ # ActionDispatch has already copied config.action_dispatch.rescue_responses into the wrapper by now.
24
+ initializer "graphiti-rails.rescue_responses", after: "action_dispatch.configure" do
25
+ responses = ActionDispatch::ExceptionWrapper.rescue_responses
26
+
27
+ Graphiti::Rails::CLIENT_ERROR_STATUSES.each do |exception, status|
28
+ # rescue_responses answers :internal_server_error for a missing key, so ||= never assigns.
29
+ responses[exception] = status unless responses.key?(exception)
30
+ end
31
+ end
32
+
23
33
  initializer "graphiti-rails.config" do |app|
24
34
  Graphiti::Rails.handled_exception_formats = app.config.graphiti.handled_exception_formats
25
35
  Graphiti::Rails.respond_to_formats = app.config.graphiti.respond_to_formats
@@ -15,6 +15,11 @@ module Graphiti
15
15
  @session ||= ActionDispatch::Integration::Session.new(::Rails.application)
16
16
  end
17
17
 
18
+ # An engine runs the task from its own directory, not the host application's root.
19
+ def schema_path(path = nil)
20
+ path.nil? ? Graphiti.config.schema_path : File.expand_path(path, Dir.pwd)
21
+ end
22
+
18
23
  def setup_rails!
19
24
  ::Rails.application.eager_load!
20
25
  ::Rails.application.config.cache_classes = true
@@ -38,6 +38,24 @@ module Graphiti
38
38
  DEPRECATOR
39
39
  )
40
40
 
41
+ # Rails reports an exception to the error reporter unless its rescue_responses names it.
42
+ CLIENT_ERROR_STATUSES = {
43
+ "Graphiti::Errors::InvalidRequest" => :bad_request,
44
+ "Graphiti::Errors::RemoteWrite" => :bad_request,
45
+ "Graphiti::Errors::SingularSideload" => :bad_request,
46
+ "Graphiti::Errors::InvalidInclude" => :bad_request,
47
+ "Graphiti::Errors::UnsupportedSort" => :bad_request,
48
+ "Graphiti::Errors::UnsupportedOperator" => :bad_request,
49
+ "Graphiti::Errors::InvalidFilterValue" => :bad_request,
50
+ "Graphiti::Errors::RequiredFilter" => :bad_request,
51
+ "Graphiti::Errors::UnsupportedPageSize" => :bad_request,
52
+ "Graphiti::Errors::UnsupportedBeforeCursor" => :bad_request,
53
+ "Graphiti::Errors::UnsupportedPagination" => :bad_request,
54
+ "Graphiti::Errors::FilterGroupMissingRequiredFilters" => :bad_request,
55
+ "Graphiti::Errors::RecordNotFound" => :not_found,
56
+ "Graphiti::Errors::ConflictRequest" => :conflict
57
+ }.freeze
58
+
41
59
  # @!attribute self.handled_exception_formats
42
60
  # A list of formats as symbols whose exceptions will be handled by Graphiti. See {Railtie}.
43
61
  cattr_accessor :handled_exception_formats, default: []
@@ -13,11 +13,7 @@ module Graphiti
13
13
 
14
14
  def attribute_mismatch(attr_path)
15
15
  @error_class = Graphiti::Errors::ConflictRequest
16
- @errors.add(
17
- attr_path.join("."),
18
- :attribute_mismatch,
19
- message: "does not match the server endpoint"
20
- )
16
+ @errors.add(attr_path.join("."), :attribute_mismatch)
21
17
  end
22
18
 
23
19
  def required_payload?
@@ -54,14 +54,14 @@ module Graphiti
54
54
  page = @params[:page]
55
55
  return if page.nil? || page.respond_to?(:each_pair)
56
56
 
57
- @errors.add(:page, :invalid, message: "must be an object")
57
+ @errors.add(:page, :invalid)
58
58
  end
59
59
 
60
60
  def validate_data_shape
61
61
  data = @params[:data]
62
62
  return true if data.nil? || data.respond_to?(:each_pair)
63
63
 
64
- @errors.add(:data, :invalid, message: "must be an object")
64
+ @errors.add(:data, :invalid)
65
65
  false
66
66
  end
67
67
 
@@ -69,7 +69,7 @@ module Graphiti
69
69
  relationships.each_key do |name|
70
70
  unless resource.class.sideload(name.to_sym)
71
71
  full_key = fully_qualified_key(name, payload_path, :relationships)
72
- @errors.add(full_key, :invalid_relationship, message: "is not a valid relationship")
72
+ @errors.add(full_key, :invalid_relationship)
73
73
  end
74
74
  end
75
75
 
@@ -110,11 +110,11 @@ module Graphiti
110
110
  begin
111
111
  attributes[key] = resource.typecast(key, value, :writable)
112
112
  rescue Graphiti::Errors::UnknownAttribute
113
- @errors.add(fully_qualified_key(key, payload_path), :unknown_attribute, message: "is an unknown attribute")
113
+ @errors.add(fully_qualified_key(key, payload_path), :unknown_attribute)
114
114
  rescue Graphiti::Errors::InvalidAttributeAccess
115
- @errors.add(fully_qualified_key(key, payload_path), :unwritable_attribute, message: "cannot be written")
115
+ @errors.add(fully_qualified_key(key, payload_path), :unwritable_attribute)
116
116
  rescue Graphiti::Errors::TypecastFailed => e
117
- @errors.add(fully_qualified_key(key, payload_path), :type_error, message: "should be type #{e.type_name}")
117
+ @errors.add(fully_qualified_key(key, payload_path), :type_error, type: e.type_name)
118
118
  end
119
119
  end
120
120
  end
@@ -0,0 +1,69 @@
1
+ module Graphiti
2
+ class Schema
3
+ class Check
4
+ attr_reader :path, :errors
5
+
6
+ def initialize(schema, path)
7
+ @path = path
8
+ @schema = schema
9
+ @generated = normalize(schema)
10
+ @committed = normalize(JSON.parse(File.read(path))) if File.exist?(path)
11
+ @errors = @committed ? SchemaDiff.new(@committed, @generated).compare : []
12
+ end
13
+
14
+ def missing?
15
+ @committed.nil?
16
+ end
17
+
18
+ def stale?
19
+ !missing? && @committed != @generated
20
+ end
21
+
22
+ def compatible?
23
+ errors.empty?
24
+ end
25
+
26
+ def ok?
27
+ !missing? && !stale? && compatible?
28
+ end
29
+
30
+ def write!
31
+ FileUtils.mkdir_p(File.dirname(path))
32
+ File.write(path, JSON.pretty_generate(@schema))
33
+ path
34
+ end
35
+
36
+ def message
37
+ return "Schema is up to date: #{path}" if ok?
38
+ return "#{missing_message}\n\n#{regenerate}" if missing?
39
+ return "#{incompatible_message}\n\n#{errors.join("\n")}" unless compatible?
40
+
41
+ "Schema file is outdated: #{path}\n\n#{regenerate}"
42
+ end
43
+
44
+ private
45
+
46
+ def normalize(schema)
47
+ JSON.parse(JSON.generate(schema))
48
+ end
49
+
50
+ def missing_message
51
+ "Schema file not found: #{path}"
52
+ end
53
+
54
+ def incompatible_message
55
+ <<~MSG.chomp
56
+ Found backwards-incompatibilities in schema: #{path}
57
+
58
+ Re-run with FORCE_SCHEMA=true to accept them and overwrite the file.
59
+
60
+ Incompatibilities:
61
+ MSG
62
+ end
63
+
64
+ def regenerate
65
+ "Run `rake graphiti:schema:generate` and commit the file."
66
+ end
67
+ end
68
+ end
69
+ end
@@ -11,19 +11,18 @@ module Graphiti
11
11
  new(resources).generate
12
12
  end
13
13
 
14
- def self.generate!(resources = nil)
15
- schema = generate(resources)
14
+ def self.generate!(resources = nil, path: Graphiti.config.schema_path, force: ENV["FORCE_SCHEMA"] == "true")
15
+ result = check(resources, path: path)
16
+ return result.errors if !force && !result.compatible?
16
17
 
17
- if ENV["FORCE_SCHEMA"] != "true" && File.exist?(Graphiti.config.schema_path)
18
- old = JSON.parse(File.read(Graphiti.config.schema_path))
19
- errors = Graphiti::SchemaDiff.new(old, schema).compare
20
- return errors if errors.any?
21
- end
22
- FileUtils.mkdir_p(Graphiti.config.schema_path.to_s.gsub("/schema.json", ""))
23
- File.write(Graphiti.config.schema_path, JSON.pretty_generate(schema))
18
+ result.write!
24
19
  []
25
20
  end
26
21
 
22
+ def self.check(resources = nil, path: Graphiti.config.schema_path)
23
+ Check.new(generate(resources), path)
24
+ end
25
+
27
26
  def initialize(resources)
28
27
  @resources = resources.sort_by(&:name)
29
28
  @remote_resources = @resources.select(&:remote?)
@@ -127,22 +127,14 @@ module Graphiti
127
127
  end
128
128
  end
129
129
 
130
- def self.schema!(resources = nil)
130
+ def self.schema!(resources = nil, path: nil)
131
131
  ::RSpec.describe "Graphiti Schema" do
132
132
  it "generates a backwards-compatible schema" do
133
- message = <<~MSG
134
- Found backwards-incompatibilities in schema! Run with FORCE_SCHEMA=true to ignore.
133
+ check = Graphiti::Schema.check(resources, path: path || Graphiti.config.schema_path)
134
+ forced = ENV["FORCE_SCHEMA"] == "true"
135
+ check.write! if check.compatible? || forced
135
136
 
136
- Incompatibilities:
137
-
138
- MSG
139
-
140
- errors = Graphiti::Schema.generate!(resources)
141
- errors.each do |e|
142
- message << "#{e}\n"
143
- end
144
-
145
- expect(errors.empty?).to eq(true), message
137
+ expect(check.compatible? || forced).to eq(true), check.message
146
138
  end
147
139
  end
148
140
  end
@@ -6,6 +6,21 @@ module Graphiti
6
6
  class SimpleErrors
7
7
  include Enumerable
8
8
 
9
+ # Overridable under graphiti.errors.messages.
10
+ DEFAULT_MESSAGES = {
11
+ missing: "is missing",
12
+ invalid: "must be an object",
13
+ invalid_relationship: "is not a valid relationship",
14
+ unwritable_relationship: "cannot be written",
15
+ unknown_attribute: "is an unknown attribute",
16
+ unwritable_attribute: "cannot be written",
17
+ type_error: "should be type %{type}",
18
+ attribute_mismatch: "does not match the server endpoint"
19
+ }.freeze
20
+
21
+ # Joins an attribute to its message, like Rails' own errors.format.
22
+ DEFAULT_FORMAT = "%{attribute} %{message}"
23
+
9
24
  attr_reader :messages, :details
10
25
 
11
26
  def initialize(validation_target)
@@ -50,11 +65,9 @@ module Graphiti
50
65
  end
51
66
  alias_method :blank?, :empty?
52
67
 
53
- def add(attribute, code, message: nil)
54
- message ||= "is #{code.to_s.humanize.downcase}"
55
-
68
+ def add(attribute, code, message: nil, **interpolations)
56
69
  details[attribute.to_sym] << {error: code}
57
- messages[attribute.to_sym] << message
70
+ messages[attribute.to_sym] << translate(code, message, **interpolations, attribute: attribute)
58
71
  end
59
72
 
60
73
  def added?(attribute, code)
@@ -73,11 +86,19 @@ module Graphiti
73
86
 
74
87
  def full_message(attribute, message)
75
88
  return message if attribute == :base
76
- "#{attribute} #{message}"
89
+
90
+ translate(:format, DEFAULT_FORMAT, [:graphiti, :errors], attribute: attribute, message: message)
77
91
  end
78
92
 
79
93
  private
80
94
 
95
+ def translate(key, fallback, scope = [:graphiti, :errors, :messages], **interpolations)
96
+ fallback ||= DEFAULT_MESSAGES.fetch(key) { "is #{key.to_s.humanize.downcase}" }
97
+ return fallback % interpolations unless defined?(::I18n)
98
+
99
+ ::I18n.t(key, scope: scope, default: fallback, **interpolations)
100
+ end
101
+
81
102
  def apply_default_array(hash)
82
103
  hash.default_proc = proc { |h, key| h[key] = [] }
83
104
  hash
@@ -1,3 +1,3 @@
1
1
  module Graphiti
2
- VERSION = "2.0.0.beta.11"
2
+ VERSION = "2.0.0.beta.12"
3
3
  end
data/lib/graphiti.rb CHANGED
@@ -175,6 +175,7 @@ require "graphiti/audit"
175
175
  require "graphiti/audit/report"
176
176
  require "graphiti/schema"
177
177
  require "graphiti/schema_diff"
178
+ require "graphiti/schema/check"
178
179
  require "graphiti/adapters/abstract"
179
180
  require "graphiti/resource/sideloading"
180
181
  require "graphiti/resource/links"
@@ -16,6 +16,24 @@ namespace :graphiti do
16
16
  Graphiti::Debugger.flush if debug
17
17
  end
18
18
 
19
+ namespace :schema do
20
+ desc "Write the schema file. Refuses backwards-incompatible changes unless FORCE_SCHEMA=true. Takes an optional path, defaulting to Graphiti.config.schema_path."
21
+ task :generate, [:path] => [:environment] do |_, args|
22
+ check = Graphiti::Schema.check(path: helpers.schema_path(args[:path]))
23
+ abort check.message unless check.compatible? || ENV["FORCE_SCHEMA"] == "true"
24
+
25
+ puts "Schema written: #{check.write!}"
26
+ end
27
+
28
+ desc "Fail unless the committed schema file exists, is up to date, and is backwards-compatible. Takes an optional path, defaulting to Graphiti.config.schema_path."
29
+ task :check, [:path] => [:environment] do |_, args|
30
+ check = Graphiti::Schema.check(path: helpers.schema_path(args[:path]))
31
+ abort check.message unless check.ok?
32
+
33
+ puts check.message
34
+ end
35
+ end
36
+
19
37
  desc "Audit every relationship: what will raise, what loads to render ids, which render no ids, and which checks passed."
20
38
  task audit: [:environment] do
21
39
  helpers.setup_rails!
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphiti
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta.11
4
+ version: 2.0.0.beta.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
@@ -287,6 +287,7 @@ files:
287
287
  - lib/generators/graphiti/api_test_generator.rb
288
288
  - lib/generators/graphiti/generator_mixin.rb
289
289
  - lib/generators/graphiti/install_generator.rb
290
+ - lib/generators/graphiti/locale_generator.rb
290
291
  - lib/generators/graphiti/resource_generator.rb
291
292
  - lib/generators/graphiti/resource_test_generator.rb
292
293
  - lib/generators/graphiti/templates/application_resource.rb.erb
@@ -294,6 +295,7 @@ files:
294
295
  - lib/generators/graphiti/templates/create_request_spec.rb.erb
295
296
  - lib/generators/graphiti/templates/destroy_request_spec.rb.erb
296
297
  - lib/generators/graphiti/templates/index_request_spec.rb.erb
298
+ - lib/generators/graphiti/templates/locale.yml.erb
297
299
  - lib/generators/graphiti/templates/resource.rb.erb
298
300
  - lib/generators/graphiti/templates/resource_reads_spec.rb.erb
299
301
  - lib/generators/graphiti/templates/resource_writes_spec.rb.erb
@@ -359,6 +361,7 @@ files:
359
361
  - lib/graphiti/responders.rb
360
362
  - lib/graphiti/runner.rb
361
363
  - lib/graphiti/schema.rb
364
+ - lib/graphiti/schema/check.rb
362
365
  - lib/graphiti/schema_diff.rb
363
366
  - lib/graphiti/scope.rb
364
367
  - lib/graphiti/scoping/base.rb