Class: RodaPlugins::Kabk::Helpers
- Inherits:
-
Object
- Object
- RodaPlugins::Kabk::Helpers
- Defined in:
- lib/roda/plugins/kabk/helpers.rb
Overview
Helper object providing Smart Dispatch routing, static asset serving, and utility endpoints for Kabk.
Constant Summary collapse
- PUBLIC_DIR =
Absolute directory path to bundled Simurgh frontend public assets.
File.("../../../../public", __dir__)
Instance Attribute Summary collapse
-
#options ⇒ Hash
readonly
Configured plugin options.
-
#request ⇒ Roda::RodaRequest
readonly
The current Roda request instance.
Class Method Summary collapse
-
.asset_content_type(asset_name) ⇒ String
Determines MIME content type based on file extension.
-
.build_index_html(opts = {}) ⇒ String?
Generates index.html content with injected APP_CONFIG and dynamic schema manifest.
-
.build_system_config(opts = {}) ⇒ Hash
Merges default auth and endpoints configuration into system_config.
-
.cached_index_html(opts = {}) ⇒ String?
Returns the memoized index.html content with embedded schema for the given options.
-
.reset_cache! ⇒ void
Clears the cached HTML templates in memory.
Instance Method Summary collapse
-
#initialize(request, options = {}) ⇒ Helpers
constructor
Initializes a new Helpers instance.
-
#route(context: {}) ⇒ void?
Dispatches the current HTTP request to the matching registered Kabk resource based on api_path.
-
#schema ⇒ void
Renders and returns the dynamic protocol schema manifest JSON.
-
#server ⇒ void
Serves the Vue.js SPA index.html dynamically.
-
#statics ⇒ void
Serves global static assets (JS, CSS, Fonts, Images) from the public directory.
-
#upload ⇒ void
Handles multipart file upload requests.
Constructor Details
#initialize(request, options = {}) ⇒ Helpers
Initializes a new Helpers instance.
133 134 135 136 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 133 def initialize(request, = {}) @request = request @options = || {} end |
Instance Attribute Details
#options ⇒ Hash (readonly)
Returns Configured plugin options.
19 20 21 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 19 def @options end |
#request ⇒ Roda::RodaRequest (readonly)
Returns The current Roda request instance.
16 17 18 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 16 def request @request end |
Class Method Details
.asset_content_type(asset_name) ⇒ String
Determines MIME content type based on file extension.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 114 def self.asset_content_type(asset_name) case File.extname(asset_name).downcase when ".js" then "application/javascript; charset=utf-8" when ".css" then "text/css; charset=utf-8" when ".svg" then "image/svg+xml" when ".woff2" then "font/woff2" when ".png" then "image/png" when ".ttf" then "font/ttf" when ".mp4" then "video/mp4" when ".webp" then "image/webp" when ".gif" then "image/gif" else "application/octet-stream" end end |
.build_index_html(opts = {}) ⇒ String?
Generates index.html content with injected APP_CONFIG and dynamic schema manifest.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 91 def self.build_index_html(opts = {}) index_path = File.join(PUBLIC_DIR, "index.html") return nil unless File.file?(index_path) content = File.read(index_path) sys_config = build_system_config(opts) schema_renderer = ::Kabk::SchemaRenderer.new(system_config: sys_config) dynamic_schema = schema_renderer.render dynamic_schema_json = JSON.pretty_generate(dynamic_schema) content = content.sub( %r{<script id="simurgh-schema" type="application/json">.*?</script>}m, "<script id=\"simurgh-schema\" type=\"application/json\">\n#{dynamic_schema_json}\n </script>" ) config_snippet = "window.APP_CONFIG = { baseURL: '' };" content.sub(/window\.APP_CONFIG\s*=\s*\{[^}]*\};/m, config_snippet) end |
.build_system_config(opts = {}) ⇒ Hash
Merges default auth and endpoints configuration into system_config.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 46 def self.build_system_config(opts = {}) raw_config = (opts[:system_config] || {}).dup endpoints = { upload: "/uploads" }.merge(raw_config[:endpoints] || {}) auth_defaults = { strategy: "session", sso_redirect_url: nil, login_url: "/auth/login", logout_url: "/auth/logout", me_url: "/auth/me", refresh_url: "/auth/refresh", show_demo_credentials: false, login_fields: [ { name: "username", label: { en: "Username", fa: "نام کاربری" }, placeholder: { en: "Enter your username...", fa: "نام کاربری خود را وارد کنید..." }, type: "text", required: true }, { name: "password", label: { en: "Password", fa: "کلمه عبور" }, placeholder: { en: "Enter your password...", fa: "کلمه عبور خود را وارد کنید..." }, type: "password", required: true } ] } auth = auth_defaults.merge(raw_config[:auth] || {}) base_defaults = { direction: "ltr", default_locale: "en", supported_locales: ["en", "fa"], show_demo_credentials: false } base_defaults.merge(raw_config).merge(endpoints: endpoints, auth: auth) end |
.cached_index_html(opts = {}) ⇒ String?
Returns the memoized index.html content with embedded schema for the given options.
35 36 37 38 39 40 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 35 def self.cached_index_html(opts = {}) cache_key = (opts[:system_config] || {}).hash @cache_mutex.synchronize do @cached_html[cache_key] ||= build_index_html(opts) end end |
.reset_cache! ⇒ void
This method returns an undefined value.
Clears the cached HTML templates in memory.
27 28 29 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 27 def self.reset_cache! @cache_mutex.synchronize { @cached_html.clear } end |
Instance Method Details
#route(context: {}) ⇒ void?
Dispatches the current HTTP request to the matching registered Kabk resource based on api_path.
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 216 def route(context: {}) resource, id_param = find_matching_resource return unless resource engine = ::Kabk::RestEngine.new(resource.name) if id_param.nil? || id_param.empty? if request.get? handle_errors do respond_json(engine.list(request.params, context: context)) end elsif request.post? handle_errors do body = parse_json_body respond_json(engine.create(body, context: context)) end end else record_id = id_param =~ /\A\d+\z/ ? id_param.to_i : id_param if request.get? handle_errors do respond_json(engine.get(record_id, context: context)) end elsif request.put? || request.patch? handle_errors do body = parse_json_body respond_json(engine.update(record_id, body, context: context)) end elsif request.delete? handle_errors do respond_json(engine.delete(record_id, context: context)) end end end end |
#schema ⇒ void
This method returns an undefined value.
Renders and returns the dynamic protocol schema manifest JSON.
175 176 177 178 179 180 181 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 175 def schema handle_errors do sys_config = self.class.build_system_config() schema_renderer = ::Kabk::SchemaRenderer.new(system_config: sys_config) respond_json(schema_renderer.render) end end |
#server ⇒ void
This method returns an undefined value.
Serves the Vue.js SPA index.html dynamically.
162 163 164 165 166 167 168 169 170 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 162 def server content = self.class.cached_index_html() if content request.response["Content-Type"] = "text/html; charset=utf-8" request.halt [200, request.response.headers, [content]] else handle_errors { raise ::Kabk::NotFoundError, "Simurgh UI index.html not found" } end end |
#statics ⇒ void
This method returns an undefined value.
Serves global static assets (JS, CSS, Fonts, Images) from the public directory.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 141 def statics request.get "assets", String do |asset_name| asset_path = File.join(PUBLIC_DIR, "assets", asset_name) if File.file?(asset_path) request.response["Content-Type"] = self.class.asset_content_type(asset_name) request.halt [200, request.response.headers, [File.read(asset_path)]] end end request.get "simurgh-logo.svg" do logo_path = File.join(PUBLIC_DIR, "simurgh-logo.svg") if File.file?(logo_path) request.response["Content-Type"] = "image/svg+xml" request.halt [200, request.response.headers, [File.read(logo_path)]] end end end |
#upload ⇒ void
This method returns an undefined value.
Handles multipart file upload requests.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 186 def upload handle_errors do file_param = request.params["file"] || request.params upload_handler = [:upload_handler] if upload_handler.respond_to?(:call) result = upload_handler.call(file_param, request) respond_json(::Kabk::UploadHandler.format_response( url: result[:url] || result["url"], file_name: result[:file_name] || result["file_name"] || result[:filename] || result["filename"], size: result[:size] || result["size"], mime_type: result[:mime_type] || result["mime_type"] )) elsif file_param.is_a?(Hash) && file_param[:tempfile] respond_json(::Kabk::UploadHandler.format_response( url: "/uploads/#{file_param[:filename]}", file_name: file_param[:filename], size: file_param[:tempfile].size, mime_type: file_param[:type] )) else raise ::Kabk::ValidationError, "No file uploaded or file parameter missing" end end end |