acrylic 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ffa3dcf17f46e9e75b17e95c9ca52b0e82dd7bed3ce4f637cbbab1032f97826b
4
- data.tar.gz: 5c4a8b1143cdb8c4d0a78287b2b60fde38873f5b7570b73e7fbe8227aceefe86
3
+ metadata.gz: 4a0411b437d94694ff9761a6f9466fa909d650eb933ecd5fc0b6438f66ff10fc
4
+ data.tar.gz: c04dd9a1311e53216b18600f0847dc6004895ae826daf36cea728ede98b59c70
5
5
  SHA512:
6
- metadata.gz: cec1122bf513bce029509915c01c649675c830bc23509a593389a92124266b5d4e2a7d0f8c4124cc25099986dc599f0dd83ad4cae195b8a1fc0f0055f7d5ce1b
7
- data.tar.gz: 9a3303e5e18660ffec7c13a484db93be42e6d4e37f345ef0cd5394fff2002ae0896678451da7247dc964a6e274116f241c32ece1e6cd5799b77d8e2a9266ff46
6
+ metadata.gz: 71b6752fa603ed57e4c2f30545456baf445a011a54d21b13c4223825b646d0e4c5fe2e0ef80a106eb6c1732611663e31b38c2b8e3fdcc8c0a69fd1723c1fe5b5
7
+ data.tar.gz: c7ebde805dd400055725b095ea7f1ce78e0ac6fafb03ec3904dcf8a777aadc3111d09e9a7d868623f377abf4387115fcc42af841386dfc936a34c47d3ed16750
data/lib/bits.rb CHANGED
@@ -2,6 +2,10 @@ class Object
2
2
  def containerize
3
3
  if self.is_a? Array then self else [self].compact end
4
4
  end
5
+
6
+ def fallback value
7
+ if nil? then value else self end
8
+ end
5
9
  end
6
10
 
7
11
  class Class
@@ -11,7 +15,7 @@ class Class
11
15
  end
12
16
 
13
17
  class Hash
14
- def self.from_keys keys
15
- keys.map do |k| [k, nil] end.to_h
18
+ def self.from_keys keys, value = nil
19
+ keys.map do |k| [k, value] end.to_h
16
20
  end
17
21
  end
@@ -4,6 +4,10 @@
4
4
  # response with an empty body.
5
5
  # to add content to this empty response, Cascade.error_page will
6
6
  # use a similar route definition system to regular Cascade routes to create error pages.
7
+ require 'markaby'
8
+ require 'rack/utils'
9
+
10
+ Rack::Utils::HTTP_STATUS_CODES[418] = "I'm a Teapot"
7
11
 
8
12
  module Acrylic
9
13
  ERROR_ROUTES = []
@@ -22,17 +26,65 @@ module Acrylic
22
26
  end
23
27
 
24
28
  class Cascade
