graphiti 2.0.0.beta.13 → 2.0.1
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 +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/CHANGELOG.md +132 -0
- data/Gemfile +1 -2
- data/graphiti.gemspec +1 -1
- data/lib/graphiti/adapters/active_record.rb +10 -13
- data/lib/graphiti/adapters/persistence/associations.rb +5 -1
- data/lib/graphiti/configuration.rb +1 -4
- data/lib/graphiti/debugger.rb +6 -5
- data/lib/graphiti/delegates/pagination.rb +1 -1
- data/lib/graphiti/query.rb +3 -4
- data/lib/graphiti/schema.rb +5 -1
- data/lib/graphiti/sideload.rb +4 -3
- data/lib/graphiti/spec_helpers/rspec.rb +1 -1
- data/lib/graphiti/types.rb +6 -0
- data/lib/graphiti/version.rb +1 -1
- data/lib/tasks/graphiti.rake +7 -4
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c38c96bcf6d48078c1361d22da7e563506b385b4bfe74b7b0fbdb8bd45ccb3a
|
|
4
|
+
data.tar.gz: 52e3079715304dc15408f6945f7515a6ba07db792cc55eda66887d2227e533c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab09db3099f66a44e8a453ee336aa93075b06a5cb46119a505380d08e9a7ae305f58da4a5822e319fb0e74b381537aee556681bcc6b9e353a7d1bec58705b2fa
|
|
7
|
+
data.tar.gz: 963db95d086610db6bd4600b56db8674804aac397ef4e4bbf687a387d4f2fea10cee7b0842f7d7d2bc89d65387210702d93b810819e5e663a8e7ed46bad9d6f5
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,129 @@
|
|
|
1
1
|
graphiti changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.1](https://github.com/graphiti-api/graphiti/compare/v2.0.0...v2.0.1) (2026-09-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* count distinct on the primary key rather than every column ([be85c18](https://github.com/graphiti-api/graphiti/commit/be85c18b695bf482f95ae72496600b40e3531c44)), closes [#439](https://github.com/graphiti-api/graphiti/issues/439)
|
|
9
|
+
* keep the request body out of pagination links ([64040f2](https://github.com/graphiti-api/graphiti/commit/64040f200c307062d0b04204013e35963cec4ceb)), closes [#369](https://github.com/graphiti-api/graphiti/issues/369)
|
|
10
|
+
* read flags through one coercion ([72a39a7](https://github.com/graphiti-api/graphiti/commit/72a39a7c126e2d6d89fb4a829cad20efd207df4d))
|
|
11
|
+
* respect polymorphic_name when sideposting ([45d9eb7](https://github.com/graphiti-api/graphiti/commit/45d9eb73b1dba2e4587ee67387f0c3117c9c4fcf)), closes [#437](https://github.com/graphiti-api/graphiti/issues/437)
|
|
12
|
+
* stop the debugger requiring an id on every model ([8111b68](https://github.com/graphiti-api/graphiti/commit/8111b6897bd735bed84a63c312a6a01cf69317a1)), closes [#152](https://github.com/graphiti-api/graphiti/issues/152)
|
|
13
|
+
|
|
14
|
+
# [2.0.0](https://github.com/graphiti-api/graphiti/compare/v1.13.3...v2.0.0) (2026-09-01)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* a subclass redeclaring a relationship reaches its serializer ([976dbc4](https://github.com/graphiti-api/graphiti/commit/976dbc47e7bbf951da925a13a34f1bc9679470f8))
|
|
20
|
+
* accept a single value for array filters ([#517](https://github.com/graphiti-api/graphiti/issues/517)) ([ee685b6](https://github.com/graphiti-api/graphiti/commit/ee685b625e967a8225d48b486bd093e3a6970176))
|
|
21
|
+
* always render included when the client asked to include ([8691b3f](https://github.com/graphiti-api/graphiti/commit/8691b3fd08f3cae0481ba72839911fdc71ef5634))
|
|
22
|
+
* apply sideloads at definition once setup! has run ([39ef393](https://github.com/graphiti-api/graphiti/commit/39ef39383520816319282854c0ae99677bcd5127)), closes [#524](https://github.com/graphiti-api/graphiti/issues/524)
|
|
23
|
+
* autolink = true no longer clobbers an inherited :on_demand ([2d26f8c](https://github.com/graphiti-api/graphiti/commit/2d26f8cb567e82a16918345de9114b8ceef64523))
|
|
24
|
+
* bridge the last 1.x names that died with a bare NameError ([34e1dbd](https://github.com/graphiti-api/graphiti/commit/34e1dbd3e34bb8e6be56292c51fcb32674f75995))
|
|
25
|
+
* build the entity map when the root query is, not on first use ([134d18b](https://github.com/graphiti-api/graphiti/commit/134d18b12b9ebb6903cca813209f60e5626b25a6))
|
|
26
|
+
* coerce debug flags from env strings ([46be6aa](https://github.com/graphiti-api/graphiti/commit/46be6aa05d4e2a9e5d6b2562f223b4b05582bb39))
|
|
27
|
+
* compare each concurrency path against itself in the table to better illustrate the performance wins ([d0f0e92](https://github.com/graphiti-api/graphiti/commit/d0f0e92860b3b4affe3fca6dbb9b871fe8a1374f))
|
|
28
|
+
* compare the endpoint id to the payload id as strings ([62051d7](https://github.com/graphiti-api/graphiti/commit/62051d7531432357db7bc464cce77ccc55168d07))
|
|
29
|
+
* drop the relationship guard install notice ([c204312](https://github.com/graphiti-api/graphiti/commit/c20431214e126cb8e72c82022ee4c852b10a024b))
|
|
30
|
+
* evaluate writable guards under the action being performed ([d56b86a](https://github.com/graphiti-api/graphiti/commit/d56b86a5ffaac4106aaea1e2ee5400069a4205fe))
|
|
31
|
+
* **generators:** stop injecting a routes host into config/application.rb ([db92d06](https://github.com/graphiti-api/graphiti/commit/db92d0649ca0246662a86b1172229eaa2a817d2b))
|
|
32
|
+
* give client-caused errors real detail and stop 500ing on bad query params ([35acc3e](https://github.com/graphiti-api/graphiti/commit/35acc3e6c78f68eeeb05728ea16264b136455c30)), closes [#531](https://github.com/graphiti-api/graphiti/issues/531)
|
|
33
|
+
* keep a belongs_to linkage when another include shares its name ([2c9c7c7](https://github.com/graphiti-api/graphiti/commit/2c9c7c7ac06cd319ac95e1445eb55a0322841de2))
|
|
34
|
+
* keep a customized sideload's instances out of entity dedup ([b1beee3](https://github.com/graphiti-api/graphiti/commit/b1beee3288fae2b20b009983aaa2f6c71189e2ca))
|
|
35
|
+
* keep deep filters narrow when an include path repeats ([833a10b](https://github.com/graphiti-api/graphiti/commit/833a10be120a4f2cd615ad05f750c7f246d62801))
|
|
36
|
+
* keep rake task helpers out of the global namespace ([0a41a60](https://github.com/graphiti-api/graphiti/commit/0a41a6022fa4c9151948714c31db367aee330e22)), closes [graphiti-api/graphiti-rails#91](https://github.com/graphiti-api/graphiti-rails/issues/91)
|
|
37
|
+
* keep request state in fiber storage so it survives into child fibers ([6569935](https://github.com/graphiti-api/graphiti/commit/6569935c2140d4dd91cd6d4a7f9ec7c1bd05c888))
|
|
38
|
+
* let an abstract resource declare relationships ([6036392](https://github.com/graphiti-api/graphiti/commit/6036392ebd611c7ed492beb3fe5754433eac9ffd)), closes [#453](https://github.com/graphiti-api/graphiti/issues/453)
|
|
39
|
+
* make each appraisal test the Rails version it is named for ([9e00652](https://github.com/graphiti-api/graphiti/commit/9e00652e124a411a2916d0fef52dc4fd2dc59020))
|
|
40
|
+
* only register the jsonapi mime type when it is missing ([88401ab](https://github.com/graphiti-api/graphiti/commit/88401abc8c77f1e859b4b8da3f9574c75834eb43))
|
|
41
|
+
* raise a more helpful named error when belongs_to linkage reads an unselected foreign key ([f59ea0b](https://github.com/graphiti-api/graphiti/commit/f59ea0bda94b388b1c2c0ae0e50b258f8ce0eb11))
|
|
42
|
+
* read the links param from the query, not the context object ([3b934cb](https://github.com/graphiti-api/graphiti/commit/3b934cb25be049e1e80ba400123da944cfd23d04))
|
|
43
|
+
* reject a non-object data payload instead of raising TypeError ([51603b8](https://github.com/graphiti-api/graphiti/commit/51603b854270715b80a75d9aa05a4020e6bbdce5))
|
|
44
|
+
* reject invalid page parameters ([#537](https://github.com/graphiti-api/graphiti/issues/537)) ([bb3698b](https://github.com/graphiti-api/graphiti/commit/bb3698b52911c658c5d023ad8fd55b5106195001)), closes [#347](https://github.com/graphiti-api/graphiti/issues/347)
|
|
45
|
+
* remove the unused ActiveRecord adapter create and update ([b66fb8e](https://github.com/graphiti-api/graphiti/commit/b66fb8e5033b2ed7c35b5784cb8bcac67ceaa87f))
|
|
46
|
+
* require active_support so graphiti boots without Rails ([d431a03](https://github.com/graphiti-api/graphiti/commit/d431a0328fb4071429f39f4c69cda9c6cee308f2))
|
|
47
|
+
* require rescue_registry 1.1 for the fiber storage fix ([ac63996](https://github.com/graphiti-api/graphiti/commit/ac63996767d26adccf7ef63d63ac15b591a4a45a))
|
|
48
|
+
* resolve inline when already on a sideload pool thread ([11c9de7](https://github.com/graphiti-api/graphiti/commit/11c9de7fb4bfc2d83b02aaba3e58c1f94c84cec4))
|
|
49
|
+
* scope debugger chunks to the request rather than the class ([9a77896](https://github.com/graphiti-api/graphiti/commit/9a77896c6e56d23b89d0a2aef358d8e8e0c28c54))
|
|
50
|
+
* stop assigning the same child twice when a resource repeats in the include path ([588503b](https://github.com/graphiti-api/graphiti/commit/588503b109508495d8170373d80019c6971f7d9c))
|
|
51
|
+
* surface the first child error from concurrent polymorphic sideloads ([5a08c0e](https://github.com/graphiti-api/graphiti/commit/5a08c0edab2bc1ee0c87c6abbe1067297569411e))
|
|
52
|
+
* treat empty polymorphic configuration as unset ([#538](https://github.com/graphiti-api/graphiti/issues/538)) ([5c17899](https://github.com/graphiti-api/graphiti/commit/5c1789993fbb4638d4443cf014b8bef358addb80)), closes [#199](https://github.com/graphiti-api/graphiti/issues/199)
|
|
53
|
+
* typecast null values in filter lists ([#515](https://github.com/graphiti-api/graphiti/issues/515)) ([3756fd1](https://github.com/graphiti-api/graphiti/commit/3756fd12c48d2fb3cf5e2d40c38aab92f12218b0))
|
|
54
|
+
* Update some missing sections and terms after renames, register unsupported pagination error ([39cff19](https://github.com/graphiti-api/graphiti/commit/39cff19f6f1f73126514c8b18234a18ad5eb7379))
|
|
55
|
+
* with_options accepts the predicate backed relationship options ([71ab441](https://github.com/graphiti-api/graphiti/commit/71ab4418bccc4cff7e6cc10151c1728641d25d34))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
### Code Refactoring
|
|
59
|
+
|
|
60
|
+
* bridge the remaining 1.x names ([3d80ef9](https://github.com/graphiti-api/graphiti/commit/3d80ef98cf765a152032b7fed89b3cdc10be23dc))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### Features
|
|
64
|
+
|
|
65
|
+
* add full set of commented-out Resource defaults in ApplicationResource when using the generator ([367678e](https://github.com/graphiti-api/graphiti/commit/367678eb3c2c737331f8edb00e00e70483a778b4))
|
|
66
|
+
* Add graphiti:audit task to audit resources for issues ([84436ea](https://github.com/graphiti-api/graphiti/commit/84436eab7c7d0713ec6f355b62ba8b06913ee31a))
|
|
67
|
+
* add rspec matchers for resource relationships and attributes ([70525f7](https://github.com/graphiti-api/graphiti/commit/70525f7e10c511aa0c867ecc873f63f1790b8247)), closes [graphiti-api/graphiti_spec_helpers#14](https://github.com/graphiti-api/graphiti_spec_helpers/issues/14)
|
|
68
|
+
* add schema rake tasks, so checking a schema no longer means running the suite ([6f4783d](https://github.com/graphiti-api/graphiti/commit/6f4783d5654659125b7eb358bf1175b6feaacb7c))
|
|
69
|
+
* belongs_to renders resource linkage by default ([024824d](https://github.com/graphiti-api/graphiti/commit/024824d319619811ade886c72ce345cfeb584dbc)), closes [#168](https://github.com/graphiti-api/graphiti/issues/168) [#185](https://github.com/graphiti-api/graphiti/issues/185) [#167](https://github.com/graphiti-api/graphiti/issues/167) [#167](https://github.com/graphiti-api/graphiti/issues/167)
|
|
70
|
+
* carry CurrentAttributes into concurrent sideloads ([7092096](https://github.com/graphiti-api/graphiti/commit/7092096f6d99ad277cc56817c616d946f655d55b))
|
|
71
|
+
* carry the assigned model on the resource, not through override signatures ([8ad848d](https://github.com/graphiti-api/graphiti/commit/8ad848d9bcd24cd63efb67e8ce32d5c8f3cfe147))
|
|
72
|
+
* declare Graphiti's client errors in rescue_responses ([e369824](https://github.com/graphiti-api/graphiti/commit/e369824d6e11b671ffd212caad3d0a43a7ceefcf))
|
|
73
|
+
* dedupe under concurrency and across distinct resources ([800b1a2](https://github.com/graphiti-api/graphiti/commit/800b1a2bf9bb59702efd00afe8e4f54ae06b500e))
|
|
74
|
+
* deduplicate sideloaded entities across include paths ([0c2829a](https://github.com/graphiti-api/graphiti/commit/0c2829a634e9b96e2403ff168be9a48c6a663c78))
|
|
75
|
+
* deprecate SpecHelpers::Sugar in favor of the full helper names ([b155849](https://github.com/graphiti-api/graphiti/commit/b155849f55fe84b2d0911fa4681d82682dfa39ae))
|
|
76
|
+
* drop Ruby 2.7 and Rails 5.2 support ([e905ddb](https://github.com/graphiti-api/graphiti/commit/e905ddb5c842299ffbfe5ec3c4ff98ec9b603a51))
|
|
77
|
+
* fold allow_nil and deny_empty into one blanks: filter option ([a108403](https://github.com/graphiti-api/graphiti/commit/a108403e5cd87fd2fdf177da30c4c4f97b9fe750))
|
|
78
|
+
* fold graphiti_spec_helpers into graphiti ([da955a1](https://github.com/graphiti-api/graphiti/commit/da955a1e090ba44be31bf043ed90baa6661a4772))
|
|
79
|
+
* fold graphiti-rails into graphiti ([7740f8a](https://github.com/graphiti-api/graphiti/commit/7740f8a5803f1fbf02ef4e27d8baa6e0809d2b43)), closes [graphiti-rails#52](https://github.com/graphiti-rails/issues/52)
|
|
80
|
+
* **generators:** explicit rendering by default, respond_with only when Responders is included ([70741fe](https://github.com/graphiti-api/graphiti/commit/70741fef2a3a585bbef32c3e535027ff610fda77))
|
|
81
|
+
* handle exceptions with rescue_registry, fold in graphiti_errors ([e48171c](https://github.com/graphiti-api/graphiti/commit/e48171c117e7b8141fb6f966a972b0c1cd50c5ab))
|
|
82
|
+
* in-tree plain ruby and sinatra examples ([b92c6d9](https://github.com/graphiti-api/graphiti/commit/b92c6d9af22f759cc1f1eaccc250ecd04901e2aa))
|
|
83
|
+
* let the resource generator name the controller ([6ea7141](https://github.com/graphiti-api/graphiti/commit/6ea714181f3da011cae9f42477b4c3681a7a90ff)), closes [graphiti-api/graphiti-rails#53](https://github.com/graphiti-api/graphiti-rails/issues/53)
|
|
84
|
+
* mark deprecated settings in the generated ApplicationResource ([52b0642](https://github.com/graphiti-api/graphiti/commit/52b0642e689a16d14dacaf4e28a2641f10774cf0))
|
|
85
|
+
* move link rendering onto the resource as page_links and relationship_links ([57878d1](https://github.com/graphiti-api/graphiti/commit/57878d14fdfc4741e8d418c8edbc4a8687335843))
|
|
86
|
+
* move typecast_reads onto the resource and let the railtie own Rails config ([236e970](https://github.com/graphiti-api/graphiti/commit/236e9706d7d8f08e9640c5c22ac596e2f7466849))
|
|
87
|
+
* omit relationships that render no ids and no link ([916aa8c](https://github.com/graphiti-api/graphiti/commit/916aa8c9c596c5d9b6c802c5ab13b766a13d1e70))
|
|
88
|
+
* one link mode per relationship, cascading from relationship_links ([f0e1da1](https://github.com/graphiti-api/graphiti/commit/f0e1da1e13a8d12b47458495b378779f5687ffe2))
|
|
89
|
+
* point connection pool timeouts at the sizing formula and add an audit task to check ([6e017c6](https://github.com/graphiti-api/graphiti/commit/6e017c60fd45338e4e6c8527adebfd46be4bfd8d))
|
|
90
|
+
* raise MissingRelationshipMethod when rendering reads an association the model does not define ([1c41cee](https://github.com/graphiti-api/graphiti/commit/1c41cee787b4f747d2906b2230f8fb926e3d887d))
|
|
91
|
+
* rename always_include_resource_ids to resource_ids, with a belongs_to_resource_ids_by_default setting ([8b11151](https://github.com/graphiti-api/graphiti/commit/8b111516822f6fc6e3675b59941688791cb34e74))
|
|
92
|
+
* require Ruby 3.2 and Rails 7.1 ([635b249](https://github.com/graphiti-api/graphiti/commit/635b249a99f7d1ef726ae2328707ee6210cc0608))
|
|
93
|
+
* ship the Rails application template in this repo ([76d5329](https://github.com/graphiti-api/graphiti/commit/76d53291f94c576792e3649044784f88fbaa47a7))
|
|
94
|
+
* split validate_endpoints into validate_requests and validate_links ([100a370](https://github.com/graphiti-api/graphiti/commit/100a370deec6a0e6ae165bdf77e50b6b14d068d3))
|
|
95
|
+
* 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)
|
|
96
|
+
* the model you inspect is the model that saves ([#465](https://github.com/graphiti-api/graphiti/issues/465)) ([a905fff](https://github.com/graphiti-api/graphiti/commit/a905fffc3a2aa5e663ff4cadcd632e68f053c81a))
|
|
97
|
+
* write every error code Graphiti renders into the generated locale file ([15f19c1](https://github.com/graphiti-api/graphiti/commit/15f19c1dbe56559d9d041fa50e2cc5ea7b2dcf4b))
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
### Performance Improvements
|
|
101
|
+
|
|
102
|
+
* fingerprint the checkout being measured, not the working tree ([99656e1](https://github.com/graphiti-api/graphiti/commit/99656e17ca63c4057013fa9727b72d1e6c157086))
|
|
103
|
+
* memoize whether a belongs_to renders ids from its foreign key ([dcb60b2](https://github.com/graphiti-api/graphiti/commit/dcb60b2096c414756ccff534773d2e45594f0144))
|
|
104
|
+
* nest the entity map instead of keying it by an array ([20bf625](https://github.com/graphiti-api/graphiti/commit/20bf6259d0347b02568b7d47054bb799e69629c3))
|
|
105
|
+
* only deduplicate resources that two include paths can both reach ([744f014](https://github.com/graphiti-api/graphiti/commit/744f014249382bc25d5ea43f692778ad7adc25c3))
|
|
106
|
+
* record latest performance stats ([7380ef9](https://github.com/graphiti-api/graphiti/commit/7380ef912e9f3b99618bf47ed04e06d1efad4e6c))
|
|
107
|
+
* resolve a lone sideload inline rather than through the pool ([3415592](https://github.com/graphiti-api/graphiti/commit/3415592d75900389a8f11f53b65ab399e297e4a9))
|
|
108
|
+
* reuse the resolved data and proxies when building cache keys ([8a17350](https://github.com/graphiti-api/graphiti/commit/8a17350542ba0062fdcddd115afe8041b62198c7))
|
|
109
|
+
* skip the on-demand link strip when no relationship renders links on demand ([cf86a8c](https://github.com/graphiti-api/graphiti/commit/cf86a8c249077d9f9d5a13de49989d102bbaed04))
|
|
110
|
+
* skip the promise machinery when nothing is sideloaded ([d879923](https://github.com/graphiti-api/graphiti/commit/d879923070a35d1a0e908b2d04746aa81effb262))
|
|
111
|
+
* skip zipping a lone sideload promise ([7ef2cea](https://github.com/graphiti-api/graphiti/commit/7ef2cea654c48175504105f907b5b651c9fcdaf3))
|
|
112
|
+
* stop building a key for every record an association is checked against ([ccb5f71](https://github.com/graphiti-api/graphiti/commit/ccb5f71dab092988998a5f0c286ba65206e4fa35))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
### BREAKING CHANGES
|
|
116
|
+
|
|
117
|
+
* nothing removed, everything warns and goes away in 3.0. Except `include GraphitiErrors`, which now raises, as rescue_registry replaced it, so there's nothing to point it at.
|
|
118
|
+
* graphiti_errors is no longer a dependency and must be removed from the Gemfile, along with any `include GraphitiErrors`.
|
|
119
|
+
|
|
120
|
+
GraphitiErrors::Validation::Serializer is now Graphiti::ErrorSerializers::Validation, and GraphitiErrors.enable!/disable! becomes handle_request_exceptions. 409 responses now report code "conflict" and title "Conflict Error".
|
|
121
|
+
* Ruby >= 3.2 and Rails >= 7.1 are now required.
|
|
122
|
+
* remove graphiti-rails from your Gemfile. Controllers serving Graphiti resources must `include Graphiti::Rails::Controller` — previously every controller received it whether it wanted it or not. Graphiti::Responders is now Graphiti::Rails::Responders.
|
|
123
|
+
* remove graphiti_spec_helpers from your Gemfile. Prefer Graphiti::SpecHelpers and "graphiti/spec_helpers/rspec"; the old namespace and require paths still resolve, warn, and are removed in 3.0.
|
|
124
|
+
* around_persistence hooks receive the assigned model instead of the attributes hash. Move attribute-hash modifications to before_attributes, or set values on the model. Custom create/update overrides that should receive a pre-assigned model must accept an assigned_model: keyword. See UPGRADING.md
|
|
125
|
+
* Ruby >= 3.0 / Rails >= 6 are now required.
|
|
126
|
+
|
|
3
127
|
# [2.0.0-beta.13](https://github.com/graphiti-api/graphiti/compare/v2.0.0-beta.12...v2.0.0-beta.13) (2026-08-31)
|
|
4
128
|
|
|
5
129
|
|
|
@@ -228,6 +352,14 @@ GraphitiErrors::Validation::Serializer is now Graphiti::ErrorSerializers::Valida
|
|
|
228
352
|
* around_persistence hooks receive the assigned model instead of the attributes hash. Move attribute-hash modifications to before_attributes, or set values on the model. Custom create/update overrides that should receive a pre-assigned model must accept an assigned_model: keyword. See UPGRADING.md
|
|
229
353
|
* Ruby >= 3.0 / Rails >= 6 are now required.
|
|
230
354
|
|
|
355
|
+
## [1.13.4](https://github.com/graphiti-api/graphiti/compare/v1.13.3...v1.13.4) (2026-08-20)
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
### Bug Fixes
|
|
359
|
+
|
|
360
|
+
* resolve inline when already on a sideload pool thread ([11c9de7](https://github.com/graphiti-api/graphiti/commit/11c9de7fb4bfc2d83b02aaba3e58c1f94c84cec4))
|
|
361
|
+
* scope debugger chunks to the request rather than the class ([9a77896](https://github.com/graphiti-api/graphiti/commit/9a77896c6e56d23b89d0a2aef358d8e8e0c28c54))
|
|
362
|
+
|
|
231
363
|
## [1.13.3](https://github.com/graphiti-api/graphiti/compare/v1.13.2...v1.13.3) (2026-08-09)
|
|
232
364
|
|
|
233
365
|
|
data/Gemfile
CHANGED
|
@@ -3,8 +3,7 @@ source "https://rubygems.org"
|
|
|
3
3
|
# Specify your gem's dependencies in graphiti.gemspec
|
|
4
4
|
gemspec
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
gem "rescue_registry", github: "wagenet/rescue_registry", branch: "develop"
|
|
6
|
+
gem "rescue_registry", "~> 1.1"
|
|
8
7
|
|
|
9
8
|
group :test do
|
|
10
9
|
gem "database_cleaner"
|
data/graphiti.gemspec
CHANGED
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.add_dependency "jsonapi-serializable", "~> 0.3.0"
|
|
22
22
|
spec.add_dependency "jsonapi-renderer", "~> 0.2", ">= 0.2.2"
|
|
23
23
|
spec.add_dependency "dry-types", ">= 0.15.0", "< 2.0"
|
|
24
|
-
spec.add_dependency "rescue_registry", "~> 1.
|
|
24
|
+
spec.add_dependency "rescue_registry", "~> 1.1"
|
|
25
25
|
spec.add_dependency "concurrent-ruby", ">= 1.2", "< 2.0"
|
|
26
26
|
spec.add_dependency "activesupport", ">= 7.1"
|
|
27
27
|
# Bundled (no longer default) as of Ruby 4.0; graphiti uses OpenStruct in lib/
|
|
@@ -198,7 +198,7 @@ module Graphiti
|
|
|
198
198
|
# (see Adapters::Abstract#count)
|
|
199
199
|
def count(scope, attr)
|
|
200
200
|
if attr.to_sym == :total
|
|
201
|
-
scope.distinct.count(
|
|
201
|
+
scope.distinct.count(distinct_count_column(scope))
|
|
202
202
|
else
|
|
203
203
|
scope.distinct.count(attr)
|
|
204
204
|
end
|
|
@@ -281,18 +281,8 @@ module Graphiti
|
|
|
281
281
|
# Nothing to do in the else case, happened when we merged foreign key
|
|
282
282
|
end
|
|
283
283
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
instance = model_class.new(create_params)
|
|
287
|
-
instance.save
|
|
288
|
-
instance
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# (see Adapters::Abstract#update)
|
|
292
|
-
def update(model_class, update_params)
|
|
293
|
-
instance = model_class.find(update_params.only(:id))
|
|
294
|
-
instance.update_attributes(update_params.except(:id))
|
|
295
|
-
instance
|
|
284
|
+
def polymorphic_type_value(parent_object)
|
|
285
|
+
parent_object.class.polymorphic_name
|
|
296
286
|
end
|
|
297
287
|
|
|
298
288
|
def save(model_instance)
|
|
@@ -323,6 +313,13 @@ module Graphiti
|
|
|
323
313
|
|
|
324
314
|
private
|
|
325
315
|
|
|
316
|
+
def distinct_count_column(scope)
|
|
317
|
+
primary_key = scope.klass.primary_key
|
|
318
|
+
return :all unless primary_key.is_a?(String)
|
|
319
|
+
|
|
320
|
+
scope.klass.arel_table[primary_key]
|
|
321
|
+
end
|
|
322
|
+
|
|
326
323
|
def column_for(scope, name)
|
|
327
324
|
table = scope.klass.arel_table
|
|
328
325
|
if (other = scope.attribute_alias(name))
|
|
@@ -61,13 +61,17 @@ module Graphiti
|
|
|
61
61
|
update_foreign_type(attrs, x, null: true) if x[:is_polymorphic]
|
|
62
62
|
else
|
|
63
63
|
if x[:sideload].polymorphic_has_one? || x[:sideload].polymorphic_has_many?
|
|
64
|
-
attrs[:"#{x[:sideload].polymorphic_as}_type"] = parent_object
|
|
64
|
+
attrs[:"#{x[:sideload].polymorphic_as}_type"] = polymorphic_type_value(parent_object)
|
|
65
65
|
end
|
|
66
66
|
attrs[x[:foreign_key]] = parent_object.send(x[:primary_key])
|
|
67
67
|
update_foreign_type(attrs, x) if x[:is_polymorphic]
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
def polymorphic_type_value(parent_object)
|
|
72
|
+
parent_object.class.name
|
|
73
|
+
end
|
|
74
|
+
|
|
71
75
|
def update_foreign_type(attrs, x, null: false)
|
|
72
76
|
grouping_field = x[:sideload].parent.grouper.field_name
|
|
73
77
|
attrs[grouping_field] = null ? nil : x[:sideload].group_name
|
|
@@ -72,11 +72,8 @@ module Graphiti
|
|
|
72
72
|
Debugger.debug_models = @debug_models
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
# every value comes back from ENV as a string and "false" is truthy
|
|
76
75
|
def coerce_flag(val)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
!!val
|
|
76
|
+
Types.flag(val)
|
|
80
77
|
end
|
|
81
78
|
|
|
82
79
|
def with_option(key, value)
|
data/lib/graphiti/debugger.rb
CHANGED
|
@@ -63,12 +63,14 @@ module Graphiti
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
private def results(raw_results)
|
|
66
|
-
raw_results.map { |r|
|
|
66
|
+
raw_results.map { |r|
|
|
67
|
+
identifier = r.respond_to?(:id) ? r.id.inspect : "no id"
|
|
68
|
+
"[#{r.class.name}, #{identifier}]"
|
|
69
|
+
}.join(", ")
|
|
67
70
|
end
|
|
68
71
|
|
|
69
72
|
private def on_sideload_data(payload, params, took)
|
|
70
73
|
sideload = payload[:sideload]
|
|
71
|
-
results = results(payload[:results])
|
|
72
74
|
add_chunk(payload[:resource], payload[:parent]) do |logs, json|
|
|
73
75
|
logs << [" \\_ #{sideload.name}", :yellow, true]
|
|
74
76
|
json[:name] = sideload.name
|
|
@@ -79,14 +81,13 @@ module Graphiti
|
|
|
79
81
|
end
|
|
80
82
|
logs << [" #{query}", :cyan, true]
|
|
81
83
|
json[:query] = query
|
|
82
|
-
logs << [" Returned Models: #{results}"] if debug_models
|
|
84
|
+
logs << [" Returned Models: #{results(payload[:results])}"] if debug_models
|
|
83
85
|
logs << [" Took: #{took}ms", :magenta, true]
|
|
84
86
|
json[:took] = took
|
|
85
87
|
end
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
private def on_primary_data(payload, params, took)
|
|
89
|
-
results = results(payload[:results])
|
|
90
91
|
add_chunk(payload[:resource], payload[:parent]) do |logs, json|
|
|
91
92
|
logs << [""]
|
|
92
93
|
logs << ["=== Graphiti Debug", :green, true]
|
|
@@ -96,7 +97,7 @@ module Graphiti
|
|
|
96
97
|
query = "#{payload[:resource].class.name}.#{payload[:action]}(#{params.inspect})"
|
|
97
98
|
logs << [query, :cyan, true]
|
|
98
99
|
json[:query] = query
|
|
99
|
-
logs << ["Returned Models: #{results}"] if debug_models
|
|
100
|
+
logs << ["Returned Models: #{results(payload[:results])}"] if debug_models
|
|
100
101
|
logs << ["Took: #{took}ms", :magenta, true]
|
|
101
102
|
json[:took] = took
|
|
102
103
|
end
|
|
@@ -32,7 +32,7 @@ module Graphiti
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
34
|
def pagination_params
|
|
35
|
-
@pagination_params ||= @proxy.query.params.except(:action, :controller, :format)
|
|
35
|
+
@pagination_params ||= @proxy.query.params.except(:action, :controller, :format, :data, :included)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def pagination_link(page)
|
data/lib/graphiti/query.rb
CHANGED
|
@@ -2,7 +2,6 @@ require "digest"
|
|
|
2
2
|
|
|
3
3
|
module Graphiti
|
|
4
4
|
class Query
|
|
5
|
-
TRUTHY_LINKS = [true, "true"].freeze
|
|
6
5
|
LINKLESS_FORMATS = [:json, :xml, "json", "xml"].freeze
|
|
7
6
|
|
|
8
7
|
attr_reader :resource, :association_name, :params, :action
|
|
@@ -80,7 +79,7 @@ module Graphiti
|
|
|
80
79
|
def links_requested?
|
|
81
80
|
return @links_requested if defined?(@links_requested)
|
|
82
81
|
|
|
83
|
-
@links_requested =
|
|
82
|
+
@links_requested = Types.flag(@params[:links])
|
|
84
83
|
end
|
|
85
84
|
|
|
86
85
|
def suppress_links?
|
|
@@ -107,11 +106,11 @@ module Graphiti
|
|
|
107
106
|
|
|
108
107
|
def page_links_requested?
|
|
109
108
|
[@params[:page_links], @params[:pagination_links]]
|
|
110
|
-
.any? { |value|
|
|
109
|
+
.any? { |value| Types.flag(value) }
|
|
111
110
|
end
|
|
112
111
|
|
|
113
112
|
def debug_requested?
|
|
114
|
-
|
|
113
|
+
Types.flag(@params[:debug])
|
|
115
114
|
end
|
|
116
115
|
|
|
117
116
|
def hash
|
data/lib/graphiti/schema.rb
CHANGED
|
@@ -11,7 +11,11 @@ module Graphiti
|
|
|
11
11
|
new(resources).generate
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def self.
|
|
14
|
+
def self.forced?
|
|
15
|
+
Types.flag(ENV["FORCE_SCHEMA"])
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.generate!(resources = nil, path: Graphiti.config.schema_path, force: forced?)
|
|
15
19
|
result = check(resources, path: path)
|
|
16
20
|
return result.errors if !force && !result.compatible?
|
|
17
21
|
|
data/lib/graphiti/sideload.rb
CHANGED
|
@@ -79,7 +79,8 @@ module Graphiti
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def self.assigned?(query, record, association_name)
|
|
82
|
-
query.association_owners
|
|
82
|
+
owners = query.association_owners[association_name]
|
|
83
|
+
!owners.nil? && owners.key?(record.object_id)
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
def self.assign(&blk)
|
|
@@ -562,8 +563,8 @@ module Graphiti
|
|
|
562
563
|
query = self.class.current_assigning_query
|
|
563
564
|
return true if query.nil?
|
|
564
565
|
|
|
565
|
-
|
|
566
|
-
|
|
566
|
+
owners = query.association_owners.compute_if_absent(association_name) { Concurrent::Map.new }
|
|
567
|
+
owners.compute_if_absent(parent.object_id) { query.hash } == query.hash
|
|
567
568
|
end
|
|
568
569
|
|
|
569
570
|
def with_error_handling(error_class)
|
|
@@ -131,7 +131,7 @@ module Graphiti
|
|
|
131
131
|
::RSpec.describe "Graphiti Schema" do
|
|
132
132
|
it "generates a backwards-compatible schema" do
|
|
133
133
|
check = Graphiti::Schema.check(resources, path: path || Graphiti.config.schema_path)
|
|
134
|
-
forced =
|
|
134
|
+
forced = Graphiti::Schema.forced?
|
|
135
135
|
check.write! if check.compatible? || forced
|
|
136
136
|
|
|
137
137
|
expect(check.compatible? || forced).to eq(true), check.message
|
data/lib/graphiti/types.rb
CHANGED
|
@@ -222,6 +222,12 @@ module Graphiti
|
|
|
222
222
|
map[key.to_sym] = value
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
+
def self.flag(value)
|
|
226
|
+
self[:boolean][:params].call(value.to_s.strip)
|
|
227
|
+
rescue Dry::Types::CoercionError
|
|
228
|
+
false
|
|
229
|
+
end
|
|
230
|
+
|
|
225
231
|
def self.name_for(key)
|
|
226
232
|
key = key.to_sym
|
|
227
233
|
type = map[key]
|
data/lib/graphiti/version.rb
CHANGED
data/lib/tasks/graphiti.rake
CHANGED
|
@@ -9,7 +9,7 @@ namespace :graphiti do
|
|
|
9
9
|
Graphiti.logger = Graphiti.stdout_logger
|
|
10
10
|
Graphiti::Debugger.preserve = true
|
|
11
11
|
require "pp"
|
|
12
|
-
path, debug = args[:path], args[:debug]
|
|
12
|
+
path, debug = args[:path], Graphiti::Types.flag(args[:debug])
|
|
13
13
|
puts "Graphiti Request: #{path}"
|
|
14
14
|
json = helpers.make_request(path, debug)
|
|
15
15
|
pp json
|
|
@@ -20,7 +20,7 @@ namespace :graphiti do
|
|
|
20
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
21
|
task :generate, [:path] => [:environment] do |_, args|
|
|
22
22
|
check = Graphiti::Schema.check(path: helpers.schema_path(args[:path]))
|
|
23
|
-
abort check.message unless check.compatible? ||
|
|
23
|
+
abort check.message unless check.compatible? || Graphiti::Schema.forced?
|
|
24
24
|
|
|
25
25
|
puts "Schema written: #{check.write!}"
|
|
26
26
|
end
|
|
@@ -49,12 +49,15 @@ namespace :graphiti do
|
|
|
49
49
|
|
|
50
50
|
desc "Execute benchmark without web server."
|
|
51
51
|
task :benchmark, [:path, :requests] => [:environment] do |_, args|
|
|
52
|
+
requests = args[:requests].to_i
|
|
53
|
+
abort "Needs a request count, as in graphiti:benchmark[/path,100]" unless requests > 0
|
|
54
|
+
|
|
52
55
|
helpers.setup_rails!
|
|
53
56
|
took = Benchmark.ms {
|
|
54
|
-
|
|
57
|
+
requests.times do
|
|
55
58
|
helpers.make_request(args[:path])
|
|
56
59
|
end
|
|
57
60
|
}
|
|
58
|
-
puts "Took: #{(took /
|
|
61
|
+
puts "Took: #{(took / requests).round(2)}ms"
|
|
59
62
|
end
|
|
60
63
|
end
|
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.
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lee Richmond
|
|
@@ -69,14 +69,14 @@ dependencies:
|
|
|
69
69
|
requirements:
|
|
70
70
|
- - "~>"
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '1.
|
|
72
|
+
version: '1.1'
|
|
73
73
|
type: :runtime
|
|
74
74
|
prerelease: false
|
|
75
75
|
version_requirements: !ruby/object:Gem::Requirement
|
|
76
76
|
requirements:
|
|
77
77
|
- - "~>"
|
|
78
78
|
- !ruby/object:Gem::Version
|
|
79
|
-
version: '1.
|
|
79
|
+
version: '1.1'
|
|
80
80
|
- !ruby/object:Gem::Dependency
|
|
81
81
|
name: concurrent-ruby
|
|
82
82
|
requirement: !ruby/object:Gem::Requirement
|