better_auth-cli 0.10.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: 6f43bdbfe1ccede48e41d7ea7ff77f974ad177daec7f1b3e41925009a638d23d
4
+ data.tar.gz: aadb7a3c1aee35097385d9e9a27c437312d3c38673bd8c70ff74b4e2292459ec
5
+ SHA512:
6
+ metadata.gz: ee5873d758ffdb11eabf209cc80de5052929035775493fb9e46bf981260ba360877aa52b763ed39ff9c0266b80cecdec42517078fa8d0d30f5d63fc57a03c9d0
7
+ data.tar.gz: b2b28e050690c78559ac01ae3235b02a7509d018c6583dc87fc899a44b54af0a8d4234e1e31b283c23803b1a8abb384adf8e8e2c4dea29e72bc0e2f5651de1db
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 0.10.0
4
+
5
+ - Improved CLI error handling and expanded command coverage.
6
+
7
+ ## 0.9.0
8
+
9
+ - Initial Better Auth CLI package with `better-auth generate`, `better-auth migrate`, `better-auth migrate status`, `better-auth doctor`, and `better-auth mongo indexes`.
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # better_auth-cli
2
+
3
+ Command-line tools for Better Auth Ruby.
4
+
5
+ ```bash
6
+ better-auth generate --config config/better_auth.rb --dialect postgres --output db/better_auth/schema.sql
7
+ better-auth migrate --config config/better_auth.rb --yes
8
+ better-auth migrate status --config config/better_auth.rb
9
+ better-auth doctor --config config/better_auth.rb
10
+ better-auth mongo indexes --config config/better_auth.rb
11
+ ```
12
+
13
+ The config file should return a `Hash` or `BetterAuth::Configuration`.
14
+ `doctor` validates the config, secret strength, HTTPS base URL, rate-limit
15
+ storage, SQL adapter support, and pending Better Auth migrations.
16
+ `mongo indexes` is for MongoDB adapters and idempotently ensures the indexes
17
+ declared by the active Better Auth schema.
18
+
19
+ Install `openauth-cli` for the `openauth` executable alias.
data/exe/better-auth ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "better_auth/cli"
5
+
6
+ exit BetterAuth::CLI.run(ARGV)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ class CLI
5
+ VERSION = "0.10.0"
6
+ end
7
+ end
@@ -0,0 +1,240 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "better_auth"
4
+ require "better_auth/cli/version"
5
+ require "better_auth/doctor"
6
+ require "better_auth/sql_migration"
7
+ require "fileutils"
8
+ require "optparse"
9
+
10
+ module BetterAuth
11
+ class CLI
12
+ class Error < StandardError; end
13
+
14
+ class << self
15
+ attr_accessor :configuration
16
+
17
+ def configure(value = nil)
18
+ @configuration = block_given? ? yield : value
19
+ end
20
+
21
+ def run(argv = ARGV, stdout: $stdout, stderr: $stderr)
22
+ new(argv, stdout: stdout, stderr: stderr).run
23
+ rescue Error, BetterAuth::SQLMigration::UnsupportedAdapterError, BetterAuth::Error, OptionParser::ParseError => error
24
+ stderr.puts error.message
25
+ 1
26
+ end
27
+ end
28
+
29
+ def initialize(argv, stdout:, stderr:)
30
+ @argv = argv.dup
31
+ @stdout = stdout
32
+ @stderr = stderr
33
+ end
34
+
35
+ def run
36
+ command = argv.shift
37
+ case command
38
+ when "generate"
39
+ generate(argv)
40
+ when "migrate"
41
+ migrate(argv)
42
+ when "doctor"
43
+ doctor(argv)
44
+ when "mongo"
45
+ mongo(argv)
46
+ when "-h", "--help", "help", nil
47
+ stdout.puts usage
48
+ 0
49
+ else
50
+ raise Error, "Unknown command: #{command}"
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :argv, :stdout, :stderr
57
+
58
+ def generate(args)
59
+ options = parse_generate_options(args)
60
+ config = load_config(options.fetch(:config))
61
+ adapter = sql_adapter_for(config)
62
+ connection = adapter&.connection
63
+ dialect = BetterAuth::SQLMigration.normalize_dialect(options[:dialect] || adapter&.dialect || "postgres")
64
+ sql = if connection
65
+ BetterAuth::SQLMigration.render_pending(config, connection: connection, dialect: dialect, generator: "better_auth-cli")
66
+ else
67
+ BetterAuth::SQLMigration.render(config, dialect: dialect, generator: "better_auth-cli")
68
+ end
69
+
70
+ if sql.empty?
71
+ stdout.puts "No migrations needed."
72
+ return 0
73
+ end
74
+
75
+ output = options.fetch(:output)
76
+ FileUtils.mkdir_p(File.dirname(output))
77
+ File.write(output, sql)
78
+ stdout.puts "generated #{output}"
79
+ 0
80
+ end
81
+
82
+ def migrate(args)
83
+ if args.first == "status"
84
+ args.shift
85
+ return migration_status(args)
86
+ end
87
+
88
+ options = parse_migrate_options(args)
89
+ raise Error, "Pass --yes to apply migrations." unless options[:yes]
90
+
91
+ auth = auth_for(load_config(options.fetch(:config)))
92
+ migrated = BetterAuth::SQLMigration.migrate_pending(auth)
93
+ stdout.puts(migrated ? "migration completed successfully." : "No migrations needed.")
94
+ 0
95
+ end
96
+
97
+ def migration_status(args)
98
+ options = parse_config_options(args, "migrate status --config PATH is required")
99
+ config = load_config(options.fetch(:config))
100
+ adapter = required_sql_adapter_for(config)
101
+ plan = BetterAuth::SQLMigration.plan(config, connection: adapter.connection, dialect: adapter.dialect)
102
+
103
+ if plan.empty?
104
+ stdout.puts "No migrations needed."
105
+ else
106
+ plan.to_create.each { |change| stdout.puts "create table #{change.table_name}" }
107
+ plan.to_add.each { |change| stdout.puts "add #{change.fields.keys.join(", ")} to #{change.table_name}" }
108
+ plan.to_index.each { |change| stdout.puts "create index #{change.name}" }
109
+ plan.warnings.each { |warning| stdout.puts "warning: #{warning}" }
110
+ end
111
+ 0
112
+ end
113
+
114
+ def doctor(args)
115
+ options = parse_config_options(args, "doctor --config PATH is required")
116
+ config = load_config(options.fetch(:config))
117
+ BetterAuth::Doctor.print(BetterAuth::Doctor.check(config), stdout: stdout, stderr: stderr)
118
+ end
119
+
120
+ def mongo(args)
121
+ command = args.shift
122
+ case command
123
+ when "indexes"
124
+ mongo_indexes(args)
125
+ else
126
+ raise Error, "Unknown mongo command: #{command || "(none)"}"
127
+ end
128
+ end
129
+
130
+ def mongo_indexes(args)
131
+ options = parse_config_options(args, "mongo indexes --config PATH is required")
132
+ auth = auth_for(load_config(options.fetch(:config)))
133
+ adapter = auth.context.adapter
134
+ unless adapter.respond_to?(:ensure_indexes!)
135
+ raise Error, "MongoDB index setup requires an adapter that supports ensure_indexes!"
136
+ end
137
+
138
+ indexes = adapter.ensure_indexes!
139
+ if indexes.empty?
140
+ stdout.puts "No MongoDB indexes needed."
141
+ else
142
+ indexes.each do |index|
143
+ validate_mongo_index!(index)
144
+ unique = index[:unique] ? " unique" : ""
145
+ stdout.puts "ensured#{unique} index #{index[:collection]}.#{index[:field]}"
146
+ end
147
+ end
148
+ 0
149
+ end
150
+
151
+ def parse_generate_options(args)
152
+ options = {}
153
+ OptionParser.new do |parser|
154
+ parser.on("--config PATH") { |value| options[:config] = value }
155
+ parser.on("--dialect DIALECT") { |value| options[:dialect] = value }
156
+ parser.on("--output PATH") { |value| options[:output] = value }
157
+ end.parse!(args)
158
+ require_option!(options, :config, "generate --config PATH is required")
159
+ require_option!(options, :output, "generate --output PATH is required")
160
+ options
161
+ end
162
+
163
+ def parse_migrate_options(args)
164
+ options = {yes: false}
165
+ OptionParser.new do |parser|
166
+ parser.on("--config PATH") { |value| options[:config] = value }
167
+ parser.on("--yes", "-y") { options[:yes] = true }
168
+ end.parse!(args)
169
+ require_option!(options, :config, "migrate --config PATH is required")
170
+ options
171
+ end
172
+
173
+ def parse_config_options(args, missing_message)
174
+ options = {}
175
+ OptionParser.new do |parser|
176
+ parser.on("--config PATH") { |value| options[:config] = value }
177
+ end.parse!(args)
178
+ require_option!(options, :config, missing_message)
179
+ options
180
+ end
181
+
182
+ def require_option!(options, key, message)
183
+ raise Error, message unless options[key]
184
+ end
185
+
186
+ def load_config(path)
187
+ raise Error, "Config file not found: #{path}" unless File.exist?(path)
188
+
189
+ self.class.configure(nil)
190
+ result = TOPLEVEL_BINDING.eval(File.read(path), path)
191
+ value = normalize_config_value(result) || self.class.configuration
192
+ raise Error, "Config file must return a Hash, BetterAuth::Configuration, or BetterAuth::Auth" unless value
193
+
194
+ BetterAuth::SQLMigration.configuration_for(value)
195
+ end
196
+
197
+ def normalize_config_value(value)
198
+ value if value.is_a?(Hash) || value.is_a?(BetterAuth::Configuration) || value.is_a?(BetterAuth::Auth)
199
+ end
200
+
201
+ def validate_mongo_index!(index)
202
+ return if index[:collection] && index[:field]
203
+
204
+ raise Error, "MongoDB index metadata must include collection and field"
205
+ end
206
+
207
+ def sql_adapter_for(config)
208
+ required_sql_adapter_for(config)
209
+ rescue BetterAuth::SQLMigration::UnsupportedAdapterError
210
+ nil
211
+ end
212
+
213
+ def required_sql_adapter_for(config)
214
+ adapter = auth_for(config).context.adapter
215
+ unless adapter.respond_to?(:dialect) && adapter.respond_to?(:connection)
216
+ raise BetterAuth::SQLMigration::UnsupportedAdapterError,
217
+ "Better Auth SQL migrations require core SQL adapters with connection and dialect support"
218
+ end
219
+
220
+ adapter
221
+ end
222
+
223
+ def auth_for(config)
224
+ return config if config.is_a?(BetterAuth::Auth)
225
+
226
+ BetterAuth.auth(config.to_h)
227
+ end
228
+
229
+ def usage
230
+ <<~TEXT
231
+ Usage:
232
+ better-auth generate --config PATH --dialect DIALECT --output PATH
233
+ better-auth migrate --config PATH --yes
234
+ better-auth migrate status --config PATH
235
+ better-auth doctor --config PATH
236
+ better-auth mongo indexes --config PATH
237
+ TEXT
238
+ end
239
+ end
240
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: better_auth-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.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.10.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - '='
24
+ - !ruby/object:Gem::Version
25
+ version: 0.10.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: minitest
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.25'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '5.25'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rake
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '13.2'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '13.2'
54
+ - !ruby/object:Gem::Dependency
55
+ name: sqlite3
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.0'
68
+ description: Generates and applies Better Auth Ruby database migrations from app configuration.
69
+ email:
70
+ - sebastian.sala.tech@gmail.com
71
+ executables:
72
+ - better-auth
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - CHANGELOG.md
77
+ - README.md
78
+ - exe/better-auth
79
+ - lib/better_auth/cli.rb
80
+ - lib/better_auth/cli/version.rb
81
+ homepage: https://github.com/sebasxsala/better-auth-rb
82
+ licenses:
83
+ - MIT
84
+ metadata:
85
+ homepage_uri: https://github.com/sebasxsala/better-auth-rb
86
+ source_code_uri: https://github.com/sebasxsala/better-auth-rb
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 3.2.0
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubygems_version: 3.6.9
102
+ specification_version: 4
103
+ summary: Command-line tools for Better Auth Ruby
104
+ test_files: []