snowpack 1.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +3 -0
  4. data/.tool-versions +1 -0
  5. data/.travis.yml +16 -0
  6. data/Brewfile +2 -0
  7. data/CHANGELOG.md +25 -0
  8. data/Gemfile +13 -0
  9. data/LICENSE +21 -0
  10. data/README.md +116 -0
  11. data/Rakefile +6 -0
  12. data/bin/bootstrap +25 -0
  13. data/exe/snowpack +7 -0
  14. data/lib/snowpack/application.rb +98 -0
  15. data/lib/snowpack/application_cli.rb +39 -0
  16. data/lib/snowpack/cli/application/cli.rb +32 -0
  17. data/lib/snowpack/cli/application/command.rb +53 -0
  18. data/lib/snowpack/cli/application/commands/assets/clobber.rb +31 -0
  19. data/lib/snowpack/cli/application/commands/assets/compile.rb +32 -0
  20. data/lib/snowpack/cli/application/commands/console.rb +55 -0
  21. data/lib/snowpack/cli/application/commands/db/create.rb +33 -0
  22. data/lib/snowpack/cli/application/commands/db/create_migration.rb +38 -0
  23. data/lib/snowpack/cli/application/commands/db/drop.rb +33 -0
  24. data/lib/snowpack/cli/application/commands/db/migrate.rb +47 -0
  25. data/lib/snowpack/cli/application/commands/db/reset.rb +28 -0
  26. data/lib/snowpack/cli/application/commands/db/rollback.rb +54 -0
  27. data/lib/snowpack/cli/application/commands/db/sample_data.rb +41 -0
  28. data/lib/snowpack/cli/application/commands/db/seed.rb +41 -0
  29. data/lib/snowpack/cli/application/commands/db/structure/dump.rb +38 -0
  30. data/lib/snowpack/cli/application/commands/db/utils/database.rb +76 -0
  31. data/lib/snowpack/cli/application/commands/db/utils/database_config.rb +49 -0
  32. data/lib/snowpack/cli/application/commands/db/version.rb +37 -0
  33. data/lib/snowpack/cli/application/commands/generate/slice.rb +32 -0
  34. data/lib/snowpack/cli/application/commands/routes/update.rb +35 -0
  35. data/lib/snowpack/cli/application/commands.rb +27 -0
  36. data/lib/snowpack/cli/command.rb +48 -0
  37. data/lib/snowpack/cli/standalone/cli.rb +14 -0
  38. data/lib/snowpack/cli/standalone/commands/new.rb +33 -0
  39. data/lib/snowpack/cli/standalone/commands.rb +13 -0
  40. data/lib/snowpack/components/formalist.rb +27 -0
  41. data/lib/snowpack/components/persistence.rb +56 -0
  42. data/lib/snowpack/components.rb +5 -0
  43. data/lib/snowpack/console/context.rb +32 -0
  44. data/lib/snowpack/console/plugins/relation_readers.rb +17 -0
  45. data/lib/snowpack/console/plugins/slice_readers.rb +33 -0
  46. data/lib/snowpack/generator.rb +57 -0
  47. data/lib/snowpack/generators/application/generator.rb +67 -0
  48. data/lib/snowpack/generators/application/templates/.env-example.tt +10 -0
  49. data/lib/snowpack/generators/application/templates/.env.test-example.tt +1 -0
  50. data/lib/snowpack/generators/application/templates/.gitignore +20 -0
  51. data/lib/snowpack/generators/application/templates/.rspec +2 -0
  52. data/lib/snowpack/generators/application/templates/Brewfile +4 -0
  53. data/lib/snowpack/generators/application/templates/Gemfile.tt +46 -0
  54. data/lib/snowpack/generators/application/templates/Guardfile +7 -0
  55. data/lib/snowpack/generators/application/templates/Procfile.dev +3 -0
  56. data/lib/snowpack/generators/application/templates/Procfile.support +1 -0
  57. data/lib/snowpack/generators/application/templates/README.md.tt +45 -0
  58. data/lib/snowpack/generators/application/templates/Rakefile +5 -0
  59. data/lib/snowpack/generators/application/templates/bin/run +7 -0
  60. data/lib/snowpack/generators/application/templates/config/application.rb.tt +19 -0
  61. data/lib/snowpack/generators/application/templates/config/puma.rb.tt +14 -0
  62. data/lib/snowpack/generators/application/templates/config/routes.rb.tt +15 -0
  63. data/lib/snowpack/generators/application/templates/config.ru +5 -0
  64. data/lib/snowpack/generators/application/templates/db/migrate/.keep +0 -0
  65. data/lib/snowpack/generators/application/templates/db/sample_data.rb +1 -0
  66. data/lib/snowpack/generators/application/templates/db/seed.rb +1 -0
  67. data/lib/snowpack/generators/application/templates/lib/__application_path__/operation.rb.tt +12 -0
  68. data/lib/snowpack/generators/application/templates/lib/__application_path__/persistence/relations/.keep +0 -0
  69. data/lib/snowpack/generators/application/templates/lib/__application_path__/types.rb.tt +11 -0
  70. data/lib/snowpack/generators/application/templates/lib/__application_path__/web/action.rb.tt +56 -0
  71. data/lib/snowpack/generators/application/templates/lib/__application_path__/web/view/context.rb.tt +31 -0
  72. data/lib/snowpack/generators/application/templates/lib/hanami/action/csrf_protection.rb +225 -0
  73. data/lib/snowpack/generators/application/templates/log/.keep +0 -0
  74. data/lib/snowpack/generators/application/templates/package.json.tt +25 -0
  75. data/lib/snowpack/generators/application/templates/public/.keep +0 -0
  76. data/lib/snowpack/generators/application/templates/script/bootstrap +32 -0
  77. data/lib/snowpack/generators/application/templates/script/console +26 -0
  78. data/lib/snowpack/generators/application/templates/script/server +13 -0
  79. data/lib/snowpack/generators/application/templates/script/setup +27 -0
  80. data/lib/snowpack/generators/application/templates/script/support +9 -0
  81. data/lib/snowpack/generators/application/templates/script/test +19 -0
  82. data/lib/snowpack/generators/application/templates/script/update +13 -0
  83. data/lib/snowpack/generators/application/templates/spec/spec_helper.rb +13 -0
  84. data/lib/snowpack/generators/application/templates/spec/suite/.keep +0 -0
  85. data/lib/snowpack/generators/application/templates/spec/support/suite.rb +9 -0
  86. data/lib/snowpack/generators/application/templates/system/__application_path__/import.rb.tt +5 -0
  87. data/lib/snowpack/generators/application/templates/system/boot/assets.rb.tt +17 -0
  88. data/lib/snowpack/generators/application/templates/system/boot/logger.rb.tt +10 -0
  89. data/lib/snowpack/generators/application/templates/system/boot/monitor.rb.tt +9 -0
  90. data/lib/snowpack/generators/application/templates/system/boot/persistence.rb.tt +9 -0
  91. data/lib/snowpack/generators/application/templates/system/boot/settings.rb.tt +18 -0
  92. data/lib/snowpack/generators/application/templates/system/boot/web.rb.tt +9 -0
  93. data/lib/snowpack/generators/slice/generator.rb +62 -0
  94. data/lib/snowpack/generators/slice/templates/lib/__slice_path__/.keep +0 -0
  95. data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/action.rb.tt +10 -0
  96. data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/actions/.keep +0 -0
  97. data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/view.rb.tt +17 -0
  98. data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/views/.keep +0 -0
  99. data/lib/snowpack/generators/slice/templates/system/__slice_path__/import.rb.tt +9 -0
  100. data/lib/snowpack/generators/slice/templates/system/__slice_path__/slice.rb.tt +10 -0
  101. data/lib/snowpack/instrumentation/appsignal/appsignal_ext.rb +13 -0
  102. data/lib/snowpack/instrumentation/appsignal/que.rb +70 -0
  103. data/lib/snowpack/instrumentation/appsignal/rack.rb +84 -0
  104. data/lib/snowpack/roda/web.rb +47 -0
  105. data/lib/snowpack/slice.rb +85 -0
  106. data/lib/snowpack/test/suite.rb +164 -0
  107. data/lib/snowpack/test/tasks.rake +40 -0
  108. data/lib/snowpack/test_tasks.rb +4 -0
  109. data/lib/snowpack/types.rb +9 -0
  110. data/lib/snowpack/version.rb +5 -0
  111. data/lib/snowpack/view/part_builder.rb +45 -0
  112. data/lib/snowpack/view/parts/pager.rb +107 -0
  113. data/lib/snowpack/view/parts/paginated.rb +22 -0
  114. data/lib/snowpack/web/application.rb +38 -0
  115. data/lib/snowpack/web/assets.rb +56 -0
  116. data/lib/snowpack/web/endpoint_resolver.rb +66 -0
  117. data/lib/snowpack/web/form.rb +38 -0
  118. data/lib/snowpack/web/plugin.rb +44 -0
  119. data/lib/snowpack/web/rack_logger.rb +73 -0
  120. data/lib/snowpack/web/router.rb +58 -0
  121. data/lib/snowpack/web.rb +20 -0
  122. data/lib/snowpack.rb +27 -0
  123. data/snowpack.gemspec +34 -0
  124. metadata +327 -0
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Snowpack
4
+ module CLI
5
+ module Standalone
6
+ module Commands
7
+ extend Hanami::CLI::Registry
8
+
9
+ require_relative "commands/new"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/system"
4
+ require "snowpack/types"
5
+
6
+ Dry::System.register_component(:formalist, provider: :snowpack) do
7
+ settings do
8
+ key :embedded_forms_container, Snowpack::Types::Any
9
+ key :embedded_forms, Snowpack::Types::Hash
10
+ end
11
+
12
+ init do
13
+ require "formalist"
14
+ end
15
+
16
+ start do
17
+ embedded_forms_container = config.embedded_forms_container
18
+
19
+ if embedded_forms_container
20
+ config.embedded_forms.each do |name, klass|
21
+ embedded_forms_container.register(name, klass)
22
+ end
23
+
24
+ register "container", embedded_forms_container
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/system"
4
+ require "snowpack/types"
5
+
6
+ Dry::System.register_component(:persistence, provider: :snowpack) do
7
+ settings do
8
+ types = Snowpack::Types
9
+
10
+ key :database_url, types::String
11
+ key :global_extensions, types::Array.of(types::Symbol)
12
+ key :connection_extensions, types::Array.of(types::Symbol)
13
+ key :auto_registration_root, types::String.optional.default(nil)
14
+ key :auto_registration_namespace, types::String.optional.default(nil)
15
+ key :max_connections, types::Integer.optional.default(4)
16
+ end
17
+
18
+ init do
19
+ require "sequel"
20
+ require "rom"
21
+ require "rom/sql"
22
+
23
+ use :settings
24
+
25
+ ROM::SQL.load_extensions(*config.global_extensions)
26
+
27
+ Sequel.database_timezone = :utc
28
+ Sequel.application_timezone = :local
29
+
30
+ rom_config = ROM::Configuration.new(
31
+ :sql,
32
+ config.database_url,
33
+ max_connections: config.max_connections,
34
+ extensions: config.connection_extensions
35
+ )
36
+
37
+ rom_config.plugin :sql, relations: :instrumentation do |plugin_config|
38
+ plugin_config.notifications = notifications
39
+ end
40
+
41
+ rom_config.plugin :sql, relations: :auto_restrictions
42
+
43
+ register "config", rom_config
44
+ register "db", rom_config.gateways[:default].connection
45
+ end
46
+
47
+ start do
48
+ rom_config = container["persistence.config"]
49
+ rom_config.auto_registration(
50
+ config.auto_registration_root || target.root.join("lib/persistence"),
51
+ namespace: config.auto_registration_namespace || true,
52
+ )
53
+
54
+ register "rom", ROM.container(rom_config)
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/system'
4
+
5
+ Dry::System.register_provider(:snowpack, boot_path: Pathname(__dir__).join('components').realpath)
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "plugins/relation_readers"
4
+ require_relative "plugins/slice_readers"
5
+
6
+ module Snowpack
7
+ module Console
8
+ class Context < SimpleDelegator
9
+ attr_reader :application
10
+
11
+ def self.new(*args)
12
+ ctx = super
13
+
14
+ if ctx.rom
15
+ ctx.extend(Snowpack::Console::Plugins::RelationReaders.new(ctx))
16
+ ctx.extend(Snowpack::Console::Plugins::SliceReaders.new(ctx))
17
+ end
18
+
19
+ ctx
20
+ end
21
+
22
+ def initialize(application)
23
+ super(application)
24
+ @application = application
25
+ end
26
+
27
+ def rom
28
+ application["persistence.rom"] if application.key?("persistence.rom")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Snowpack
4
+ module Console
5
+ module Plugins
6
+ class RelationReaders < Module
7
+ def initialize(ctx)
8
+ ctx.rom.relations.each do |name, relation|
9
+ define_method(name) do
10
+ relation
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Snowpack
4
+ module Console
5
+ module Plugins
6
+ class SliceReaders < Module
7
+ def initialize(ctx)
8
+ ctx.application.slices.each do |name, slice|
9
+ define_method(name) do
10
+ SliceDelegator.new(slice)
11
+ end
12
+ end
13
+ end
14
+
15
+ class SliceDelegator < SimpleDelegator
16
+ def method_missing(name, *args, &block)
17
+ if args.empty? && key?(name)
18
+ self[name]
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def respond_to_missing?(name)
27
+ key?(name)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+ require "hanami/utils/files"
5
+ require "pathname"
6
+
7
+ module Snowpack
8
+ class Generator
9
+ attr_reader :templates_dir
10
+ # attr_reader :templates
11
+ attr_reader :files
12
+ attr_reader :file_helper
13
+
14
+ def initialize(templates_dir:)
15
+ @templates_dir = templates_dir
16
+ @files = Hanami::Utils::Files
17
+ end
18
+
19
+ def call(output_dir, **env)
20
+ templates(**env).each do |template|
21
+ output_file_path = render_file_path(template.relative_path_from(templates_dir).to_s, env)
22
+
23
+ if File.extname(template) == ".tt"
24
+ result = render(template.to_s, env)
25
+
26
+ files.write \
27
+ File.join(output_dir, output_file_path.sub(%r{#{File.extname(template)}$}, "")),
28
+ result
29
+ else
30
+ files.cp template, File.join(output_dir, output_file_path)
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ # TODO: when we go to multi-template dirs, we'll need to make it so that the
38
+ # returned templates are bundled up with their root dirs
39
+ def templates(**env)
40
+ Dir[File.join(templates_dir, "**/{*,.*}")].select(&File.method(:file?)).map(&method(:Pathname))
41
+ end
42
+
43
+ def render(template, env)
44
+ ERB.new(File.read(template), nil, _trim_mode = "-").result_with_hash(env)
45
+ end
46
+
47
+ FILE_PATH_VAR_DELIMITER = "__"
48
+ FILE_PATH_VAR_REGEXP = /#{FILE_PATH_VAR_DELIMITER}\S+#{FILE_PATH_VAR_DELIMITER}/
49
+
50
+ def render_file_path(path, env)
51
+ path.gsub(FILE_PATH_VAR_REGEXP) { |match|
52
+ var_name = match.gsub(FILE_PATH_VAR_DELIMITER, "")
53
+ env.fetch(var_name.to_sym).to_s
54
+ }
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/inflector"
4
+ require "securerandom"
5
+ require "shellwords"
6
+ require "snowpack/version"
7
+ require_relative "../../generator"
8
+
9
+ module Snowpack
10
+ module Generators
11
+ module Application
12
+ class Generator < Snowpack::Generator
13
+ # FIXME: need to make templates_dir handling nicer, also support multiple dirs
14
+ def initialize(templates_dir: nil)
15
+ templates_dir ||= File.join(__dir__, "templates")
16
+ super(templates_dir: templates_dir)
17
+ end
18
+
19
+ def call(output_dir, application_name)
20
+ super(output_dir, env(application_name))
21
+ generate_tool_versions output_dir
22
+ end
23
+
24
+ private
25
+
26
+ def env(application_name)
27
+ {
28
+ application_path: inflector.underscore(application_name),
29
+ application_module: inflector.camelize(application_name),
30
+ random: -> name, *args { SecureRandom.public_send(name, *args) },
31
+ snowpack_version: Snowpack::VERSION,
32
+ }
33
+ end
34
+
35
+ def generate_tool_versions(output_dir)
36
+ if `which asdf` && $?.success?
37
+ versions = %w[nodejs postgres ruby]
38
+ .map { |tool|
39
+ version = asdf_current_version(tool)
40
+ "#{tool} #{version}" if version
41
+ }
42
+ .compact
43
+
44
+ if versions.any?
45
+ files.write(
46
+ File.join(output_dir, ".tool-versions"),
47
+ versions.join("\n") + "\n",
48
+ )
49
+ end
50
+ end
51
+ end
52
+
53
+ def asdf_current_version(tool)
54
+ output = `asdf current #{Shellwords.shellescape(tool)}`
55
+
56
+ # Handle this output:
57
+ # 2.6.2 (set by /path/to/.tool-versions)
58
+ output.split(" ").first if $?.success?
59
+ end
60
+
61
+ def inflector
62
+ @inflector ||= Dry::Inflector.new
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,10 @@
1
+ # Web app
2
+ LOG_TO_STDOUT=false
3
+ SESSION_SECRET=_____replace_me_with_a_real_secret_____
4
+
5
+ # Assets
6
+ ASSETS_PRECOMPILED=false
7
+ ASSETS_SERVER_URL=http://localhost:8080
8
+
9
+ # Persistence
10
+ DATABASE_URL=postgres://localhost/<%= application_path %>_development
@@ -0,0 +1 @@
1
+ DATABASE_URL=postgres://localhost/<%= application_path %>_test
@@ -0,0 +1,20 @@
1
+ # Local service data
2
+ /data/*
3
+
4
+ # App settings (keeping e.g. *-example files checked in)
5
+ /.env*
6
+ !/.env-*
7
+ !/.env*-*
8
+
9
+ # RSpec
10
+ /spec/examples.txt
11
+
12
+ # Logs
13
+ /log/*.log
14
+
15
+ # Temp files
16
+ tmp/*
17
+
18
+ # Front-end
19
+ /node_modules
20
+ /public/assets
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,4 @@
1
+ tap "icelab/devtools"
2
+ brew "asdf"
3
+ brew "overmind"
4
+ brew "yarn"
@@ -0,0 +1,46 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ ruby "<%= RUBY_VERSION %>"
6
+
7
+ gem "rake"
8
+ gem "snowpack", "<%= snowpack_version %>"
9
+ gem "hanami-cli", github: "hanami/cli", branch: "unstable"
10
+
11
+ # Web framework
12
+ gem "dry-system"
13
+ gem "dry-web"
14
+ gem "hanami-utils", github: "hanami/utils", branch: "unstable"
15
+ gem "hanami-router", github: "hanami/router", branch: "unstable"
16
+ gem "hanami-controller", github: "hanami/controller", branch: "unstable"
17
+ gem "puma", "~> 3.0"
18
+ gem "rack", "~> 2.0"
19
+
20
+ # Persistence
21
+ gem "pg"
22
+ gem "rom", "~> 5.0"
23
+ gem "rom-sql", "~> 3.0"
24
+ gem "sequel_pg"
25
+
26
+ # Application dependencies
27
+ gem "dry-auto_inject"
28
+ gem "dry-matcher"
29
+ gem "dry-monads", "~> 1.0"
30
+ gem "dry-schema", "~> 1.0"
31
+ gem "dry-struct", "~> 1.0"
32
+ gem "dry-transaction"
33
+ gem "dry-types", "~> 1.0"
34
+ gem "dry-validation", "~> 1.0"
35
+ gem "dry-view"
36
+ gem "slim", "~> 4.0"
37
+
38
+ group :development, :test do
39
+ gem "guard"
40
+ gem "guard-puma"
41
+ gem "pry-byebug", platform: :mri
42
+ end
43
+
44
+ group :test do
45
+ gem "rspec", "~> 3.0"
46
+ end
@@ -0,0 +1,7 @@
1
+ guard "puma" do
2
+ watch "Gemfile.lock"
3
+ watch %r{config/.+}
4
+ watch %r{lib/.+}
5
+ watch %r{slices/.+}
6
+ watch %r{system/.+}
7
+ end
@@ -0,0 +1,3 @@
1
+ web: bundle exec guard --no-notify --no-interactions
2
+ # assets: yarn run start
3
+ # worker: bundle exec que ./config/que.rb
@@ -0,0 +1 @@
1
+ postgres: postgres
@@ -0,0 +1,45 @@
1
+ # <%= application_module %>
2
+
3
+ ## Installation
4
+
5
+ After cloning, run:
6
+
7
+ ```
8
+ ./script/bootstrap
9
+ ```
10
+
11
+ ## Running support services
12
+
13
+ To start the supporting services, run:
14
+
15
+ ```
16
+ ./script/support
17
+ ```
18
+
19
+ This must be running before completing the following steps.
20
+
21
+ ## Setup
22
+
23
+ To set up for the first time, run:
24
+
25
+ ```
26
+ ./script/setup
27
+ ```
28
+
29
+ ## After pulling changes
30
+
31
+ After pulling changes from the remote, run:
32
+
33
+ ```
34
+ ./script/update
35
+ ```
36
+
37
+ This will install any new dependencies and run any migrations.
38
+
39
+ ## Running the app
40
+
41
+ After updating, run:
42
+
43
+ ```
44
+ ./script/server
45
+ ```
@@ -0,0 +1,5 @@
1
+ require "bundler/setup"
2
+ require_relative "config/application"
3
+ require "snowpack/test_tasks"
4
+
5
+ Rake.add_rakelib "tasks"
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "snowpack/cli/application/cli"
5
+ require_relative "../config/application"
6
+
7
+ Snowpack::CLI::Application::CLI.new.call
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "snowpack/application"
5
+ require "snowpack/components"
6
+ require "snowpack/web/plugin"
7
+
8
+ module <%= application_module %>
9
+ class Application < Snowpack::Application
10
+ use :web
11
+
12
+ configure do
13
+ config.name = :<%= application_path %>
14
+ config.log_levels = %i[test development production].map { |e| [e, Logger::DEBUG] }.to_h
15
+ config.default_namespace = "<%= application_path %>"
16
+ config.auto_register = %w[lib/<%= application_path %>]
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ workers Integer(ENV["WEB_CONCURRENCY"] || 2)
2
+
3
+ threads_count = Integer(ENV["MAX_THREADS"] || 4)
4
+ threads threads_count, threads_count
5
+
6
+ preload_app!
7
+
8
+ rackup DefaultRackup
9
+ port ENV["PORT"] || 3000
10
+ environment ENV["RACK_ENV"] || "development"
11
+
12
+ before_fork do
13
+ <%= application_module %>::Application["persistence.rom"].disconnect
14
+ end
@@ -0,0 +1,15 @@
1
+ require "snowpack/web"
2
+ require "rack"
3
+
4
+ Snowpack::Web.routes do |application|
5
+ use Rack::Lint
6
+
7
+ use Rack::Static,
8
+ urls: ["/assets"],
9
+ root: "public"
10
+
11
+ use Rack::Session::Cookie,
12
+ key: "<%= application_path %>.session",
13
+ secret: application[:settings].session_secret,
14
+ expire_after: 10 * 365 * 24 * 60 * 60 # 10 years
15
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "config/application"
2
+ require_relative "config/routes"
3
+
4
+ Snowpack.application.boot!
5
+ run Snowpack::Web.application
@@ -0,0 +1 @@
1
+ # Build your sample data here
@@ -0,0 +1 @@
1
+ # Build your seed data here
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ # auto_register: false
3
+
4
+ require "dry/transaction/operation"
5
+
6
+ module <%= application_path %>
7
+ class Operation
8
+ def self.inherited(subclass)
9
+ subclass.include Dry::Transaction::Operation
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ # auto_register: false
3
+
4
+ require "dry/struct"
5
+ require "dry/types"
6
+
7
+ module <%= application_module %>
8
+ module Types
9
+ include Dry.Types(default: :strict)
10
+ end
11
+ end
@@ -0,0 +1,56 @@
1
+ # auto_register: false
2
+
3
+ require "json" # required for Hanami::Action::Flash to work
4
+ require "hanami/controller"
5
+ require "hanami/action/cookies"
6
+ require "hanami/action/csrf_protection"
7
+ require "hanami/action/session"
8
+ require "<%= application_path %>/import"
9
+
10
+ module <%= application_module %>
11
+ module Web
12
+ class Action < Hanami::Action
13
+ def self.inherited(klass)
14
+ super
15
+
16
+ # It would be nice if these could just be included on the top class,
17
+ # rather than on subclasses via this inherited hook
18
+ klass.include Hanami::Action::Cookies
19
+ klass.include Hanami::Action::Session
20
+ klass.include Hanami::Action::CSRFProtection
21
+ end
22
+
23
+ include Import[
24
+ "assets",
25
+ "web.action.configuration",
26
+ view_context: "web.view.context",
27
+ ]
28
+
29
+ attr_reader :_deps
30
+
31
+ def initialize(**deps)
32
+ @_deps = deps
33
+ super
34
+ end
35
+
36
+ def with(**new_deps)
37
+ self.class.new(_deps.merge(new_deps))
38
+ end
39
+
40
+ private
41
+
42
+ def render(view, req, res, **args)
43
+ res.body = view.(context: view_context.with(view_context_options(req, res)), **args)
44
+ res
45
+ end
46
+
47
+ def view_context_options(req, res)
48
+ {
49
+ assets: assets,
50
+ csrf_token: req.session[Hanami::Action::CSRFProtection::CSRF_TOKEN],
51
+ flash: res.flash,
52
+ }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,31 @@
1
+ require "dry/view/context"
2
+
3
+ module <%= application_module %>
4
+ module Web
5
+ module View
6
+ class Context < Dry::View::Context
7
+ def assets
8
+ self[:assets]
9
+ end
10
+
11
+ def csrf_token
12
+ self[:csrf_token]
13
+ end
14
+
15
+ def flash
16
+ self[:flash]
17
+ end
18
+
19
+ def flash?
20
+ %i[notice alert].any? { |type| flash[type] }
21
+ end
22
+
23
+ private
24
+
25
+ def [](name)
26
+ _options.fetch(name)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end