syntropy 0.11 → 0.13

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: 6f33d7721410d70a9d5b86977c73b36f6a410a6534c253269df5f2d47123a54f
4
- data.tar.gz: 6f961a74dd9fa299296d6699244076dfc09fa3697faad7c28cc6c2db81f5fb46
3
+ metadata.gz: a4c3c2fbefeef68829e103cde25cc9d82d5b4199da47dc58162d3d4d017a2727
4
+ data.tar.gz: fb634fd50a87d5ecc61e3f1a4f55df95f7bd451079852ecae74ce92142819c3a
5
5
  SHA512:
6
- metadata.gz: 158e46fd1e09da1af72a5ffd50a1ccde7699ce52f9a9d7a317903e3aa29234a5f924371712571b4d0188bcc5e7484b7bced4be7ee7440140ba5cfb07b492bccf
7
- data.tar.gz: 6a45ef64e1ef65cf5c86c15dd5858a3f028343c55f68be253d07626800c4f534782898e4e7d83697fb324b4169050ce913a911575d31936c5a852e12f0eb4be0
6
+ metadata.gz: 33a01aa5a0fb645fe5d16638066c2e3d5d6b26429376469a22ef8f8e06d5b9ea18ca9b5d36a728e10f4440413e683e4d0fbbb7a936fab1214b1acdc9bb83d07e
7
+ data.tar.gz: 6a3066395aa7573fc87ec15cd76d83a38995b9d6ac37b22fdd1743662ac7d37861f8d111e5c03cf0c3f49a79ac4f42f3a9cbd0f1d0fc6006652969a7f5411406
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 0.13 2025-08-28
2
+
3
+ - Reimplement module loading
4
+ - Refactor RoutingTree
5
+
6
+ # 0.12 2025-08-28
7
+
8
+ - Add routing info to request: `#route`, `#route_params`
9
+ - Improve validations
10
+ - Improve errors
11
+ - Reimplement `App`
12
+ - Add support for parametric routes
13
+ - Reimplement `RoutingTree` (was `Router`)
14
+
1
15
  ## 0.11 2025-08-17
2
16
 
3
17
  - Upgrade to P2 2.8
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ end
10
10
  task :release do
11
11
  require_relative './lib/syntropy/version'
12
12
  version = Syntropy::VERSION
13
-
13
+
14
14
  puts 'Building syntropy...'
15
15
  `gem build syntropy.gemspec`
16
16
 
