rsodx 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9530a9b38e69fdae2f3eee74634ab298aabf3fa11df94d5e28dffd46e7fbffed
4
+ data.tar.gz: 45db9f15c1a2fbee0d2047373c2958ac913fa262e1833ba9c07b925d76f2577e
5
+ SHA512:
6
+ metadata.gz: 2074732db6099bd5681845ed895d5679e9b33b5aea3fe5a8a83d767ac47dbc670d86511d330599b79e940ae51797a6c9d77861dff8472082ec8806d4c9f07c9b
7
+ data.tar.gz: eb6590b94d33281d0d179a9c6cb62b1c70fef8115c8b8486e230f21154672cdf618ed37738b1fe1d6e918fa60282d5e98c27cec1b5a41dfe56226002661b4d2b
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Первушин
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,180 @@
1
+ # Rsodx
2
+
3
+ > Add Rsodx and just code ✨
4
+
5
+ Rsodx is a lightweight, modular microservice framework for Ruby — designed to be fast, clean, and scalable. It provides a minimal architecture inspired by Rails, Sinatra, and Sequel, allowing you to focus on writing business logic without boilerplate.
6
+
7
+ ---
8
+
9
+ ## 🧠 Philosophy
10
+
11
+ - No monoliths — build small services
12
+ - No magic — just plain Ruby
13
+ - No opinionated ORM or router — just simple tools
14
+ - Easily extendable and production-ready
15
+
16
+ ---
17
+
18
+ Вот аккуратно оформленный раздел `Installation` для твоего README:
19
+
20
+ ---
21
+
22
+ ## 📦 Installation
23
+
24
+ ```text
25
+ gem 'rsodx', github: 'eugene-ruby/rsodx'
26
+ ```
27
+
28
+ You can install the gem directly from [RubyGems.org](https://rubygems.org/gems/rsodx) after release:
29
+
30
+ ### With Bundler
31
+
32
+ ```bash
33
+ bundle add rsodx
34
+ ```
35
+
36
+ ### Without Bundler
37
+
38
+ ```bash
39
+ gem install rsodx
40
+ ```
41
+
42
+ > ✅ `rsodx` is designed for microservice architecture and includes routing, interactors, validation, and more — all in one lightweight package.
43
+
44
+ ---
45
+
46
+
47
+ ## 📦 Project Structure
48
+
49
+ ```text
50
+ my_service/
51
+ ├── app/
52
+ │ ├── api/
53
+ │ ├── interactors/
54
+ │ ├── models/
55
+ │ ├── presenters/
56
+ │ ├── serializers/
57
+ │ ├── app.rb
58
+ │ └── router.rb
59
+ ├── config/
60
+ │ ├── environment.rb
61
+ │ ├── environments/
62
+ │ └── initializers/
63
+ ├── db/
64
+ │ └── migrations/
65
+ ├── bin/
66
+ │ └── console
67
+ ├── .env
68
+ ├── config.ru
69
+ ├── Gemfile
70
+ └── Rakefile
71
+ ```
72
+
73
+ ---
74
+
75
+ ## 🧰 CLI Commands
76
+
77
+ ### Create new service
78
+
79
+ ```bash
80
+ rsodx new my_service
81
+ ```
82
+
83
+ ---
84
+
85
+ ### Generate interactor
86
+
87
+ ```bash
88
+ bin/rsodx generate interactor CreateUser
89
+ ```
90
+ Creates `app/interactors/create_user.rb`:
91
+
92
+ ```ruby
93
+ class CreateUser < Rsodx::Interactor
94
+ def call
95
+ # business logic here
96
+ end
97
+ end
98
+ ```
99
+
100
+ ---
101
+
102
+ ### Generate migration
103
+
104
+ ```bash
105
+ bin/rsodx generate migration CreateUsers
106
+ ```
107
+ Creates `db/migrations/20240413_create_users.rb`:
108
+
109
+ ```ruby
110
+ Sequel.migration do
111
+ change do
112
+ # create_table :users do
113
+ # primary_key :id
114
+ # String :email
115
+ # DateTime :created_at
116
+ # end
117
+ end
118
+ end
119
+ ```
120
+
121
+ ---
122
+
123
+ ## 📂 DSL Router Example
124
+
125
+ ```ruby
126
+ class Router < Rsodx::Router
127
+ namespace "/v1" do
128
+ post "/users", CreateUsers
129
+ end
130
+ end
131
+ ```
132
+
133
+ ---
134
+
135
+ ## ⚙️ Rake Tasks
136
+
137
+ You can define your own `DB.connect` logic and use built-in tasks:
138
+
139
+ ```ruby
140
+ # config/environment.rb
141
+ require "rsodx"
142
+ require "rsodx/db"
143
+ Rsodx::DB.connect
144
+ ```
145
+
146
+ ### Run migration
147
+ ```bash
148
+ rake db:migrate
149
+ ```
150
+
151
+ ### Rollback migration
152
+ ```bash
153
+ rake db:rollback
154
+ ```
155
+
156
+ ---
157
+
158
+ ## 💻 Interactive Console
159
+
160
+ ```bash
161
+ bin/console
162
+ ```
163
+ Inside IRB:
164
+ ```ruby
165
+ reload! # reload environment
166
+ CreateUser.call(params: {...})
167
+ ```
168
+
169
+ ---
170
+
171
+ ## 🔜 Roadmap
172
+ - Generator for models, serializers, presenters
173
+ - HTTP + JSON helpers
174
+ - Authentication middleware
175
+ - Better documentation site
176
+
177
+ ---
178
+
179
+ ## 🧬 License
180
+ MIT — created by Eugene Pervushin
data/bin/console ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "rsodx"
6
+ require_relative '../lib/config/environment'
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+
11
+ require "irb"
12
+ IRB.start(__FILE__)
data/bin/rsodx ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "fileutils"
4
+ require "optparse"
5
+ require "rsodx"
6
+
7
+ if __FILE__ == $0
8
+ Rsodx::Cli::Handler.run
9
+ end
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/rsodx/base.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'sinatra/base'
2
+
3
+ module Rsodx
4
+ class Base < Sinatra::Base
5
+ end
6
+ end
data/lib/rsodx/boot.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Rsodx
2
+ module Boot
3
+ def self.load_app_structure(app_root)
4
+ %w[models interactors presenters serializers api].each do |folder|
5
+ path = File.join(app_root, "app", folder)
6
+ $LOAD_PATH.unshift(path) if Dir.exist?(path)
7
+ Dir["#{path}/**/*.rb"].sort.each { |file| require file }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Rsodx::Cli
2
+ class Generate
3
+ def self.run(args)
4
+ type = args.shift
5
+ name = args.shift
6
+ case type
7
+ when "interactor", "in"
8
+ GenerateInteractor.new(name).create
9
+ when "migration"
10
+ GenerateMigration.new(name).create
11
+ else
12
+ puts "Unknown generate type: #{type}"
13
+ exit(1)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ module Rsodx
2
+ module Cli
3
+ class GenerateInteractor
4
+ def initialize(name)
5
+ @name = name
6
+ @file_name = File.join("app/interactors", snake_case(name) + ".rb")
7
+ end
8
+
9
+ def create
10
+ puts "📦 Creating interactor: #{@file_name}"
11
+ FileUtils.mkdir_p("app/interactors")
12
+ File.write(@file_name, content)
13
+ end
14
+
15
+ def content
16
+ <<~RUBY
17
+ class #{@name} < AppInteractor
18
+ def call
19
+ # implement logic here
20
+ end
21
+ end
22
+ RUBY
23
+ end
24
+
25
+ def snake_case(str)
26
+ str.gsub(/::/, '/').
27
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
28
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
29
+ tr("-", "_").
30
+ downcase
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ require "fileutils"
2
+ require "time"
3
+
4
+ module Rsodx::Cli
5
+ class GenerateMigration
6
+ def initialize(name)
7
+ @name = name
8
+ @timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S")
9
+ @file_name = File.join("db/migrations", "#{@timestamp}_#{snake_case(name)}.rb")
10
+ end
11
+
12
+ def create
13
+ puts "📦 Creating migration: #{@file_name}"
14
+ FileUtils.mkdir_p("db/migrations")
15
+ File.write(@file_name, content)
16
+ end
17
+
18
+ private
19
+
20
+ def content
21
+ <<~RUBY
22
+ Sequel.migration do
23
+ change do
24
+ # create_table(:example) do
25
+ # primary_key :id
26
+ # String :name
27
+ # DateTime :created_at
28
+ # DateTime :updated_at
29
+ # end
30
+ end
31
+ end
32
+ RUBY
33
+ end
34
+
35
+ def snake_case(str)
36
+ str.gsub(/::/, '/')
37
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\\1_\\2')
38
+ .gsub(/([a-z\\d])([A-Z])/,'\\1_\\2')
39
+ .tr("-", "_")
40
+ .downcase
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ require_relative "scaffold"
2
+
3
+ module Rsodx::Cli
4
+ class Handler
5
+ def self.run
6
+ command = ARGV.shift
7
+ case command
8
+ when "s", "server"
9
+ Rsodx::Cli::Server.run
10
+ when "generate", "g"
11
+ Rsodx::Cli::Generate.run(ARGV)
12
+ when "new"
13
+ name = ARGV.shift
14
+ if name.nil? || name.empty?
15
+ puts "Usage: rsodx new <project_name>"
16
+ exit(1)
17
+ end
18
+ Scaffold.new(name).create
19
+ else
20
+ puts "Unknown command: #{command}"
21
+ puts "Usage: rsodx new <project_name>"
22
+ exit(1)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,133 @@
1
+ module Rsodx::Cli
2
+ class Scaffold
3
+ attr_reader :name
4
+
5
+ RUBY_VERSION = "3.4.2".freeze
6
+
7
+ # path: "../rsodx"
8
+ GEMFILE = <<~GEMFILE.freeze
9
+ source "https://rubygems.org"
10
+
11
+ gem "rsodx"
12
+ gem "pg"
13
+ GEMFILE
14
+
15
+ BINRSODX = <<~BINRSODX.freeze
16
+ #!/usr/bin/env ruby
17
+
18
+ require "fileutils"
19
+ require "optparse"
20
+ require "rsodx"
21
+
22
+ if __FILE__ == $0
23
+ Rsodx::Cli::Handler.run
24
+ end
25
+ BINRSODX
26
+
27
+ CONSOLE = <<~CONSOLE.freeze
28
+ #!/usr/bin/env ruby
29
+
30
+ require "irb"
31
+ require "irb/completion"
32
+
33
+ def reload!
34
+ puts "🔄 Reloading..."
35
+ load File.expand_path("../config/environment.rb", __dir__)
36
+ end
37
+
38
+ require_relative "../config/environment"
39
+
40
+ puts "🔬 Welcome to Rsodx console (#{ENV['RACK_ENV'] || 'development'})"
41
+ puts "Tip: access Rsodx modules, models, interactors, etc."
42
+
43
+ IRB.start
44
+ CONSOLE
45
+
46
+ CONFIGRU = <<~RACK.freeze
47
+ require_relative "./app/app"
48
+ run App
49
+ RACK
50
+
51
+ ROUTE = <<~ROUTE.freeze
52
+ class Router < Rsodx::Router
53
+ get "/healthcheck", Rsodx::Interactors::Healthcheck
54
+ end
55
+ ROUTE
56
+
57
+ APP = <<~APP.freeze
58
+ require "rsodx"
59
+ require_relative "router"
60
+
61
+ class App < Rsodx::Base
62
+ use Router
63
+ end
64
+ APP
65
+
66
+ APP_INTERACTOR = <<~APP_INTERACTOR.freeze
67
+ class AppInteractor < Rsodx::Interactor
68
+ end
69
+ APP_INTERACTOR
70
+
71
+ RAKEFILE = <<~RAKEFILE.freeze
72
+ require_relative "config/environment"
73
+ require "rsodx/tasks"
74
+ RAKEFILE
75
+
76
+ ENVFILE = <<~ENVFILE.freeze
77
+ DATABASE_URL=postgres://user:password@localhost:5432/base_development
78
+ ENVFILE
79
+
80
+ FOLDERS = %w[app/api app/interactors app/models app/presenters
81
+ app/serializers config/initializers
82
+ config/environments db/migrations spec bin].freeze
83
+
84
+ def initialize(name)
85
+ @name = name
86
+ @app_path = File.join(Dir.pwd, name)
87
+ end
88
+
89
+ def create
90
+ puts "Creating project: #{name}"
91
+ create_folders
92
+ create_files
93
+ puts "✅ Done!"
94
+ end
95
+
96
+ def create_folders
97
+ FOLDERS.each do |path|
98
+ FileUtils.mkdir_p(File.join(@app_path, path))
99
+ end
100
+ end
101
+
102
+ def create_files
103
+ write("Gemfile", GEMFILE)
104
+ write(".ruby-version", RUBY_VERSION)
105
+ write(".env", ENVFILE)
106
+ write("config/environment.rb", env_loader)
107
+ write("Rakefile", RAKEFILE)
108
+ write("app/interactors/app_interactor.rb", APP_INTERACTOR)
109
+ write("app/app.rb", APP)
110
+ write("app/router.rb", ROUTE)
111
+ write("config/environments/development.rb", "")
112
+ write("config.ru", CONFIGRU)
113
+ write("bin/console", CONSOLE)
114
+ write("bin/rsodx", BINRSODX)
115
+ FileUtils.chmod("+x", File.join(@app_path, "bin/console"))
116
+ end
117
+
118
+ def write(relative_path, content)
119
+ full_path = File.join(@app_path, relative_path)
120
+ File.write(full_path, content)
121
+ end
122
+
123
+ def env_loader
124
+ <<~RB
125
+ require "rsodx"
126
+ Rsodx::Environment.load_dotenv(ENV["RACK_ENV"] || "development")
127
+ Rsodx::Connect.connect ENV["DATABASE_URL"]
128
+ Rsodx::Environment.load_initializers(File.expand_path("../..", __FILE__))
129
+ Rsodx::Boot.load_app_structure(File.expand_path("../..", __FILE__))
130
+ RB
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,12 @@
1
+ require "rack/handler/puma"
2
+ module Rsodx::Cli
3
+ class Server
4
+ def self.run
5
+ pid = spawn("bundle exec rake server")
6
+ Process.wait(pid)
7
+ puts "🚀 Starting Rsodx server PID: #{pid} at http://localhost:9292"
8
+ rescue LoadError => e
9
+ abort "❌ Error #{e.message}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ require "sequel"
2
+
3
+ module Rsodx
4
+ module Connect
5
+ def self.connect(url)
6
+ raise "Missing DATABASE_URL" unless url
7
+
8
+ db = Sequel.connect(url)
9
+ Sequel::Model.db = db
10
+ db
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ require "dry-validation"
2
+ module Rsodx
3
+ class Contract < Dry::Validation::Contract
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module Rsodx
2
+ module Environment
3
+ def self.load_dotenv(env = nil)
4
+ require "dotenv"
5
+ Dotenv.load('.env', ".env.#{env}") if env
6
+ end
7
+
8
+ def self.load_initializers(config_path)
9
+ Dir[File.join(config_path, "initializers", "*.rb")].sort.each { |file| require file }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ module Rsodx
2
+ module Error
3
+ class Error < StandardError; end
4
+ class ContractError < Error; end
5
+ end
6
+ end
@@ -0,0 +1,39 @@
1
+ require "interactor"
2
+ require "json"
3
+ module Rsodx
4
+ class Interactor
5
+ include ::Interactor
6
+
7
+ class << self
8
+ attr_accessor :contract_class
9
+
10
+ def contract(&block)
11
+ before do
12
+ self.class.contract_class ||= Class.new(Rsodx::Contract, &block)
13
+ contract = self.class.contract_class.new.call(context.params.to_h)
14
+
15
+ if contract.failure?
16
+ halt(400, contract.errors.to_h)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ def halt(code, message)
23
+ log_error(code, message)
24
+ context.fail!(error_code: code, error: Rsodx::Error::ContractError.new(message))
25
+ end
26
+
27
+ private
28
+
29
+ def log_error(code, message)
30
+ puts JSON.pretty_generate({
31
+ level: "error",
32
+ code: code,
33
+ message: message,
34
+ context: context.to_h,
35
+ backtrace: caller
36
+ })
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ module Rsodx::Interactors
2
+ class Healthcheck < Rsodx::Interactor
3
+ def call
4
+ context.data = { ok: true }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ require 'json'
2
+ require_relative "router_dsl"
3
+
4
+ module Rsodx
5
+ class Router < Base
6
+ include RouterDSL
7
+ set :show_exceptions, false
8
+ set :raise_errors, true
9
+
10
+ before do
11
+ content_type :json
12
+ end
13
+
14
+ error do
15
+ status 500
16
+ { error: env['sinatra.error'].message }.to_json
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,61 @@
1
+ require 'json'
2
+
3
+ module Rsodx
4
+ module RouterDSL
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def route(verb, path, interactor, opts = {})
11
+ define_route(verb, path) do
12
+ payload = begin
13
+ request.body.rewind
14
+ JSON.parse(request.body.read, symbolize_names: true)
15
+ rescue JSON::ParserError
16
+ {}
17
+ end
18
+
19
+ ctx = {
20
+ params: params.to_h,
21
+ json: payload
22
+ }.merge(opts)
23
+
24
+ result = interactor.call(ctx)
25
+
26
+ status(result.error_code || 200)
27
+
28
+ if result.success?
29
+ { success: true, data: result.data }.to_json
30
+ else
31
+ { success: false, error: result.error }.to_json
32
+ end
33
+ end
34
+ end
35
+
36
+ %i[get post put patch delete].each do |verb|
37
+ define_method(verb) do |path, interactor = nil, **opts, &block|
38
+ if interactor
39
+ route(verb, path, interactor, opts)
40
+ else
41
+ super(path, &block)
42
+ end
43
+ end
44
+ end
45
+
46
+ def namespace(prefix, &block)
47
+ raise ArgumentError, "Block required for namespace" unless block_given?
48
+ previous = @namespace_prefix || ""
49
+ @namespace_prefix = previous + prefix
50
+ class_eval(&block)
51
+ @namespace_prefix = previous
52
+ end
53
+
54
+ def define_route(method, path, *args, &block)
55
+ route_block = block || args.pop
56
+ full_path = (@namespace_prefix || "") + path
57
+ Sinatra::Base.send(method.downcase, full_path, *args, &route_block)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ return unless defined?(Rake::DSL) rescue false
2
+ include Rake::DSL if defined?(Rake::DSL)
3
+
4
+ require "sequel/extensions/migration"
5
+
6
+ desc "Запуск Puma-сервера"
7
+ task :server do
8
+ sh "bundle exec puma -p 9292 config.ru"
9
+ end
10
+
11
+ namespace :db do
12
+ task :migrate do
13
+ Sequel::Migrator.run(DB.connect, "db/migrations")
14
+ end
15
+
16
+ task :rollback do
17
+ target = Sequel::Migrator.apply(DB.connect, "db/migrations", :down) - 1
18
+ Sequel::Migrator.run(DB.connect, "db/migrations", target: target)
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rsodx
4
+ VERSION = "0.0.1"
5
+ end
data/lib/rsodx.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.join(__dir__, "rsodx/*.rb")].sort.each { |f| require_relative f }
4
+ Dir[File.join(__dir__, "rsodx/**/*.rb")].sort.each { |f| require_relative f }
5
+
6
+ module Rsodx
7
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Rsodx do
4
+ it "has a version number" do
5
+ expect(Rsodx::VERSION).not_to be nil
6
+ end
7
+
8
+ it "does something useful" do
9
+ expect(false).to eq(true)
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rsodx"
4
+
5
+ RSpec.configure do |config|
6
+ # Enable flags like --only-failures and --next-failure
7
+ config.example_status_persistence_file_path = ".rspec_status"
8
+
9
+ # Disable RSpec exposing methods globally on `Module` and `main`
10
+ config.disable_monkey_patching!
11
+
12
+ config.expect_with :rspec do |c|
13
+ c.syntax = :expect
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,240 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rsodx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Eugene Pervushin
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-04-14 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rake
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '13.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '13.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: sinatra
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '4.1'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '4.1'
40
+ - !ruby/object:Gem::Dependency
41
+ name: sequel
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '5.91'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '5.91'
54
+ - !ruby/object:Gem::Dependency
55
+ name: pg
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.5'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.5'
68
+ - !ruby/object:Gem::Dependency
69
+ name: dry-validation
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.11'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.11'
82
+ - !ruby/object:Gem::Dependency
83
+ name: interactor
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.1'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.1'
96
+ - !ruby/object:Gem::Dependency
97
+ name: dotenv
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.1'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '3.1'
110
+ - !ruby/object:Gem::Dependency
111
+ name: puma
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '6.4'
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '6.4'
124
+ - !ruby/object:Gem::Dependency
125
+ name: json
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '2.7'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '2.7'
138
+ - !ruby/object:Gem::Dependency
139
+ name: ostruct
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.5'
145
+ type: :runtime
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '0.5'
152
+ - !ruby/object:Gem::Dependency
153
+ name: rspec
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '3.0'
159
+ type: :development
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '3.0'
166
+ - !ruby/object:Gem::Dependency
167
+ name: rubocop
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '1.75'
173
+ type: :development
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '1.75'
180
+ description: Rsodx is a lightweight Ruby microframework designed for modular, service-oriented
181
+ applications. Built with simplicity and performance in mind, it's perfect for small
182
+ web apps, microservices, and CLI tools.
183
+ email:
184
+ - sodium229897@gmail.com
185
+ executables:
186
+ - rsodx
187
+ extensions: []
188
+ extra_rdoc_files: []
189
+ files:
190
+ - LICENSE.txt
191
+ - README.md
192
+ - bin/console
193
+ - bin/rsodx
194
+ - bin/setup
195
+ - lib/rsodx.rb
196
+ - lib/rsodx/base.rb
197
+ - lib/rsodx/boot.rb
198
+ - lib/rsodx/cli/generate.rb
199
+ - lib/rsodx/cli/generate_interactor.rb
200
+ - lib/rsodx/cli/generate_migration.rb
201
+ - lib/rsodx/cli/handler.rb
202
+ - lib/rsodx/cli/scaffold.rb
203
+ - lib/rsodx/cli/server.rb
204
+ - lib/rsodx/connect.rb
205
+ - lib/rsodx/contract.rb
206
+ - lib/rsodx/environment.rb
207
+ - lib/rsodx/error.rb
208
+ - lib/rsodx/interactor.rb
209
+ - lib/rsodx/interactors/healthcheck.rb
210
+ - lib/rsodx/router.rb
211
+ - lib/rsodx/router_dsl.rb
212
+ - lib/rsodx/tasks.rb
213
+ - lib/rsodx/version.rb
214
+ - spec/rsodx_spec.rb
215
+ - spec/spec_helper.rb
216
+ homepage: https://github.com/eugene-ruby/rsodx
217
+ licenses:
218
+ - MIT
219
+ metadata:
220
+ allowed_push_host: https://rubygems.org
221
+ source_code_uri: https://github.com/eugene-ruby/rsodx
222
+ changelog_uri: https://github.com/eugene-ruby/rsodx/blob/main/CHANGELOG.md
223
+ rdoc_options: []
224
+ require_paths:
225
+ - lib
226
+ required_ruby_version: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - ">="
229
+ - !ruby/object:Gem::Version
230
+ version: 3.4.0
231
+ required_rubygems_version: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ requirements: []
237
+ rubygems_version: 3.6.2
238
+ specification_version: 4
239
+ summary: Minimal Ruby toolkit for clean, modular service-based apps
240
+ test_files: []