stipa 0.2.2 → 0.2.4
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 +4 -4
- data/lib/stipa/generators/api.rb +56 -9
- data/lib/stipa/generators/base.rb +17 -7
- data/lib/stipa/generators/vue.rb +100 -48
- data/lib/stipa/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 035d22e299975a792e6b72649c0160e6a9af69c1b50f5b529503e35e772f5cf6
|
|
4
|
+
data.tar.gz: df2d1f4bd439bb41f008e4468c19c0c9538f56ca820570e3afc46fce7b1f6bc0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 23b23d3954f3801027e4c396334cab70e3d3091e0ba4a305f740374172a160d489c7ba91eab9a37274f326c0d616bb0caf0d10e619b4ce0cd2e6f82f215d64da
|
|
7
|
+
data.tar.gz: e858a068ada0a89e2a7fb256718679fb55a428c1fd3da570bad18618851f50a922baa4dc015a81ef21d7709952e4569d7741ce2356028536b9efc659fe8f2d9f
|
data/lib/stipa/generators/api.rb
CHANGED
|
@@ -54,8 +54,7 @@ module Stipa
|
|
|
54
54
|
Stipa::Database.connect!
|
|
55
55
|
|
|
56
56
|
# Models must be loaded after the database connection is established.
|
|
57
|
-
|
|
58
|
-
require_relative 'models/application_model' rescue warn "⚠ Run 'rake db:migrate' to set up the database."
|
|
57
|
+
require_relative 'models/application_model'
|
|
59
58
|
|
|
60
59
|
app = Stipa::App.new
|
|
61
60
|
|
|
@@ -93,20 +92,68 @@ module Stipa
|
|
|
93
92
|
|
|
94
93
|
private
|
|
95
94
|
|
|
95
|
+
# ── Success helpers ──────────────────────────────
|
|
96
|
+
|
|
96
97
|
def json(data, status: 200)
|
|
97
98
|
res.status = status
|
|
98
99
|
res.json(data)
|
|
99
100
|
end
|
|
100
101
|
|
|
101
|
-
def
|
|
102
|
-
res.status =
|
|
103
|
-
res.json(
|
|
104
|
-
|
|
102
|
+
def created!(data = nil)
|
|
103
|
+
res.status = 201
|
|
104
|
+
data ? res.json(data) : res.tap { _1.body = '' }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def no_content!
|
|
108
|
+
res.status = 204
|
|
109
|
+
res.body = ''
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# ── Redirection ──────────────────────────────────
|
|
113
|
+
|
|
114
|
+
def redirect_to(path, status: 302)
|
|
115
|
+
res.status = status
|
|
116
|
+
res['Location'] = path
|
|
117
|
+
res.body = ''
|
|
105
118
|
end
|
|
106
119
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
120
|
+
# ── Error helpers ────────────────────────────────
|
|
121
|
+
|
|
122
|
+
def bad_request!(message = 'Bad Request')
|
|
123
|
+
error(400, message)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def unauthorized!(message = 'Unauthorized')
|
|
127
|
+
error(401, message)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def forbidden!(message = 'Forbidden')
|
|
131
|
+
error(403, message)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def not_found!(message = 'Not Found')
|
|
135
|
+
error(404, message)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def conflict!(message = 'Conflict')
|
|
139
|
+
error(409, message)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def unprocessable_entity!(message = 'Unprocessable Entity')
|
|
143
|
+
error(422, message)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def too_many_requests!(message = 'Too Many Requests')
|
|
147
|
+
error(429, message)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def internal_server_error!(message = 'Internal Server Error')
|
|
151
|
+
error(500, message)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def error(status, message)
|
|
155
|
+
res.status = status
|
|
156
|
+
res.json(error: { message: message })
|
|
110
157
|
throw :halt
|
|
111
158
|
end
|
|
112
159
|
|
|
@@ -5,7 +5,7 @@ require 'pathname'
|
|
|
5
5
|
module Stipa
|
|
6
6
|
module Generators
|
|
7
7
|
class Base
|
|
8
|
-
GEM_JS
|
|
8
|
+
GEM_JS = File.expand_path('../../js', __dir__)
|
|
9
9
|
GEM_MEDIA = File.expand_path('../../../media', __dir__)
|
|
10
10
|
GEM_ROOT = File.expand_path('../..', GEM_JS)
|
|
11
11
|
|
|
@@ -51,7 +51,7 @@ module Stipa
|
|
|
51
51
|
system('git', 'commit', '-q', '-m', 'Initial commit')
|
|
52
52
|
end
|
|
53
53
|
say ' git initialized repository with initial commit'
|
|
54
|
-
rescue => e
|
|
54
|
+
rescue StandardError => e
|
|
55
55
|
say " warn git init failed: #{e.message}"
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -150,7 +150,7 @@ module Stipa
|
|
|
150
150
|
%w[get post put patch delete].each do |verb|
|
|
151
151
|
define_method(verb) do |pattern, to:|
|
|
152
152
|
klass, action = resolve(to)
|
|
153
|
-
@app.public_send(verb, pattern) { |req, res| klass.new(req, res).public_send(action) }
|
|
153
|
+
@app.public_send(verb, pattern) { |req, res| catch(:halt) { klass.new(req, res).public_send(action) } }
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
156
|
end
|
|
@@ -190,8 +190,18 @@ module Stipa
|
|
|
190
190
|
|
|
191
191
|
require 'stipa/model'
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
# Include this in any Sequel::Model subclass to get
|
|
194
|
+
# timestamps, UUID, soft delete, and serialization.
|
|
195
|
+
#
|
|
196
|
+
# Usage:
|
|
197
|
+
# class Post < Sequel::Model
|
|
198
|
+
# include ApplicationModel
|
|
199
|
+
# end
|
|
200
|
+
|
|
201
|
+
module ApplicationModel
|
|
202
|
+
def self.included(base)
|
|
203
|
+
base.include Stipa::Model
|
|
204
|
+
end
|
|
195
205
|
end
|
|
196
206
|
RUBY
|
|
197
207
|
end
|
|
@@ -217,7 +227,7 @@ module Stipa
|
|
|
217
227
|
RUBY
|
|
218
228
|
end
|
|
219
229
|
|
|
220
|
-
def t_rakefile
|
|
230
|
+
def t_rakefile(config_path: 'config')
|
|
221
231
|
<<~RUBY
|
|
222
232
|
# frozen_string_literal: true
|
|
223
233
|
|
|
@@ -251,7 +261,7 @@ module Stipa
|
|
|
251
261
|
task default: 'db:migrate'
|
|
252
262
|
|
|
253
263
|
def load_config
|
|
254
|
-
require_relative '
|
|
264
|
+
require_relative '#{config_path}/database'
|
|
255
265
|
Stipa::Database.connect!
|
|
256
266
|
end
|
|
257
267
|
|
data/lib/stipa/generators/vue.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Stipa
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def post_generate
|
|
24
|
-
copy_asset 'stipa-vue.js',
|
|
24
|
+
copy_asset 'stipa-vue.js', from: GEM_JS
|
|
25
25
|
copy_asset 'logo.png', from: GEM_MEDIA
|
|
26
26
|
copy_asset 'favicon.ico', from: GEM_MEDIA
|
|
27
27
|
end
|
|
@@ -54,30 +54,30 @@ module Stipa
|
|
|
54
54
|
|
|
55
55
|
def files
|
|
56
56
|
{
|
|
57
|
-
'.gitignore'
|
|
58
|
-
'Gemfile'
|
|
59
|
-
'Rakefile'
|
|
60
|
-
'package.json'
|
|
61
|
-
'rollup.config.js'
|
|
62
|
-
'tsconfig.json'
|
|
63
|
-
'server.rb'
|
|
64
|
-
'app/config/database.rb'
|
|
65
|
-
'app/config/routes.rb'
|
|
57
|
+
'.gitignore' => t_gitignore,
|
|
58
|
+
'Gemfile' => t_gemfile,
|
|
59
|
+
'Rakefile' => t_rakefile(config_path: 'app/config'),
|
|
60
|
+
'package.json' => t_package_json,
|
|
61
|
+
'rollup.config.js' => t_rollup_config,
|
|
62
|
+
'tsconfig.json' => t_tsconfig,
|
|
63
|
+
'server.rb' => t_server,
|
|
64
|
+
'app/config/database.rb' => t_database_config,
|
|
65
|
+
'app/config/routes.rb' => t_routes(
|
|
66
66
|
extra_requires: ['../controllers/home_controller', '../controllers/health_controller'],
|
|
67
|
-
extra_routes:
|
|
68
|
-
method_override: true
|
|
67
|
+
extra_routes: ["get '/', to: 'home#index'", "get '/api/health', to: 'health#show'"],
|
|
68
|
+
method_override: true
|
|
69
69
|
),
|
|
70
|
-
'app/controllers/application_controller.rb'
|
|
71
|
-
'app/controllers/home_controller.rb'
|
|
72
|
-
'app/controllers/health_controller.rb'
|
|
73
|
-
'app/models/application_model.rb'
|
|
74
|
-
'db/migrate/001_create_posts.rb'
|
|
75
|
-
'app/views/layouts/application.html.erb'
|
|
76
|
-
'app/views/home/index.html.erb'
|
|
77
|
-
'public/app.css'
|
|
78
|
-
'app/components/RequestCard.vue'
|
|
79
|
-
'app/main.ts'
|
|
80
|
-
'app/shims-vue.d.ts'
|
|
70
|
+
'app/controllers/application_controller.rb' => t_application_controller,
|
|
71
|
+
'app/controllers/home_controller.rb' => t_home_controller,
|
|
72
|
+
'app/controllers/health_controller.rb' => t_health_controller,
|
|
73
|
+
'app/models/application_model.rb' => t_application_model,
|
|
74
|
+
'db/migrate/001_create_posts.rb' => t_migration_create_posts,
|
|
75
|
+
'app/views/layouts/application.html.erb' => t_layout,
|
|
76
|
+
'app/views/home/index.html.erb' => t_home_index,
|
|
77
|
+
'public/app.css' => t_app_css,
|
|
78
|
+
'app/components/RequestCard.vue' => t_request_card_vue,
|
|
79
|
+
'app/main.ts' => t_main_ts,
|
|
80
|
+
'app/shims-vue.d.ts' => t_shims_vue
|
|
81
81
|
}
|
|
82
82
|
end
|
|
83
83
|
|
|
@@ -101,22 +101,22 @@ module Stipa
|
|
|
101
101
|
private: true,
|
|
102
102
|
type: 'module',
|
|
103
103
|
scripts: {
|
|
104
|
-
'copy:vue'
|
|
105
|
-
build:
|
|
106
|
-
watch:
|
|
107
|
-
dev:
|
|
108
|
-
typecheck:
|
|
104
|
+
'copy:vue' => 'cp node_modules/vue/dist/vue.esm-browser.prod.js public/vendor/vue.esm-browser.prod.js',
|
|
105
|
+
build: 'npm run copy:vue && rollup -c',
|
|
106
|
+
watch: 'rollup -c --watch',
|
|
107
|
+
dev: 'npm run copy:vue && concurrently "STIPA_RELOAD=1 bundle exec ruby server.rb" "rollup -c --watch"',
|
|
108
|
+
typecheck: 'vue-tsc --noEmit'
|
|
109
109
|
},
|
|
110
110
|
devDependencies: {
|
|
111
|
-
'concurrently'
|
|
112
|
-
'rollup'
|
|
113
|
-
'rollup-plugin-vue'
|
|
111
|
+
'concurrently' => '^8.0.0',
|
|
112
|
+
'rollup' => '^4.0.0',
|
|
113
|
+
'rollup-plugin-vue' => '^6.0.0',
|
|
114
114
|
'@rollup/plugin-typescript' => '^11.0.0',
|
|
115
|
-
'@vue/compiler-sfc'
|
|
116
|
-
'typescript'
|
|
117
|
-
'vue'
|
|
118
|
-
'vue-tsc'
|
|
119
|
-
}
|
|
115
|
+
'@vue/compiler-sfc' => '^3.4.0',
|
|
116
|
+
'typescript' => '^5.0.0',
|
|
117
|
+
'vue' => '^3.4.0',
|
|
118
|
+
'vue-tsc' => '^2.0.0'
|
|
119
|
+
}
|
|
120
120
|
) + "\n"
|
|
121
121
|
end
|
|
122
122
|
|
|
@@ -142,14 +142,14 @@ module Stipa
|
|
|
142
142
|
def t_tsconfig
|
|
143
143
|
JSON.pretty_generate(
|
|
144
144
|
compilerOptions: {
|
|
145
|
-
target:
|
|
146
|
-
module:
|
|
145
|
+
target: 'ESNext',
|
|
146
|
+
module: 'ESNext',
|
|
147
147
|
moduleResolution: 'bundler',
|
|
148
|
-
strict:
|
|
149
|
-
skipLibCheck:
|
|
150
|
-
allowJs:
|
|
148
|
+
strict: true,
|
|
149
|
+
skipLibCheck: true,
|
|
150
|
+
allowJs: true
|
|
151
151
|
},
|
|
152
|
-
include: ['app/**/*']
|
|
152
|
+
include: ['app/**/*']
|
|
153
153
|
) + "\n"
|
|
154
154
|
end
|
|
155
155
|
|
|
@@ -164,8 +164,7 @@ module Stipa
|
|
|
164
164
|
Stipa::Database.connect!
|
|
165
165
|
|
|
166
166
|
# Models must be loaded after the database connection is established.
|
|
167
|
-
|
|
168
|
-
require_relative 'app/models/application_model' rescue warn "⚠ Run 'rake db:migrate' to set up the database."
|
|
167
|
+
require_relative 'app/models/application_model'
|
|
169
168
|
|
|
170
169
|
APP_DIR = __dir__
|
|
171
170
|
|
|
@@ -210,15 +209,68 @@ module Stipa
|
|
|
210
209
|
res.render(template, locals: locals, layout: layout)
|
|
211
210
|
end
|
|
212
211
|
|
|
212
|
+
# ── Success helpers ──────────────────────────────
|
|
213
|
+
|
|
214
|
+
def json(data, status: 200)
|
|
215
|
+
res.status = status
|
|
216
|
+
res.json(data)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def created!(data = nil)
|
|
220
|
+
res.status = 201
|
|
221
|
+
data ? res.json(data) : res.tap { _1.body = '' }
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def no_content!
|
|
225
|
+
res.status = 204
|
|
226
|
+
res.body = ''
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# ── Redirection ──────────────────────────────────
|
|
230
|
+
|
|
213
231
|
def redirect_to(path, status: 302)
|
|
214
232
|
res.status = status
|
|
215
233
|
res['Location'] = path
|
|
216
234
|
res.body = ''
|
|
217
235
|
end
|
|
218
236
|
|
|
237
|
+
# ── Error helpers ────────────────────────────────
|
|
238
|
+
|
|
239
|
+
def bad_request!(message = 'Bad Request')
|
|
240
|
+
error(400, message)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def unauthorized!(message = 'Unauthorized')
|
|
244
|
+
error(401, message)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def forbidden!(message = 'Forbidden')
|
|
248
|
+
error(403, message)
|
|
249
|
+
end
|
|
250
|
+
|
|
219
251
|
def not_found!(message = 'Not Found')
|
|
220
|
-
|
|
221
|
-
|
|
252
|
+
error(404, message)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def conflict!(message = 'Conflict')
|
|
256
|
+
error(409, message)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def unprocessable_entity!(message = 'Unprocessable Entity')
|
|
260
|
+
error(422, message)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def too_many_requests!(message = 'Too Many Requests')
|
|
264
|
+
error(429, message)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def internal_server_error!(message = 'Internal Server Error')
|
|
268
|
+
error(500, message)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def error(status, message)
|
|
272
|
+
res.status = status
|
|
273
|
+
res.json(error: { message: message })
|
|
222
274
|
throw :halt
|
|
223
275
|
end
|
|
224
276
|
|
|
@@ -238,6 +290,8 @@ module Stipa
|
|
|
238
290
|
k, v = pair.split('=', 2)
|
|
239
291
|
p[k.to_sym] = URI.decode_www_form_component(v.to_s)
|
|
240
292
|
end
|
|
293
|
+
elsif req['content-type']&.include?('application/json')
|
|
294
|
+
JSON.parse(req.body).each { |k, v| p[k.to_sym] = v }
|
|
241
295
|
end
|
|
242
296
|
|
|
243
297
|
p
|
|
@@ -424,8 +478,6 @@ module Stipa
|
|
|
424
478
|
CSS
|
|
425
479
|
end
|
|
426
480
|
|
|
427
|
-
|
|
428
|
-
|
|
429
481
|
def t_shims_vue
|
|
430
482
|
<<~TS
|
|
431
483
|
declare module '*.vue' {
|
data/lib/stipa/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stipa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jānis Harbs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|