stipa 0.2.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 629ad04a4c8bcd7193a81038be6845f90d9e01b229bfbc0b2d1cb7931359ac06
4
- data.tar.gz: 7d57a8f7839381d2abfe434221cc58de4a8bddf945d7f55ced2c7c9f272c6bef
3
+ metadata.gz: 035d22e299975a792e6b72649c0160e6a9af69c1b50f5b529503e35e772f5cf6
4
+ data.tar.gz: df2d1f4bd439bb41f008e4468c19c0c9538f56ca820570e3afc46fce7b1f6bc0
5
5
  SHA512:
6
- metadata.gz: d96ce9f31e87e046095910f784526cc9a7eb7ca98e5af626b07dd668a12c0eb46e7bab0bd60950788ca924ea75aea08b97b981e38b4ba6615edb2dfbaf72661c
7
- data.tar.gz: 74e83a3380253c27ef9eddbd4cdba82b3a7658b9261a4dc5ad2b2a58a75cd5820799f9a6ba0cd2512f485ec38c5cb7b354dd07368769c34dc2ab214bee89fc7a
6
+ metadata.gz: 23b23d3954f3801027e4c396334cab70e3d3091e0ba4a305f740374172a160d489c7ba91eab9a37274f326c0d616bb0caf0d10e619b4ce0cd2e6f82f215d64da
7
+ data.tar.gz: e858a068ada0a89e2a7fb256718679fb55a428c1fd3da570bad18618851f50a922baa4dc015a81ef21d7709952e4569d7741ce2356028536b9efc659fe8f2d9f
@@ -92,20 +92,68 @@ module Stipa
92
92
 
93
93
  private
94
94
 
95
+ # ── Success helpers ──────────────────────────────
96
+
95
97
  def json(data, status: 200)
96
98
  res.status = status
97
99
  res.json(data)
98
100
  end
99
101
 
100
- def not_found!(message = 'Not found')
101
- res.status = 404
102
- res.json(error: message)
103
- throw :halt
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 = ''
104
118
  end
105
119
 
106
- def unprocessable!(errors)
107
- res.status = 422
108
- res.json(errors: errors)
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 })
109
157
  throw :halt
110
158
  end
111
159
 
@@ -5,7 +5,7 @@ require 'pathname'
5
5
  module Stipa
6
6
  module Generators
7
7
  class Base
8
- GEM_JS = File.expand_path('../../js', __dir__)
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
@@ -21,7 +21,7 @@ module Stipa
21
21
  end
22
22
 
23
23
  def post_generate
24
- copy_asset 'stipa-vue.js', from: GEM_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' => 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(
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: ["get '/', to: 'home#index'", "get '/api/health', to: 'health#show'"],
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' => 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,
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' => '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',
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' => '^8.0.0',
112
- 'rollup' => '^4.0.0',
113
- 'rollup-plugin-vue' => '^6.0.0',
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' => '^3.4.0',
116
- 'typescript' => '^5.0.0',
117
- 'vue' => '^3.4.0',
118
- 'vue-tsc' => '^2.0.0',
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: 'ESNext',
146
- module: 'ESNext',
145
+ target: 'ESNext',
146
+ module: 'ESNext',
147
147
  moduleResolution: 'bundler',
148
- strict: true,
149
- skipLibCheck: true,
150
- allowJs: true,
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
 
@@ -209,15 +209,68 @@ module Stipa
209
209
  res.render(template, locals: locals, layout: layout)
210
210
  end
211
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
+
212
231
  def redirect_to(path, status: 302)
213
232
  res.status = status
214
233
  res['Location'] = path
215
234
  res.body = ''
216
235
  end
217
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
+
218
251
  def not_found!(message = 'Not Found')
219
- res.status = 404
220
- res.body = message
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 })
221
274
  throw :halt
222
275
  end
223
276
 
@@ -237,6 +290,8 @@ module Stipa
237
290
  k, v = pair.split('=', 2)
238
291
  p[k.to_sym] = URI.decode_www_form_component(v.to_s)
239
292
  end
293
+ elsif req['content-type']&.include?('application/json')
294
+ JSON.parse(req.body).each { |k, v| p[k.to_sym] = v }
240
295
  end
241
296
 
242
297
  p
@@ -423,8 +478,6 @@ module Stipa
423
478
  CSS
424
479
  end
425
480
 
426
-
427
-
428
481
  def t_shims_vue
429
482
  <<~TS
430
483
  declare module '*.vue' {
data/lib/stipa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Stipa
2
- VERSION = '0.2.3'
2
+ VERSION = '0.2.4'
3
3
  end
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.3
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-26 00:00:00.000000000 Z
11
+ date: 2026-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest