tina4 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +96 -0
- data/lib/tina4/cli.rb +69 -0
- data/lib/tina4/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5418ddd6412424d2a754ec45b7a435d1d189dcbfdfc0ddfcff54b02f5993d5ca
|
|
4
|
+
data.tar.gz: 8729da6284e85d545426c96b8b8e5a33b22b040270cd6e0fd754bb9f75e71198
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e63ae672c5752d40cb22785438897ae0b6cbdea0e52402cf749dec6eba22786b4da72873ab87f2de3df8df73ed0a2abd15e925dcf8aeffaddb660900834f5b5d
|
|
7
|
+
data.tar.gz: 1fdfcf15878f12d1cc4451dd0a9cdb73e659455d8e1c54ccbeba41d4acd1396d08c5c7022f75037fb4590c7d36c99e67968fdc7c3ae1d6461f5a50208a731263
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.0] - 2026-03-18
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Multi-stage Dockerfile (ruby:3.3-alpine, build + runtime stages, optimized layer caching)
|
|
7
|
+
- .dockerignore for clean Docker builds
|
|
8
|
+
- `tina4 init` now generates Dockerfile and .dockerignore alongside project scaffolding
|
|
9
|
+
|
|
3
10
|
## [0.3.0] - 2026-03-14
|
|
4
11
|
|
|
5
12
|
### Added
|
data/README.md
CHANGED
|
@@ -517,6 +517,102 @@ end
|
|
|
517
517
|
|
|
518
518
|
Visit `http://localhost:7145/swagger` for the interactive Swagger UI.
|
|
519
519
|
|
|
520
|
+
## GraphQL
|
|
521
|
+
|
|
522
|
+
Zero-dependency GraphQL support with a custom parser, executor, and ORM auto-schema generation.
|
|
523
|
+
|
|
524
|
+
### Manual Schema
|
|
525
|
+
|
|
526
|
+
```ruby
|
|
527
|
+
schema = Tina4::GraphQLSchema.new
|
|
528
|
+
|
|
529
|
+
# Add queries
|
|
530
|
+
schema.add_query("hello", type: "String") { |_root, _args, _ctx| "Hello World!" }
|
|
531
|
+
|
|
532
|
+
schema.add_query("user", type: "User", args: { "id" => { type: "ID!" } }) do |_root, args, _ctx|
|
|
533
|
+
User.find(args["id"])&.to_hash
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
# Add mutations
|
|
537
|
+
schema.add_mutation("createUser", type: "User",
|
|
538
|
+
args: { "name" => { type: "String!" }, "email" => { type: "String!" } }
|
|
539
|
+
) do |_root, args, _ctx|
|
|
540
|
+
User.create(name: args["name"], email: args["email"]).to_hash
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
# Register the /graphql endpoint
|
|
544
|
+
gql = Tina4::GraphQL.new(schema)
|
|
545
|
+
gql.register_route # POST /graphql + GET /graphql (GraphiQL UI)
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### ORM Auto-Schema
|
|
549
|
+
|
|
550
|
+
Generate full CRUD queries and mutations from your ORM models with one line:
|
|
551
|
+
|
|
552
|
+
```ruby
|
|
553
|
+
schema = Tina4::GraphQLSchema.new
|
|
554
|
+
schema.from_orm(User) # Creates: user, users, createUser, updateUser, deleteUser
|
|
555
|
+
schema.from_orm(Product) # Creates: product, products, createProduct, updateProduct, deleteProduct
|
|
556
|
+
|
|
557
|
+
gql = Tina4::GraphQL.new(schema)
|
|
558
|
+
gql.register_route("/graphql")
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
This auto-generates:
|
|
562
|
+
- **Queries:** `user(id)` (single), `users(limit, offset)` (list with pagination)
|
|
563
|
+
- **Mutations:** `createUser(input)`, `updateUser(id, input)`, `deleteUser(id)`
|
|
564
|
+
|
|
565
|
+
### Query Examples
|
|
566
|
+
|
|
567
|
+
```graphql
|
|
568
|
+
# Simple query
|
|
569
|
+
{ hello }
|
|
570
|
+
|
|
571
|
+
# Nested fields with arguments
|
|
572
|
+
{ user(id: 42) { id name email } }
|
|
573
|
+
|
|
574
|
+
# List with pagination
|
|
575
|
+
{ users(limit: 10, offset: 0) { id name } }
|
|
576
|
+
|
|
577
|
+
# Aliases
|
|
578
|
+
{ admin: user(id: 1) { name } guest: user(id: 2) { name } }
|
|
579
|
+
|
|
580
|
+
# Variables
|
|
581
|
+
query GetUser($userId: ID!) {
|
|
582
|
+
user(id: $userId) { id name email }
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
# Fragments
|
|
586
|
+
fragment UserFields on User { id name email }
|
|
587
|
+
{ user(id: 1) { ...UserFields } }
|
|
588
|
+
|
|
589
|
+
# Mutations
|
|
590
|
+
mutation {
|
|
591
|
+
createUser(name: "Alice", email: "alice@example.com") { id name }
|
|
592
|
+
}
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### Programmatic Execution
|
|
596
|
+
|
|
597
|
+
```ruby
|
|
598
|
+
gql = Tina4::GraphQL.new(schema)
|
|
599
|
+
|
|
600
|
+
# Execute a query directly
|
|
601
|
+
result = gql.execute('{ hello }')
|
|
602
|
+
puts result["data"]["hello"] # "Hello World!"
|
|
603
|
+
|
|
604
|
+
# With variables
|
|
605
|
+
result = gql.execute(
|
|
606
|
+
'query($id: ID!) { user(id: $id) { name } }',
|
|
607
|
+
variables: { "id" => 42 }
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
# Handle an HTTP request body (JSON string)
|
|
611
|
+
result = gql.handle_request('{"query": "{ hello }"}')
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
Visit `http://localhost:7145/graphql` for the interactive GraphiQL UI.
|
|
615
|
+
|
|
520
616
|
## REST API Client
|
|
521
617
|
|
|
522
618
|
```ruby
|
data/lib/tina4/cli.rb
CHANGED
|
@@ -217,6 +217,75 @@ module Tina4
|
|
|
217
217
|
TEXT
|
|
218
218
|
end
|
|
219
219
|
|
|
220
|
+
# Dockerfile
|
|
221
|
+
unless File.exist?(File.join(dir, "Dockerfile"))
|
|
222
|
+
File.write(File.join(dir, "Dockerfile"), <<~DOCKERFILE)
|
|
223
|
+
# === Build Stage ===
|
|
224
|
+
FROM ruby:3.3-alpine AS builder
|
|
225
|
+
|
|
226
|
+
# Install build dependencies
|
|
227
|
+
RUN apk add --no-cache \\
|
|
228
|
+
build-base \\
|
|
229
|
+
libffi-dev \\
|
|
230
|
+
gcompat
|
|
231
|
+
|
|
232
|
+
WORKDIR /app
|
|
233
|
+
|
|
234
|
+
# Copy dependency definition first (layer caching)
|
|
235
|
+
COPY Gemfile Gemfile.lock* ./
|
|
236
|
+
|
|
237
|
+
# Install gems
|
|
238
|
+
RUN bundle config set --local without 'development test' && \\
|
|
239
|
+
bundle install --jobs 4 --retry 3
|
|
240
|
+
|
|
241
|
+
# Copy application code
|
|
242
|
+
COPY . .
|
|
243
|
+
|
|
244
|
+
# === Runtime Stage ===
|
|
245
|
+
FROM ruby:3.3-alpine
|
|
246
|
+
|
|
247
|
+
# Runtime packages only
|
|
248
|
+
RUN apk add --no-cache libffi gcompat
|
|
249
|
+
|
|
250
|
+
WORKDIR /app
|
|
251
|
+
|
|
252
|
+
# Copy installed gems
|
|
253
|
+
COPY --from=builder /usr/local/bundle /usr/local/bundle
|
|
254
|
+
|
|
255
|
+
# Copy application code
|
|
256
|
+
COPY --from=builder /app /app
|
|
257
|
+
|
|
258
|
+
EXPOSE 7145
|
|
259
|
+
|
|
260
|
+
# Swagger defaults (override with env vars in docker-compose/k8s if needed)
|
|
261
|
+
ENV SWAGGER_TITLE="Tina4 API"
|
|
262
|
+
ENV SWAGGER_VERSION="0.1.0"
|
|
263
|
+
ENV SWAGGER_DESCRIPTION="Auto-generated API documentation"
|
|
264
|
+
|
|
265
|
+
# Start the server on all interfaces
|
|
266
|
+
CMD ["bundle", "exec", "tina4", "start", "-p", "7145", "-h", "0.0.0.0"]
|
|
267
|
+
DOCKERFILE
|
|
268
|
+
puts " Created Dockerfile"
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# .dockerignore
|
|
272
|
+
unless File.exist?(File.join(dir, ".dockerignore"))
|
|
273
|
+
File.write(File.join(dir, ".dockerignore"), <<~TEXT)
|
|
274
|
+
.git
|
|
275
|
+
.env
|
|
276
|
+
.keys/
|
|
277
|
+
logs/
|
|
278
|
+
sessions/
|
|
279
|
+
.queue/
|
|
280
|
+
*.db
|
|
281
|
+
*.gem
|
|
282
|
+
tmp/
|
|
283
|
+
spec/
|
|
284
|
+
vendor/bundle
|
|
285
|
+
TEXT
|
|
286
|
+
puts " Created .dockerignore"
|
|
287
|
+
end
|
|
288
|
+
|
|
220
289
|
# Base template
|
|
221
290
|
templates_dir = File.join(dir, "templates")
|
|
222
291
|
unless File.exist?(File.join(templates_dir, "base.twig"))
|
data/lib/tina4/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tina4
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tina4 Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|