snowpack 1.0.0.alpha2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.tool-versions +1 -0
- data/.travis.yml +16 -0
- data/Brewfile +2 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile +13 -0
- data/LICENSE +21 -0
- data/README.md +116 -0
- data/Rakefile +6 -0
- data/bin/bootstrap +25 -0
- data/exe/snowpack +7 -0
- data/lib/snowpack/application.rb +98 -0
- data/lib/snowpack/application_cli.rb +39 -0
- data/lib/snowpack/cli/application/cli.rb +32 -0
- data/lib/snowpack/cli/application/command.rb +53 -0
- data/lib/snowpack/cli/application/commands/assets/clobber.rb +31 -0
- data/lib/snowpack/cli/application/commands/assets/compile.rb +32 -0
- data/lib/snowpack/cli/application/commands/console.rb +55 -0
- data/lib/snowpack/cli/application/commands/db/create.rb +33 -0
- data/lib/snowpack/cli/application/commands/db/create_migration.rb +38 -0
- data/lib/snowpack/cli/application/commands/db/drop.rb +33 -0
- data/lib/snowpack/cli/application/commands/db/migrate.rb +47 -0
- data/lib/snowpack/cli/application/commands/db/reset.rb +28 -0
- data/lib/snowpack/cli/application/commands/db/rollback.rb +54 -0
- data/lib/snowpack/cli/application/commands/db/sample_data.rb +41 -0
- data/lib/snowpack/cli/application/commands/db/seed.rb +41 -0
- data/lib/snowpack/cli/application/commands/db/structure/dump.rb +38 -0
- data/lib/snowpack/cli/application/commands/db/utils/database.rb +76 -0
- data/lib/snowpack/cli/application/commands/db/utils/database_config.rb +49 -0
- data/lib/snowpack/cli/application/commands/db/version.rb +37 -0
- data/lib/snowpack/cli/application/commands/generate/slice.rb +32 -0
- data/lib/snowpack/cli/application/commands/routes/update.rb +35 -0
- data/lib/snowpack/cli/application/commands.rb +27 -0
- data/lib/snowpack/cli/command.rb +48 -0
- data/lib/snowpack/cli/standalone/cli.rb +14 -0
- data/lib/snowpack/cli/standalone/commands/new.rb +33 -0
- data/lib/snowpack/cli/standalone/commands.rb +13 -0
- data/lib/snowpack/components/formalist.rb +27 -0
- data/lib/snowpack/components/persistence.rb +56 -0
- data/lib/snowpack/components.rb +5 -0
- data/lib/snowpack/console/context.rb +32 -0
- data/lib/snowpack/console/plugins/relation_readers.rb +17 -0
- data/lib/snowpack/console/plugins/slice_readers.rb +33 -0
- data/lib/snowpack/generator.rb +57 -0
- data/lib/snowpack/generators/application/generator.rb +67 -0
- data/lib/snowpack/generators/application/templates/.env-example.tt +10 -0
- data/lib/snowpack/generators/application/templates/.env.test-example.tt +1 -0
- data/lib/snowpack/generators/application/templates/.gitignore +20 -0
- data/lib/snowpack/generators/application/templates/.rspec +2 -0
- data/lib/snowpack/generators/application/templates/Brewfile +4 -0
- data/lib/snowpack/generators/application/templates/Gemfile.tt +46 -0
- data/lib/snowpack/generators/application/templates/Guardfile +7 -0
- data/lib/snowpack/generators/application/templates/Procfile.dev +3 -0
- data/lib/snowpack/generators/application/templates/Procfile.support +1 -0
- data/lib/snowpack/generators/application/templates/README.md.tt +45 -0
- data/lib/snowpack/generators/application/templates/Rakefile +5 -0
- data/lib/snowpack/generators/application/templates/bin/run +7 -0
- data/lib/snowpack/generators/application/templates/config/application.rb.tt +19 -0
- data/lib/snowpack/generators/application/templates/config/puma.rb.tt +14 -0
- data/lib/snowpack/generators/application/templates/config/routes.rb.tt +15 -0
- data/lib/snowpack/generators/application/templates/config.ru +5 -0
- data/lib/snowpack/generators/application/templates/db/migrate/.keep +0 -0
- data/lib/snowpack/generators/application/templates/db/sample_data.rb +1 -0
- data/lib/snowpack/generators/application/templates/db/seed.rb +1 -0
- data/lib/snowpack/generators/application/templates/lib/__application_path__/operation.rb.tt +12 -0
- data/lib/snowpack/generators/application/templates/lib/__application_path__/persistence/relations/.keep +0 -0
- data/lib/snowpack/generators/application/templates/lib/__application_path__/types.rb.tt +11 -0
- data/lib/snowpack/generators/application/templates/lib/__application_path__/web/action.rb.tt +56 -0
- data/lib/snowpack/generators/application/templates/lib/__application_path__/web/view/context.rb.tt +31 -0
- data/lib/snowpack/generators/application/templates/lib/hanami/action/csrf_protection.rb +225 -0
- data/lib/snowpack/generators/application/templates/log/.keep +0 -0
- data/lib/snowpack/generators/application/templates/package.json.tt +25 -0
- data/lib/snowpack/generators/application/templates/public/.keep +0 -0
- data/lib/snowpack/generators/application/templates/script/bootstrap +32 -0
- data/lib/snowpack/generators/application/templates/script/console +26 -0
- data/lib/snowpack/generators/application/templates/script/server +13 -0
- data/lib/snowpack/generators/application/templates/script/setup +27 -0
- data/lib/snowpack/generators/application/templates/script/support +9 -0
- data/lib/snowpack/generators/application/templates/script/test +19 -0
- data/lib/snowpack/generators/application/templates/script/update +13 -0
- data/lib/snowpack/generators/application/templates/spec/spec_helper.rb +13 -0
- data/lib/snowpack/generators/application/templates/spec/suite/.keep +0 -0
- data/lib/snowpack/generators/application/templates/spec/support/suite.rb +9 -0
- data/lib/snowpack/generators/application/templates/system/__application_path__/import.rb.tt +5 -0
- data/lib/snowpack/generators/application/templates/system/boot/assets.rb.tt +17 -0
- data/lib/snowpack/generators/application/templates/system/boot/logger.rb.tt +10 -0
- data/lib/snowpack/generators/application/templates/system/boot/monitor.rb.tt +9 -0
- data/lib/snowpack/generators/application/templates/system/boot/persistence.rb.tt +9 -0
- data/lib/snowpack/generators/application/templates/system/boot/settings.rb.tt +18 -0
- data/lib/snowpack/generators/application/templates/system/boot/web.rb.tt +9 -0
- data/lib/snowpack/generators/slice/generator.rb +62 -0
- data/lib/snowpack/generators/slice/templates/lib/__slice_path__/.keep +0 -0
- data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/action.rb.tt +10 -0
- data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/actions/.keep +0 -0
- data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/view.rb.tt +17 -0
- data/lib/snowpack/generators/slice/templates/lib/__slice_path__/web/views/.keep +0 -0
- data/lib/snowpack/generators/slice/templates/system/__slice_path__/import.rb.tt +9 -0
- data/lib/snowpack/generators/slice/templates/system/__slice_path__/slice.rb.tt +10 -0
- data/lib/snowpack/instrumentation/appsignal/appsignal_ext.rb +13 -0
- data/lib/snowpack/instrumentation/appsignal/que.rb +70 -0
- data/lib/snowpack/instrumentation/appsignal/rack.rb +84 -0
- data/lib/snowpack/roda/web.rb +47 -0
- data/lib/snowpack/slice.rb +85 -0
- data/lib/snowpack/test/suite.rb +164 -0
- data/lib/snowpack/test/tasks.rake +40 -0
- data/lib/snowpack/test_tasks.rb +4 -0
- data/lib/snowpack/types.rb +9 -0
- data/lib/snowpack/version.rb +5 -0
- data/lib/snowpack/view/part_builder.rb +45 -0
- data/lib/snowpack/view/parts/pager.rb +107 -0
- data/lib/snowpack/view/parts/paginated.rb +22 -0
- data/lib/snowpack/web/application.rb +38 -0
- data/lib/snowpack/web/assets.rb +56 -0
- data/lib/snowpack/web/endpoint_resolver.rb +66 -0
- data/lib/snowpack/web/form.rb +38 -0
- data/lib/snowpack/web/plugin.rb +44 -0
- data/lib/snowpack/web/rack_logger.rb +73 -0
- data/lib/snowpack/web/router.rb +58 -0
- data/lib/snowpack/web.rb +20 -0
- data/lib/snowpack.rb +27 -0
- data/snowpack.gemspec +34 -0
- 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
|
File without changes
|
@@ -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
|
+
}
|
File without changes
|
@@ -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,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
|
File without changes
|
@@ -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,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,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
|
File without changes
|
File without changes
|
@@ -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
|
File without changes
|
@@ -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
|