raketa_admin 0.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a6f8663004f085cb88532d478ee4db2530e3e09064e4066aad8fe7fe9941e834
4
+ data.tar.gz: 665981fe49843b6adcfd20fd1cfcc6a974b04d4c3e92aa62999973d908b7724b
5
+ SHA512:
6
+ metadata.gz: c83edcaec34c54731d2cdcf3c1eb4dea1a555423b909df4159159264b41b3496f4cf3a69805288b06975c6f5f681971514d8b2314d8f48f0af595095d2ab7c60
7
+ data.tar.gz: 8a7889c5b3d5d5af3f7e696eb804fe3cf0831530998c7e2245484de102a6b9822f9e976043c4f1c58bca114ff6ed3c91fab893ff6f54fd29844388d157c4ab01
data/Gemfile ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ # We're requiring sinatra/base, rather than plain sinatra, since we're using the modular Sinatra style
7
+ gem 'sinatra', '~> 4.0', require: 'sinatra/base'
8
+
9
+ group :development do
10
+ gem 'bundler'
11
+ gem 'pry'
12
+ gem 'rack'
13
+ gem 'rackup'
14
+ gem 'rake'
15
+ gem 'rerun'
16
+ gem 'rubocop', require: false
17
+ gem 'rubocop-rake'
18
+ gem 'rubocop-rspec'
19
+ end
20
+
21
+ group :development, :test do
22
+ gem 'rack-test'
23
+ gem 'rspec'
24
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,134 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ raketa_admin (0.0.0)
5
+ sinatra (~> 4.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.2)
11
+ base64 (0.2.0)
12
+ coderay (1.1.3)
13
+ diff-lcs (1.5.1)
14
+ ffi (1.17.0)
15
+ ffi (1.17.0-aarch64-linux-gnu)
16
+ ffi (1.17.0-aarch64-linux-musl)
17
+ ffi (1.17.0-arm-linux-gnu)
18
+ ffi (1.17.0-arm-linux-musl)
19
+ ffi (1.17.0-arm64-darwin)
20
+ ffi (1.17.0-x86-linux-gnu)
21
+ ffi (1.17.0-x86-linux-musl)
22
+ ffi (1.17.0-x86_64-darwin)
23
+ ffi (1.17.0-x86_64-linux-gnu)
24
+ ffi (1.17.0-x86_64-linux-musl)
25
+ json (2.7.2)
26
+ language_server-protocol (3.17.0.3)
27
+ listen (3.9.0)
28
+ rb-fsevent (~> 0.10, >= 0.10.3)
29
+ rb-inotify (~> 0.9, >= 0.9.10)
30
+ method_source (1.1.0)
31
+ mustermann (3.0.0)
32
+ ruby2_keywords (~> 0.0.1)
33
+ parallel (1.25.1)
34
+ parser (3.3.3.0)
35
+ ast (~> 2.4.1)
36
+ racc
37
+ pry (0.14.2)
38
+ coderay (~> 1.1)
39
+ method_source (~> 1.0)
40
+ racc (1.8.0)
41
+ rack (3.1.3)
42
+ rack-protection (4.0.0)
43
+ base64 (>= 0.1.0)
44
+ rack (>= 3.0.0, < 4)
45
+ rack-session (2.0.0)
46
+ rack (>= 3.0.0)
47
+ rack-test (2.1.0)
48
+ rack (>= 1.3)
49
+ rackup (2.1.0)
50
+ rack (>= 3)
51
+ webrick (~> 1.8)
52
+ rainbow (3.1.1)
53
+ rake (13.2.1)
54
+ rb-fsevent (0.11.2)
55
+ rb-inotify (0.11.1)
56
+ ffi (~> 1.0)
57
+ regexp_parser (2.9.2)
58
+ rerun (0.14.0)
59
+ listen (~> 3.0)
60
+ rexml (3.3.0)
61
+ strscan
62
+ rspec (3.13.0)
63
+ rspec-core (~> 3.13.0)
64
+ rspec-expectations (~> 3.13.0)
65
+ rspec-mocks (~> 3.13.0)
66
+ rspec-core (3.13.0)
67
+ rspec-support (~> 3.13.0)
68
+ rspec-expectations (3.13.1)
69
+ diff-lcs (>= 1.2.0, < 2.0)
70
+ rspec-support (~> 3.13.0)
71
+ rspec-mocks (3.13.1)
72
+ diff-lcs (>= 1.2.0, < 2.0)
73
+ rspec-support (~> 3.13.0)
74
+ rspec-support (3.13.1)
75
+ rubocop (1.64.1)
76
+ json (~> 2.3)
77
+ language_server-protocol (>= 3.17.0)
78
+ parallel (~> 1.10)
79
+ parser (>= 3.3.0.2)
80
+ rainbow (>= 2.2.2, < 4.0)
81
+ regexp_parser (>= 1.8, < 3.0)
82
+ rexml (>= 3.2.5, < 4.0)
83
+ rubocop-ast (>= 1.31.1, < 2.0)
84
+ ruby-progressbar (~> 1.7)
85
+ unicode-display_width (>= 2.4.0, < 3.0)
86
+ rubocop-ast (1.31.3)
87
+ parser (>= 3.3.1.0)
88
+ rubocop-rake (0.6.0)
89
+ rubocop (~> 1.0)
90
+ rubocop-rspec (3.0.1)
91
+ rubocop (~> 1.61)
92
+ ruby-progressbar (1.13.0)
93
+ ruby2_keywords (0.0.5)
94
+ sinatra (4.0.0)
95
+ mustermann (~> 3.0)
96
+ rack (>= 3.0.0, < 4)
97
+ rack-protection (= 4.0.0)
98
+ rack-session (>= 2.0.0, < 3)
99
+ tilt (~> 2.0)
100
+ strscan (3.1.0)
101
+ tilt (2.3.0)
102
+ unicode-display_width (2.5.0)
103
+ webrick (1.8.1)
104
+
105
+ PLATFORMS
106
+ aarch64-linux-gnu
107
+ aarch64-linux-musl
108
+ arm-linux-gnu
109
+ arm-linux-musl
110
+ arm64-darwin
111
+ ruby
112
+ x86-linux-gnu
113
+ x86-linux-musl
114
+ x86_64-darwin
115
+ x86_64-linux-gnu
116
+ x86_64-linux-musl
117
+
118
+ DEPENDENCIES
119
+ bundler
120
+ pry
121
+ rack
122
+ rack-test
123
+ rackup
124
+ rake
125
+ raketa_admin!
126
+ rerun
127
+ rspec
128
+ rubocop
129
+ rubocop-rake
130
+ rubocop-rspec
131
+ sinatra (~> 4.0)
132
+
133
+ BUNDLED WITH
134
+ 2.5.11
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Raketa Admin
2
+
3
+ ## Setup and run for development
4
+
5
+ This is a [Ruby](https://www.ruby-lang.org/en/) and [Sinatra](https://sinatrarb.com) based application.
6
+ Dependencies are managed with [Bundler](https://bundler.io).
7
+
8
+ Make sure you have installed ruby (check `.tool-versions` for the required version, check [asdf](https://asdf-vm.com) for managing the versions)
9
+
10
+ ```shell
11
+ gem install sinatra
12
+ gem install bundler
13
+ ./run.sh
14
+ ```
15
+
16
+ `./run-pry.sh` will not reload the code on change but you can add `binding.pry` in the ruby code to debug something
17
+
18
+ ## Build and Use the gem
19
+
20
+ ### To build it
21
+
22
+ `gem build raketa_admin.gemspec`
23
+
24
+ ### To use it
25
+
26
+ `gem install ./raketa_admin-0.0.0.gem`
27
+
28
+ Make sure to point the gem
29
+
30
+ ```bash
31
+ bundle config set local.raketa_admin /Users/zi/raketa/raketa-admin-ruby
32
+ ```
33
+
34
+ ```ruby
35
+ require "raketa_admin"
36
+ ```
37
+
38
+ ## Code quality
39
+
40
+ - Run the tests with `bundle exec rspec`
41
+ - Run rubocop with `bundle exec rake rubocop`
@@ -0,0 +1,629 @@
1
+ /*
2
+ ! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com
3
+ */
4
+
5
+ /*
6
+ 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
7
+ 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
8
+ */
9
+
10
+ *,
11
+ ::before,
12
+ ::after {
13
+ box-sizing: border-box;
14
+ /* 1 */
15
+ border-width: 0;
16
+ /* 2 */
17
+ border-style: solid;
18
+ /* 2 */
19
+ border-color: #e5e7eb;
20
+ /* 2 */
21
+ }
22
+
23
+ ::before,
24
+ ::after {
25
+ --tw-content: '';
26
+ }
27
+
28
+ /*
29
+ 1. Use a consistent sensible line-height in all browsers.
30
+ 2. Prevent adjustments of font size after orientation changes in iOS.
31
+ 3. Use a more readable tab size.
32
+ 4. Use the user's configured `sans` font-family by default.
33
+ 5. Use the user's configured `sans` font-feature-settings by default.
34
+ 6. Use the user's configured `sans` font-variation-settings by default.
35
+ 7. Disable tap highlights on iOS
36
+ */
37
+
38
+ html,
39
+ :host {
40
+ line-height: 1.5;
41
+ /* 1 */
42
+ -webkit-text-size-adjust: 100%;
43
+ /* 2 */
44
+ -moz-tab-size: 4;
45
+ /* 3 */
46
+ -o-tab-size: 4;
47
+ tab-size: 4;
48
+ /* 3 */
49
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
50
+ /* 4 */
51
+ font-feature-settings: normal;
52
+ /* 5 */
53
+ font-variation-settings: normal;
54
+ /* 6 */
55
+ -webkit-tap-highlight-color: transparent;
56
+ /* 7 */
57
+ }
58
+
59
+ /*
60
+ 1. Remove the margin in all browsers.
61
+ 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
62
+ */
63
+
64
+ body {
65
+ margin: 0;
66
+ /* 1 */
67
+ line-height: inherit;
68
+ /* 2 */
69
+ }
70
+
71
+ /*
72
+ 1. Add the correct height in Firefox.
73
+ 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
74
+ 3. Ensure horizontal rules are visible by default.
75
+ */
76
+
77
+ hr {
78
+ height: 0;
79
+ /* 1 */
80
+ color: inherit;
81
+ /* 2 */
82
+ border-top-width: 1px;
83
+ /* 3 */
84
+ }
85
+
86
+ /*
87
+ Add the correct text decoration in Chrome, Edge, and Safari.
88
+ */
89
+
90
+ abbr:where([title]) {
91
+ -webkit-text-decoration: underline dotted;
92
+ text-decoration: underline dotted;
93
+ }
94
+
95
+ /*
96
+ Remove the default font size and weight for headings.
97
+ */
98
+
99
+ h1,
100
+ h2,
101
+ h3,
102
+ h4,
103
+ h5,
104
+ h6 {
105
+ font-size: inherit;
106
+ font-weight: inherit;
107
+ }
108
+
109
+ /*
110
+ Reset links to optimize for opt-in styling instead of opt-out.
111
+ */
112
+
113
+ a {
114
+ color: inherit;
115
+ text-decoration: inherit;
116
+ }
117
+
118
+ /*
119
+ Add the correct font weight in Edge and Safari.
120
+ */
121
+
122
+ b,
123
+ strong {
124
+ font-weight: bolder;
125
+ }
126
+
127
+ /*
128
+ 1. Use the user's configured `mono` font-family by default.
129
+ 2. Use the user's configured `mono` font-feature-settings by default.
130
+ 3. Use the user's configured `mono` font-variation-settings by default.
131
+ 4. Correct the odd `em` font sizing in all browsers.
132
+ */
133
+
134
+ code,
135
+ kbd,
136
+ samp,
137
+ pre {
138
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
139
+ /* 1 */
140
+ font-feature-settings: normal;
141
+ /* 2 */
142
+ font-variation-settings: normal;
143
+ /* 3 */
144
+ font-size: 1em;
145
+ /* 4 */
146
+ }
147
+
148
+ /*
149
+ Add the correct font size in all browsers.
150
+ */
151
+
152
+ small {
153
+ font-size: 80%;
154
+ }
155
+
156
+ /*
157
+ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
158
+ */
159
+
160
+ sub,
161
+ sup {
162
+ font-size: 75%;
163
+ line-height: 0;
164
+ position: relative;
165
+ vertical-align: baseline;
166
+ }
167
+
168
+ sub {
169
+ bottom: -0.25em;
170
+ }
171
+
172
+ sup {
173
+ top: -0.5em;
174
+ }
175
+
176
+ /*
177
+ 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
178
+ 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
179
+ 3. Remove gaps between table borders by default.
180
+ */
181
+
182
+ table {
183
+ text-indent: 0;
184
+ /* 1 */
185
+ border-color: inherit;
186
+ /* 2 */
187
+ border-collapse: collapse;
188
+ /* 3 */
189
+ }
190
+
191
+ /*
192
+ 1. Change the font styles in all browsers.
193
+ 2. Remove the margin in Firefox and Safari.
194
+ 3. Remove default padding in all browsers.
195
+ */
196
+
197
+ button,
198
+ input,
199
+ optgroup,
200
+ select,
201
+ textarea {
202
+ font-family: inherit;
203
+ /* 1 */
204
+ font-feature-settings: inherit;
205
+ /* 1 */
206
+ font-variation-settings: inherit;
207
+ /* 1 */
208
+ font-size: 100%;
209
+ /* 1 */
210
+ font-weight: inherit;
211
+ /* 1 */
212
+ line-height: inherit;
213
+ /* 1 */
214
+ letter-spacing: inherit;
215
+ /* 1 */
216
+ color: inherit;
217
+ /* 1 */
218
+ margin: 0;
219
+ /* 2 */
220
+ padding: 0;
221
+ /* 3 */
222
+ }
223
+
224
+ /*
225
+ Remove the inheritance of text transform in Edge and Firefox.
226
+ */
227
+
228
+ button,
229
+ select {
230
+ text-transform: none;
231
+ }
232
+
233
+ /*
234
+ 1. Correct the inability to style clickable types in iOS and Safari.
235
+ 2. Remove default button styles.
236
+ */
237
+
238
+ button,
239
+ input:where([type='button']),
240
+ input:where([type='reset']),
241
+ input:where([type='submit']) {
242
+ -webkit-appearance: button;
243
+ /* 1 */
244
+ background-color: transparent;
245
+ /* 2 */
246
+ background-image: none;
247
+ /* 2 */
248
+ }
249
+
250
+ /*
251
+ Use the modern Firefox focus style for all focusable elements.
252
+ */
253
+
254
+ :-moz-focusring {
255
+ outline: auto;
256
+ }
257
+
258
+ /*
259
+ Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
260
+ */
261
+
262
+ :-moz-ui-invalid {
263
+ box-shadow: none;
264
+ }
265
+
266
+ /*
267
+ Add the correct vertical alignment in Chrome and Firefox.
268
+ */
269
+
270
+ progress {
271
+ vertical-align: baseline;
272
+ }
273
+
274
+ /*
275
+ Correct the cursor style of increment and decrement buttons in Safari.
276
+ */
277
+
278
+ ::-webkit-inner-spin-button,
279
+ ::-webkit-outer-spin-button {
280
+ height: auto;
281
+ }
282
+
283
+ /*
284
+ 1. Correct the odd appearance in Chrome and Safari.
285
+ 2. Correct the outline style in Safari.
286
+ */
287
+
288
+ [type='search'] {
289
+ -webkit-appearance: textfield;
290
+ /* 1 */
291
+ outline-offset: -2px;
292
+ /* 2 */
293
+ }
294
+
295
+ /*
296
+ Remove the inner padding in Chrome and Safari on macOS.
297
+ */
298
+
299
+ ::-webkit-search-decoration {
300
+ -webkit-appearance: none;
301
+ }
302
+
303
+ /*
304
+ 1. Correct the inability to style clickable types in iOS and Safari.
305
+ 2. Change font properties to `inherit` in Safari.
306
+ */
307
+
308
+ ::-webkit-file-upload-button {
309
+ -webkit-appearance: button;
310
+ /* 1 */
311
+ font: inherit;
312
+ /* 2 */
313
+ }
314
+
315
+ /*
316
+ Add the correct display in Chrome and Safari.
317
+ */
318
+
319
+ summary {
320
+ display: list-item;
321
+ }
322
+
323
+ /*
324
+ Removes the default spacing and border for appropriate elements.
325
+ */
326
+
327
+ blockquote,
328
+ dl,
329
+ dd,
330
+ h1,
331
+ h2,
332
+ h3,
333
+ h4,
334
+ h5,
335
+ h6,
336
+ hr,
337
+ figure,
338
+ p,
339
+ pre {
340
+ margin: 0;
341
+ }
342
+
343
+ fieldset {
344
+ margin: 0;
345
+ padding: 0;
346
+ }
347
+
348
+ legend {
349
+ padding: 0;
350
+ }
351
+
352
+ ol,
353
+ ul,
354
+ menu {
355
+ list-style: none;
356
+ margin: 0;
357
+ padding: 0;
358
+ }
359
+
360
+ /*
361
+ Reset default styling for dialogs.
362
+ */
363
+
364
+ dialog {
365
+ padding: 0;
366
+ }
367
+
368
+ /*
369
+ Prevent resizing textareas horizontally by default.
370
+ */
371
+
372
+ textarea {
373
+ resize: vertical;
374
+ }
375
+
376
+ /*
377
+ 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
378
+ 2. Set the default placeholder color to the user's configured gray 400 color.
379
+ */
380
+
381
+ input::-moz-placeholder, textarea::-moz-placeholder {
382
+ opacity: 1;
383
+ /* 1 */
384
+ color: #9ca3af;
385
+ /* 2 */
386
+ }
387
+
388
+ input::placeholder,
389
+ textarea::placeholder {
390
+ opacity: 1;
391
+ /* 1 */
392
+ color: #9ca3af;
393
+ /* 2 */
394
+ }
395
+
396
+ /*
397
+ Set the default cursor for buttons.
398
+ */
399
+
400
+ button,
401
+ [role="button"] {
402
+ cursor: pointer;
403
+ }
404
+
405
+ /*
406
+ Make sure disabled buttons don't get the pointer cursor.
407
+ */
408
+
409
+ :disabled {
410
+ cursor: default;
411
+ }
412
+
413
+ /*
414
+ 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
415
+ 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
416
+ This can trigger a poorly considered lint error in some tools but is included by design.
417
+ */
418
+
419
+ img,
420
+ svg,
421
+ video,
422
+ canvas,
423
+ audio,
424
+ iframe,
425
+ embed,
426
+ object {
427
+ display: block;
428
+ /* 1 */
429
+ vertical-align: middle;
430
+ /* 2 */
431
+ }
432
+
433
+ /*
434
+ Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
435
+ */
436
+
437
+ img,
438
+ video {
439
+ max-width: 100%;
440
+ height: auto;
441
+ }
442
+
443
+ /* Make elements with the HTML hidden attribute stay hidden by default */
444
+
445
+ [hidden] {
446
+ display: none;
447
+ }
448
+
449
+ *, ::before, ::after {
450
+ --tw-border-spacing-x: 0;
451
+ --tw-border-spacing-y: 0;
452
+ --tw-translate-x: 0;
453
+ --tw-translate-y: 0;
454
+ --tw-rotate: 0;
455
+ --tw-skew-x: 0;
456
+ --tw-skew-y: 0;
457
+ --tw-scale-x: 1;
458
+ --tw-scale-y: 1;
459
+ --tw-pan-x: ;
460
+ --tw-pan-y: ;
461
+ --tw-pinch-zoom: ;
462
+ --tw-scroll-snap-strictness: proximity;
463
+ --tw-gradient-from-position: ;
464
+ --tw-gradient-via-position: ;
465
+ --tw-gradient-to-position: ;
466
+ --tw-ordinal: ;
467
+ --tw-slashed-zero: ;
468
+ --tw-numeric-figure: ;
469
+ --tw-numeric-spacing: ;
470
+ --tw-numeric-fraction: ;
471
+ --tw-ring-inset: ;
472
+ --tw-ring-offset-width: 0px;
473
+ --tw-ring-offset-color: #fff;
474
+ --tw-ring-color: rgb(59 130 246 / 0.5);
475
+ --tw-ring-offset-shadow: 0 0 #0000;
476
+ --tw-ring-shadow: 0 0 #0000;
477
+ --tw-shadow: 0 0 #0000;
478
+ --tw-shadow-colored: 0 0 #0000;
479
+ --tw-blur: ;
480
+ --tw-brightness: ;
481
+ --tw-contrast: ;
482
+ --tw-grayscale: ;
483
+ --tw-hue-rotate: ;
484
+ --tw-invert: ;
485
+ --tw-saturate: ;
486
+ --tw-sepia: ;
487
+ --tw-drop-shadow: ;
488
+ --tw-backdrop-blur: ;
489
+ --tw-backdrop-brightness: ;
490
+ --tw-backdrop-contrast: ;
491
+ --tw-backdrop-grayscale: ;
492
+ --tw-backdrop-hue-rotate: ;
493
+ --tw-backdrop-invert: ;
494
+ --tw-backdrop-opacity: ;
495
+ --tw-backdrop-saturate: ;
496
+ --tw-backdrop-sepia: ;
497
+ --tw-contain-size: ;
498
+ --tw-contain-layout: ;
499
+ --tw-contain-paint: ;
500
+ --tw-contain-style: ;
501
+ }
502
+
503
+ ::backdrop {
504
+ --tw-border-spacing-x: 0;
505
+ --tw-border-spacing-y: 0;
506
+ --tw-translate-x: 0;
507
+ --tw-translate-y: 0;
508
+ --tw-rotate: 0;
509
+ --tw-skew-x: 0;
510
+ --tw-skew-y: 0;
511
+ --tw-scale-x: 1;
512
+ --tw-scale-y: 1;
513
+ --tw-pan-x: ;
514
+ --tw-pan-y: ;
515
+ --tw-pinch-zoom: ;
516
+ --tw-scroll-snap-strictness: proximity;
517
+ --tw-gradient-from-position: ;
518
+ --tw-gradient-via-position: ;
519
+ --tw-gradient-to-position: ;
520
+ --tw-ordinal: ;
521
+ --tw-slashed-zero: ;
522
+ --tw-numeric-figure: ;
523
+ --tw-numeric-spacing: ;
524
+ --tw-numeric-fraction: ;
525
+ --tw-ring-inset: ;
526
+ --tw-ring-offset-width: 0px;
527
+ --tw-ring-offset-color: #fff;
528
+ --tw-ring-color: rgb(59 130 246 / 0.5);
529
+ --tw-ring-offset-shadow: 0 0 #0000;
530
+ --tw-ring-shadow: 0 0 #0000;
531
+ --tw-shadow: 0 0 #0000;
532
+ --tw-shadow-colored: 0 0 #0000;
533
+ --tw-blur: ;
534
+ --tw-brightness: ;
535
+ --tw-contrast: ;
536
+ --tw-grayscale: ;
537
+ --tw-hue-rotate: ;
538
+ --tw-invert: ;
539
+ --tw-saturate: ;
540
+ --tw-sepia: ;
541
+ --tw-drop-shadow: ;
542
+ --tw-backdrop-blur: ;
543
+ --tw-backdrop-brightness: ;
544
+ --tw-backdrop-contrast: ;
545
+ --tw-backdrop-grayscale: ;
546
+ --tw-backdrop-hue-rotate: ;
547
+ --tw-backdrop-invert: ;
548
+ --tw-backdrop-opacity: ;
549
+ --tw-backdrop-saturate: ;
550
+ --tw-backdrop-sepia: ;
551
+ --tw-contain-size: ;
552
+ --tw-contain-layout: ;
553
+ --tw-contain-paint: ;
554
+ --tw-contain-style: ;
555
+ }
556
+
557
+ .h1 {
558
+ font-family: Montserrat, sans-serif;
559
+ font-size: 36px;
560
+ font-weight: 600;
561
+ line-height: 1.3;
562
+ --tw-text-opacity: 1;
563
+ color: rgb(153 27 27 / var(--tw-text-opacity));
564
+ }
565
+
566
+ @media (min-width: 1024px) {
567
+ .h1 {
568
+ font-size: 52px;
569
+ }
570
+ }
571
+
572
+ .h2 {
573
+ font-family: Montserrat, sans-serif;
574
+ font-size: 32px;
575
+ font-weight: 600;
576
+ line-height: 1.1;
577
+ --tw-text-opacity: 1;
578
+ color: rgb(21 128 61 / var(--tw-text-opacity));
579
+ }
580
+
581
+ @media (min-width: 1024px) {
582
+ .h2 {
583
+ font-size: 44px;
584
+ }
585
+ }
586
+
587
+ .font-headline {
588
+ font-family: Montserrat, sans-serif;
589
+ }
590
+
591
+ .text-\[32px\] {
592
+ font-size: 32px;
593
+ }
594
+
595
+ .text-\[36px\] {
596
+ font-size: 36px;
597
+ }
598
+
599
+ .font-semibold {
600
+ font-weight: 600;
601
+ }
602
+
603
+ .leading-\[1\.1\] {
604
+ line-height: 1.1;
605
+ }
606
+
607
+ .leading-\[1\.3\] {
608
+ line-height: 1.3;
609
+ }
610
+
611
+ .text-green-700 {
612
+ --tw-text-opacity: 1;
613
+ color: rgb(21 128 61 / var(--tw-text-opacity));
614
+ }
615
+
616
+ .text-red-800 {
617
+ --tw-text-opacity: 1;
618
+ color: rgb(153 27 27 / var(--tw-text-opacity));
619
+ }
620
+
621
+ @media (min-width: 1024px) {
622
+ .lg\:text-\[44px\] {
623
+ font-size: 44px;
624
+ }
625
+
626
+ .lg\:text-\[52px\] {
627
+ font-size: 52px;
628
+ }
629
+ }
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helpers/link_helper'
4
+
5
+ module RaketaAdmin
6
+ module Handlers
7
+ class Handler
8
+ extend RaketaAdmin::Helpers::LinkHelper
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../raketa_context'
4
+
5
+ module RaketaAdmin
6
+ module Handlers
7
+ module RedirectsHandler
8
+ def self.type
9
+ 'redirects'
10
+ end
11
+
12
+ def self.before_filter(_ctx, action)
13
+ filters = []
14
+
15
+ # Add a filter to check for the bearer token and set ctx.authenticated
16
+ filters << lambda { |ctx|
17
+ if ctx.headers['HTTP_AUTHORIZATION'] && ctx.headers['HTTP_AUTHORIZATION'].start_with?('Bearer ')
18
+ ctx.assigns[:authenticated] = true
19
+ end
20
+ }
21
+
22
+ # Add a filter to check for cookies, only for index and update actions
23
+ if %i[index update].include?(action)
24
+ filters << lambda { |ctx|
25
+ ctx.assigns[:has_cookies] = !ctx.cookies.empty?
26
+ }
27
+ end
28
+
29
+ filters
30
+ end
31
+
32
+ def self.after_filter(_ctx, action)
33
+ [
34
+ lambda { |_ctx|
35
+ puts "After filter for #{action}"
36
+ { assigns: { after_action: true } }
37
+ }
38
+ ]
39
+ end
40
+
41
+ def self.index(_ctx)
42
+ # ctx.params[:page] ||= 1
43
+ items = [{ name: 'google', location: 'google.com' }, { name: 'google2', location: 'google.com' }]
44
+
45
+ {
46
+ assigns: { items: }
47
+ }
48
+ end
49
+
50
+ def self.show(_ctx)
51
+ item = { name: 'google', location: 'google.com' }
52
+
53
+ {
54
+ assigns: { item: }
55
+ }
56
+ end
57
+
58
+ def self.create_form(_ctx)
59
+ defaults = { name: '', location: '' }
60
+ placeholders = { name: 'Enter name', location: 'Enter url' }
61
+
62
+ {
63
+ assigns: { defaults:, placeholders: }
64
+ }
65
+ end
66
+
67
+ def self.edit_form(_ctx)
68
+ item = { name: 'google', location: 'google.com' }
69
+
70
+ {
71
+ assigns: { item: }
72
+ }
73
+ end
74
+
75
+ def self.create(ctx)
76
+ created = { name: 'New', location: 'location' }
77
+ ctx.paths.link(ctx.resource_name, ctx.action)
78
+
79
+ {
80
+ redirect: ctx.paths.link(ctx.resource_name, :index),
81
+ assigns: { item: created }
82
+ }
83
+ end
84
+
85
+ def self.update(ctx)
86
+ updated = { name: 'Updated', location: 'location' }
87
+ ctx.paths.link(ctx.resource_name, ctx.action)
88
+
89
+ {
90
+ redirect: ctx.paths.link(ctx.resource_name, :index),
91
+ assigns: { item: updated }
92
+ }
93
+ end
94
+
95
+ def self.destroy(ctx)
96
+ {
97
+ redirect: ctx.paths.link(ctx.resource_name, :index)
98
+ }
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RaketaAdmin
4
+ module Helpers
5
+ module LinkHelper
6
+ def self.link(resource, action, id = nil)
7
+ case action
8
+ when :index then "/#{resource}"
9
+ when :new then "/#{resources}/new"
10
+ when :show then "/#{resource}/#{id}"
11
+ when :edit then "/#{resource}/#{id}/edit"
12
+
13
+ else raise 'Undefined link location'
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sinatra/base'
4
+ require_relative 'helpers/link_helper'
5
+
6
+ module RaketaAdmin
7
+ class RaketaContext
8
+ attr_reader :resource_name, :params, :request, :response, :parent_resource, :assigns, :halted
9
+
10
+ def initialize(resource_name, params, request, response, parent_resource = nil)
11
+ @resource_name = resource_name
12
+ @params = params
13
+ @request = request
14
+ @response = response
15
+ @parent_resource = parent_resource
16
+ @halted = false
17
+ @assigns = {}
18
+ end
19
+
20
+ def halt
21
+ @halted = true
22
+ end
23
+
24
+ def redirect(url)
25
+ @redirect_url = url
26
+ halt
27
+ end
28
+
29
+ def redirected?
30
+ !!@redirect_url
31
+ end
32
+
33
+ def paths
34
+ # TBD: An interface to get link to resource and method
35
+ RaketaAdmin::Helpers::LinkHelper
36
+ end
37
+
38
+ def request_method
39
+ request.request_method
40
+ end
41
+
42
+ def url_params
43
+ params.reject { |k, v| get_params[k] == v }
44
+ end
45
+
46
+ # rubocop:disable Naming/AccessorMethodName
47
+ def get_params
48
+ request.GET
49
+ end
50
+ # rubocop:enable Naming/AccessorMethodName
51
+
52
+ def request_body
53
+ request.body&.read || ''
54
+ end
55
+
56
+ def headers
57
+ request.env.select { |k, _v| k.start_with?('HTTP_') }
58
+ end
59
+
60
+ def cookies
61
+ request.cookies
62
+ end
63
+
64
+ def raw_request
65
+ request
66
+ end
67
+
68
+ def raw_response
69
+ response
70
+ end
71
+
72
+ # Raw router library access
73
+ def raw_router
74
+ Sinatra::Base
75
+ end
76
+
77
+ # This is just for easy view of the context!
78
+ def to_h
79
+ {
80
+ resource_name:,
81
+ params:,
82
+ request_method:,
83
+ url_params:,
84
+ get_params:,
85
+ request_body:,
86
+ parent_resource:,
87
+ halted:,
88
+ assigns:,
89
+ paths:,
90
+ headers:,
91
+ cookies:
92
+ }
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RaketaAdmin
4
+ module ResourceBuilder
5
+ def create_resource(routing_adapter, resource, handler)
6
+ routing_adapter.generate_routes(self, resource, handler)
7
+ end
8
+
9
+ def create_nested_resource(routing_adapter, parent, resource, handler)
10
+ routing_adapter.generate_routes(self, resource, handler, parent)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sinatra/base'
4
+ require_relative 'raketa_context'
5
+
6
+ class String
7
+ def singularize
8
+ return self if empty?
9
+
10
+ case self
11
+ when /(s|x|z|ch|sh)es$/ then self[0..-3]
12
+ when /ies$/ then "#{self[0..-4]}y"
13
+ when /ves$/ then "#{self[0..-4]}f"
14
+ when /s$/ then self[0..-2]
15
+ else self
16
+ end
17
+ end
18
+ end
19
+
20
+ module RaketaAdmin
21
+ class SinatraAdapter
22
+ def self.generate_routes(app, resource, handler, parent = nil)
23
+ router = new(app, resource, handler, parent)
24
+ router.generate_routes
25
+ end
26
+
27
+ attr_reader :resource, :handler, :parent, :app
28
+
29
+ def initialize(app, resource, handler, parent = nil)
30
+ @app = app
31
+ @resource = resource
32
+ @handler = handler
33
+ @parent = parent
34
+ end
35
+
36
+ def resource_path(action)
37
+ return resource unless parent
38
+
39
+ %i[index new create].include?(action) ? "#{parent}/:#{parent.singularize}_id/#{resource}" : resource
40
+ end
41
+
42
+ def generate_routes
43
+ define_route('GET', resource_path(:index), :index)
44
+ define_route('GET', "#{resource_path(:new)}/new", :create_form)
45
+ define_route('GET', "#{resource_path(:show)}/:id", :show)
46
+ define_route('GET', "#{resource_path(:edit)}/:id/edit", :edit_form)
47
+ define_route('POST', resource_path(:create), :create)
48
+ define_route('PUT', "#{resource_path(:update)}/:id", :update)
49
+ define_route('DELETE', "#{resource_path(:delete)}/:id", :destroy)
50
+ end
51
+
52
+ def define_route(http_method, path, action)
53
+ # Action methods are defined on the "app" and the self changes inside the blocks.
54
+ # Let's keep a reference to the router
55
+ router = self
56
+
57
+ app.send(http_method.downcase, "/#{path}") do
58
+ @ctx = RaketaContext.new(router.resource, params, request, response, router.parent)
59
+ router.process_filters(@ctx, :before, action)
60
+ result = router.handler.send(action, @ctx)
61
+ router.process_filters(@ctx, :after, action)
62
+
63
+ if result[:redirect]
64
+ redirect result[:redirect]
65
+ else
66
+ erb :"#{router.handler.type}/#{action}", layout: :base_layout
67
+ end
68
+ end
69
+ end
70
+
71
+ def process_filters(ctx, filter_type, action)
72
+ filters = handler.send("#{filter_type}_filter", ctx, action)
73
+ filters.each do |filter|
74
+ result = filter.call(ctx)
75
+ halt 302, { 'Location' => result[:redirect] } if result.is_a?(Hash) && result[:redirect]
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sinatra/base'
4
+ require_relative 'raketa_admin/resource_builder'
5
+ require_relative 'raketa_admin/sinatra_adapter'
6
+ require_relative 'raketa_admin/handlers/redirects_handler'
7
+
8
+ class RaketaAdminApp < Sinatra::Base
9
+ register RaketaAdmin::ResourceBuilder
10
+
11
+ set :root, File.dirname(__FILE__)
12
+ set :views, proc { File.join(root, 'raketa_admin', 'views') }
13
+ set :public_folder, File.join(root, 'public')
14
+
15
+ get '/' do
16
+ 'Wellcome to the Raketa admin'
17
+ end
18
+
19
+ create_resource RaketaAdmin::SinatraAdapter, 'redirects', RaketaAdmin::Handlers::RedirectsHandler
20
+ create_resource RaketaAdmin::SinatraAdapter, 'posts', RaketaAdmin::Handlers::RedirectsHandler
21
+ create_nested_resource RaketaAdmin::SinatraAdapter, 'posts', 'comments', RaketaAdmin::Handlers::RedirectsHandler
22
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: raketa_admin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Studio Raketa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-07-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ description: ''
28
+ email: zvezdalina.dimitrova@raketadesign.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - Gemfile
34
+ - Gemfile.lock
35
+ - README.md
36
+ - lib/public/styles.css
37
+ - lib/raketa_admin.rb
38
+ - lib/raketa_admin/handlers/handler.rb
39
+ - lib/raketa_admin/handlers/redirects_handler.rb
40
+ - lib/raketa_admin/helpers/link_helper.rb
41
+ - lib/raketa_admin/raketa_context.rb
42
+ - lib/raketa_admin/resource_builder.rb
43
+ - lib/raketa_admin/sinatra_adapter.rb
44
+ homepage: https://rubygems.org/gems/raketa_admin
45
+ licenses:
46
+ - MIT
47
+ metadata:
48
+ rubygems_mfa_required: 'true'
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '='
56
+ - !ruby/object:Gem::Version
57
+ version: 3.2.2
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 3.5.13
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: ''
68
+ test_files: []