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