data/TODO.md CHANGED
@@ -1,137 +1,187 @@
1
- - a way to inject cookies into the response
2
-
3
- - add support for applets
4
-
5
- - can be implemented as separate gems
6
- - can route requests to a different directory (i.e. inside the gem directory)
7
- - simple way to instantiate and setup the applet
8
- - as a first example, implement an auth/signin applet:
9
- - session hook
10
- - session persistence
11
- - login page
12
- - support for custom behaviour and custom workflows (2FA, signin using OTP etc.)
13
-
14
- - Some standard middleware:
15
-
16
- - request rewriter
17
- - logger
18
- - auth
19
- - selector + terminator
20
-
21
- ```Ruby
22
- # For the chainable DSL shown below, we need to create a custom class:
23
- class Syntropy::Middleware::Selector
24
- def initialize(select_proc, terminator_proc = nil)
25
- @select_proc = select_proc
26
- @terminator_proc = terminator_proc
27
- end
28
-
29
- def to_proc
30
- ->(req, proc) {
31
- @select_proc.(req) ? @terminator_proc.(req) : proc(req)
32
- }
33
- end
34
-
35
- def terminate(&proc)
36
- @terminator_proc = proc
37
- end
1
+ - [ ] Improve serving of static files:
2
+ - [ ] support for compression
3
+ - [ ] support for caching headers
4
+ - [ ] add `Request#render_static_file(route, fn)
5
+
6
+ ## Support for applets
7
+
8
+ - can be implemented as separate gems
9
+ - can route requests to a different directory (i.e. inside the gem directory)
10
+ - simple way to instantiate and setup the applet
11
+ - as a first example, implement an auth/signin applet:
12
+ - session hook
13
+ - session persistence
14
+ - login page
15
+ - support for custom behaviour and custom workflows (2FA, signin using OTP etc.)
16
+
17
+ Example usage:
18
+
19
+ ```ruby
20
+ # /admin+.rb
21
+ require 'syntropy/admin'
22
+
23
+ export Syntropy::Admin.new(@ref, @env)
24
+ ```
25
+
26
+ Implementation:
27
+
28
+ ```ruby
29
+ # syntropy-admin/lib/syntropy/admin.rb
30
+ APP_ROOT = File.expand_path(File.join(__dir__, '../../app'))
31
+
32
+ class Syntropy::Admin < Syntropy::App
33
+ def new(mount_path, env)
34
+ super(env[:machine], APP_ROOT, mount_path, env)
38
35
  end
36
+ end
37
+ ```
38
+
39
+ ## Response: cookies and headers
40
+
41
+ We need a way to inject cookies into the response. This probably should be done
42
+ in the TP2 code:
43
+
44
+ ```ruby
45
+ @@default_set_cookie_attr = 'HttpOnly'
46
+ def self.default_set_cookie_attr=(v)
47
+ @@default_set_cookie_attr = v
48
+ end
49
+
50
+ def set_cookie(key, value, attr = @@default_set_cookie_attr)
51
+ @buffered_headers ||= +''
52
+ @buffered_headers << format(
53
+ "Set-Cookie: %<key>s=%<value>s; %<attr>s\n",
54
+ key:, value:, attr:
55
+ )
56
+ end
39
57
 
40
- def Syntropy
41
- ```
42
-
43
- ```Ruby
44
- # a _site.rb file can be used to wrap a whole app
45
- # site/_site.rb
46
-
47
- # this means we route according to the host header, with each
48
- export Syntropy.route_by_host
49
-
50
- # we can also rewrite requests:
51
- rewriter = Syntropy
52
- .select { it.host =~ /^tolkora\.(org|com)$/ }
53
- .terminate { it.redirect_permanent('https://tolkora.net') }
54
-
55
- # This is actuall a pretty interesting DSL design:
56
- # a chain of operations that compose functions. So, we can select a
57
- export rewriter.wrap(default_app)
58
-
59
- # composing
60
- export rewriter.wrap(Syntropy.some_custom_app.wrap(app))
61
-
62
- # or maybe
63
- export rewriter << some_other_middleware << app
64
- ```
65
-
66
-
67
-
68
-
69
- - CLI tool for setting up a site repo:
70
-
71
- ```bash
72
- # clone a newly created repo
73
- ~/repo$ git clone https://github.com/foo/bar
74
- ...
75
- ~/repo$ syntropy setup bar
76
-
77
- (syntropy banner)
78
-
79
- Setting up Syntropy project in /home/sharon/repo/bar:
80
-
81
- bar/
82
- bin/
83
- start
84
- stop
85
- restart
86
- console
87
- server
88
- docker-compose.yml
89
- Dockerfile
90
- Gemfile
91
- proxy/
92
-
93
- README.md
94
- site/
95
- _layout/
96
- default.rb
97
- _lib/
98
- about.md
99
- articles/
100
- long-form.md
101
- assets/
102
- js/
103
- css/
104
- style.css
105
- img/
106
- syntropy.png
107
- index.rb
108
- ```
109
-
110
- - Some of the files might need templating, but we can maybe do without, or at
111
- least make it as generic as possible.
112
-
113
- - `syntropy setup` steps:
114
-
115
- 1. Verify existence of target directory
116
- 2. Copy files from Syntropy template to target directory
117
- 3. Do chmod +x for bin/*
118
- 4. Do bundle install in the target directory
119
- 5. Show some information with regard to how to get started working with the
120
- repo
121
-
122
- - `syntropy provision` steps:
123
-
124
- 1. Verify Ubuntu 22.x or higher
125
- 2. Install git, docker, docker-compose
126
-
127
- - `syntropy deploy` steps:
128
-
129
- 1. Verify no uncommitted changes.
130
- 2. SSH to remote machine.
131
- 2.1. If not exists, clone repo
132
- 2.2. Otherwise, verify remote machine repo is on same branch as local repo
133
- 2.3. Do a git pull (what about credentials?)
134
- 2.4. If gem bundle has changed, do a docker compose build
135
- 2.5. If docker compose services are running, restart
136
- 2.6. Otherwise, start services
137
- 2.7. Verify service is running correctly
58
+ def set_headers(headers)
59
+ @buffered_headers ||= +''
60
+ @buffered_headers << format_headers(headers)
61
+ end
62
+
63
+ ...
64
+
65
+ req.set_cookie('at', 'foobar', 'SameSite=none; Secure; HttpOnly')
66
+ ```
67
+
68
+ ## Middleware
69
+
70
+ Some standard middleware:
71
+
72
+ - request rewriter
73
+ - logger
74
+ - auth
75
+ - selector + terminator
76
+
77
+ ```Ruby
78
+ # For the chainable DSL shown below, we need to create a custom class:
79
+ class Syntropy::Middleware::Selector
80
+ def initialize(select_proc, terminator_proc = nil)
81
+ @select_proc = select_proc
82
+ @terminator_proc = terminator_proc
83
+ end
84
+
85
+ def to_proc
86
+ ->(req, proc) {
87
+ @select_proc.(req) ? @terminator_proc.(req) : proc(req)
88
+ }
89
+ end
90
+
91
+ def terminate(&proc)
92
+ @terminator_proc = proc
93
+ end
94
+ end
95
+ ```
96
+
97
+ ```Ruby
98
+ # a _site.rb file can be used to wrap a whole app
99
+ # site/_site.rb
100
+
101
+ # this means we route according to the host header, with each
102
+ export Syntropy.route_by_host
103
+
104
+ # we can also rewrite requests:
105
+ rewriter = Syntropy
106
+ .select { it.host =~ /^tolkora\.(org|com)$/ }
107
+ .terminate { it.redirect_permanent('https://tolkora.net') }
108
+
109
+ # This is actuall a pretty interesting DSL design:
110
+ # a chain of operations that compose functions. So, we can select a
111
+ export rewriter.wrap(default_app)
112
+
113
+ # composing
114
+ export rewriter.wrap(Syntropy.some_custom_app.wrap(app))
115
+
116
+ # or maybe
117
+ export rewriter << some_other_middleware << app
118
+ ```
119
+
120
+ ## CLI tool for setting up a site repo:
121
+
122
+ ```bash
123
+ # clone a newly created repo
124
+ ~/repo$ git clone https://github.com/foo/bar
125
+ ...
126
+ ~/repo$ syntropy setup bar
127
+
128
+ (syntropy banner)
129
+
130
+ Setting up Syntropy project in /home/sharon/repo/bar:
131
+
132
+ bar/
133
+ bin/
134
+ start
135
+ stop
136
+ restart
137
+ console
138
+ server
139
+ docker-compose.yml
140
+ Dockerfile
141
+ Gemfile
142
+ proxy/
143
+ README.md
144
+ site/
145
+ _layout/
146
+ default.rb
147
+ _lib/
148
+ about.md
149
+ articles/
150
+ long-form.md
151
+ assets/
152
+ js/
153
+ css/
154
+ style.css
155
+ img/
156
+ syntropy.png
157
+ index.rb
158
+ ```
159
+
160
+ Some of the files might need templating, but we can maybe do without, or at
161
+ least make it as generic as possible.
162
+
163
+ `syntropy setup` steps:
164
+
165
+ 1. Verify existence of target directory
166
+ 2. Copy files from Syntropy template to target directory
167
+ 3. Do chmod +x for bin/*
168
+ 4. Do bundle install in the target directory
169
+ 5. Show some information with regard to how to get started working with the
170
+ repo
171
+
172
+ `syntropy provision` steps:
173
+
174
+ 1. Verify Ubuntu 22.x or higher
175
+ 2. Install git, docker, docker-compose
176
+
177
+ `syntropy deploy` steps:
178
+
179
+ 1. Verify no uncommitted changes.
180
+ 2. SSH to remote machine.
181
+ 2.1. If not exists, clone repo
182
+ 2.2. Otherwise, verify remote machine repo is on same branch as local repo
183
+ 2.3. Do a git pull (what about credentials?)
184
+ 2.4. If gem bundle has changed, do a docker compose build
185
+ 2.5. If docker compose services are running, restart
186
+ 2.6. Otherwise, start services
187
+ 2.7. Verify service is running correctly
data/bin/syntropy CHANGED
@@ -5,6 +5,7 @@ require 'syntropy'
5
5
  require 'optparse'
6
6
 
7
7
  opts = {
8
+ mount_path: '/',
8
9
  banner: Syntropy::BANNER,
9
10
  logger: true
10
11
  }
@@ -32,6 +33,10 @@ parser = OptionParser.new do |o|
32
33
  exit
33
34
  end
34
35
 
36
+ o.on('-m', '--mount', 'Set mount path (default: /)') do
37
+ opts[:mount_path] = it
38
+ end
39
+
35
40
  o.on('-v', '--version', 'Show version') do
36
41
  require 'syntropy/version'
37
42
  puts "Syntropy version #{Syntropy::VERSION}"
@@ -49,10 +54,10 @@ rescue StandardError => e
49
54
  exit
50
55
  end
51
56
 
52
- opts[:location] = ARGV.shift || '.'
57
+ opts[:root_dir] = ARGV.shift || '.'
53
58
 
54
- if !File.directory?(opts[:location])
55
- puts "#{File.expand_path(opts[:location])} Not a directory"
59
+ if !File.directory?(opts[:root_dir])
60
+ puts "#{File.expand_path(opts[:root_dir])} Not a directory"
56
61
  exit
57
62
  end
58
63