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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 551e19bc7da675500d290d83212f35f4fa8562abeb5500033a7e6c824f3b15f0
4
- data.tar.gz: 1735f627d2f29068201cd97169e22dff27c4e49014197e0f66dc5c401dbbec46
3
+ metadata.gz: 31a329bb3535c369f12cf509dd4f39e713340fa026772640c929a9ffd78ac2be
4
+ data.tar.gz: cd974b6f21729d0a84a4690865905e9c279ed66e832cfef6935b52f11d0c65cd
5
5
  SHA512:
6
- metadata.gz: 3a6c78e97b72e1725b77ccc8a8baffff3f13d30f1bdb12dca821c6b9ec4d6df22ed97981196b6bb671b16b443de84a094a5b4deebcbef687602e09a35cb34973
7
- data.tar.gz: e59ea0c9a98f710336776783d4273f260cf36f3e1c6dcdbdc97aff2a2097814ebd54cd5e006620fcbf7e754557e7c796e316eca99e01309818db8b9e39e4a155
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
@@ -24,6 +24,10 @@ module Rhino
24
24
  name || email
25
25
  end
26
26
 
27
+ def token_validation_response
28
+ to_caching_json
29
+ end
30
+
27
31
  def self.roles_for_auth(auth_owner, record = nil)
28
32
  return {} unless auth_owner
29
33
 
@@ -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
@@ -10,6 +10,7 @@ require "arel-helpers"
10
10
  require "countries"
11
11
  require "devise"
12
12
  require "devise_token_auth"
13
+ require "discard"
13
14
  require "friendly_id"
14
15
  require "geocoder"
15
16
  require "omniauth"
@@ -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
- next params << { prop => [] } if desc.dig(:items, :anyOf)[0]&.dig(:$ref) == "#/components/schemas/active_storage_attachment"
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
- { prop => klasses.map(&:identifier_property).uniq }
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
- hash[param_key.remove("_attachment")] = param_value if param_value.is_a?(String) || param_value.nil?
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")] = param_value if param_value.is_a?(Array) || param_value.nil?
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
- atype = attribute_types[name.to_s].type
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
- if %i[datetime date time].include?(atype)
78
- return {
79
- type: "string",
80
- format: atype
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: atype }
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
@@ -8,9 +8,9 @@ module Rhino
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 0
11
- MINOR = 25
11
+ MINOR = 26
12
12
  TINY = 0
13
- PRE = "beta.17"
13
+ PRE = "beta.1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
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.25.0.beta.17
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: 2025-05-22 00:00:00.000000000 Z
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.2
548
+ rubygems_version: 3.6.7
529
549
  specification_version: 4
530
550
  summary: ''
531
551
  test_files: []