kabk 1.0.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 +7 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +105 -0
- data/Kabk_logo.svg +33 -0
- data/LICENSE +21 -0
- data/README.md +112 -0
- data/doc/Kabk/Adapters/Base.html +989 -0
- data/doc/Kabk/Adapters/SequelAdapter.html +1071 -0
- data/doc/Kabk/Adapters.html +120 -0
- data/doc/Kabk/ApiError.html +511 -0
- data/doc/Kabk/Auth/JwtStrategy.html +551 -0
- data/doc/Kabk/Auth.html +118 -0
- data/doc/Kabk/Concurrency.html +297 -0
- data/doc/Kabk/ConcurrencyConflictError.html +234 -0
- data/doc/Kabk/Error.html +140 -0
- data/doc/Kabk/ExportHandler.html +381 -0
- data/doc/Kabk/Field.html +2160 -0
- data/doc/Kabk/ForbiddenError.html +234 -0
- data/doc/Kabk/InvalidFieldError.html +145 -0
- data/doc/Kabk/InvalidOldPasswordError.html +234 -0
- data/doc/Kabk/NotFoundError.html +234 -0
- data/doc/Kabk/QueryBuilder.html +701 -0
- data/doc/Kabk/Registry.html +608 -0
- data/doc/Kabk/RelationHydrator.html +480 -0
- data/doc/Kabk/Resource.html +1986 -0
- data/doc/Kabk/ResourceBuilder.html +1002 -0
- data/doc/Kabk/RestEngine.html +887 -0
- data/doc/Kabk/SchemaRenderer.html +318 -0
- data/doc/Kabk/UnauthorizedError.html +234 -0
- data/doc/Kabk/UploadHandler.html +308 -0
- data/doc/Kabk/ValidationError.html +234 -0
- data/doc/Kabk/Validator.html +802 -0
- data/doc/Kabk.html +330 -0
- data/doc/_index.html +369 -0
- data/doc/class_list.html +54 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +206 -0
- data/doc/css/style.css +1089 -0
- data/doc/file.README.html +162 -0
- data/doc/file_list.html +59 -0
- data/doc/frames.html +22 -0
- data/doc/index.html +162 -0
- data/doc/js/app.js +801 -0
- data/doc/js/full_list.js +334 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +982 -0
- data/doc/top-level-namespace.html +112 -0
- data/docs/API_REFERENCE.md +255 -0
- data/lib/kabk/adapters/base.rb +53 -0
- data/lib/kabk/adapters/sequel_adapter.rb +138 -0
- data/lib/kabk/concurrency.rb +30 -0
- data/lib/kabk/errors.rb +68 -0
- data/lib/kabk/field.rb +97 -0
- data/lib/kabk/query_builder.rb +103 -0
- data/lib/kabk/registry.rb +41 -0
- data/lib/kabk/relation_hydrator.rb +107 -0
- data/lib/kabk/resource.rb +88 -0
- data/lib/kabk/resource_builder.rb +95 -0
- data/lib/kabk/rest_engine.rb +120 -0
- data/lib/kabk/schema_renderer.rb +69 -0
- data/lib/kabk/upload_handler.rb +24 -0
- data/lib/kabk/validator.rb +121 -0
- data/lib/kabk/version.rb +6 -0
- data/lib/kabk.rb +50 -0
- metadata +178 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "registry"
|
|
4
|
+
|
|
5
|
+
module Kabk
|
|
6
|
+
# Renders the JSON Schema manifest for the protocol v1.6.0
|
|
7
|
+
class SchemaRenderer
|
|
8
|
+
# Initializes the schema renderer
|
|
9
|
+
#
|
|
10
|
+
# @param system_config [Hash, nil] Optional system config overrides (e.g., title, logo_url, endpoints)
|
|
11
|
+
# @param validation_schema_url [String, nil] Custom URL for the validation schema
|
|
12
|
+
def initialize(system_config: nil, validation_schema_url: nil)
|
|
13
|
+
@system_config = system_config ? default_system_config.merge(system_config) : default_system_config
|
|
14
|
+
@validation_schema_url = validation_schema_url || "/schemas/admin-protocol-1.6.0.json"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def render
|
|
18
|
+
{
|
|
19
|
+
"$schema_version": "1.6.0",
|
|
20
|
+
system: @system_config,
|
|
21
|
+
validation_schema_url: @validation_schema_url,
|
|
22
|
+
resources: Registry.instance.all.map(&:to_h)
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def default_system_config
|
|
29
|
+
{
|
|
30
|
+
title: { fa: "پنل مدیریت سیمرغ", en: "Simurgh Panel" },
|
|
31
|
+
logo_url: "/simurgh-logo.svg",
|
|
32
|
+
default_locale: "en",
|
|
33
|
+
supported_locales: %w[en fa],
|
|
34
|
+
direction: "ltr",
|
|
35
|
+
endpoints: {
|
|
36
|
+
upload: "/api/admin/uploads"
|
|
37
|
+
},
|
|
38
|
+
custom_fonts: [
|
|
39
|
+
{
|
|
40
|
+
name: "Lalezar",
|
|
41
|
+
url: "https://fonts.gstatic.com/s/lalezar/v14/OpUp1a5dqj36gZ2zXh_WfQ.woff2",
|
|
42
|
+
format: "woff2",
|
|
43
|
+
label: { en: "Lalezar (Title)", fa: "لالهزار (عنوان)" }
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "Sahel",
|
|
47
|
+
url: "https://cdn.jsdelivr.net/gh/rastikerdar/sahel-font@v3.4.0/dist/Sahel.woff2",
|
|
48
|
+
format: "woff2",
|
|
49
|
+
label: { en: "Sahel (Clean)", fa: "ساحل (خوانا)" }
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
custom_font_sizes: [
|
|
53
|
+
{
|
|
54
|
+
size: "15px",
|
|
55
|
+
label: { en: "Medium Fine (15px)", fa: "متوسط ظریف (۱۵px)" }
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
size: "20px",
|
|
59
|
+
label: { en: "Sub-heading (20px)", fa: "زیرعنوان (۲۰px)" }
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
size: "32px",
|
|
63
|
+
label: { en: "Hero Display (32px)", fa: "تیتر برجسته (۳۲px)" }
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kabk
|
|
4
|
+
# Handles generic file uploads and formats them according to Protocol v1.6.0
|
|
5
|
+
class UploadHandler
|
|
6
|
+
# @param url [String] Public URL of the uploaded file
|
|
7
|
+
# @param file_name [String] Original file name
|
|
8
|
+
# @param size [Integer] File size in bytes
|
|
9
|
+
# @param mime_type [String] File mime type
|
|
10
|
+
# @return [Hash] Formatted upload response
|
|
11
|
+
def self.format_response(url:, file_name:, size:, mime_type: nil)
|
|
12
|
+
{
|
|
13
|
+
success: true,
|
|
14
|
+
message: "File uploaded successfully",
|
|
15
|
+
data: {
|
|
16
|
+
url: url,
|
|
17
|
+
file_name: file_name,
|
|
18
|
+
size: size,
|
|
19
|
+
mime_type: mime_type || "application/octet-stream"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "errors"
|
|
4
|
+
|
|
5
|
+
module Kabk
|
|
6
|
+
# Handles input sanitization (strong parameters) and validation
|
|
7
|
+
class Validator
|
|
8
|
+
# Sanitizes input parameters against defined fields and validates them
|
|
9
|
+
# @param resource [Kabk::Resource]
|
|
10
|
+
# @param params [Hash] Request payload
|
|
11
|
+
# @param is_update [Boolean] Is this a PUT/update request?
|
|
12
|
+
# @return [Hash] Sanitized parameters ready for the database adapter
|
|
13
|
+
def self.validate_and_sanitize!(resource, params, is_update: false)
|
|
14
|
+
sanitized = {}
|
|
15
|
+
errors = {}
|
|
16
|
+
|
|
17
|
+
resource.fields.each do |field|
|
|
18
|
+
next if field.primary_key || field.readonly
|
|
19
|
+
|
|
20
|
+
key_sym = field.name.to_sym
|
|
21
|
+
key_str = field.name.to_s
|
|
22
|
+
has_key = params.key?(key_sym) || params.key?(key_str)
|
|
23
|
+
value = params.key?(key_sym) ? params[key_sym] : params[key_str]
|
|
24
|
+
|
|
25
|
+
field_errors = validate_field(field, value, has_key, is_update)
|
|
26
|
+
errors[key_str] = field_errors unless field_errors.empty?
|
|
27
|
+
|
|
28
|
+
sanitized[key_sym] = value if has_key
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Ensure the concurrency field is included for OCC validation.
|
|
32
|
+
if resource.concurrency_field
|
|
33
|
+
c_field = resource.concurrency_field
|
|
34
|
+
sanitized[c_field.to_sym] = params[c_field.to_sym] || params[c_field.to_s] if params.key?(c_field.to_sym) || params.key?(c_field.to_s)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
raise ValidationError.new(fields: errors) unless errors.empty?
|
|
38
|
+
|
|
39
|
+
sanitized
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.validate_field(field, value, has_key, is_update)
|
|
43
|
+
rules = field.validation.is_a?(Hash) ? field.validation : nil
|
|
44
|
+
|
|
45
|
+
if field.required
|
|
46
|
+
return [resolve_message(rules, "This field is required")] if !has_key && !is_update
|
|
47
|
+
return [resolve_message(rules, "This field is required")] if has_key && (value.nil? || value.to_s.strip.empty?)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
return [] unless has_key && !value.nil? && rules
|
|
51
|
+
|
|
52
|
+
collect_rule_errors(field, rules, value)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.collect_rule_errors(field, rules, value)
|
|
56
|
+
errs = []
|
|
57
|
+
|
|
58
|
+
if field.type.to_s == "string" && value.is_a?(String)
|
|
59
|
+
len_err = validate_string_length(rules, value)
|
|
60
|
+
errs << len_err if len_err
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if (rules[:pattern] || rules["pattern"]) && value.is_a?(String)
|
|
64
|
+
pat_err = validate_pattern(rules, value)
|
|
65
|
+
errs << pat_err if pat_err
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
if field.type.to_s == "number"
|
|
69
|
+
num_err = validate_numeric_range(rules, value)
|
|
70
|
+
errs << num_err if num_err
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
errs
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.validate_string_length(rules, value)
|
|
77
|
+
min_len = rules[:min_length] || rules["min_length"]
|
|
78
|
+
max_len = rules[:max_length] || rules["max_length"]
|
|
79
|
+
|
|
80
|
+
return resolve_message(rules, "Minimum length is #{min_len}") if min_len && value.length < min_len
|
|
81
|
+
return resolve_message(rules, "Maximum length is #{max_len}") if max_len && value.length > max_len
|
|
82
|
+
|
|
83
|
+
nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.validate_pattern(rules, value)
|
|
87
|
+
pattern = rules[:pattern] || rules["pattern"]
|
|
88
|
+
return nil unless pattern
|
|
89
|
+
|
|
90
|
+
regex = pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern.to_s)
|
|
91
|
+
return nil if regex.match?(value)
|
|
92
|
+
|
|
93
|
+
resolve_message(rules, "Does not match the required format")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.validate_numeric_range(rules, value)
|
|
97
|
+
min = rules[:min] || rules["min"]
|
|
98
|
+
max = rules[:max] || rules["max"]
|
|
99
|
+
return nil unless min || max
|
|
100
|
+
|
|
101
|
+
num = parse_numeric(value)
|
|
102
|
+
return nil unless num
|
|
103
|
+
|
|
104
|
+
return resolve_message(rules, "Minimum value is #{min}") if min && num < min
|
|
105
|
+
return resolve_message(rules, "Maximum value is #{max}") if max && num > max
|
|
106
|
+
|
|
107
|
+
nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.parse_numeric(value)
|
|
111
|
+
return value if value.is_a?(Numeric)
|
|
112
|
+
return nil unless value.is_a?(String) && value =~ /\A-?\d+(\.\d+)?\z/
|
|
113
|
+
|
|
114
|
+
value.include?(".") ? value.to_f : value.to_i
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def self.resolve_message(rules, default_message)
|
|
118
|
+
rules&.dig(:custom_message) || rules&.dig("custom_message") || default_message
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
data/lib/kabk/version.rb
ADDED
data/lib/kabk.rb
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "kabk/version"
|
|
4
|
+
require_relative "kabk/registry"
|
|
5
|
+
require_relative "kabk/resource"
|
|
6
|
+
require_relative "kabk/field"
|
|
7
|
+
require_relative "kabk/resource_builder"
|
|
8
|
+
require_relative "kabk/schema_renderer"
|
|
9
|
+
require_relative "kabk/errors"
|
|
10
|
+
require_relative "kabk/concurrency"
|
|
11
|
+
require_relative "kabk/validator"
|
|
12
|
+
require_relative "kabk/query_builder"
|
|
13
|
+
require_relative "kabk/relation_hydrator"
|
|
14
|
+
require_relative "kabk/rest_engine"
|
|
15
|
+
require_relative "kabk/upload_handler"
|
|
16
|
+
require_relative "kabk/adapters/base"
|
|
17
|
+
require_relative "kabk/adapters/sequel_adapter"
|
|
18
|
+
|
|
19
|
+
# Core namespace and entrypoint for Kabk
|
|
20
|
+
module Kabk
|
|
21
|
+
# Register a new model as a resource
|
|
22
|
+
#
|
|
23
|
+
# @param name [String, Symbol] The unique identifier for the resource
|
|
24
|
+
# @param table [Class] The Model class (e.g. Sequel::Model)
|
|
25
|
+
# @param adapter [Kabk::Adapters::Base] Optional explicit adapter instance
|
|
26
|
+
# @yield Block evaluated in the context of a ResourceBuilder
|
|
27
|
+
def self.register(name:, table:, adapter: nil, &block)
|
|
28
|
+
resource = Resource.new(name: name, model_class: table)
|
|
29
|
+
builder = ResourceBuilder.new(resource)
|
|
30
|
+
builder.instance_eval(&block) if block_given?
|
|
31
|
+
|
|
32
|
+
# Fallbacks per protocol
|
|
33
|
+
resource.plural_name ||= "#{name}s"
|
|
34
|
+
resource.title ||= resource.plural_name.capitalize
|
|
35
|
+
resource.icon ||= "Database"
|
|
36
|
+
resource.api_path ||= "/api/admin/#{resource.plural_name}"
|
|
37
|
+
|
|
38
|
+
# Determine and assign adapter
|
|
39
|
+
if adapter
|
|
40
|
+
resource.adapter = adapter
|
|
41
|
+
elsif defined?(Sequel::Model) && table < Sequel::Model
|
|
42
|
+
resource.adapter = Adapters::SequelAdapter.new(resource)
|
|
43
|
+
else
|
|
44
|
+
raise ArgumentError, "Could not determine appropriate adapter for #{table}. Please provide an explicit adapter."
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
Registry.instance.register(resource)
|
|
48
|
+
resource
|
|
49
|
+
end
|
|
50
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: kabk
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Parham Taheri
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: concurrent-ruby
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.1'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: sequel
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '5.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: yard
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.9'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0.9'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: webrick
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rubocop
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '1.21'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '1.21'
|
|
82
|
+
description: Framework-agnostic engine that provides resource registration, JSON schema
|
|
83
|
+
manifest generation, generic CRUD engine, server-side validation, and relation hydration.
|
|
84
|
+
email:
|
|
85
|
+
- Par_taheri@yahoo.com
|
|
86
|
+
executables: []
|
|
87
|
+
extensions: []
|
|
88
|
+
extra_rdoc_files: []
|
|
89
|
+
files:
|
|
90
|
+
- CHANGELOG.md
|
|
91
|
+
- Gemfile
|
|
92
|
+
- Gemfile.lock
|
|
93
|
+
- Kabk_logo.svg
|
|
94
|
+
- LICENSE
|
|
95
|
+
- README.md
|
|
96
|
+
- doc/Kabk.html
|
|
97
|
+
- doc/Kabk/Adapters.html
|
|
98
|
+
- doc/Kabk/Adapters/Base.html
|
|
99
|
+
- doc/Kabk/Adapters/SequelAdapter.html
|
|
100
|
+
- doc/Kabk/ApiError.html
|
|
101
|
+
- doc/Kabk/Auth.html
|
|
102
|
+
- doc/Kabk/Auth/JwtStrategy.html
|
|
103
|
+
- doc/Kabk/Concurrency.html
|
|
104
|
+
- doc/Kabk/ConcurrencyConflictError.html
|
|
105
|
+
- doc/Kabk/Error.html
|
|
106
|
+
- doc/Kabk/ExportHandler.html
|
|
107
|
+
- doc/Kabk/Field.html
|
|
108
|
+
- doc/Kabk/ForbiddenError.html
|
|
109
|
+
- doc/Kabk/InvalidFieldError.html
|
|
110
|
+
- doc/Kabk/InvalidOldPasswordError.html
|
|
111
|
+
- doc/Kabk/NotFoundError.html
|
|
112
|
+
- doc/Kabk/QueryBuilder.html
|
|
113
|
+
- doc/Kabk/Registry.html
|
|
114
|
+
- doc/Kabk/RelationHydrator.html
|
|
115
|
+
- doc/Kabk/Resource.html
|
|
116
|
+
- doc/Kabk/ResourceBuilder.html
|
|
117
|
+
- doc/Kabk/RestEngine.html
|
|
118
|
+
- doc/Kabk/SchemaRenderer.html
|
|
119
|
+
- doc/Kabk/UnauthorizedError.html
|
|
120
|
+
- doc/Kabk/UploadHandler.html
|
|
121
|
+
- doc/Kabk/ValidationError.html
|
|
122
|
+
- doc/Kabk/Validator.html
|
|
123
|
+
- doc/_index.html
|
|
124
|
+
- doc/class_list.html
|
|
125
|
+
- doc/css/common.css
|
|
126
|
+
- doc/css/full_list.css
|
|
127
|
+
- doc/css/style.css
|
|
128
|
+
- doc/file.README.html
|
|
129
|
+
- doc/file_list.html
|
|
130
|
+
- doc/frames.html
|
|
131
|
+
- doc/index.html
|
|
132
|
+
- doc/js/app.js
|
|
133
|
+
- doc/js/full_list.js
|
|
134
|
+
- doc/js/jquery.js
|
|
135
|
+
- doc/method_list.html
|
|
136
|
+
- doc/top-level-namespace.html
|
|
137
|
+
- docs/API_REFERENCE.md
|
|
138
|
+
- lib/kabk.rb
|
|
139
|
+
- lib/kabk/adapters/base.rb
|
|
140
|
+
- lib/kabk/adapters/sequel_adapter.rb
|
|
141
|
+
- lib/kabk/concurrency.rb
|
|
142
|
+
- lib/kabk/errors.rb
|
|
143
|
+
- lib/kabk/field.rb
|
|
144
|
+
- lib/kabk/query_builder.rb
|
|
145
|
+
- lib/kabk/registry.rb
|
|
146
|
+
- lib/kabk/relation_hydrator.rb
|
|
147
|
+
- lib/kabk/resource.rb
|
|
148
|
+
- lib/kabk/resource_builder.rb
|
|
149
|
+
- lib/kabk/rest_engine.rb
|
|
150
|
+
- lib/kabk/schema_renderer.rb
|
|
151
|
+
- lib/kabk/upload_handler.rb
|
|
152
|
+
- lib/kabk/validator.rb
|
|
153
|
+
- lib/kabk/version.rb
|
|
154
|
+
homepage: https://github.com/par-taheri/Kabk
|
|
155
|
+
licenses:
|
|
156
|
+
- MIT
|
|
157
|
+
metadata:
|
|
158
|
+
homepage_uri: https://github.com/par-taheri/Kabk
|
|
159
|
+
source_code_uri: https://github.com/par-taheri/Kabk
|
|
160
|
+
changelog_uri: https://github.com/par-taheri/Kabk/blob/main/CHANGELOG.md
|
|
161
|
+
rdoc_options: []
|
|
162
|
+
require_paths:
|
|
163
|
+
- lib
|
|
164
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
|
+
requirements:
|
|
166
|
+
- - ">="
|
|
167
|
+
- !ruby/object:Gem::Version
|
|
168
|
+
version: 3.1.0
|
|
169
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
174
|
+
requirements: []
|
|
175
|
+
rubygems_version: 4.0.16
|
|
176
|
+
specification_version: 4
|
|
177
|
+
summary: Core engine for Schema-Driven Dynamic Admin Specification (Protocol v1.6.0).
|
|
178
|
+
test_files: []
|