rhino_project_core 0.25.0.beta.17 → 0.26.0.beta.1
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/app/controllers/rhino/active_record_discard_controller.rb +28 -0
- data/app/models/rhino/user.rb +4 -0
- data/app/overrides/devise_token_auth/registrations_controller_override.rb +8 -0
- data/lib/generators/rhino/ui/route/route_generator.rb +54 -0
- data/lib/generators/rhino/ui/route/templates/$id.edit.tsx.tt +12 -0
- data/lib/generators/rhino/ui/route/templates/$id.index.tsx.tt +12 -0
- data/lib/generators/rhino/ui/route/templates/index.tsx.tt +10 -0
- data/lib/generators/rhino/ui/route/templates/new.tsx.tt +17 -0
- data/lib/rhino/engine.rb +1 -0
- data/lib/rhino/resource/active_record_extension/params.rb +23 -4
- data/lib/rhino/resource/active_record_extension/properties_describe.rb +18 -11
- data/lib/rhino/version.rb +2 -2
- metadata +23 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31a329bb3535c369f12cf509dd4f39e713340fa026772640c929a9ffd78ac2be
|
|
4
|
+
data.tar.gz: cd974b6f21729d0a84a4690865905e9c279ed66e832cfef6935b52f11d0c65cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f1f3bcb8b9b1e03e8915e8cdf158dc707267a24d28c9f002854f2bc1de4ec225126695f13f9a9fe60e335138636d42843fc320444c85f58a5068382794c5b69d
|
|
7
|
+
data.tar.gz: 3791762be7a5f82b5f29833f8b9e3fc3f0470219fb1241bc4d09e178a70aa39a82ca4b0e1ab0145e6f98c0d3d0f30cad886a065bbbcb81b5bdae6fe5b99eed3d
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rhino
|
|
4
|
+
class ActiveRecordDiscardController < CrudController
|
|
5
|
+
def index
|
|
6
|
+
authorize klass
|
|
7
|
+
|
|
8
|
+
@models = klass.sieves.resolve(policy_scope(klass), params).kept
|
|
9
|
+
render json: {
|
|
10
|
+
results: @models.eager_load_refs.map { |m| permit_model(m) },
|
|
11
|
+
total: @models.unscope(:limit, :offset).reselect(:id).count
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def show
|
|
16
|
+
@model = authorize find_resource(policy_scope(klass).kept.eager_load_refs)
|
|
17
|
+
|
|
18
|
+
permit_and_render
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def destroy
|
|
22
|
+
@model = authorize find_resource
|
|
23
|
+
@model.discard!
|
|
24
|
+
|
|
25
|
+
permit_and_render
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/app/models/rhino/user.rb
CHANGED
|
@@ -13,6 +13,14 @@ module DeviseTokenAuth::RegistrationsController::Extensions
|
|
|
13
13
|
create_organization(resource) if Rhino.resources.include?("Organization")
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
# Get all the information just like the token_validation_response and sign_in
|
|
18
|
+
def render_create_success
|
|
19
|
+
render json: {
|
|
20
|
+
success: true,
|
|
21
|
+
data: resource_data(resource_json: @resource.token_validation_response)
|
|
22
|
+
}
|
|
23
|
+
end
|
|
16
24
|
end
|
|
17
25
|
|
|
18
26
|
class DeviseTokenAuth::RegistrationsController
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rhino
|
|
4
|
+
module Generators
|
|
5
|
+
module Ui
|
|
6
|
+
class RouteGenerator < ::Rails::Generators::NamedBase
|
|
7
|
+
class_option :routes_directory, type: :string, desc: "The directory to copy the routes to",
|
|
8
|
+
default: "app/frontend/routes", group: :route
|
|
9
|
+
class_option :route_path, type: :string, desc: "The path to routes relative to the routes directory", default: "_authenticated/$owner", group: :route
|
|
10
|
+
class_option :model_path, type: :string, desc: "The base path name for the model (defaults to model plural name)", group: :route
|
|
11
|
+
class_option :copy_index, type: :boolean, desc: "Copy the index route", default: true, group: :route
|
|
12
|
+
class_option :copy_show, type: :boolean, desc: "Copy the show route", default: true, group: :route
|
|
13
|
+
class_option :copy_create, type: :boolean, desc: "Copy the create route", default: true, group: :route
|
|
14
|
+
class_option :copy_edit, type: :boolean, desc: "Copy the edit route", default: true, group: :route
|
|
15
|
+
|
|
16
|
+
source_root File.expand_path("templates", __dir__)
|
|
17
|
+
|
|
18
|
+
def copy_index_route
|
|
19
|
+
return unless options.copy_index?
|
|
20
|
+
template "index.tsx", route_file_path("index.tsx")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def copy_show_route
|
|
24
|
+
return unless options.copy_show?
|
|
25
|
+
template "$id.index.tsx", route_file_path("$id.index.tsx")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def copy_create_route
|
|
29
|
+
return unless options.copy_create?
|
|
30
|
+
template "new.tsx", route_file_path("new.tsx")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def copy_edit_route
|
|
34
|
+
return unless options.copy_edit?
|
|
35
|
+
template "$id.edit.tsx", route_file_path("$id.edit.tsx")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
def model_path
|
|
40
|
+
options[:model_path] || plural_table_name
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def route_path
|
|
44
|
+
File.join("/", options[:route_path], model_path, "/")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def route_file_path(file_name)
|
|
49
|
+
File.join(options[:routes_directory], options[:route_path], model_path, file_name)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ModelEditPage } from '@rhino-project/ui-heroui';
|
|
2
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('<%= route_path %>$id/edit')({
|
|
5
|
+
component: RouteComponent
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
function RouteComponent() {
|
|
9
|
+
const { id: modelId } = Route.useParams();
|
|
10
|
+
|
|
11
|
+
return <ModelEditPage model="<%= singular_table_name %>" modelId={modelId} />;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ModelShowPage } from '@rhino-project/ui-heroui';
|
|
2
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('<%= route_path %>$id/')({
|
|
5
|
+
component: RouteComponent
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
function RouteComponent() {
|
|
9
|
+
const { id: modelId } = Route.useParams();
|
|
10
|
+
|
|
11
|
+
return <ModelShowPage model="<%= singular_table_name %>" modelId={modelId} />;
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ModelIndexPage } from '@rhino-project/ui-heroui';
|
|
2
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('<%= route_path %>')({
|
|
5
|
+
component: RouteComponent
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
function RouteComponent() {
|
|
9
|
+
return <ModelIndexPage model="<%= singular_table_name %>" syncUrl />;
|
|
10
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ModelCreatePage } from '@rhino-project/ui-heroui';
|
|
2
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('<%= route_path %>new')({
|
|
5
|
+
validateSearch: (search: Record<string, unknown>): { parentId: number } => {
|
|
6
|
+
return {
|
|
7
|
+
parentId: Number(search?.parentId)
|
|
8
|
+
};
|
|
9
|
+
},
|
|
10
|
+
component: RouteComponent
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
function RouteComponent() {
|
|
14
|
+
const { parentId } = Route.useSearch();
|
|
15
|
+
|
|
16
|
+
return <ModelCreatePage model="<%= singular_table_name %>" parentId={parentId} />;
|
|
17
|
+
}
|
data/lib/rhino/engine.rb
CHANGED
|
@@ -89,7 +89,12 @@ module Rhino
|
|
|
89
89
|
# An array of references
|
|
90
90
|
if desc[:type] == :array && (desc[:items].key?(:$ref) || desc[:items].key?(:anyOf))
|
|
91
91
|
# FIXME: Hack for has_many_attached
|
|
92
|
-
|
|
92
|
+
if desc.dig(:items, :anyOf)[0]&.dig(:$ref) == "#/components/schemas/active_storage_attachment"
|
|
93
|
+
params << { prop => [] }
|
|
94
|
+
params << { prop => ["signed_id"] }
|
|
95
|
+
|
|
96
|
+
next
|
|
97
|
+
end
|
|
93
98
|
|
|
94
99
|
# We only accept if the active record accepts it
|
|
95
100
|
next unless nested_attributes_options.key?(prop_sym) || desc.dig(:items, :anyOf)[0]&.dig(:$ref)
|
|
@@ -138,7 +143,8 @@ module Rhino
|
|
|
138
143
|
|
|
139
144
|
{ prop => assoc_params.flatten.uniq }
|
|
140
145
|
else
|
|
141
|
-
|
|
146
|
+
# For ActiveStorage::Attachment we want to accept the signed_id
|
|
147
|
+
{ prop => klasses.map { it == ActiveStorage::Attachment ? "signed_id" : it.identifier_property }.uniq }
|
|
142
148
|
end
|
|
143
149
|
end
|
|
144
150
|
|
|
@@ -162,12 +168,25 @@ module Rhino
|
|
|
162
168
|
# FIXME
|
|
163
169
|
# Hack to rewrite for attachment/attachments and guard against object resubmission
|
|
164
170
|
if param_key.end_with?("_attachment")
|
|
165
|
-
|
|
171
|
+
# If its a string, its the signed_id
|
|
172
|
+
hash[param_key.remove("_attachment")] = if param_value.is_a?(String) || param_value.nil?
|
|
173
|
+
param_value
|
|
174
|
+
|
|
175
|
+
# Otherwise if its a hash, and we want the signed_id from it
|
|
176
|
+
elsif param_value.is_a?(ActionController::Parameters)
|
|
177
|
+
param_value["signed_id"]
|
|
178
|
+
end
|
|
166
179
|
|
|
167
180
|
next
|
|
168
181
|
end
|
|
169
182
|
if param_key.end_with?("_attachments")
|
|
170
|
-
hash[param_key.remove("_attachments")] =
|
|
183
|
+
hash[param_key.remove("_attachments")] = if param_value.nil?
|
|
184
|
+
param_value
|
|
185
|
+
|
|
186
|
+
# if an element is a string, its the signed_id, if its a hash, we want the signed_id from it
|
|
187
|
+
elsif param_value.is_a?(Array)
|
|
188
|
+
param_value.map { it.is_a?(ActionController::Parameters) ? it["signed_id"] : it }
|
|
189
|
+
end
|
|
171
190
|
|
|
172
191
|
next
|
|
173
192
|
end
|
|
@@ -61,27 +61,35 @@ module Rhino
|
|
|
61
61
|
}
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
DATE_FORMATS = %i[datetime date time].freeze
|
|
64
65
|
def property_type_and_format_attr(name)
|
|
65
|
-
|
|
66
|
+
type = attribute_types[name.to_s].type
|
|
67
|
+
format = nil
|
|
66
68
|
|
|
67
69
|
# The PG array delegates type to "subtype" which is the actual type of the array elements
|
|
68
70
|
if attribute_types[name.to_s].is_a? ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array
|
|
69
71
|
return {
|
|
70
72
|
type: :array,
|
|
71
|
-
items: {
|
|
72
|
-
type: atype
|
|
73
|
-
}
|
|
73
|
+
items: { type: }
|
|
74
74
|
}
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
# Identifier is a special format for identification on the front end
|
|
78
|
+
format = :identifier if name == identifier_property
|
|
79
|
+
|
|
80
|
+
# Float is double precision in postgres by default
|
|
81
|
+
if type == :float
|
|
82
|
+
type = :number
|
|
83
|
+
format = :double
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Dates and times are strings
|
|
87
|
+
if DATE_FORMATS.include?(type)
|
|
88
|
+
format = type
|
|
89
|
+
type = :string
|
|
82
90
|
end
|
|
83
91
|
|
|
84
|
-
{ type:
|
|
92
|
+
{ type:, format: }.compact
|
|
85
93
|
end
|
|
86
94
|
|
|
87
95
|
def nested_array_options(name)
|
|
@@ -126,7 +134,6 @@ module Rhino
|
|
|
126
134
|
|
|
127
135
|
def property_type_and_format(name) # rubocop:disable Metrics/AbcSize
|
|
128
136
|
# Special cases
|
|
129
|
-
return { type: :identifier } if name == identifier_property
|
|
130
137
|
return { type: :string } if defined_enums.key?(name)
|
|
131
138
|
|
|
132
139
|
# FIXME: Hack for tags for now
|
data/lib/rhino/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rhino_project_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.26.0.beta.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- JP Rosevear
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|
|
@@ -141,6 +141,20 @@ dependencies:
|
|
|
141
141
|
- - '='
|
|
142
142
|
- !ruby/object:Gem::Version
|
|
143
143
|
version: 1.2.5
|
|
144
|
+
- !ruby/object:Gem::Dependency
|
|
145
|
+
name: discard
|
|
146
|
+
requirement: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - '='
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: 1.4.0
|
|
151
|
+
type: :runtime
|
|
152
|
+
prerelease: false
|
|
153
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
154
|
+
requirements:
|
|
155
|
+
- - '='
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: 1.4.0
|
|
144
158
|
- !ruby/object:Gem::Dependency
|
|
145
159
|
name: friendly_id
|
|
146
160
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -383,6 +397,7 @@ files:
|
|
|
383
397
|
- app/controllers/concerns/rhino/set_current_user.rb
|
|
384
398
|
- app/controllers/rhino/account_controller.rb
|
|
385
399
|
- app/controllers/rhino/active_model_extension_controller.rb
|
|
400
|
+
- app/controllers/rhino/active_record_discard_controller.rb
|
|
386
401
|
- app/controllers/rhino/base_controller.rb
|
|
387
402
|
- app/controllers/rhino/crud_controller.rb
|
|
388
403
|
- app/controllers/rhino/simple_controller.rb
|
|
@@ -450,6 +465,11 @@ files:
|
|
|
450
465
|
- lib/generators/rhino/module/templates/test/test_helper.rb
|
|
451
466
|
- lib/generators/rhino/policy/policy_generator.rb
|
|
452
467
|
- lib/generators/rhino/policy/templates/policy.rb.tt
|
|
468
|
+
- lib/generators/rhino/ui/route/route_generator.rb
|
|
469
|
+
- lib/generators/rhino/ui/route/templates/$id.edit.tsx.tt
|
|
470
|
+
- lib/generators/rhino/ui/route/templates/$id.index.tsx.tt
|
|
471
|
+
- lib/generators/rhino/ui/route/templates/index.tsx.tt
|
|
472
|
+
- lib/generators/rhino/ui/route/templates/new.tsx.tt
|
|
453
473
|
- lib/generators/rhino/update/update_generator.rb
|
|
454
474
|
- lib/generators/test_unit/rhino_policy_generator.rb
|
|
455
475
|
- lib/generators/test_unit/templates/policy_test.rb.tt
|
|
@@ -525,7 +545,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
525
545
|
- !ruby/object:Gem::Version
|
|
526
546
|
version: '0'
|
|
527
547
|
requirements: []
|
|
528
|
-
rubygems_version: 3.6.
|
|
548
|
+
rubygems_version: 3.6.7
|
|
529
549
|
specification_version: 4
|
|
530
550
|
summary: ''
|
|
531
551
|
test_files: []
|