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,225 @@
1
+ # Standalone copy of Hanami::Action::CsrfProtection from Hanami gem, copied from
2
+ # https://raw.githubusercontent.com/hanami/hanami/unstable/lib/hanami/action/csrf_protection.rb
3
+ #
4
+ # This makes it possible for us to include CSRF protection without having to
5
+ # require the "hanami" gem, which brings in a lot of unnecessary dependencies.
6
+
7
+ require 'rack/utils'
8
+ require 'securerandom'
9
+
10
+ module Hanami
11
+ # @api private
12
+ class Action
13
+ # Invalid CSRF Token
14
+ #
15
+ # @since 0.4.0
16
+ class InvalidCSRFTokenError < ::StandardError
17
+ end
18
+
19
+ # CSRF Protection
20
+ #
21
+ # This security mechanism is enabled automatically if sessions are turned on.
22
+ #
23
+ # It stores a "challenge" token in session. For each "state changing request"
24
+ # (eg. <tt>POST</tt>, <tt>PATCH</tt> etc..), we should send a special param:
25
+ # <tt>_csrf_token</tt>.
26
+ #
27
+ # If the param matches with the challenge token, the flow can continue.
28
+ # Otherwise the application detects an attack attempt, it reset the session
29
+ # and <tt>Hanami::Action::InvalidCSRFTokenError</tt> is raised.
30
+ #
31
+ # We can specify a custom handling strategy, by overriding <tt>#handle_invalid_csrf_token</tt>.
32
+ #
33
+ # Form helper (<tt>#form_for</tt>) automatically sets a hidden field with the
34
+ # correct token. A special view method (<tt>#csrf_token</tt>) is available in
35
+ # case the form markup is manually crafted.
36
+ #
37
+ # We can disable this check on action basis, by overriding <tt>#verify_csrf_token?</tt>.
38
+ #
39
+ # @since 0.4.0
40
+ #
41
+ # @see https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29
42
+ # @see https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
43
+ #
44
+ # @example Custom Handling
45
+ # module Web::Controllers::Books
46
+ # class Create
47
+ # include Web::Action
48
+ #
49
+ # def call(params)
50
+ # # ...
51
+ # end
52
+ #
53
+ # private
54
+ #
55
+ # def handle_invalid_csrf_token
56
+ # Web::Logger.warn "CSRF attack: expected #{ session[:_csrf_token] }, was #{ params[:_csrf_token] }"
57
+ # # manual handling
58
+ # end
59
+ # end
60
+ # end
61
+ #
62
+ # @example Bypass Security Check
63
+ # module Web::Controllers::Books
64
+ # class Create
65
+ # include Web::Action
66
+ #
67
+ # def call(params)
68
+ # # ...
69
+ # end
70
+ #
71
+ # private
72
+ #
73
+ # def verify_csrf_token?
74
+ # false
75
+ # end
76
+ # end
77
+ # end
78
+ module CSRFProtection
79
+ # Session and params key for CSRF token.
80
+ #
81
+ # This key is shared with <tt>hanami-controller</tt> and <tt>hanami-helpers</tt>
82
+ #
83
+ # @since 0.4.0
84
+ # @api private
85
+ CSRF_TOKEN = :_csrf_token
86
+
87
+ # Idempotent HTTP methods
88
+ #
89
+ # By default, the check isn't performed if the request method is included
90
+ # in this list.
91
+ #
92
+ # @since 0.4.0
93
+ # @api private
94
+ IDEMPOTENT_HTTP_METHODS = Hash[
95
+ 'GET' => true,
96
+ 'HEAD' => true,
97
+ 'TRACE' => true,
98
+ 'OPTIONS' => true
99
+ ].freeze
100
+
101
+ # @since 0.4.0
102
+ # @api private
103
+ # def self.included(action)
104
+ # action.class_eval do
105
+ # before :set_csrf_token, :verify_csrf_token
106
+ # end unless Hanami.env?(:test)
107
+ # end
108
+
109
+ # NOTE: Modified to remove Hanami.env? check (we don't have a Hanami.env)
110
+ def self.included(action)
111
+ action.class_eval do
112
+ before :set_csrf_token, :verify_csrf_token
113
+ end
114
+ end
115
+
116
+ private
117
+ # Set CSRF Token in session
118
+ #
119
+ # @since 0.4.0
120
+ # @api private
121
+ def set_csrf_token(req, res)
122
+ res.session[CSRF_TOKEN] ||= generate_csrf_token
123
+ end
124
+
125
+ # Verify if CSRF token from params, matches the one stored in session.
126
+ # If not, it raises an error.
127
+ #
128
+ # Don't override this method.
129
+ #
130
+ # To bypass the security check, please override <tt>#verify_csrf_token?</tt>.
131
+ # For custom handling of an attack, please override <tt>#handle_invalid_csrf_token</tt>.
132
+ #
133
+ # @since 0.4.0
134
+ # @api private
135
+ def verify_csrf_token(req, res)
136
+ handle_invalid_csrf_token(req, res) if invalid_csrf_token?(req, res)
137
+ end
138
+
139
+ # Verify if CSRF token from params, matches the one stored in session.
140
+ #
141
+ # Don't override this method.
142
+ #
143
+ # @since 0.4.0
144
+ # @api private
145
+ def invalid_csrf_token?(req, res)
146
+ return false unless verify_csrf_token?(req, res)
147
+
148
+ missing_csrf_token?(req, res) ||
149
+ !::Rack::Utils.secure_compare(req.session[CSRF_TOKEN], req.params[CSRF_TOKEN])
150
+ end
151
+
152
+ # Verify the CSRF token was passed in params.
153
+ #
154
+ # @api private
155
+ def missing_csrf_token?(req, res)
156
+ Hanami::Utils::Blank.blank?(req.params[CSRF_TOKEN])
157
+ end
158
+
159
+ # Generates a random CSRF Token
160
+ #
161
+ # @since 0.4.0
162
+ # @api private
163
+ def generate_csrf_token
164
+ SecureRandom.hex(32)
165
+ end
166
+
167
+ # Decide if perform the check or not.
168
+ #
169
+ # Override and return <tt>false</tt> if you want to bypass security check.
170
+ #
171
+ # @since 0.4.0
172
+ #
173
+ # @example
174
+ # module Web::Controllers::Books
175
+ # class Create
176
+ # include Web::Action
177
+ #
178
+ # def call(params)
179
+ # # ...
180
+ # end
181
+ #
182
+ # private
183
+ #
184
+ # def verify_csrf_token?
185
+ # false
186
+ # end
187
+ # end
188
+ # end
189
+ def verify_csrf_token?(req, res)
190
+ !IDEMPOTENT_HTTP_METHODS[req.request_method]
191
+ end
192
+
193
+ # Handle CSRF attack.
194
+ #
195
+ # The default policy resets the session and raises an exception.
196
+ #
197
+ # Override this method, for custom handling.
198
+ #
199
+ # @raise [Hanami::Action::InvalidCSRFTokenError]
200
+ #
201
+ # @since 0.4.0
202
+ #
203
+ # @example
204
+ # module Web::Controllers::Books
205
+ # class Create
206
+ # include Web::Action
207
+ #
208
+ # def call(params)
209
+ # # ...
210
+ # end
211
+ #
212
+ # private
213
+ #
214
+ # def handle_invalid_csrf_token
215
+ # # custom invalid CSRF management goes here
216
+ # end
217
+ # end
218
+ # end
219
+ def handle_invalid_csrf_token(req, res)
220
+ res.session.clear
221
+ raise InvalidCSRFTokenError.new
222
+ end
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "<%= application_path %>",
3
+ "description": "Asset compilation with webpack",
4
+ "version": "1.0.0",
5
+ "author": "Icelab",
6
+ "repository": {},
7
+ "dependencies": {
8
+ "viewloader": "^2.0.0"
9
+ },
10
+ "devDependencies": {
11
+ "icelab-assets": "^2.0.1"
12
+ },
13
+ "engines": {
14
+ "node": ">= 6",
15
+ "npm": ">= 4"
16
+ },
17
+ "scripts": {
18
+ "start": "icelab-assets start --source-path=slices",
19
+ "build": "icelab-assets build --source-path=slices",
20
+ "build-production": "icelab-assets build --source-path=slices",
21
+ "test": "icelab-assets test --source-path=slices",
22
+ "create-entry": "icelab-assets create-entry",
23
+ "heroku-postbuild": "icelab-assets build --source-path=slices"
24
+ }
25
+ }
@@ -0,0 +1,32 @@
1
+ #!/bin/sh
2
+
3
+ # script/bootstrap: Resolve all dependencies that the application requires to
4
+ # run.
5
+
6
+ set -e
7
+
8
+ cd "$(dirname "$0")/.."
9
+
10
+ if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then
11
+ brew bundle check >/dev/null 2>&1 || {
12
+ echo "==> Installing Homebrew dependencies…"
13
+ brew bundle
14
+ }
15
+ fi
16
+
17
+ if [ -f ".tool-versions" ] && [ "$(uname -s)" = "Darwin" ]; then
18
+ echo "==> Installing package versions…"
19
+ brew bootstrap-asdf
20
+ fi
21
+
22
+ if [ -f "Gemfile" ]; then
23
+ echo "==> Installing gem dependencies…"
24
+ bundle check >/dev/null 2>&1 || {
25
+ bundle install --quiet --without production
26
+ }
27
+ fi
28
+
29
+ if [ -f "package.json" ]; then
30
+ echo "==> Installing node packages…"
31
+ yarn
32
+ fi
@@ -0,0 +1,26 @@
1
+ #!/bin/sh
2
+
3
+ # script/console: Launch a console for the application. Optionally allow an
4
+ # environment to be passed in to let the script handle the specific requirements
5
+ # for connecting to a console for that environment.
6
+
7
+ set -e
8
+
9
+ cd "$(dirname "$0")/.."
10
+
11
+ if [ -n "$1" ]; then
12
+ # Use first argument as an environment name. Use this to decide how to connect
13
+ # to the appropriate console.
14
+ if [ "$1" = "production" ]; then
15
+ heroku run ./bin/run console --app heroku-app-name
16
+ elif [ "$1" = "staging" ]; then
17
+ heroku run ./bin/run console --app heroku-app-name-staging
18
+ else
19
+ echo "Sorry, I don't know how to connect to the '$1' environment."
20
+ exit 1
21
+ fi
22
+ else
23
+ # No argument provided, so just run the local console in the development
24
+ # environment.
25
+ ./bin/run console
26
+ fi
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ # script/server: Launch the application and any extra required processes
4
+ # locally.
5
+
6
+ set -e
7
+
8
+ cd "$(dirname "$0")/.."
9
+
10
+ test -z "$RACK_ENV" && RACK_ENV='development'
11
+
12
+ # Boot the app and any other necessary processes
13
+ overmind start -f Procfile.dev
@@ -0,0 +1,27 @@
1
+ #!/bin/sh
2
+
3
+ # script/setup: Set up application for the first time after cloning, or set it
4
+ # back to the initial first unused state.
5
+
6
+ set -e
7
+
8
+ cd "$(dirname "$0")/.."
9
+
10
+ script/bootstrap
11
+
12
+ echo "==> Copying config files"
13
+ if [ -f ".env-example" ] && [ ! -f ".env" ]; then
14
+ cp .env-example .env
15
+ fi
16
+ if [ -f ".env.test-example" ] && [ ! -f ".env.test" ]; then
17
+ cp .env.test-example .env.test
18
+ fi
19
+
20
+ echo "==> Setting up database…"
21
+ bin/run db create
22
+ bin/run db create -e test
23
+ bin/run db reset
24
+ bin/run db reset -e test
25
+ bin/run db seed
26
+
27
+ echo "==> App is now ready to go!"
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ # script/support: Launch supporting services for the application.
4
+
5
+ set -e
6
+
7
+ cd "$(dirname "$0")/.."
8
+
9
+ overmind start -f Procfile.support -s .overmind.support.sock
@@ -0,0 +1,19 @@
1
+ #!/bin/sh
2
+
3
+ # script/test: Run test suite for application. Optionally pass in a path to an
4
+ # individual test file to run a single test.
5
+
6
+ set -e
7
+
8
+ cd "$(dirname "$0")/.."
9
+
10
+ [ -z "$DEBUG" ] || set -x
11
+
12
+ echo "==> Running tests…"
13
+
14
+ if [ -n "$1" ]; then
15
+ # Pass arguments to test call. This is useful for calling a single test.
16
+ bundle exec rspec "$1"
17
+ else
18
+ bundle exec rake spec
19
+ fi
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ # script/update: Update application to run for its current checkout.
4
+
5
+ set -e
6
+
7
+ cd "$(dirname "$0")/.."
8
+
9
+ script/bootstrap
10
+
11
+ echo "==> Updating db…"
12
+ # run all database migrations to ensure everything is up to date.
13
+ bin/rake db:migrate
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV["RACK_ENV"] = "test"
4
+
5
+ require_relative "../config/application"
6
+ require_relative "support/suite"
7
+
8
+ SPEC_ROOT = Pathname(__dir__).freeze
9
+ FIXTURES_PATH = SPEC_ROOT.join("fixtures").freeze
10
+
11
+ suite = Test::Suite.instance
12
+
13
+ suite.start_coverage
@@ -0,0 +1,9 @@
1
+ require "snowpack/test/suite"
2
+
3
+ module Test
4
+ class Suite < Snowpack::Test::Suite
5
+ configure do |config|
6
+ # extra configuration here
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "../../config/application"
2
+
3
+ module <%= application_module %>
4
+ Import = Application.injector
5
+ end
@@ -0,0 +1,17 @@
1
+ <%= application_module %>::Application.boot :assets do |container|
2
+ init do
3
+ require "snowpack/web/assets"
4
+ end
5
+
6
+ start do
7
+ use :settings
8
+
9
+ assets = Snowpack::Web::Assets.new(
10
+ root: container.root,
11
+ precompiled: container.config.env == :production || container[:settings].assets_precompiled,
12
+ server_url: container[:settings].assets_server_url,
13
+ )
14
+
15
+ register :assets, assets
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ <%= application_module %>::Application.boot :logger do |container|
2
+ start do
3
+ use :settings
4
+
5
+ if container[:settings].log_to_stdout
6
+ $stdout.sync = true
7
+ logger.reopen($stdout)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ <%= application_module %>::Application.boot :monitor do
2
+ init do
3
+ require "dry/monitor/sql/logger"
4
+ end
5
+
6
+ start do
7
+ Dry::Monitor::SQL::Logger.new(logger).subscribe(notifications)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ <%= application_module %>::Application.boot :persistence, namespace: true, from: :snowpack do
2
+ configure do |config|
3
+ config.database_url = container[:settings].database_url
4
+ config.global_extensions = [:postgres]
5
+ config.connection_extensions = %i[error_sql pg_array pg_json pg_enum]
6
+ config.auto_registration_root = container.root.join("lib/<%= application_path %>/persistence").to_s
7
+ config.auto_registration_namespace = "<%= application_module %>::Persistence"
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ <%= application_module %>::Application.boot :settings, from: :system do
2
+ before :init do
3
+ require "<%= application_path %>/types"
4
+ end
5
+
6
+ settings do
7
+ # Web app
8
+ key :session_secret, <%= application_module %>::Types::Strict::String.constrained(filled: true)
9
+ key :log_to_stdout, <%= application_module %>::Types::Params::Bool
10
+
11
+ # Assets
12
+ key :assets_precompiled, <%= application_module %>::Types::Params::Bool
13
+ key :assets_server_url, <%= application_module %>::Types::Strict::String.constrained(filled: true).optional.default(nil)
14
+
15
+ # Persistence
16
+ key :database_url, <%= application_module %>::Types::Strict::String.constrained(filled: true)
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ <%= application_module %>::Application.boot :web, namespace: true do |container|
2
+ init do
3
+ require "hanami/controller"
4
+ end
5
+
6
+ start do
7
+ register "action.configuration", Hanami::Controller::Configuration.new
8
+ end
9
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/inflector"
4
+ require "securerandom"
5
+ require "shellwords"
6
+ require_relative "../../generator"
7
+
8
+ module Snowpack
9
+ module Generators
10
+ module Slice
11
+ class Generator < Snowpack::Generator
12
+ # FIXME: need to make templates_dir handling nicer, also support multiple dirs
13
+ def initialize(templates_dir: nil)
14
+ templates_dir ||= File.join(__dir__, "templates")
15
+ super(templates_dir: templates_dir)
16
+ end
17
+
18
+ def call(application:, slice_name:, web:)
19
+ slice_name = inflector.underscore(slice_name)
20
+
21
+ output_dir = application.config.root.join("slices", slice_name) # TODO: don't hardcode "slices"
22
+
23
+ super(
24
+ output_dir,
25
+ env(application: application, slice_name: slice_name, web: web),
26
+ )
27
+ end
28
+
29
+ private
30
+
31
+ def templates(web:, **)
32
+ super.then { |tpls|
33
+ if !web
34
+ tpls.reject { |tpl|
35
+ File.fnmatch?("*/web/**", tpl)
36
+ }
37
+ else
38
+ tpls
39
+ end
40
+ }
41
+ end
42
+
43
+ def env(application:, slice_name:, **others)
44
+ application_path = inflector.underscore(application.module.to_s)
45
+
46
+ {
47
+ application_path: application_path,
48
+ application_module: application.module.to_s,
49
+ slice_name: slice_name,
50
+ slice_path: "#{application_path}/#{slice_name}",
51
+ slice_module: inflector.camelize(slice_name),
52
+ }.merge(**others)
53
+ end
54
+
55
+ # TODO: use application's own inflector
56
+ def inflector
57
+ @inflector ||= Dry::Inflector.new
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,10 @@
1
+ require "<%= application_path %>/web/action"
2
+
3
+ module <%= application_module %>
4
+ module <%= slice_module %>
5
+ module Web
6
+ class Action < <%= application_module %>::Web::Action
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ # auto_register: false
3
+
4
+ require "slim"
5
+ require "dry/view"
6
+ require "<%= slice_path %>/slice"
7
+
8
+ module <%= application_module %>
9
+ module <%= slice_module %>
10
+ module Web
11
+ class View < Dry::View
12
+ config.paths = [Slice.root.join("web/templates")]
13
+ config.layout = "application"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "slice"
4
+
5
+ module <%= application_module %>
6
+ module <%= slice_module %>
7
+ Import = Slice.injector
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "snowpack/slice"
4
+
5
+ module <%= application_module %>
6
+ module <%= slice_module %>
7
+ class Slice < Snowpack::Slice
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "appsignal"
4
+
5
+ Appsignal::Transaction.class_eval do
6
+ def set_error_with_snowpack(*args)
7
+ restore!
8
+ set_error_without_snowpack(*args)
9
+ end
10
+
11
+ alias_method :set_error_without_snowpack, :set_error
12
+ alias_method :set_error, :set_error_with_snowpack
13
+ end