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.
137 138 139 140 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 137 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.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 118 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.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 95 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 86 87 88 89 |
# 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, subtitle: { en: "Sign in to Simurgh Admin Panel", fa: "ورود به پنل ادمین سیمرغ" }, 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] || {}) if raw_config.key?(:show_demo_credentials) && (raw_config[:auth].nil? || !raw_config[:auth].key?(:show_demo_credentials)) auth[:show_demo_credentials] = raw_config[:show_demo_credentials] end base_defaults = { subtitle: { en: "Content & Data Management System", fa: "سامانه مدیریت محتوا و دادهها" }, direction: "ltr", default_locale: "en", supported_locales: ["en", "fa"] } 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.
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 252 253 254 255 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 220 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.
179 180 181 182 183 184 185 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 179 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.
166 167 168 169 170 171 172 173 174 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 166 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.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 145 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.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/roda/plugins/kabk/helpers.rb', line 190 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 |