ruflet_rails 0.0.5 → 0.0.6
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/README.md +49 -13
- data/lib/generators/ruflet/install/install_generator.rb +62 -0
- data/lib/ruflet/rails/install_support.rb +204 -0
- data/lib/ruflet/rails/protocol/wire_codec.rb +14 -0
- data/lib/ruflet/rails/railtie.rb +19 -0
- data/lib/ruflet/version.rb +1 -1
- data/lib/ruflet_rails.rb +2 -1
- metadata +8 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ac570f3b6d92f8fc6d21723cc2814c658861c20e8b38d884e389185916d559f
|
|
4
|
+
data.tar.gz: 02cbfbdc2da5e487af2cd07b2d176066c6a5cd0487a141245ffc84ca0a23ff3f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: de4d8d0a43bda6f2ebbab447c8c25209d44cfabccae8fb584024a355cf1ba464577200737d3cfae692d2e2c52aca294ae13d556de95875dd07d8a407b5a1c8d3
|
|
7
|
+
data.tar.gz: 1b3a8dd5f338a32c9e91f30a1b0d85cd9618019b2903f931cd27de45cee4717830daeabc44dc6dff01daf9dcf1e503a7bfacff7f8f7f813e4efb06ca6dbb9b02
|
data/README.md
CHANGED
|
@@ -9,26 +9,62 @@ No separate protocol gem is required.
|
|
|
9
9
|
|
|
10
10
|
```ruby
|
|
11
11
|
# Gemfile
|
|
12
|
-
gem "ruflet_rails", ">= 0.0.
|
|
12
|
+
gem "ruflet_rails", ">= 0.0.5"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
# app/mobile/main.rb
|
|
17
|
-
require "ruflet"
|
|
15
|
+
## Install into Rails
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
page.add(text(value: "Hello Ruflet"))
|
|
23
|
-
end
|
|
24
|
-
end
|
|
17
|
+
```bash
|
|
18
|
+
bin/rails generate ruflet:install
|
|
19
|
+
```
|
|
25
20
|
|
|
26
|
-
|
|
21
|
+
This generator will:
|
|
22
|
+
- create `app/mobile/main.rb`
|
|
23
|
+
- create `ruflet.yaml`
|
|
24
|
+
- add the Ruflet mount route to `config/routes.rb`
|
|
25
|
+
- copy/configure `ruflet_client` when the template is available locally
|
|
26
|
+
|
|
27
|
+
Generated `ruflet.yaml`:
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
app:
|
|
31
|
+
name: My App
|
|
32
|
+
ruflet_client_url: ""
|
|
33
|
+
|
|
34
|
+
services: []
|
|
35
|
+
|
|
36
|
+
assets:
|
|
37
|
+
splash_screen: assets/splash.png
|
|
38
|
+
icon_launcher: assets/icon.png
|
|
27
39
|
```
|
|
28
40
|
|
|
41
|
+
For Rails apps, those asset paths are resolved from `app/assets/` during build.
|
|
42
|
+
|
|
43
|
+
## Build client from Rails
|
|
44
|
+
|
|
45
|
+
Uses the same build pipeline as `ruflet build`:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
bundle exec rake ruflet:build[web]
|
|
49
|
+
bundle exec rake ruflet:build[macos]
|
|
50
|
+
bundle exec rake ruflet:build[windows]
|
|
51
|
+
bundle exec rake ruflet:build[linux]
|
|
52
|
+
bundle exec rake ruflet:build[apk]
|
|
53
|
+
bundle exec rake ruflet:build[android]
|
|
54
|
+
bundle exec rake ruflet:build[ios]
|
|
55
|
+
bundle exec rake ruflet:build[aab]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Manual usage
|
|
59
|
+
|
|
29
60
|
```ruby
|
|
30
|
-
#
|
|
31
|
-
|
|
61
|
+
# app/mobile/main.rb
|
|
62
|
+
require "ruflet"
|
|
63
|
+
|
|
64
|
+
Ruflet.run do |page|
|
|
65
|
+
page.title = "Hello"
|
|
66
|
+
page.add(text("Hello Ruflet"))
|
|
67
|
+
end
|
|
32
68
|
```
|
|
33
69
|
|
|
34
70
|
Connect mobile to Rails base URL, e.g. `http://10.0.2.2:3000`.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "ruflet/rails/install_support"
|
|
5
|
+
|
|
6
|
+
module Ruflet
|
|
7
|
+
module Generators
|
|
8
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
9
|
+
desc "Install Ruflet into a Rails app."
|
|
10
|
+
|
|
11
|
+
def create_mobile_entrypoint
|
|
12
|
+
target = File.join(destination_root, "app/mobile/main.rb")
|
|
13
|
+
return if File.exist?(target)
|
|
14
|
+
|
|
15
|
+
FileUtils.mkdir_p(File.dirname(target))
|
|
16
|
+
File.write(
|
|
17
|
+
target,
|
|
18
|
+
Ruflet::Rails::InstallSupport.default_mobile_app_template(app_title: app_name)
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create_ruflet_yaml
|
|
23
|
+
target = File.join(destination_root, "ruflet.yaml")
|
|
24
|
+
return if File.exist?(target)
|
|
25
|
+
|
|
26
|
+
File.write(
|
|
27
|
+
target,
|
|
28
|
+
Ruflet::Rails::InstallSupport.default_ruflet_yaml(app_name: app_name)
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def copy_client_template
|
|
33
|
+
copied = Ruflet::Rails::InstallSupport.copy_ruflet_client_template(destination_root)
|
|
34
|
+
say_status(:warn, "ruflet_client template not found; add it manually before building", :yellow) unless copied
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def configure_client_template
|
|
38
|
+
Ruflet::Rails::InstallSupport.configure_ruflet_client(destination_root)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def add_routes
|
|
42
|
+
target = File.join(destination_root, "config/routes.rb")
|
|
43
|
+
return unless File.file?(target)
|
|
44
|
+
|
|
45
|
+
route = Ruflet::Rails::InstallSupport.route_snippet
|
|
46
|
+
return if File.read(target).include?(route)
|
|
47
|
+
|
|
48
|
+
insert_into_file target, " #{route}\n", after: /Rails\.application\.routes\.draw do\s*\n/
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def print_install_status
|
|
52
|
+
say "ruflet.yaml generated"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def app_name
|
|
58
|
+
File.basename(destination_root).gsub(/[_-]+/, " ").split.map(&:capitalize).join(" ")
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "yaml"
|
|
5
|
+
|
|
6
|
+
module Ruflet
|
|
7
|
+
module Rails
|
|
8
|
+
module InstallSupport
|
|
9
|
+
CLIENT_EXTENSION_MAP = {
|
|
10
|
+
"ads" => { package: "flet_ads", alias: "ruflet_ads" },
|
|
11
|
+
"audio" => { package: "flet_audio", alias: "ruflet_audio" },
|
|
12
|
+
"audio_recorder" => { package: "flet_audio_recorder", alias: "ruflet_audio_recorder" },
|
|
13
|
+
"camera" => { package: "flet_camera", alias: "ruflet_camera" },
|
|
14
|
+
"charts" => { package: "flet_charts", alias: "ruflet_charts" },
|
|
15
|
+
"code_editor" => { package: "flet_code_editor", alias: "ruflet_code_editor" },
|
|
16
|
+
"color_pickers" => { package: "flet_color_pickers", alias: "ruflet_color_picker" },
|
|
17
|
+
"datatable2" => { package: "flet_datatable2", alias: "ruflet_datatable2" },
|
|
18
|
+
"flashlight" => { package: "flet_flashlight", alias: "ruflet_flashlight" },
|
|
19
|
+
"geolocator" => { package: "flet_geolocator", alias: "ruflet_geolocator" },
|
|
20
|
+
"lottie" => { package: "flet_lottie", alias: "ruflet_lottie" },
|
|
21
|
+
"map" => { package: "flet_map", alias: "ruflet_map" },
|
|
22
|
+
"permission_handler" => { package: "flet_permission_handler", alias: "ruflet_permission_handler" },
|
|
23
|
+
"secure_storage" => { package: "flet_secure_storage", alias: "ruflet_secure_storage" },
|
|
24
|
+
"video" => { package: "flet_video", alias: "ruflet_video" },
|
|
25
|
+
"webview" => { package: "flet_webview", alias: "ruflet_webview" }
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
module_function
|
|
29
|
+
|
|
30
|
+
def default_mobile_app_template(app_title:)
|
|
31
|
+
<<~RUBY
|
|
32
|
+
require "ruflet"
|
|
33
|
+
|
|
34
|
+
Ruflet.run do |page|
|
|
35
|
+
page.title = #{app_title.inspect}
|
|
36
|
+
count = 0
|
|
37
|
+
count_text = text(count.to_s, size: 40)
|
|
38
|
+
|
|
39
|
+
page.add(
|
|
40
|
+
container(
|
|
41
|
+
expand: true,
|
|
42
|
+
alignment: Ruflet::MainAxisAlignment::CENTER,
|
|
43
|
+
content: column(
|
|
44
|
+
alignment: Ruflet::MainAxisAlignment::CENTER,
|
|
45
|
+
horizontal_alignment: Ruflet::CrossAxisAlignment::CENTER,
|
|
46
|
+
children: [
|
|
47
|
+
text("You have pushed the button this many times:"),
|
|
48
|
+
count_text
|
|
49
|
+
]
|
|
50
|
+
)
|
|
51
|
+
),
|
|
52
|
+
floating_action_button: fab(
|
|
53
|
+
icon: Ruflet::MaterialIcons::ADD,
|
|
54
|
+
on_click: ->(_e) do
|
|
55
|
+
count += 1
|
|
56
|
+
page.update(count_text, value: count.to_s)
|
|
57
|
+
end
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
RUBY
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def default_ruflet_yaml(app_name:)
|
|
65
|
+
<<~YAML
|
|
66
|
+
app:
|
|
67
|
+
name: #{app_name}
|
|
68
|
+
ruflet_client_url: ""
|
|
69
|
+
|
|
70
|
+
services: []
|
|
71
|
+
|
|
72
|
+
assets:
|
|
73
|
+
splash_screen: assets/splash.png
|
|
74
|
+
icon_launcher: assets/icon.png
|
|
75
|
+
YAML
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def route_snippet(entrypoint: "app/mobile/main.rb", mount_path: "/ws")
|
|
79
|
+
%(mount Ruflet::Rails.mobile(Rails.root.join("#{entrypoint}")), at: "#{mount_path}")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def client_template_root
|
|
83
|
+
env = ENV["RUFLET_CLIENT_TEMPLATE_DIR"].to_s.strip
|
|
84
|
+
return env if !env.empty? && Dir.exist?(env)
|
|
85
|
+
|
|
86
|
+
candidates = [
|
|
87
|
+
File.expand_path("../../../../../ruflet_client", __dir__),
|
|
88
|
+
File.expand_path("../../../../../templates/ruflet_flutter_template", __dir__)
|
|
89
|
+
]
|
|
90
|
+
candidates.find { |path| Dir.exist?(path) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def copy_ruflet_client_template(root)
|
|
94
|
+
template_root = client_template_root
|
|
95
|
+
return false unless template_root
|
|
96
|
+
|
|
97
|
+
target = File.join(root, "ruflet_client")
|
|
98
|
+
return true if Dir.exist?(target)
|
|
99
|
+
|
|
100
|
+
FileUtils.cp_r(template_root, target)
|
|
101
|
+
prune_client_template(target)
|
|
102
|
+
true
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def prune_client_template(target)
|
|
106
|
+
%w[
|
|
107
|
+
.dart_tool
|
|
108
|
+
.idea
|
|
109
|
+
build
|
|
110
|
+
ios/Pods
|
|
111
|
+
ios/.symlinks
|
|
112
|
+
ios/Podfile.lock
|
|
113
|
+
macos/Pods
|
|
114
|
+
macos/Podfile.lock
|
|
115
|
+
android/.gradle
|
|
116
|
+
android/.kotlin
|
|
117
|
+
android/local.properties
|
|
118
|
+
].each do |path|
|
|
119
|
+
full = File.join(target, path)
|
|
120
|
+
FileUtils.rm_rf(full) if File.exist?(full)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def configure_ruflet_client(root)
|
|
125
|
+
config_path = File.join(root, "ruflet.yaml")
|
|
126
|
+
return unless File.file?(config_path)
|
|
127
|
+
|
|
128
|
+
config = YAML.safe_load(File.read(config_path), aliases: true) || {}
|
|
129
|
+
extension_keys = Array(config["services"]).map { |v| normalize_extension_key(v) }.compact.uniq
|
|
130
|
+
extension_packages = extension_keys.filter_map { |key| CLIENT_EXTENSION_MAP[key]&.fetch(:package) }.uniq
|
|
131
|
+
extension_aliases = extension_keys.filter_map { |key| CLIENT_EXTENSION_MAP[key]&.fetch(:alias) }.uniq
|
|
132
|
+
|
|
133
|
+
client_dir = File.join(root, "ruflet_client")
|
|
134
|
+
return unless Dir.exist?(client_dir)
|
|
135
|
+
|
|
136
|
+
prune_client_pubspec(File.join(client_dir, "pubspec.yaml"), extension_packages)
|
|
137
|
+
prune_client_main(File.join(client_dir, "lib", "main.dart"), extension_aliases)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def normalize_extension_key(value)
|
|
141
|
+
key = value.to_s.strip.downcase
|
|
142
|
+
return nil if key.empty?
|
|
143
|
+
|
|
144
|
+
key.tr!("-", "_")
|
|
145
|
+
key.gsub!(/\A(flet_)+/, "")
|
|
146
|
+
key.gsub!(/\Aservice_/, "")
|
|
147
|
+
key.gsub!(/\Acontrol_/, "")
|
|
148
|
+
key = "file_picker" if key == "filepicker"
|
|
149
|
+
key
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def prune_client_pubspec(path, selected_packages)
|
|
153
|
+
return unless File.file?(path)
|
|
154
|
+
|
|
155
|
+
data = YAML.safe_load(File.read(path), aliases: true) || {}
|
|
156
|
+
deps = (data["dependencies"] || {}).dup
|
|
157
|
+
deps.keys.each do |name|
|
|
158
|
+
next unless name.start_with?("flet_")
|
|
159
|
+
next if name == "flet"
|
|
160
|
+
next if selected_packages.include?(name)
|
|
161
|
+
|
|
162
|
+
deps.delete(name)
|
|
163
|
+
end
|
|
164
|
+
data["dependencies"] = deps
|
|
165
|
+
File.write(path, YAML.dump(data))
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def prune_client_main(path, selected_aliases)
|
|
169
|
+
return unless File.file?(path)
|
|
170
|
+
|
|
171
|
+
lines = File.readlines(path)
|
|
172
|
+
alias_to_package = {}
|
|
173
|
+
|
|
174
|
+
lines.each do |line|
|
|
175
|
+
match = line.match(%r{\Aimport 'package:(flet_[^/]+)/\1\.dart' as ([a-zA-Z0-9_]+);})
|
|
176
|
+
alias_to_package[match[2]] = match[1] if match
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
kept = lines.select do |line|
|
|
180
|
+
import_match = line.match(%r{\Aimport 'package:(flet_[^/]+)/\1\.dart' as ([a-zA-Z0-9_]+);})
|
|
181
|
+
if import_match
|
|
182
|
+
package_name = import_match[1]
|
|
183
|
+
next true if package_name == "flet"
|
|
184
|
+
next true if selected_aliases.include?(import_match[2])
|
|
185
|
+
next false
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
extension_match = line.match(/\A\s*([a-zA-Z0-9_]+)\.Extension\(\),\s*\z/)
|
|
189
|
+
if extension_match
|
|
190
|
+
extension_alias = extension_match[1]
|
|
191
|
+
package_name = alias_to_package[extension_alias]
|
|
192
|
+
next true if package_name.nil?
|
|
193
|
+
next true if selected_aliases.include?(extension_alias)
|
|
194
|
+
next false
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
true
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
File.write(path, kept.join)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
@@ -130,10 +130,23 @@ module Ruflet
|
|
|
130
130
|
when 0xd9 then reader.read_string(reader.read_u8)
|
|
131
131
|
when 0xda then reader.read_string(reader.read_u16)
|
|
132
132
|
when 0xdb then reader.read_string(reader.read_u32)
|
|
133
|
+
when 0xc4 then reader.read_binary(reader.read_u8)
|
|
134
|
+
when 0xc5 then reader.read_binary(reader.read_u16)
|
|
135
|
+
when 0xc6 then reader.read_binary(reader.read_u32)
|
|
133
136
|
when 0xdc then read_array(reader, reader.read_u16)
|
|
134
137
|
when 0xdd then read_array(reader, reader.read_u32)
|
|
135
138
|
when 0xde then read_map(reader, reader.read_u16)
|
|
136
139
|
when 0xdf then read_map(reader, reader.read_u32)
|
|
140
|
+
when 0xd4
|
|
141
|
+
read_ext(reader, 1)
|
|
142
|
+
when 0xd5
|
|
143
|
+
read_ext(reader, 2)
|
|
144
|
+
when 0xd6
|
|
145
|
+
read_ext(reader, 4)
|
|
146
|
+
when 0xd7
|
|
147
|
+
read_ext(reader, 8)
|
|
148
|
+
when 0xd8
|
|
149
|
+
read_ext(reader, 16)
|
|
137
150
|
when 0xc7
|
|
138
151
|
read_ext(reader, reader.read_u8)
|
|
139
152
|
when 0xc8
|
|
@@ -204,6 +217,7 @@ module Ruflet
|
|
|
204
217
|
def read_f32 = read_exact(4).unpack1("g")
|
|
205
218
|
def read_f64 = read_exact(8).unpack1("G")
|
|
206
219
|
def read_string(size) = read_exact(size).force_encoding("UTF-8")
|
|
220
|
+
def read_binary(size) = read_exact(size)
|
|
207
221
|
end
|
|
208
222
|
end
|
|
209
223
|
end
|
data/lib/ruflet/rails/railtie.rb
CHANGED
|
@@ -6,6 +6,25 @@ module Ruflet
|
|
|
6
6
|
initializer "ruflet_rails.middleware" do |app|
|
|
7
7
|
app.middleware.use Ruflet::Rails::Protocol::Middleware
|
|
8
8
|
end
|
|
9
|
+
|
|
10
|
+
rake_tasks do
|
|
11
|
+
namespace :ruflet do
|
|
12
|
+
desc "Build Ruflet client for this Rails app. Usage: rake ruflet:build[web]"
|
|
13
|
+
task :build, [:platform] do |_task, args|
|
|
14
|
+
platform = args[:platform].to_s.strip
|
|
15
|
+
if platform.empty?
|
|
16
|
+
warn "Usage: rake ruflet:build[apk|android|ios|aab|web|macos|windows|linux]"
|
|
17
|
+
next
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
require "ruflet/cli"
|
|
21
|
+
exit_code = Dir.chdir(::Rails.root) do
|
|
22
|
+
Ruflet::CLI.command_build([platform])
|
|
23
|
+
end
|
|
24
|
+
raise SystemExit, exit_code unless exit_code.to_i.zero?
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
9
28
|
end
|
|
10
29
|
end
|
|
11
30
|
end
|
data/lib/ruflet/version.rb
CHANGED
data/lib/ruflet_rails.rb
CHANGED
|
@@ -5,8 +5,9 @@ if File.directory?(local_ruflet_lib) && !$LOAD_PATH.include?(local_ruflet_lib)
|
|
|
5
5
|
$LOAD_PATH.unshift(local_ruflet_lib)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
require "
|
|
8
|
+
require "ruflet_core"
|
|
9
9
|
require_relative "ruflet/rails/protocol"
|
|
10
|
+
require_relative "ruflet/rails/install_support"
|
|
10
11
|
require_relative "ruflet/rails"
|
|
11
12
|
|
|
12
13
|
if defined?(::Rails::Railtie)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruflet_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- AdamMusa
|
|
@@ -24,19 +24,19 @@ dependencies:
|
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '7.0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: ruflet_core
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
|
-
- -
|
|
30
|
+
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.0.
|
|
32
|
+
version: 0.0.11
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- -
|
|
37
|
+
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.0.
|
|
39
|
+
version: 0.0.11
|
|
40
40
|
description: Rails-first integration package for mounting Ruflet mobile apps in Rails
|
|
41
41
|
routes.
|
|
42
42
|
email:
|
|
@@ -46,7 +46,9 @@ extensions: []
|
|
|
46
46
|
extra_rdoc_files: []
|
|
47
47
|
files:
|
|
48
48
|
- README.md
|
|
49
|
+
- lib/generators/ruflet/install/install_generator.rb
|
|
49
50
|
- lib/ruflet/rails.rb
|
|
51
|
+
- lib/ruflet/rails/install_support.rb
|
|
50
52
|
- lib/ruflet/rails/protocol.rb
|
|
51
53
|
- lib/ruflet/rails/protocol/context.rb
|
|
52
54
|
- lib/ruflet/rails/protocol/endpoint.rb
|