better_auth-sinatra 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: c8cfbde43e94311d211b9d355ed4fed778af108b0f6d149e4b3a6611ab3f9e90
4
+ data.tar.gz: 95e66c4b67168cfcb669ecfcf3aaa65798cbec20e8fd1d3b19e2833209520f0d
5
+ SHA512:
6
+ metadata.gz: d158fe7e73c3a9622ebee45408fe2e6762f6372c36c310bf7b79cc1b58454c0cf507c4656d44bbbf49a7d95f84a41da1c3662bebf357fa0f9a1ddcac97e88115
7
+ data.tar.gz: 78125ddabbd5ea6fa93bf2f7447154ef1ba9f308bfc71c0244bdc99f970fe309488829c84bf19b7b7bce7007a11302f1f869fc19da3d57994d601d08ce9380a7
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Initial Sinatra adapter.
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sebastian Sala
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,91 @@
1
+ # Better Auth Sinatra
2
+
3
+ Sinatra adapter for Better Auth Ruby. This package is a thin integration around
4
+ the framework-agnostic `better_auth` Rack core.
5
+
6
+ ## Installation
7
+
8
+ ```ruby
9
+ gem "better_auth-sinatra"
10
+ ```
11
+
12
+ ```bash
13
+ bundle install
14
+ ```
15
+
16
+ ## Setup
17
+
18
+ ```ruby
19
+ require "sinatra/base"
20
+ require "better_auth/sinatra"
21
+
22
+ class App < Sinatra::Base
23
+ register BetterAuth::Sinatra
24
+
25
+ better_auth at: "/api/auth" do |config|
26
+ config.secret = ENV.fetch("BETTER_AUTH_SECRET")
27
+ config.base_url = ENV.fetch("BETTER_AUTH_URL")
28
+ config.database = ->(options) {
29
+ BetterAuth::Adapters::Postgres.new(options, url: ENV.fetch("DATABASE_URL"))
30
+ }
31
+ config.email_and_password = {enabled: true}
32
+ config.plugins = []
33
+ end
34
+
35
+ get "/dashboard" do
36
+ require_authentication
37
+ current_user.fetch("email")
38
+ end
39
+ end
40
+ ```
41
+
42
+ The extension mounts the core Rack app at `/api/auth` by default. The core app
43
+ still owns routes such as `/ok`, `/sign-up/email`, `/sign-in/email`, and plugin
44
+ endpoints.
45
+
46
+ ## Helpers
47
+
48
+ - `current_session`
49
+ - `current_user`
50
+ - `authenticated?`
51
+ - `require_authentication`
52
+
53
+ `require_authentication` halts with `401` when no Better Auth user is present.
54
+
55
+ ## Rake Tasks
56
+
57
+ Load tasks from your app Rakefile:
58
+
59
+ ```ruby
60
+ require "better_auth/sinatra/tasks"
61
+ ```
62
+
63
+ Available tasks:
64
+
65
+ ```bash
66
+ rake better_auth:install
67
+ rake better_auth:generate:migration
68
+ rake better_auth:migrate
69
+ rake better_auth:routes
70
+ ```
71
+
72
+ `better_auth:install` creates `config/better_auth.rb`. SQL migrations are
73
+ generated under `db/better_auth/migrate`.
74
+
75
+ ## Database Notes
76
+
77
+ Sinatra does not include a Rails-style database layer or migration command.
78
+ This adapter uses Better Auth core SQL adapters for migrations. Set
79
+ `BETTER_AUTH_DIALECT=postgres`, `mysql`, or `sqlite` when generating SQL.
80
+
81
+ ActiveRecord-backed Sinatra migrations are not supported yet. Apps that already
82
+ use `sinatra-activerecord` can still configure Better Auth manually, but the v1
83
+ Rake tasks do not emit ActiveRecord migrations.
84
+
85
+ ## Development
86
+
87
+ ```bash
88
+ cd packages/better_auth-sinatra
89
+ rbenv exec bundle exec rspec
90
+ RUBOCOP_CACHE_ROOT=/private/var/folders/7x/jrsz946d2w73n42fb1_ff5000000gn/T/rubocop_cache_sinatra rbenv exec bundle exec standardrb
91
+ ```
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module Sinatra
5
+ class Configuration
6
+ AUTH_OPTION_NAMES = %i[
7
+ app_name
8
+ base_url
9
+ base_path
10
+ secret
11
+ database
12
+ plugins
13
+ trusted_origins
14
+ rate_limit
15
+ session
16
+ account
17
+ user
18
+ verification
19
+ advanced
20
+ email_and_password
21
+ password_hasher
22
+ email_verification
23
+ social_providers
24
+ experimental
25
+ secondary_storage
26
+ database_hooks
27
+ hooks
28
+ on_api_error
29
+ disabled_paths
30
+ logger
31
+ ].freeze
32
+
33
+ attr_accessor(*AUTH_OPTION_NAMES)
34
+
35
+ def initialize
36
+ @base_path = BetterAuth::Configuration::DEFAULT_BASE_PATH
37
+ @plugins = []
38
+ @trusted_origins = []
39
+ end
40
+
41
+ def to_auth_options
42
+ AUTH_OPTION_NAMES.each_with_object({}) do |name, options|
43
+ value = public_send(name)
44
+ next if value.nil?
45
+ next if value.respond_to?(:empty?) && value.empty?
46
+
47
+ options[name] = value
48
+ end
49
+ end
50
+
51
+ def copy
52
+ self.class.new.tap do |copy|
53
+ AUTH_OPTION_NAMES.each do |name|
54
+ value = public_send(name)
55
+ copy.public_send("#{name}=", deep_dup(value))
56
+ end
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def deep_dup(value)
63
+ case value
64
+ when Hash
65
+ value.transform_values { |entry| deep_dup(entry) }
66
+ when Array
67
+ value.map { |entry| deep_dup(entry) }
68
+ else
69
+ value
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module Sinatra
5
+ module Extension
6
+ def self.registered(app)
7
+ app.extend ClassMethods
8
+ app.helpers Helpers
9
+ end
10
+
11
+ module ClassMethods
12
+ def better_auth(at: BetterAuth::Configuration::DEFAULT_BASE_PATH, auth: nil, **overrides)
13
+ mount_path = normalize_better_auth_mount_path(at)
14
+ config = BetterAuth::Sinatra.configuration.copy
15
+ yield config if block_given?
16
+ config.base_path = mount_path
17
+ options = config.to_auth_options.merge(overrides)
18
+ auth_instance = auth || BetterAuth.auth(options)
19
+
20
+ set :better_auth_auth, auth_instance
21
+ set :better_auth_mount_path, mount_path
22
+ use BetterAuth::Sinatra::MountedApp, -> { settings.better_auth_auth }, mount_path: mount_path
23
+ end
24
+
25
+ private
26
+
27
+ def normalize_better_auth_mount_path(path)
28
+ normalized = path.to_s
29
+ normalized = "/#{normalized}" unless normalized.start_with?("/")
30
+ normalized = normalized.squeeze("/")
31
+ (normalized == "/") ? normalized : normalized.delete_suffix("/")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module Sinatra
5
+ module Helpers
6
+ def current_session
7
+ data = better_auth_session_data
8
+ data&.fetch(:session, nil) || data&.fetch("session", nil)
9
+ end
10
+
11
+ def current_user
12
+ data = better_auth_session_data
13
+ data&.fetch(:user, nil) || data&.fetch("user", nil)
14
+ end
15
+
16
+ def authenticated?
17
+ !current_user.nil?
18
+ end
19
+
20
+ def require_authentication
21
+ return true if authenticated?
22
+
23
+ halt 401, ""
24
+ end
25
+
26
+ private
27
+
28
+ def better_auth_session_data
29
+ return request.env["better_auth.session"] if request.env.key?("better_auth.session")
30
+
31
+ request.env["better_auth.session"] = resolve_better_auth_session
32
+ end
33
+
34
+ def resolve_better_auth_session
35
+ context = BetterAuth::Endpoint::Context.new(
36
+ path: request.path_info,
37
+ method: request.request_method,
38
+ query: request.GET,
39
+ body: {},
40
+ params: params,
41
+ headers: {"cookie" => request.env["HTTP_COOKIE"]},
42
+ context: better_auth_auth.context,
43
+ request: request
44
+ )
45
+ BetterAuth::Session.find_current(context, disable_refresh: true)
46
+ end
47
+
48
+ def better_auth_auth
49
+ if respond_to?(:settings) && settings.respond_to?(:better_auth_auth)
50
+ settings.better_auth_auth
51
+ else
52
+ BetterAuth::Sinatra.auth
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module BetterAuth
6
+ module Sinatra
7
+ module Migration
8
+ DEFAULT_MIGRATIONS_PATH = "db/better_auth/migrate"
9
+
10
+ class UnsupportedAdapterError < StandardError; end
11
+
12
+ module_function
13
+
14
+ def render(options, dialect:)
15
+ config = configuration_for(options)
16
+ statements = BetterAuth::Schema::SQL.create_statements(config, dialect: dialect)
17
+ [
18
+ "-- Generated by better_auth-sinatra",
19
+ "-- Dialect: #{dialect}",
20
+ "",
21
+ statements.join("\n\n"),
22
+ ""
23
+ ].join("\n")
24
+ end
25
+
26
+ def generate(options, dialect:, migrations_path: DEFAULT_MIGRATIONS_PATH, timestamp: Time.now.utc.strftime("%Y%m%d%H%M%S"))
27
+ FileUtils.mkdir_p(migrations_path)
28
+ path = File.join(migrations_path, "#{timestamp}_create_better_auth_tables.sql")
29
+ return path if File.exist?(path)
30
+
31
+ File.write(path, render(options, dialect: dialect))
32
+ path
33
+ end
34
+
35
+ def migrate(auth_or_options, migrations_path: DEFAULT_MIGRATIONS_PATH)
36
+ auth = auth_for(auth_or_options)
37
+ adapter = auth.context.adapter
38
+ unless adapter.respond_to?(:dialect) && adapter.respond_to?(:connection)
39
+ raise UnsupportedAdapterError, "better_auth-sinatra migrations require core SQL adapters with connection and dialect support"
40
+ end
41
+
42
+ connection = adapter.connection
43
+ dialect = adapter.dialect.to_sym
44
+ files = Dir[File.join(migrations_path, "*.sql")].sort
45
+ ensure_schema_migrations!(connection, dialect)
46
+ applied = applied_migrations(connection, dialect)
47
+
48
+ files.reject { |file| applied.include?(File.basename(file)) }.each do |file|
49
+ execute_sql(connection, File.read(file))
50
+ record_migration(connection, dialect, File.basename(file))
51
+ end
52
+ end
53
+
54
+ def configuration_for(options)
55
+ return options.options if options.is_a?(BetterAuth::Auth)
56
+ return options if options.is_a?(BetterAuth::Configuration)
57
+
58
+ BetterAuth::Configuration.new(options)
59
+ end
60
+
61
+ def auth_for(value)
62
+ return value if value.is_a?(BetterAuth::Auth)
63
+
64
+ BetterAuth.auth(value)
65
+ end
66
+
67
+ def ensure_schema_migrations!(connection, dialect)
68
+ sql = case dialect
69
+ when :postgres, :sqlite
70
+ %(CREATE TABLE IF NOT EXISTS #{quote("better_auth_schema_migrations", dialect)} (#{quote("version", dialect)} text PRIMARY KEY);)
71
+ when :mysql
72
+ %(CREATE TABLE IF NOT EXISTS #{quote("better_auth_schema_migrations", dialect)} (#{quote("version", dialect)} varchar(191) PRIMARY KEY) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;)
73
+ when :mssql
74
+ %(IF OBJECT_ID(N'#{quote("better_auth_schema_migrations", dialect)}', N'U') IS NULL CREATE TABLE #{quote("better_auth_schema_migrations", dialect)} (#{quote("version", dialect)} varchar(255) PRIMARY KEY);)
75
+ else
76
+ raise UnsupportedAdapterError, "Unsupported SQL dialect for better_auth-sinatra migrations: #{dialect}"
77
+ end
78
+ execute_sql(connection, sql)
79
+ end
80
+
81
+ def applied_migrations(connection, dialect)
82
+ rows = execute_sql(connection, "SELECT #{quote("version", dialect)} FROM #{quote("better_auth_schema_migrations", dialect)};")
83
+ Array(rows).map { |row| row["version"] || row[:version] }
84
+ rescue
85
+ []
86
+ end
87
+
88
+ def record_migration(connection, dialect, version)
89
+ sql = "INSERT INTO #{quote("better_auth_schema_migrations", dialect)} (#{quote("version", dialect)}) VALUES (#{literal(version)});"
90
+ execute_sql(connection, sql)
91
+ end
92
+
93
+ def execute_sql(connection, sql)
94
+ statements(sql).each_with_object([]) do |statement, results|
95
+ result =
96
+ if connection.respond_to?(:exec)
97
+ connection.exec(statement)
98
+ elsif connection.respond_to?(:execute)
99
+ connection.execute(statement)
100
+ elsif connection.respond_to?(:query)
101
+ connection.query(statement)
102
+ else
103
+ raise UnsupportedAdapterError, "SQL connection does not support exec, execute, or query"
104
+ end
105
+ results.concat(result.to_a) if result.respond_to?(:to_a)
106
+ end
107
+ end
108
+
109
+ def statements(sql)
110
+ sql.split(/;\s*$/).map(&:strip).reject(&:empty?)
111
+ end
112
+
113
+ def quote(identifier, dialect)
114
+ BetterAuth::Schema::SQL.quote(identifier, dialect)
115
+ end
116
+
117
+ def literal(value)
118
+ "'#{value.to_s.gsub("'", "''")}'"
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module Sinatra
5
+ class MountedApp
6
+ def initialize(app, auth, mount_path:)
7
+ @app = app
8
+ @auth = auth
9
+ @mount_path = normalize_path(mount_path)
10
+ end
11
+
12
+ def call(env)
13
+ return auth.call(env) if mounted_path?(env["PATH_INFO"])
14
+
15
+ @app.call(env)
16
+ end
17
+
18
+ private
19
+
20
+ def auth
21
+ return @auth.call if @auth.respond_to?(:call) && !@auth.respond_to?(:context)
22
+
23
+ @auth
24
+ end
25
+
26
+ def mounted_path?(path)
27
+ normalized = normalize_path(path)
28
+ return true if @mount_path == "/"
29
+
30
+ normalized == @mount_path || normalized.start_with?("#{@mount_path}/")
31
+ end
32
+
33
+ def normalize_path(path)
34
+ normalized = path.to_s
35
+ normalized = "/#{normalized}" unless normalized.start_with?("/")
36
+ normalized = normalized.squeeze("/")
37
+ normalized = normalized.delete_suffix("/") unless normalized == "/"
38
+ normalized.empty? ? "/" : normalized
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "rake"
5
+ require "better_auth/sinatra"
6
+
7
+ namespace :better_auth do
8
+ desc "Create the Better Auth Sinatra config and migration directory"
9
+ task :install do
10
+ config_path = "config/better_auth.rb"
11
+ FileUtils.mkdir_p(File.dirname(config_path))
12
+ if File.exist?(config_path)
13
+ puts "skip #{config_path} already exists"
14
+ else
15
+ File.write(config_path, BetterAuth::Sinatra.default_config_template)
16
+ puts "create #{config_path}"
17
+ end
18
+
19
+ FileUtils.mkdir_p(BetterAuth::Sinatra::Migration::DEFAULT_MIGRATIONS_PATH)
20
+ end
21
+
22
+ namespace :generate do
23
+ desc "Create the Better Auth SQL migration"
24
+ task :migration do
25
+ BetterAuth::Sinatra.load_app_config
26
+ dialect = ENV.fetch("BETTER_AUTH_DIALECT", "postgres").to_sym
27
+ config = BetterAuth::Sinatra.migration_configuration
28
+ path = BetterAuth::Sinatra::Migration.generate(config, dialect: dialect)
29
+ puts "create #{path}"
30
+ end
31
+ end
32
+
33
+ desc "Create the Better Auth SQL migration"
34
+ task "generate:migration" do
35
+ Rake::Task["better_auth:generate:migration"].invoke
36
+ end
37
+
38
+ desc "Run pending Better Auth SQL migrations"
39
+ task :migrate do
40
+ BetterAuth::Sinatra.load_app_config
41
+ BetterAuth::Sinatra::Migration.migrate(BetterAuth::Sinatra.auth)
42
+ end
43
+
44
+ desc "Print Better Auth Sinatra mount information"
45
+ task :routes do
46
+ BetterAuth::Sinatra.load_app_config
47
+ puts "#{BetterAuth::Sinatra.configuration.base_path}/* -> BetterAuth.auth"
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module Sinatra
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "better_auth"
4
+ require "sinatra/base"
5
+
6
+ require_relative "sinatra/version"
7
+ require_relative "sinatra/configuration"
8
+ require_relative "sinatra/mounted_app"
9
+ require_relative "sinatra/helpers"
10
+ require_relative "sinatra/migration"
11
+ require_relative "sinatra/extension"
12
+
13
+ module BetterAuth
14
+ module Sinatra
15
+ class << self
16
+ def registered(app)
17
+ Extension.registered(app)
18
+ end
19
+
20
+ def configuration
21
+ @configuration ||= Configuration.new
22
+ end
23
+
24
+ def configure
25
+ yield configuration
26
+ @auth = nil
27
+ self
28
+ end
29
+
30
+ def reset!
31
+ @configuration = nil
32
+ @auth = nil
33
+ end
34
+
35
+ def auth(overrides = nil)
36
+ options = configuration.to_auth_options
37
+ return @auth ||= BetterAuth.auth(options) if overrides.nil? || overrides.empty?
38
+
39
+ BetterAuth.auth(options.merge(overrides))
40
+ end
41
+
42
+ def migration_configuration
43
+ options = configuration.to_auth_options
44
+ options[:secret] ||= BetterAuth::Configuration::DEFAULT_SECRET
45
+ BetterAuth::Configuration.new(options)
46
+ end
47
+
48
+ def load_app_config(path = "config/better_auth.rb")
49
+ load path if File.exist?(path)
50
+ end
51
+
52
+ def default_config_template
53
+ <<~RUBY
54
+ # frozen_string_literal: true
55
+
56
+ require "better_auth/sinatra"
57
+
58
+ BetterAuth::Sinatra.configure do |config|
59
+ config.secret = ENV.fetch("BETTER_AUTH_SECRET", "change-me-sinatra-secret-12345678901234567890")
60
+ config.base_url = ENV["BETTER_AUTH_URL"]
61
+ config.base_path = "/api/auth"
62
+
63
+ config.database = ->(options) do
64
+ case ENV.fetch("BETTER_AUTH_DATABASE_DIALECT", "postgres")
65
+ when "postgres", "postgresql"
66
+ BetterAuth::Adapters::Postgres.new(options, url: ENV.fetch("DATABASE_URL"))
67
+ when "mysql"
68
+ BetterAuth::Adapters::MySQL.new(options, url: ENV.fetch("DATABASE_URL"))
69
+ when "sqlite", "sqlite3"
70
+ BetterAuth::Adapters::SQLite.new(options, path: ENV.fetch("DATABASE_URL", "db/better_auth.sqlite3"))
71
+ else
72
+ raise "Unsupported BETTER_AUTH_DATABASE_DIALECT for better_auth-sinatra"
73
+ end
74
+ end
75
+
76
+ config.email_and_password = {
77
+ enabled: true
78
+ }
79
+
80
+ config.plugins = []
81
+ end
82
+ RUBY
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "better_auth/sinatra"
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: better_auth-sinatra
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sebastian Sala
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: better_auth
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.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: '3.0'
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: '5'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '3.0'
43
+ - - "<"
44
+ - !ruby/object:Gem::Version
45
+ version: '5'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.5'
53
+ type: :development
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.5'
60
+ - !ruby/object:Gem::Dependency
61
+ name: rack-test
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '2.2'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '2.2'
74
+ - !ruby/object:Gem::Dependency
75
+ name: rake
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '13.2'
81
+ type: :development
82
+ prerelease: false
83
+ version_requirements: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '13.2'
88
+ - !ruby/object:Gem::Dependency
89
+ name: rspec
90
+ requirement: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '3.13'
95
+ type: :development
96
+ prerelease: false
97
+ version_requirements: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '3.13'
102
+ - !ruby/object:Gem::Dependency
103
+ name: standardrb
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '1.0'
109
+ type: :development
110
+ prerelease: false
111
+ version_requirements: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '1.0'
116
+ description: Sinatra integration for Better Auth Ruby. Provides mounting helpers,
117
+ request helpers, and SQL migration tasks.
118
+ email:
119
+ - sebastian.sala.tech@gmail.com
120
+ executables: []
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - CHANGELOG.md
125
+ - LICENSE.md
126
+ - README.md
127
+ - lib/better_auth/sinatra.rb
128
+ - lib/better_auth/sinatra/configuration.rb
129
+ - lib/better_auth/sinatra/extension.rb
130
+ - lib/better_auth/sinatra/helpers.rb
131
+ - lib/better_auth/sinatra/migration.rb
132
+ - lib/better_auth/sinatra/mounted_app.rb
133
+ - lib/better_auth/sinatra/tasks.rb
134
+ - lib/better_auth/sinatra/version.rb
135
+ - lib/better_auth_sinatra.rb
136
+ homepage: https://github.com/sebasxsala/better-auth
137
+ licenses:
138
+ - MIT
139
+ metadata:
140
+ homepage_uri: https://github.com/sebasxsala/better-auth
141
+ source_code_uri: https://github.com/sebasxsala/better-auth
142
+ changelog_uri: https://github.com/sebasxsala/better-auth/blob/main/packages/better_auth-sinatra/CHANGELOG.md
143
+ bug_tracker_uri: https://github.com/sebasxsala/better-auth/issues
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: 3.2.0
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubygems_version: 3.6.9
159
+ specification_version: 4
160
+ summary: Sinatra adapter for Better Auth
161
+ test_files: []