snowpack 1.0.0.alpha2

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.
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