strum 0.0.21
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 +7 -0
- data/.gitignore +23 -0
- data/.rakeTasks +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +25 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +71 -0
- data/README.md +35 -0
- data/Rakefile +8 -0
- data/bin/strum +5 -0
- data/lib/strum/Rakefile +6 -0
- data/lib/strum/cli.rb +37 -0
- data/lib/strum/command.rb +18 -0
- data/lib/strum/commands/generate.rb +33 -0
- data/lib/strum/commands/mixin/app_check.rb +21 -0
- data/lib/strum/commands/mixin/fields.rb +29 -0
- data/lib/strum/commands/mixin/names.rb +57 -0
- data/lib/strum/commands/new.rb +68 -0
- data/lib/strum/commands/resource/migration.rb +59 -0
- data/lib/strum/commands/resource/model.rb +31 -0
- data/lib/strum/commands/resource/route.rb +47 -0
- data/lib/strum/commands/resource/scaffold.rb +20 -0
- data/lib/strum/commands/resource/serializer.rb +31 -0
- data/lib/strum/commands/resource/service.rb +42 -0
- data/lib/strum/service.rb +116 -0
- data/lib/strum/sub_command_base.rb +18 -0
- data/lib/strum/tasks/sequel.rake +87 -0
- data/lib/strum/templates/app/blank/.env.local.tt +6 -0
- data/lib/strum/templates/app/blank/.env.test.tt +4 -0
- data/lib/strum/templates/app/blank/.gitignore +26 -0
- data/lib/strum/templates/app/blank/.rubocop.yml +28 -0
- data/lib/strum/templates/app/blank/Dockerfile +15 -0
- data/lib/strum/templates/app/blank/Gemfile.tt +68 -0
- data/lib/strum/templates/app/blank/Rakefile +8 -0
- data/lib/strum/templates/app/blank/bin/console.tt +15 -0
- data/lib/strum/templates/app/blank/config/app.rb.tt +60 -0
- data/lib/strum/templates/app/blank/config/env.rb +12 -0
- data/lib/strum/templates/app/blank/config.ru.tt +18 -0
- data/lib/strum/templates/app/blank/lib/.keep +0 -0
- data/lib/strum/templates/app/blank/routes/.keep +0 -0
- data/lib/strum/templates/app/blank/services/.keep +0 -0
- data/lib/strum/templates/app/json/serializers/.keep +0 -0
- data/lib/strum/templates/app/sequel/config/models.rb +18 -0
- data/lib/strum/templates/app/sequel/config/sequel.rb +10 -0
- data/lib/strum/templates/app/sequel/db/migrations/001_setup.rb +17 -0
- data/lib/strum/templates/app/sequel/models/.keep +0 -0
- data/lib/strum/templates/migration/%migration_filename%.rb.tt +27 -0
- data/lib/strum/templates/model/%resource_filename%.rb.tt +12 -0
- data/lib/strum/templates/route/%resource_filename%.rb.tt +9 -0
- data/lib/strum/templates/route_crud/%resource_filename%.rb.tt +44 -0
- data/lib/strum/templates/serializer/%resource_name%_serializer.rb.tt +17 -0
- data/lib/strum/templates/service/%resource_filename%.rb.tt +22 -0
- data/lib/strum/templates/service_crud/%resource_name%/create.rb.tt +28 -0
- data/lib/strum/templates/service_crud/%resource_name%/delete.rb.tt +27 -0
- data/lib/strum/templates/service_crud/%resource_name%/find.rb.tt +25 -0
- data/lib/strum/templates/service_crud/%resource_name%/search.rb.tt +23 -0
- data/lib/strum/templates/service_crud/%resource_name%/update.rb.tt +28 -0
- data/lib/strum/version.rb +5 -0
- data/lib/strum.rb +9 -0
- data/strum.gemspec +46 -0
- metadata +219 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "strum/commands/mixin/app_check"
|
4
|
+
require "strum/commands/mixin/names"
|
5
|
+
require "strum/commands/mixin/fields"
|
6
|
+
|
7
|
+
module Strum::Commands::Resource
|
8
|
+
# Strum generate sub command
|
9
|
+
# `strum generate service`
|
10
|
+
class Service < Thor::Group
|
11
|
+
include Thor::Actions
|
12
|
+
include Strum::Commands::Mixin::AppCheck
|
13
|
+
include Strum::Commands::Mixin::Names
|
14
|
+
include Strum::Commands::Mixin::Fields
|
15
|
+
|
16
|
+
argument :name
|
17
|
+
class_option :crud, type: :boolean, aliases: ["-c"]
|
18
|
+
class_option :fields, type: :array, default: []
|
19
|
+
|
20
|
+
def self.source_root
|
21
|
+
File.expand_path("../../templates", __dir__)
|
22
|
+
end
|
23
|
+
|
24
|
+
def pre_check
|
25
|
+
raise StrumGenerateError, "This is not Strum application" unless strum?
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_service_files
|
29
|
+
options[:crud] ? crud_service : basic_service
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def basic_service
|
35
|
+
directory("service", File.expand_path(namespace_path, "services"))
|
36
|
+
end
|
37
|
+
|
38
|
+
def crud_service
|
39
|
+
directory("service_crud", File.expand_path(namespace_path, "services"))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/matcher"
|
4
|
+
|
5
|
+
module Strum
|
6
|
+
# Module
|
7
|
+
module Service
|
8
|
+
class Failure < StandardError; end
|
9
|
+
|
10
|
+
StrumMatcher = Dry::Matcher.new(
|
11
|
+
success: Dry::Matcher::Case.new(
|
12
|
+
match: lambda do |value, *pattern|
|
13
|
+
value[0] && (pattern.any? ? pattern.include?(value[1]) : true)
|
14
|
+
end,
|
15
|
+
resolve: ->(value) { value.last }
|
16
|
+
),
|
17
|
+
failure: Dry::Matcher::Case.new(
|
18
|
+
match: lambda do |value, *pattern|
|
19
|
+
!value[0] && (pattern.any? ? pattern.include?(value[1]) : true)
|
20
|
+
end,
|
21
|
+
resolve: ->(value) { value.last }
|
22
|
+
)
|
23
|
+
)
|
24
|
+
|
25
|
+
def self.included(base)
|
26
|
+
base.class_eval do
|
27
|
+
extend ClassMethods
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Internal: Interactor class methods.
|
32
|
+
module ClassMethods
|
33
|
+
def call(input = {}, &block)
|
34
|
+
strum = new(input)
|
35
|
+
strum.audit
|
36
|
+
strum.call if strum.valid?
|
37
|
+
strum.valid? ? valid_result(strum, &block) : invalid_result(strum, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def valid_result(strum, &block)
|
43
|
+
return strum.output || strum.outputs unless block_given?
|
44
|
+
return StrumMatcher.call([true, strum.output], &block) if strum.output
|
45
|
+
|
46
|
+
StrumMatcher.call([true, *strum.outputs.keys, strum.outputs], &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def invalid_result(strum, &block)
|
50
|
+
return nil unless block_given?
|
51
|
+
|
52
|
+
StrumMatcher.call([false, *strum.errors.values, strum.errors], &block)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_reader :output, :outputs
|
57
|
+
|
58
|
+
# Instance methods
|
59
|
+
def initialize(input)
|
60
|
+
self.strum_errors = {}
|
61
|
+
self.outputs = {}
|
62
|
+
raise Failure, "'input' must be a Hash" unless input.is_a?(Hash)
|
63
|
+
|
64
|
+
self.input = input.transform_keys do |key|
|
65
|
+
key_to_sym(key)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def call
|
70
|
+
raise Failure, "call method must be implemented"
|
71
|
+
end
|
72
|
+
|
73
|
+
def audit; end
|
74
|
+
|
75
|
+
def valid?
|
76
|
+
strum_errors.empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
def errors
|
80
|
+
strum_errors
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
attr_accessor :input, :strum_errors
|
86
|
+
attr_writer :output, :outputs
|
87
|
+
|
88
|
+
def add_error(field, value)
|
89
|
+
if field.is_a?(Array)
|
90
|
+
field.each do |key|
|
91
|
+
value.is_a?(Array) ? value.each { |v| add_error(key, v) } : add_error(key, value)
|
92
|
+
add_error(key, value.is_a?(Array) ? value.first : value)
|
93
|
+
end
|
94
|
+
else
|
95
|
+
strum_errors[field] ||= []
|
96
|
+
strum_errors[field] = strum_errors[field] + Array(value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_errors(errors)
|
101
|
+
errors.each { |field, value| add_error(field, value) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def required(*keys)
|
105
|
+
keys.each { |key| add_error(key, :field_must_exist) unless input[key] }
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def key_to_sym(key)
|
111
|
+
key.to_sym
|
112
|
+
rescue StandardError
|
113
|
+
key
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
|
5
|
+
module Strum
|
6
|
+
# SubCommand Base class
|
7
|
+
class SubCommandBase < Thor
|
8
|
+
def self.banner(command, _namespace = nil, _subcommand = false)
|
9
|
+
"#{basename} #{subcommand_prefix} #{command.usage}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.subcommand_prefix
|
13
|
+
name.gsub(/.*::/, "")
|
14
|
+
.gsub(/^[A-Z]/) { |match| match[0].downcase }
|
15
|
+
.gsub(/[A-Z]/) { |match| "-#{match[0].downcase}" }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :sequel do # rubocop:disable Metrics/BlockLength
|
4
|
+
require "sequel"
|
5
|
+
Sequel.extension :migration
|
6
|
+
|
7
|
+
def postgres_cmd
|
8
|
+
postgres_db = Sequel.connect(adapter: "postgres",
|
9
|
+
host: ENV.fetch("DATABASE_HOST", "localhost"),
|
10
|
+
database: "postgres",
|
11
|
+
user: ENV.fetch("DATABASE_USER", "postgres"),
|
12
|
+
password: ENV.fetch("DATABASE_PASSWORD", nil))
|
13
|
+
yield(postgres_db)
|
14
|
+
postgres_db.disconnect
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Drop database"
|
18
|
+
task :drop do
|
19
|
+
postgres_cmd do |db|
|
20
|
+
db.execute "DROP DATABASE IF EXISTS \"#{ENV.fetch('DATABASE_NAME')}\""
|
21
|
+
puts "Database #{ENV.fetch('DATABASE_NAME')} dropped"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Create database"
|
26
|
+
task :create do
|
27
|
+
postgres_cmd do |db|
|
28
|
+
db.execute "CREATE DATABASE \"#{ENV.fetch('DATABASE_NAME')}\""
|
29
|
+
puts "Database #{ENV.fetch('DATABASE_NAME')} created"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Reset database"
|
34
|
+
task :reset do
|
35
|
+
postgres_cmd do |db|
|
36
|
+
db.execute "DROP DATABASE IF EXISTS \"#{ENV.fetch('DATABASE_NAME')}\""
|
37
|
+
db.execute "CREATE DATABASE \"#{ENV.fetch('DATABASE_NAME')}\""
|
38
|
+
puts "Database #{ENV.fetch('DATABASE_NAME')} recreated"
|
39
|
+
end
|
40
|
+
Rake::Task["sequel:migrate"].execute
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Prints current schema version"
|
44
|
+
task :version do
|
45
|
+
require "config/sequel"
|
46
|
+
version = if DB.tables.include?(:schema_migrations) && DB[:schema_migrations].count.positive?
|
47
|
+
DB[:schema_migrations].order(:filename).last[:filename]
|
48
|
+
end || 0
|
49
|
+
|
50
|
+
puts "Current schema version: #{version}"
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Migrate database"
|
54
|
+
task :migrate, [:version] do |_t, args|
|
55
|
+
require "config/sequel"
|
56
|
+
require "logger"
|
57
|
+
Sequel.extension :migration
|
58
|
+
DB.loggers << Logger.new($stdout) if DB.loggers.empty?
|
59
|
+
Sequel::TimestampMigrator.apply(DB, File.join(ENV["STRUM_ROOT"], "db/migrations"), args.version)
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Rollback database"
|
63
|
+
task :rollback do
|
64
|
+
require "config/sequel"
|
65
|
+
Rake::Task["sequel:version"].execute
|
66
|
+
if DB[:schema_migrations].count > 1
|
67
|
+
prev_version = DB[:schema_migrations]
|
68
|
+
.order(Sequel.desc(:filename))
|
69
|
+
.limit(2)
|
70
|
+
.all
|
71
|
+
.last[:filename]
|
72
|
+
target = prev_version.split("_").first.to_i
|
73
|
+
end
|
74
|
+
|
75
|
+
Rake::Task["sequel:migrate"].invoke(target || 0)
|
76
|
+
Rake::Task["sequel:version"].execute
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Annotate Sequel models"
|
80
|
+
task "annotate" do
|
81
|
+
ENV["RACK_ENV"] = "development"
|
82
|
+
require File.join(ENV["STRUM_ROOT"], "config", "models.rb")
|
83
|
+
DB.loggers.clear
|
84
|
+
require "sequel/annotate"
|
85
|
+
Sequel::Annotate.annotate(Dir[File.join(ENV["STRUM_ROOT"], "models/*.rb")])
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
# Ignore bundler config.
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore all logfiles and tempfiles.
|
11
|
+
/log/*
|
12
|
+
/tmp/*
|
13
|
+
!/log/.keep
|
14
|
+
!/tmp/.keep
|
15
|
+
|
16
|
+
.byebug_history
|
17
|
+
|
18
|
+
# Editor directories and files
|
19
|
+
.idea
|
20
|
+
.vscode
|
21
|
+
*.suo
|
22
|
+
*.ntvs*
|
23
|
+
*.njsproj
|
24
|
+
*.sln
|
25
|
+
*.sw*
|
26
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.6
|
3
|
+
|
4
|
+
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
5
|
+
Style/HashSyntax:
|
6
|
+
Enabled: true
|
7
|
+
|
8
|
+
# Method definitions after `private` or `protected` isolated calls need one
|
9
|
+
# extra level of indentation.
|
10
|
+
Layout/IndentationConsistency:
|
11
|
+
Enabled: true
|
12
|
+
# EnforcedStyle: rails
|
13
|
+
|
14
|
+
# Two spaces, no tabs (for indentation).
|
15
|
+
Layout/IndentationWidth:
|
16
|
+
Enabled: true
|
17
|
+
|
18
|
+
# Check quotes usage according to lint rule below.
|
19
|
+
Style/StringLiterals:
|
20
|
+
Enabled: true
|
21
|
+
EnforcedStyle: double_quotes
|
22
|
+
|
23
|
+
Metrics/LineLength:
|
24
|
+
Max: 120
|
25
|
+
IgnoredPatterns: ['\A#']
|
26
|
+
|
27
|
+
Style/Semicolon:
|
28
|
+
AllowAsExpressionSeparator: true
|
@@ -0,0 +1,15 @@
|
|
1
|
+
FROM registry.gitlab.com/qpard/ruby:latest as builder
|
2
|
+
|
3
|
+
WORKDIR /usr/src/app
|
4
|
+
ENV RACK_ENV production
|
5
|
+
RUN apk add curl-dev ruby-dev build-base tzdata postgresql-dev
|
6
|
+
COPY Gemfile* ./
|
7
|
+
RUN bundle install --without development test
|
8
|
+
|
9
|
+
FROM registry.gitlab.com/qpard/ruby:latest AS runtime
|
10
|
+
WORKDIR /usr/src/app
|
11
|
+
ENV RACK_ENV production
|
12
|
+
|
13
|
+
RUN apk add tzdata postgresql-dev
|
14
|
+
COPY --from=builder /usr/local/bundle /usr/local/bundle
|
15
|
+
COPY . ./
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
# framework
|
6
|
+
<% if rabbit? -%>
|
7
|
+
gem "bunny", ">= 2.14.1"
|
8
|
+
<% end -%>
|
9
|
+
<% if json? -%>
|
10
|
+
gem "fast_jsonapi"
|
11
|
+
<% end -%>
|
12
|
+
gem "puma", "~> 4.2.0"
|
13
|
+
<% if cors? -%>
|
14
|
+
gem "rack-cors"
|
15
|
+
<% end -%>
|
16
|
+
gem "rack-unreloader", "~> 1.7"
|
17
|
+
gem "rake", "~> 13"
|
18
|
+
<% if redis? -%>
|
19
|
+
gem "redis-objects"
|
20
|
+
<% end -%>
|
21
|
+
gem "roda", "~> 3.24"
|
22
|
+
<% if sequel? -%>
|
23
|
+
|
24
|
+
# database
|
25
|
+
gem "pg", "~> 1.1.4"
|
26
|
+
gem "sequel", "~> 5.24"
|
27
|
+
gem "sequel_pg", "~> 1.12"
|
28
|
+
<% end -%>
|
29
|
+
|
30
|
+
# Strum framework
|
31
|
+
gem "strum", "~> 0.0.19"
|
32
|
+
|
33
|
+
group :development do
|
34
|
+
# A Ruby code quality reporter
|
35
|
+
gem "rubycritic", require: false
|
36
|
+
|
37
|
+
# A Ruby static code analyzer and formatter,
|
38
|
+
# based on the community Ruby style guide. https://docs.rubocop.org
|
39
|
+
gem "rubocop", "~> 0.62.0", require: false
|
40
|
+
|
41
|
+
gem "roda-route_list"
|
42
|
+
end
|
43
|
+
|
44
|
+
group :test do
|
45
|
+
<% if sequel? -%>
|
46
|
+
gem "database_cleaner"
|
47
|
+
<% end -%>
|
48
|
+
gem "email_spec"
|
49
|
+
gem "json_spec"
|
50
|
+
end
|
51
|
+
|
52
|
+
group :development, :test do
|
53
|
+
# Call "byebug" anywhere in the code
|
54
|
+
# to stop execution and get a debugger console
|
55
|
+
gem "byebug", platforms: %i[mri mingw x64_mingw]
|
56
|
+
gem "factory_bot"
|
57
|
+
gem "rspec"
|
58
|
+
gem "rspec_junit_formatter"
|
59
|
+
|
60
|
+
gem "debase", "~> 0.2.4"
|
61
|
+
gem "ruby-debug-ide", "~> 0.7.0"
|
62
|
+
<% if sequel? -%>
|
63
|
+
gem "sequel-annotate"
|
64
|
+
<% end -%>
|
65
|
+
|
66
|
+
# A Ruby gem to load environment variables from `.env`.
|
67
|
+
gem "dotenv"
|
68
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "irb"
|
5
|
+
require "logger"
|
6
|
+
require "./config/env"
|
7
|
+
unless defined?(Unreloader)
|
8
|
+
require "rack/unreloader"
|
9
|
+
Unreloader = Rack::Unreloader.new(subclasses: %w[Sequel::Model], logger: Logger.new($stdout), reload: true) { <%= app_class_name %> }
|
10
|
+
end
|
11
|
+
<% if sequel? %>
|
12
|
+
require "config/sequel"
|
13
|
+
Unreloader.require('models'){|f| Sequel::Model.send(:camelize, File.basename(f).sub(/\.rb\z/, ''))}
|
14
|
+
<% end %>
|
15
|
+
IRB.start
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
<% if sequel? -%>
|
4
|
+
require "config/sequel"
|
5
|
+
require "config/models"
|
6
|
+
|
7
|
+
<% end -%>
|
8
|
+
require "roda"
|
9
|
+
<% if json? -%>
|
10
|
+
require "fast_jsonapi"
|
11
|
+
<% end -%>
|
12
|
+
require "strum"
|
13
|
+
<% if cors? -%>
|
14
|
+
require "rack/cors"
|
15
|
+
<% end -%>
|
16
|
+
<% if rabbit? -%>
|
17
|
+
require "bunny"
|
18
|
+
<% end -%>
|
19
|
+
<% if redis? -%>
|
20
|
+
require "redis/objects"
|
21
|
+
<% end -%>
|
22
|
+
|
23
|
+
unless defined?(Unreloader)
|
24
|
+
require "rack/unreloader"
|
25
|
+
Unreloader = Rack::Unreloader.new(reload: false)
|
26
|
+
end
|
27
|
+
|
28
|
+
Unreloader.require("services")
|
29
|
+
<% if json? -%>
|
30
|
+
Unreloader.require("serializers")
|
31
|
+
<% end -%>
|
32
|
+
|
33
|
+
# Main <%= app_class_name %> route class
|
34
|
+
class <%= app_class_name %> < Roda
|
35
|
+
opts[:root] = ENV["STRUM_ROOT"]
|
36
|
+
plugin :all_verbs
|
37
|
+
plugin :symbol_status
|
38
|
+
plugin :json, content_type: "application/vnd.api+json"
|
39
|
+
plugin :json_parser
|
40
|
+
<% if cors? %>
|
41
|
+
# Rack Middleware for handling Cross-Origin Resource Sharing (CORS), which makes cross-origin AJAX possible.
|
42
|
+
# https://github.com/cyu/rack-cors#rack-configuration
|
43
|
+
use Rack::Cors do
|
44
|
+
allow do
|
45
|
+
origins "*"
|
46
|
+
resource "*", headers: :any, methods: %i[get post options]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
<% end %>
|
50
|
+
plugin :hash_routes
|
51
|
+
Unreloader.require("routes")
|
52
|
+
|
53
|
+
route(&:hash_routes)
|
54
|
+
|
55
|
+
# for more details usage
|
56
|
+
# route do |req|
|
57
|
+
# req.public
|
58
|
+
# req.hash_routes
|
59
|
+
# end
|
60
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("..", __dir__), File.expand_path("../lib", __dir__))
|
4
|
+
|
5
|
+
ENV["RACK_ENV"] ||= "development"
|
6
|
+
|
7
|
+
unless ENV["RACK_ENV"] == "production"
|
8
|
+
require "dotenv"
|
9
|
+
Dotenv.load(".env.#{ENV['RACK_ENV'].downcase}", ".env.local")
|
10
|
+
end
|
11
|
+
|
12
|
+
ENV["STRUM_ROOT"] = File.expand_path("..", __dir__)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "./config/env"
|
4
|
+
|
5
|
+
dev = ENV["RACK_ENV"] == "development"
|
6
|
+
|
7
|
+
if dev
|
8
|
+
require "logger"
|
9
|
+
logger = Logger.new($stdout)
|
10
|
+
end
|
11
|
+
|
12
|
+
require "rack/unreloader"
|
13
|
+
Unreloader = Rack::Unreloader.new(subclasses: %w[Roda Sequel::Model],
|
14
|
+
logger: logger,
|
15
|
+
reload: dev) { <%= app_class_name %> }
|
16
|
+
|
17
|
+
Unreloader.require("config/app.rb") { "<%= app_class_name %>" }
|
18
|
+
run(dev ? Unreloader : <%= app_class_name %>.freeze.app)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sequel/model"
|
4
|
+
require "config/sequel.rb"
|
5
|
+
|
6
|
+
Sequel::Model.plugin(:auto_validations)
|
7
|
+
Sequel::Model.plugin(:constraint_validations)
|
8
|
+
Sequel::Model.plugin(:subclasses)
|
9
|
+
Sequel::Model.cache_associations = false if ENV["RACK_ENV"] == "development"
|
10
|
+
|
11
|
+
unless defined?(Unreloader)
|
12
|
+
require "rack/unreloader"
|
13
|
+
Unreloader = Rack::Unreloader.new(reload: false)
|
14
|
+
end
|
15
|
+
|
16
|
+
Unreloader.require("models") do |f|
|
17
|
+
Sequel::Model.send(:camelize, File.basename(f).sub(/\.rb\z/, ""))
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sequel"
|
4
|
+
|
5
|
+
DB = Sequel.connect adapter: "postgres",
|
6
|
+
host: ENV.delete("DATABASE_HOST") || "localhost",
|
7
|
+
database: ENV.delete("DATABASE_NAME"),
|
8
|
+
user: ENV.delete("DATABASE_USER"),
|
9
|
+
password: ENV.delete("DATABASE_PASSWORD")
|
10
|
+
DB.extension(:pg_array, :pg_json)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Sequel.migration do
|
4
|
+
up do
|
5
|
+
DB.extension(:constraint_validations)
|
6
|
+
DB.extension(:pg_array)
|
7
|
+
DB.extension(:pg_json)
|
8
|
+
DB.create_constraint_validations_table
|
9
|
+
extension :date_arithmetic
|
10
|
+
run "CREATE EXTENSION IF NOT EXISTS citext;"
|
11
|
+
end
|
12
|
+
|
13
|
+
down do
|
14
|
+
DB.extension(:constraint_validations)
|
15
|
+
DB.drop_constraint_validations_table
|
16
|
+
end
|
17
|
+
end
|
File without changes
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Sequel.migration do
|
4
|
+
<%- if model? -%>
|
5
|
+
change do
|
6
|
+
extension(:constraint_validations)
|
7
|
+
create_table(:<%= table_name %>) do
|
8
|
+
primary_key :id
|
9
|
+
# code here ...
|
10
|
+
end
|
11
|
+
end
|
12
|
+
<%- else -%>
|
13
|
+
change do
|
14
|
+
primary_key :id
|
15
|
+
# code here...
|
16
|
+
end
|
17
|
+
|
18
|
+
# or use up/down
|
19
|
+
# up do
|
20
|
+
# # up here...
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# down do
|
24
|
+
# # down here...
|
25
|
+
# end
|
26
|
+
<%- end -%>
|
27
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
<%- namespace_names.each_with_index do |c,i| -%>
|
4
|
+
<%= ' ' * i %>module <%= c %>
|
5
|
+
<%- end -%>
|
6
|
+
<%= ident %># Strum service
|
7
|
+
<%= ident %># You model description here...
|
8
|
+
<%= ident %>class <%= resource_class_name -%> < Sequel::Model
|
9
|
+
<%= ident %>end
|
10
|
+
<%- (namespace_names.size - 1).downto(0) do |i| -%>
|
11
|
+
<%= ' ' * i %>end
|
12
|
+
<%- end -%>
|