graphqlite 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d664c52492cd6c6123fd189d696821d2451226faa81da7a907a7b6f8122f1149
4
+ data.tar.gz: 8a9ba16f20ab76d50eec3193df266ee9408a2d9903d55dd5af25fc26ec4b2d2a
5
+ SHA512:
6
+ metadata.gz: ae10a69e2a419d5f999a35fc25ac627f0f178c5da708c49fe2dd377f09909b321fe543a244f0bf885e1be16dd293838d2f3e95d3b94ea93a2b85b84529b6c1a3
7
+ data.tar.gz: 4eadc6a3cf8446dcca32e06a020ce5d2658a305175008a55e3403aa7d1414153243ba90ae9e75634ebe95865463d65e4bea3d26216ec8fce820723d3c1bc3250
data/CHANGELOG.md ADDED
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2025-01-17
9
+
10
+ ### Added
11
+ - Initial release of GraphQLite
12
+ - Complete GraphQL spec compliance (October 2021)
13
+ - Zero runtime dependencies
14
+ - Full lexer and parser implementation
15
+ - Complete type system (Scalar, Object, Interface, Union, Enum, InputObject)
16
+ - Query execution engine
17
+ - Validation system
18
+ - Full introspection support
19
+ - Clean DSL for schema definition
20
+ - Support for queries, mutations, and subscriptions
21
+ - Built-in scalar types (Int, Float, String, Boolean, ID)
22
+ - Custom scalar type support
23
+ - Field arguments and resolvers
24
+ - Variable support
25
+ - Context passing
26
+ - Comprehensive error handling
27
+ - Full test suite
28
+ - Documentation and examples
29
+
30
+ ### Features
31
+ - **Simple DSL**: Easy-to-use schema definition with minimal boilerplate
32
+ - **Fast Execution**: Efficient parser and executor
33
+ - **Production Ready**: Comprehensive validation and error handling
34
+ - **Type Safe**: Full type checking and validation
35
+ - **Extensible**: Easy to add custom scalars and directives
36
+
37
+ ## [Unreleased]
38
+
39
+ ### Planned
40
+ - Subscription support (real-time updates)
41
+ - Custom directive implementation
42
+ - Query complexity analysis
43
+ - Performance optimizations
44
+ - Additional validation rules
45
+ - Schema stitching support
46
+ - Federation support
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 GraphQLite Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,339 @@
1
+ # GraphQLite
2
+
3
+ ## Description
4
+
5
+ A lightweight, production-ready GraphQL implementation for Ruby with zero dependencies. GraphQLite is designed to be simple, minimal, and clean while maintaining full GraphQL spec compliance. It's easier to use and more straightforward than existing solutions.
6
+
7
+ ## Features
8
+
9
+ - Zero runtime dependencies - pure Ruby implementation
10
+ - Simple, intuitive DSL for schema definition
11
+ - Full GraphQL spec compliance (October 2021)
12
+ - Production-ready with comprehensive error handling
13
+ - Complete introspection support
14
+ - Fast execution with efficient parser
15
+ - Clean, maintainable codebase
16
+
17
+ ## Installation
18
+
19
+ Add to your Gemfile:
20
+
21
+ ```ruby
22
+ gem 'graphqlite'
23
+ ```
24
+
25
+ Or install directly:
26
+
27
+ ```bash
28
+ gem install graphqlite
29
+ ```
30
+
31
+ ## Basic Usage
32
+
33
+ ```ruby
34
+ require 'graphqlite'
35
+
36
+ schema = GraphQLite::Schema.new do
37
+ query do
38
+ field :hello, :String do
39
+ "World"
40
+ end
41
+ end
42
+ end
43
+
44
+ result = schema.execute('{ hello }')
45
+ # => { "data" => { "hello" => "World" } }
46
+ ```
47
+
48
+ ## Available Usages
49
+
50
+ ### Define Object Types
51
+
52
+ ```ruby
53
+ object :User do
54
+ field :id, :ID, null: false
55
+ field :name, :String
56
+ field :email, :String
57
+ end
58
+ ```
59
+
60
+ ### Query with Arguments
61
+
62
+ ```ruby
63
+ query do
64
+ field :user, :User do |f|
65
+ f.argument :id, :ID
66
+ f.resolve do |args|
67
+ User.find(args[:id])
68
+ end
69
+ end
70
+ end
71
+ ```
72
+
73
+ ### Lists and Non-Null Types
74
+
75
+ ```ruby
76
+ query do
77
+ field :users, [:User] do # List of users
78
+ User.all
79
+ end
80
+
81
+ field :count, :Int, null: false do # Required field
82
+ User.count
83
+ end
84
+ end
85
+ ```
86
+
87
+ ### Mutations
88
+
89
+ ```ruby
90
+ mutation do
91
+ field :createUser, :User do |f|
92
+ f.argument :name, :String
93
+ f.argument :email, :String
94
+ f.resolve do |args|
95
+ User.create(name: args[:name], email: args[:email])
96
+ end
97
+ end
98
+ end
99
+ ```
100
+
101
+ ### Execute with Variables
102
+
103
+ ```ruby
104
+ query = 'query GetUser($id: ID!) { user(id: $id) { name } }'
105
+ result = schema.execute(query, variables: { 'id' => '123' })
106
+ ```
107
+
108
+ ### Execute with Context
109
+
110
+ ```ruby
111
+ result = schema.execute(
112
+ '{ me { name } }',
113
+ context: { current_user: current_user }
114
+ )
115
+
116
+ # Access in resolvers
117
+ field :me, :User do |_, args, context|
118
+ context[:current_user]
119
+ end
120
+ ```
121
+
122
+ ## Advanced Usage
123
+
124
+ ### Custom Resolvers
125
+
126
+ ```ruby
127
+ object :User do
128
+ field :fullName, :String do |user|
129
+ "#{user[:first_name]} #{user[:last_name]}"
130
+ end
131
+
132
+ field :posts, [:Post] do |user|
133
+ Post.where(user_id: user[:id])
134
+ end
135
+ end
136
+ ```
137
+
138
+ ### Enum Types
139
+
140
+ ```ruby
141
+ enum :Role, values: {
142
+ 'ADMIN' => { value: 'admin', description: 'Administrator' },
143
+ 'USER' => { value: 'user', description: 'Regular user' },
144
+ 'GUEST' => { value: 'guest', description: 'Guest user' }
145
+ }
146
+
147
+ object :User do
148
+ field :role, :Role
149
+ end
150
+ ```
151
+
152
+ ### Custom Scalars
153
+
154
+ ```ruby
155
+ scalar :DateTime,
156
+ description: 'ISO 8601 datetime',
157
+ serialize: ->(value) { value.iso8601 },
158
+ parse_value: ->(value) { Time.parse(value) },
159
+ parse_literal: ->(value) {
160
+ value.is_a?(Parser::StringValue) ? Time.parse(value.value) : nil
161
+ }
162
+ ```
163
+
164
+ ### Introspection
165
+
166
+ ```ruby
167
+ # Schema introspection
168
+ schema.execute('{ __schema { types { name } } }')
169
+
170
+ # Type introspection
171
+ schema.execute('{ __type(name: "User") { name fields { name } } }')
172
+
173
+ # Typename in queries
174
+ schema.execute('{ user { __typename id } }')
175
+ ```
176
+
177
+ ## Detailed Documentation
178
+
179
+ ### Built-in Scalar Types
180
+
181
+ - `Int` - 32-bit signed integer
182
+ - `Float` - Double-precision floating-point
183
+ - `String` - UTF-8 character sequence
184
+ - `Boolean` - true or false
185
+ - `ID` - Unique identifier (serialized as string)
186
+
187
+ ### Schema Definition API
188
+
189
+ **Object Types**
190
+ ```ruby
191
+ object :TypeName do
192
+ field :fieldName, :FieldType
193
+ field :requiredField, :Type, null: false
194
+ field :listField, [:Type]
195
+ field :computedField, :Type do |object, args, context|
196
+ # resolver logic
197
+ end
198
+ end
199
+ ```
200
+
201
+ **Fields with Arguments**
202
+ ```ruby
203
+ field :search, [:User] do |f|
204
+ f.argument :query, :String
205
+ f.argument :limit, :Int
206
+ f.resolve do |args, context|
207
+ User.search(args[:query]).limit(args[:limit] || 10)
208
+ end
209
+ end
210
+ ```
211
+
212
+ **Query Root**
213
+ ```ruby
214
+ query do
215
+ field :fieldName, :Type do |f|
216
+ f.argument :arg, :ArgType
217
+ f.resolve { |args| ... }
218
+ end
219
+ end
220
+ ```
221
+
222
+ **Mutation Root**
223
+ ```ruby
224
+ mutation do
225
+ field :actionName, :ReturnType do |f|
226
+ f.argument :input, :InputType
227
+ f.resolve { |args| ... }
228
+ end
229
+ end
230
+ ```
231
+
232
+ ### Query Execution API
233
+
234
+ ```ruby
235
+ # Basic execution
236
+ schema.execute(query_string)
237
+
238
+ # With variables
239
+ schema.execute(query_string, variables: { 'key' => 'value' })
240
+
241
+ # With context
242
+ schema.execute(query_string, context: { user: current_user })
243
+
244
+ # Combined
245
+ schema.execute(
246
+ query_string,
247
+ variables: variables_hash,
248
+ context: context_hash
249
+ )
250
+ ```
251
+
252
+ ### Error Handling
253
+
254
+ GraphQLite automatically validates and reports errors:
255
+
256
+ ```ruby
257
+ result = schema.execute('{ invalidField }')
258
+ # => { "errors" => [{ "message" => "Field 'invalidField' does not exist..." }] }
259
+ ```
260
+
261
+ Errors include:
262
+ - Syntax errors in queries
263
+ - Field validation errors
264
+ - Type mismatch errors
265
+ - Argument validation errors
266
+ - Runtime resolver errors
267
+
268
+ ### Complete Example
269
+
270
+ ```ruby
271
+ schema = GraphQLite::Schema.new do
272
+ enum :Status, values: {
273
+ 'ACTIVE' => { value: 'active' },
274
+ 'INACTIVE' => { value: 'inactive' }
275
+ }
276
+
277
+ object :Post do
278
+ field :id, :ID, null: false
279
+ field :title, :String
280
+ field :content, :String
281
+ field :status, :Status
282
+ field :author, :User do |post|
283
+ User.find(post[:author_id])
284
+ end
285
+ end
286
+
287
+ object :User do
288
+ field :id, :ID, null: false
289
+ field :name, :String
290
+ field :email, :String
291
+ field :posts, [:Post] do |user|
292
+ Post.where(author_id: user[:id])
293
+ end
294
+ end
295
+
296
+ query do
297
+ field :user, :User do |f|
298
+ f.argument :id, :ID
299
+ f.resolve { |args| User.find(args[:id]) }
300
+ end
301
+
302
+ field :posts, [:Post] do |f|
303
+ f.argument :status, :Status
304
+ f.resolve do |args|
305
+ query = Post.all
306
+ query = query.where(status: args[:status]) if args[:status]
307
+ query
308
+ end
309
+ end
310
+ end
311
+
312
+ mutation do
313
+ field :createPost, :Post do |f|
314
+ f.argument :title, :String
315
+ f.argument :content, :String
316
+ f.argument :authorId, :ID
317
+ f.resolve do |args|
318
+ Post.create(
319
+ title: args[:title],
320
+ content: args[:content],
321
+ author_id: args[:authorId]
322
+ )
323
+ end
324
+ end
325
+ end
326
+ end
327
+
328
+ # Execute queries
329
+ schema.execute('{ posts { title author { name } } }')
330
+ schema.execute('{ posts(status: ACTIVE) { title } }')
331
+
332
+ # Execute mutations
333
+ mutation = 'mutation { createPost(title: "Hello", content: "World", authorId: "1") { id } }'
334
+ schema.execute(mutation)
335
+ ```
336
+
337
+ ## License
338
+
339
+ MIT License
@@ -0,0 +1,7 @@
1
+ module GraphQLite
2
+ class Error < StandardError; end
3
+ class ParseError < Error; end
4
+ class ValidationError < Error; end
5
+ class ExecutionError < Error; end
6
+ class TypeError < Error; end
7
+ end