25
- def default_error_body code, req
26
-
29
+ def self.default_error_body code, req
30
+ mab = Markaby::Builder.new
31
+
32
+ mab.html do
33
+ style <<-CSS
34
+ body,html { font-family:"arial"; background-color:#fed; height:100%; display:flex; justify-content:center; align-items:center }
35
+ .pane { padding:10px 20px; width:500px; background:#F004; border:5px solid #F006; border-radius:20px; position:absolute }
36
+ .pane .description { padding:10px; background-color:#FFF4; display:flex;gap:5px; flex-direction:column; }
37
+ .pane .description p { margin:0 }
38
+ CSS
39
+
40
+ meta charset: 'utf-8'
41
+ body do
42
+ div.pane do
43
+ p do
44
+ span code, style: "font-size: 5em"
45
+ sub do
46
+ span (Rack::Utils::HTTP_STATUS_CODES[code]&.downcase), style: "font-size: 2em"
47
+ end
48
+ end
49
+
50
+ div.description do
51
+ case code
52
+ when 400
53
+ p do "Your browser (or HTTP client) sent a request that completely bamboozled the server." end
54
+ p do "If you're a developer, please RTFM. If you're a user, please tell the developer to fix their app." end
55
+
56
+ when 403
57
+ p do "You are not allowed to access the resource at this address." end
58
+ p do "A solution would be to mind your own damn business." end
59
+
60
+ when 404
61
+ p do "You've stumbled on a path which maps to <em>nothing</em>." end
62
+ p do "If someone sent you here, please tell them to <strong>fix their hyperlinks</strong>." end
63
+
64
+ when 418
65
+ p do "You pathetic attempt at an HTTP Request was so humerous, it even made the server laugh." end
66
+
67
+ when 429
68
+ h1 do "IT'S TIME TO STOP." end
69
+ h1 do "IT'S TIME TO STOP, OKAY!???" end
70
+
71
+ else
72
+ p do "An error has occured. I have no idea what it is though. ¯\\_(ツ)_/¯" end
73
+ end
74
+ end
75
+
76
+ small style: "color: #844; font-weight: bold; padding-top: 20px" do
77
+ em "served by acrylic #{Acrylic::Version.version}"
78
+ end
79
+ end
80
+ end
81
+ end
27
82
  end
28
83
 
29
84
  # returns body of response.
30
- def error_body code, req
85
+ def self.error_body code, req
31
86
  route = ERROR_ROUTES.find do |route| route.match? code, req end
32
- body = if route.nil? then default_error_page code, req else route.call req end
33
-
34
- raise TypeError("return value of error_handler body must be a string") unless body.is_a? String
35
- body
87
+ if route.nil? then default_error_body code, req else route.call req end
36
88
  end
37
89
  end
38
90
  end
data/lib/cascade.rb CHANGED
@@ -41,7 +41,6 @@ module Acrylic
41
41
 
42
42
  class Cascade
43
43
  # returns a response based on the defined routes.
44
- # if the response is empty, it shall be passed through Cascade.ServeError
45
44
  def self.handle req
46
45
  headers = {}
47
46
 
@@ -51,9 +50,12 @@ module Acrylic
51
50
 
52
51
  res = route.call req
53
52
  res = case true
54
- when (res.nil?) then next
55
- when (res.is_a? String) then Rack::Response.new res
56
- when (res.is_a? Integer) then Rack::Response.new nil, res
53
+ when (res.is_a? Rack::Response) then res
54
+ when (res.respond_to? :to_h) then res.to_h
55
+ when (res.is_a? Integer) then Rack::Response.new nil, res
56
+ when (res.is_a? String) then Rack::Response.new res
57
+ when (res.nil?) then next
58
+ else raise TypeError
57
59
  end
58
60
 
59
61
  # if the returned route has a body, return it. else, add its headers to the existing response.
@@ -61,12 +63,12 @@ module Acrylic
61
63
  res.headers.merge! headers
62
64
  return res
63
65
  elsif res.is_a? Hash
64
- headers.merge! res.headers
66
+ headers.merge! res
65
67
  end
66
68
  end
67
69
 
68
70
  # if no route returned a response, return a 404
69
- return Rack::Response.new nil, 404
71
+ Rack::Response.new nil, 404, headers
70
72
  end
71
73
 
72
74
 
@@ -74,8 +76,17 @@ module Acrylic
74
76
  req = Rack::Request.new env
75
77
 
76
78
  res = handle req
77
- res.body = error_page res.status, req if res.body.nil?
78
- res
79
+ # apply a series of transformations to the response
80
+ # unfortunately since Response is immutable we have to make a copy
81
+ # 1. if res has an empty body, transform it into a full response with cascade/errors
82
+ # why rack uses a goddamn empty array instead of nil i have no clue of
83
+ # (it doesnt give a fuck about strings, but it TURNS NILS INTO ARRAYS!? WHY!? WHY!!!!!!?)
84
+ if res.body == [] then res.body = error_body res.status, req end
85
+
86
+ # 2. transform every header key of res into a string
87
+ headers = res.headers.map do |k, v| [k.to_s, v] end.to_h
88
+
89
+ Rack::Response.new res.body, res.status, headers
79
90
  end
80
91
  end
81
92
  end
data/lib/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Acrylic
2
2
  class Version
3
3
  MAJOR = 0
4
- MINOR = 1
4
+ MINOR = 2
5
5
  HOTFIX = 0
6
6
 
7
7
  def self.semver
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acrylic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - fmixolydian
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-12-14 00:00:00.000000000 Z
10
+ date: 2025-12-16 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rack
@@ -23,6 +23,26 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: '3.2'
26
+ - !ruby/object:Gem::Dependency
27
+ name: markaby
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.9'
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 0.9.4
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '0.9'
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 0.9.4
26
46
  description: |2
27
47
  Acrylic is a web framework that simplifies your life by automatically generating migrations,
28
48
  as well as providing several macros for repeating common operations (e.g. defining REST APIs).