dhs 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/.github/workflows/rubocop.yml +27 -0
- data/.github/workflows/test.yml +27 -0
- data/.gitignore +39 -0
- data/.rubocop.yml +186 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +674 -0
- data/README.md +2807 -0
- data/Rakefile +26 -0
- data/dhs.gemspec +44 -0
- data/docs/accessing-data.png +0 -0
- data/lib/dhs.rb +67 -0
- data/lib/dhs/collection.rb +84 -0
- data/lib/dhs/complex.rb +158 -0
- data/lib/dhs/concerns/autoload_records.rb +57 -0
- data/lib/dhs/concerns/collection/handle_nested.rb +43 -0
- data/lib/dhs/concerns/collection/internal_collection.rb +74 -0
- data/lib/dhs/concerns/configuration.rb +20 -0
- data/lib/dhs/concerns/data/becomes.rb +18 -0
- data/lib/dhs/concerns/data/equality.rb +14 -0
- data/lib/dhs/concerns/data/extend.rb +87 -0
- data/lib/dhs/concerns/data/json.rb +14 -0
- data/lib/dhs/concerns/data/to_hash.rb +14 -0
- data/lib/dhs/concerns/inspect.rb +70 -0
- data/lib/dhs/concerns/is_href.rb +15 -0
- data/lib/dhs/concerns/item/destroy.rb +38 -0
- data/lib/dhs/concerns/item/endpoint_lookup.rb +27 -0
- data/lib/dhs/concerns/item/save.rb +55 -0
- data/lib/dhs/concerns/item/update.rb +50 -0
- data/lib/dhs/concerns/item/validation.rb +61 -0
- data/lib/dhs/concerns/o_auth.rb +25 -0
- data/lib/dhs/concerns/option_blocks.rb +26 -0
- data/lib/dhs/concerns/proxy/accessors.rb +132 -0
- data/lib/dhs/concerns/proxy/create.rb +45 -0
- data/lib/dhs/concerns/proxy/link.rb +25 -0
- data/lib/dhs/concerns/proxy/problems.rb +27 -0
- data/lib/dhs/concerns/record/attribute_assignment.rb +25 -0
- data/lib/dhs/concerns/record/batch.rb +40 -0
- data/lib/dhs/concerns/record/chainable.rb +465 -0
- data/lib/dhs/concerns/record/configuration.rb +103 -0
- data/lib/dhs/concerns/record/create.rb +24 -0
- data/lib/dhs/concerns/record/custom_setters.rb +22 -0
- data/lib/dhs/concerns/record/destroy.rb +18 -0
- data/lib/dhs/concerns/record/endpoints.rb +108 -0
- data/lib/dhs/concerns/record/equality.rb +14 -0
- data/lib/dhs/concerns/record/find.rb +86 -0
- data/lib/dhs/concerns/record/find_by.rb +38 -0
- data/lib/dhs/concerns/record/first.rb +20 -0
- data/lib/dhs/concerns/record/href_for.rb +19 -0
- data/lib/dhs/concerns/record/last.rb +27 -0
- data/lib/dhs/concerns/record/mapping.rb +25 -0
- data/lib/dhs/concerns/record/merge.rb +26 -0
- data/lib/dhs/concerns/record/model.rb +23 -0
- data/lib/dhs/concerns/record/pagination.rb +49 -0
- data/lib/dhs/concerns/record/provider.rb +23 -0
- data/lib/dhs/concerns/record/relations.rb +26 -0
- data/lib/dhs/concerns/record/request.rb +581 -0
- data/lib/dhs/concerns/record/scope.rb +25 -0
- data/lib/dhs/concerns/record/tracing.rb +24 -0
- data/lib/dhs/concerns/record/update.rb +17 -0
- data/lib/dhs/config.rb +24 -0
- data/lib/dhs/data.rb +180 -0
- data/lib/dhs/endpoint.rb +12 -0
- data/lib/dhs/interceptors/auto_oauth/interceptor.rb +33 -0
- data/lib/dhs/interceptors/auto_oauth/thread_registry.rb +18 -0
- data/lib/dhs/interceptors/extended_rollbar/handler.rb +40 -0
- data/lib/dhs/interceptors/extended_rollbar/interceptor.rb +20 -0
- data/lib/dhs/interceptors/extended_rollbar/thread_registry.rb +19 -0
- data/lib/dhs/interceptors/request_cycle_cache/interceptor.rb +41 -0
- data/lib/dhs/interceptors/request_cycle_cache/thread_registry.rb +18 -0
- data/lib/dhs/item.rb +59 -0
- data/lib/dhs/pagination/base.rb +90 -0
- data/lib/dhs/pagination/link.rb +21 -0
- data/lib/dhs/pagination/offset.rb +22 -0
- data/lib/dhs/pagination/page.rb +18 -0
- data/lib/dhs/pagination/start.rb +22 -0
- data/lib/dhs/pagination/total_pages.rb +9 -0
- data/lib/dhs/problems/base.rb +113 -0
- data/lib/dhs/problems/errors.rb +69 -0
- data/lib/dhs/problems/nested/base.rb +54 -0
- data/lib/dhs/problems/nested/errors.rb +16 -0
- data/lib/dhs/problems/nested/warnings.rb +15 -0
- data/lib/dhs/problems/warnings.rb +24 -0
- data/lib/dhs/proxy.rb +69 -0
- data/lib/dhs/railtie.rb +34 -0
- data/lib/dhs/record.rb +112 -0
- data/lib/dhs/rspec.rb +10 -0
- data/lib/dhs/test/stubbable_records.rb +34 -0
- data/lib/dhs/unprocessable.rb +6 -0
- data/lib/dhs/version.rb +5 -0
- data/script/ci/build.sh +18 -0
- data/spec/auto_oauth_spec.rb +163 -0
- data/spec/autoloading_spec.rb +45 -0
- data/spec/collection/accessors_spec.rb +31 -0
- data/spec/collection/collection_items_spec.rb +44 -0
- data/spec/collection/configurable_spec.rb +43 -0
- data/spec/collection/delegate_spec.rb +21 -0
- data/spec/collection/enumerable_spec.rb +27 -0
- data/spec/collection/href_spec.rb +17 -0
- data/spec/collection/meta_data_spec.rb +58 -0
- data/spec/collection/respond_to_spec.rb +20 -0
- data/spec/collection/to_a_spec.rb +34 -0
- data/spec/collection/to_ary_spec.rb +40 -0
- data/spec/collection/without_object_items_spec.rb +27 -0
- data/spec/complex/reduce_spec.rb +202 -0
- data/spec/concerns/record/request_spec.rb +78 -0
- data/spec/data/collection_spec.rb +56 -0
- data/spec/data/equality_spec.rb +23 -0
- data/spec/data/inspect_spec.rb +88 -0
- data/spec/data/is_item_or_collection_spec.rb +40 -0
- data/spec/data/item_spec.rb +106 -0
- data/spec/data/merge_spec.rb +27 -0
- data/spec/data/parent_spec.rb +39 -0
- data/spec/data/raw_spec.rb +48 -0
- data/spec/data/respond_to_spec.rb +26 -0
- data/spec/data/root_spec.rb +25 -0
- data/spec/data/select_spec.rb +27 -0
- data/spec/data/to_ary_spec.rb +28 -0
- data/spec/data/to_json_spec.rb +68 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +26 -0
- data/spec/dummy/app/controllers/automatic_authentication_controller.rb +29 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/error_handling_with_chains_controller.rb +36 -0
- data/spec/dummy/app/controllers/extended_rollbar_controller.rb +10 -0
- data/spec/dummy/app/controllers/option_blocks_controller.rb +15 -0
- data/spec/dummy/app/controllers/request_cycle_cache_controller.rb +27 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/concerns/dummy_customer/some_concern.rb +9 -0
- data/spec/dummy/app/models/dummy_customer.rb +7 -0
- data/spec/dummy/app/models/dummy_record.rb +6 -0
- data/spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb +6 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb +7 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb +7 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb +6 -0
- data/spec/dummy/app/models/dummy_record_with_oauth.rb +7 -0
- data/spec/dummy/app/models/dummy_user.rb +6 -0
- data/spec/dummy/app/models/providers/customer_system.rb +7 -0
- data/spec/dummy/app/models/providers/internal_services.rb +7 -0
- data/spec/dummy/app/views/error_handling_with_chains/error.html.erb +1 -0
- data/spec/dummy/app/views/error_handling_with_chains/show.html.erb +3 -0
- data/spec/dummy/app/views/form_for.html.erb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +5 -0
- data/spec/dummy/bin/rails +6 -0
- data/spec/dummy/bin/rake +6 -0
- data/spec/dummy/config.ru +6 -0
- data/spec/dummy/config/application.rb +16 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +36 -0
- data/spec/dummy/config/environments/production.rb +77 -0
- data/spec/dummy/config/environments/test.rb +40 -0
- data/spec/dummy/config/initializers/assets.rb +10 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/dhs.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +6 -0
- data/spec/dummy/config/initializers/rollbar.rb +9 -0
- data/spec/dummy/config/initializers/session_store.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +11 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +27 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/endpoint/for_url_spec.rb +27 -0
- data/spec/extended_rollbar_spec.rb +67 -0
- data/spec/item/access_errors_spec.rb +31 -0
- data/spec/item/accessors_spec.rb +21 -0
- data/spec/item/add_error_spec.rb +21 -0
- data/spec/item/becomes_spec.rb +38 -0
- data/spec/item/blacklisted_keywords_spec.rb +28 -0
- data/spec/item/delegate_spec.rb +32 -0
- data/spec/item/destroy_spec.rb +113 -0
- data/spec/item/dig_spec.rb +29 -0
- data/spec/item/error_codes_spec.rb +55 -0
- data/spec/item/errors_spec.rb +324 -0
- data/spec/item/fetch_spec.rb +39 -0
- data/spec/item/getter_spec.rb +24 -0
- data/spec/item/internal_data_structure_spec.rb +37 -0
- data/spec/item/map_spec.rb +46 -0
- data/spec/item/nested_errors_spec.rb +27 -0
- data/spec/item/partial_update_spec.rb +168 -0
- data/spec/item/respond_to_spec.rb +31 -0
- data/spec/item/save_spec.rb +115 -0
- data/spec/item/setter_spec.rb +44 -0
- data/spec/item/translate_errors_spec.rb +257 -0
- data/spec/item/update_spec.rb +161 -0
- data/spec/item/validation_spec.rb +131 -0
- data/spec/item/warning_codes_spec.rb +55 -0
- data/spec/item/warnings_spec.rb +51 -0
- data/spec/option_blocks/ensure_reset_between_requests_spec.rb +23 -0
- data/spec/option_blocks/main_spec.rb +54 -0
- data/spec/pagination/link/current_page_spec.rb +19 -0
- data/spec/pagination/link/pages_left_spec.rb +36 -0
- data/spec/pagination/link/parallel_spec.rb +19 -0
- data/spec/pagination/link/total_spec.rb +45 -0
- data/spec/pagination/offset/pages_left_spec.rb +26 -0
- data/spec/pagination/parameters_spec.rb +59 -0
- data/spec/pagination/total_pages_spec.rb +51 -0
- data/spec/proxy/create_sub_resource_spec.rb +182 -0
- data/spec/proxy/load_spec.rb +75 -0
- data/spec/proxy/record_identification_spec.rb +35 -0
- data/spec/rails_helper.rb +13 -0
- data/spec/record/all_spec.rb +133 -0
- data/spec/record/attribute_assignment_spec.rb +28 -0
- data/spec/record/build_spec.rb +26 -0
- data/spec/record/cast_nested_data_spec.rb +80 -0
- data/spec/record/compact_spec.rb +93 -0
- data/spec/record/create_spec.rb +160 -0
- data/spec/record/creation_failed_spec.rb +55 -0
- data/spec/record/custom_setters_spec.rb +42 -0
- data/spec/record/definitions_spec.rb +29 -0
- data/spec/record/destroy_spec.rb +38 -0
- data/spec/record/dig_configuration_spec.rb +75 -0
- data/spec/record/dup_spec.rb +20 -0
- data/spec/record/endpoint_inheritance_spec.rb +65 -0
- data/spec/record/endpoint_options_spec.rb +51 -0
- data/spec/record/endpoint_priorities_spec.rb +24 -0
- data/spec/record/endpoints_spec.rb +96 -0
- data/spec/record/equality_spec.rb +27 -0
- data/spec/record/error_handling_integration_spec.rb +25 -0
- data/spec/record/error_handling_spec.rb +40 -0
- data/spec/record/expanded_spec.rb +69 -0
- data/spec/record/fetch_spec.rb +40 -0
- data/spec/record/find_by_chains_spec.rb +21 -0
- data/spec/record/find_by_spec.rb +76 -0
- data/spec/record/find_each_spec.rb +57 -0
- data/spec/record/find_in_batches_spec.rb +122 -0
- data/spec/record/find_in_parallel_spec.rb +67 -0
- data/spec/record/find_spec.rb +103 -0
- data/spec/record/first_spec.rb +39 -0
- data/spec/record/force_merge_spec.rb +55 -0
- data/spec/record/handle_includes_errors_spec.rb +33 -0
- data/spec/record/has_many_spec.rb +118 -0
- data/spec/record/has_one_spec.rb +114 -0
- data/spec/record/href_for_spec.rb +24 -0
- data/spec/record/ignore_errors_spec.rb +137 -0
- data/spec/record/immutable_chains_spec.rb +22 -0
- data/spec/record/includes_after_expansion_spec.rb +70 -0
- data/spec/record/includes_expanded_spec.rb +37 -0
- data/spec/record/includes_first_page_spec.rb +738 -0
- data/spec/record/includes_missing_spec.rb +57 -0
- data/spec/record/includes_spec.rb +690 -0
- data/spec/record/includes_warning_spec.rb +46 -0
- data/spec/record/item_key_spec.rb +81 -0
- data/spec/record/items_created_key_configuration_spec.rb +37 -0
- data/spec/record/last_spec.rb +64 -0
- data/spec/record/loading_twice_spec.rb +19 -0
- data/spec/record/mapping_spec.rb +103 -0
- data/spec/record/model_name_spec.rb +17 -0
- data/spec/record/new_spec.rb +106 -0
- data/spec/record/options_getter_spec.rb +25 -0
- data/spec/record/options_spec.rb +164 -0
- data/spec/record/paginatable_collection_spec.rb +360 -0
- data/spec/record/pagination_chain_spec.rb +101 -0
- data/spec/record/pagination_links_spec.rb +72 -0
- data/spec/record/pagination_spec.rb +71 -0
- data/spec/record/persisted_spec.rb +52 -0
- data/spec/record/provider_spec.rb +40 -0
- data/spec/record/references_spec.rb +95 -0
- data/spec/record/relation_caching_spec.rb +120 -0
- data/spec/record/reload_by_id_spec.rb +43 -0
- data/spec/record/reload_spec.rb +64 -0
- data/spec/record/request_spec.rb +90 -0
- data/spec/record/save_spec.rb +40 -0
- data/spec/record/scope_chains_spec.rb +39 -0
- data/spec/record/select_spec.rb +17 -0
- data/spec/record/to_ary_spec.rb +65 -0
- data/spec/record/to_hash_spec.rb +22 -0
- data/spec/record/to_json_spec.rb +22 -0
- data/spec/record/tracing_spec.rb +149 -0
- data/spec/record/update_spec.rb +61 -0
- data/spec/record/where_chains_spec.rb +57 -0
- data/spec/record/where_spec.rb +62 -0
- data/spec/record/where_values_hash_spec.rb +32 -0
- data/spec/request_cycle_cache_spec.rb +106 -0
- data/spec/require_dhs_spec.rb +9 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/stubs/all_spec.rb +69 -0
- data/spec/support/fixtures/json/feedback.json +11 -0
- data/spec/support/fixtures/json/feedbacks.json +174 -0
- data/spec/support/fixtures/json/localina_content_ad.json +23 -0
- data/spec/support/load_json.rb +5 -0
- data/spec/support/request_cycle_cache.rb +10 -0
- data/spec/support/reset.rb +67 -0
- data/spec/views/form_for_spec.rb +20 -0
- metadata +783 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'rdoc/task'
|
|
10
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
11
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
12
|
+
rdoc.title = 'DHS'
|
|
13
|
+
rdoc.options << '--line-numbers'
|
|
14
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
15
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
begin
|
|
19
|
+
require 'rspec/core/rake_task'
|
|
20
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
21
|
+
task default: :spec
|
|
22
|
+
rescue LoadError
|
|
23
|
+
# no rspec available
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Bundler::GemHelper.install_tasks
|
data/dhs.gemspec
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
|
4
|
+
|
|
5
|
+
# Maintain your gem's version:
|
|
6
|
+
require 'dhs/version'
|
|
7
|
+
|
|
8
|
+
# Describe your gem and declare its dependencies:
|
|
9
|
+
Gem::Specification.new do |s|
|
|
10
|
+
s.name = 'dhs'
|
|
11
|
+
s.version = DHS::VERSION
|
|
12
|
+
s.authors = ['https://github.com/DePayFi/dhs/graphs/contributors']
|
|
13
|
+
s.email = ['engineering@depay.fi']
|
|
14
|
+
s.homepage = 'https://github.com/DePayFi/dhs'
|
|
15
|
+
s.summary = 'REST services accelerator: Rails gem providing an easy, active-record-like interface for http (hypermedia) json services'
|
|
16
|
+
s.description = 'DHS ia a Rails-Gem, providing an ActiveRecord like interface to access HTTP-JSON-Services from Rails Applications. Special features provided by this gem are: Multiple endpoint configuration per resource, active-record-like query-chains, scopes, error handling, relations, request cycle cache, batch processing, including linked resources (hypermedia), data maps (data accessing), nested-resource handling, ActiveModel like backend validation conversion, formbuilder-compatible, three types of pagination support, service configuration per resource, kaminari-support and much more.'
|
|
17
|
+
|
|
18
|
+
s.files = `git ls-files`.split("\n")
|
|
19
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
|
20
|
+
s.require_paths = ['lib']
|
|
21
|
+
|
|
22
|
+
s.requirements << 'Ruby >= 3.0.0'
|
|
23
|
+
s.required_ruby_version = '>= 3.0.0'
|
|
24
|
+
|
|
25
|
+
s.add_dependency 'activemodel'
|
|
26
|
+
s.add_dependency 'activesupport', '>= 6'
|
|
27
|
+
s.add_dependency 'dhc'
|
|
28
|
+
s.add_dependency 'local_uri'
|
|
29
|
+
|
|
30
|
+
s.add_development_dependency 'capybara'
|
|
31
|
+
s.add_development_dependency 'json', '>= 1.8.2'
|
|
32
|
+
s.add_development_dependency 'pry'
|
|
33
|
+
s.add_development_dependency 'pry-byebug'
|
|
34
|
+
s.add_development_dependency 'rails', '>= 6'
|
|
35
|
+
s.add_development_dependency 'rollbar', '<= 2.24.0'
|
|
36
|
+
s.add_development_dependency 'rspec-rails', '>= 3.7.0'
|
|
37
|
+
s.add_development_dependency 'rubocop'
|
|
38
|
+
s.add_development_dependency 'rubocop-rspec'
|
|
39
|
+
s.add_development_dependency 'sprockets', '< 4'
|
|
40
|
+
s.add_development_dependency 'webmock'
|
|
41
|
+
s.add_development_dependency 'webrick'
|
|
42
|
+
|
|
43
|
+
s.license = 'GPL-3.0'
|
|
44
|
+
end
|
|
Binary file
|
data/lib/dhs.rb
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'dhc'
|
|
4
|
+
|
|
5
|
+
module DHS
|
|
6
|
+
autoload :Configuration, 'dhs/concerns/configuration'
|
|
7
|
+
autoload :AutoloadRecords, 'dhs/concerns/autoload_records'
|
|
8
|
+
autoload :Collection, 'dhs/collection'
|
|
9
|
+
autoload :Complex, 'dhs/complex'
|
|
10
|
+
autoload :Config, 'dhs/config'
|
|
11
|
+
autoload :Data, 'dhs/data'
|
|
12
|
+
autoload :ExtendedRollbar, 'dhs/interceptors/extended_rollbar/interceptor'
|
|
13
|
+
autoload :Endpoint, 'dhs/endpoint'
|
|
14
|
+
autoload :Inspect, 'dhs/concerns/inspect'
|
|
15
|
+
module Interceptors
|
|
16
|
+
module AutoOauth
|
|
17
|
+
autoload :ThreadRegistry, 'dhs/interceptors/auto_oauth/thread_registry'
|
|
18
|
+
autoload :Interceptor, 'dhs/interceptors/auto_oauth/interceptor'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module RequestCycleCache
|
|
22
|
+
autoload :ThreadRegistry, 'dhs/interceptors/request_cycle_cache/thread_registry'
|
|
23
|
+
autoload :Interceptor, 'dhs/interceptors/request_cycle_cache/interceptor'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module ExtendedRollbar
|
|
27
|
+
autoload :ThreadRegistry, 'dhs/interceptors/extended_rollbar/thread_registry'
|
|
28
|
+
autoload :Interceptor, 'dhs/interceptors/extended_rollbar/interceptor'
|
|
29
|
+
autoload :Handler, 'dhs/interceptors/extended_rollbar/handler'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
autoload :IsHref, 'dhs/concerns/is_href'
|
|
33
|
+
autoload :Item, 'dhs/item'
|
|
34
|
+
autoload :OAuth, 'dhs/concerns/o_auth.rb'
|
|
35
|
+
autoload :OptionBlocks, 'dhs/concerns/option_blocks'
|
|
36
|
+
autoload :Pagination, 'dhs/pagination/base'
|
|
37
|
+
module Pagination
|
|
38
|
+
autoload :Offset, 'dhs/pagination/offset'
|
|
39
|
+
autoload :Page, 'dhs/pagination/page'
|
|
40
|
+
autoload :TotalPages, 'dhs/pagination/total_pages'
|
|
41
|
+
autoload :Start, 'dhs/pagination/start'
|
|
42
|
+
autoload :Link, 'dhs/pagination/link'
|
|
43
|
+
end
|
|
44
|
+
autoload :Problems, 'dhs/problems/base'
|
|
45
|
+
module Problems
|
|
46
|
+
autoload :Base, 'dhs/problems/base'
|
|
47
|
+
autoload :Errors, 'dhs/problems/errors'
|
|
48
|
+
autoload :Nested, 'dhs/problems/nested/base'
|
|
49
|
+
module Nested
|
|
50
|
+
autoload :Base, 'dhs/problems/nested/base'
|
|
51
|
+
autoload :Errors, 'dhs/problems/nested/errors'
|
|
52
|
+
autoload :Warnings, 'dhs/problems/nested/warnings'
|
|
53
|
+
end
|
|
54
|
+
autoload :Warnings, 'dhs/problems/warnings'
|
|
55
|
+
end
|
|
56
|
+
autoload :Proxy, 'dhs/proxy'
|
|
57
|
+
autoload :Record, 'dhs/record'
|
|
58
|
+
autoload :Unprocessable, 'dhs/unprocessable'
|
|
59
|
+
|
|
60
|
+
include Configuration
|
|
61
|
+
include AutoloadRecords if defined?(Rails)
|
|
62
|
+
include OptionBlocks
|
|
63
|
+
|
|
64
|
+
require 'dhs/record' # as dhs records in an application are directly inheriting it
|
|
65
|
+
|
|
66
|
+
require 'dhs/railtie' if defined?(Rails)
|
|
67
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# A collection is a special type of data
|
|
4
|
+
# that contains multiple items
|
|
5
|
+
class DHS::Collection < DHS::Proxy
|
|
6
|
+
autoload :HandleNested,
|
|
7
|
+
'dhs/concerns/collection/handle_nested'
|
|
8
|
+
autoload :InternalCollection,
|
|
9
|
+
'dhs/concerns/collection/internal_collection'
|
|
10
|
+
|
|
11
|
+
include HandleNested
|
|
12
|
+
include InternalCollection
|
|
13
|
+
include Create
|
|
14
|
+
|
|
15
|
+
METHOD_NAMES_EXLCUDED_FROM_WRAPPING = %w(to_a to_ary map).freeze
|
|
16
|
+
|
|
17
|
+
delegate :select, :length, :size, :insert, to: :_collection
|
|
18
|
+
delegate :_record, :_raw, to: :_data
|
|
19
|
+
delegate :limit, :count, :total, :offset, :current_page, :start,
|
|
20
|
+
:next?, :previous?, to: :_pagination
|
|
21
|
+
|
|
22
|
+
def _pagination
|
|
23
|
+
_record.pagination(_data)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def href
|
|
27
|
+
return _data._raw[:href] if _data._raw.is_a? Hash
|
|
28
|
+
nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def _collection
|
|
32
|
+
@_collection ||= begin
|
|
33
|
+
raw = _data._raw if _data._raw.is_a?(Array)
|
|
34
|
+
raw ||= _data.access(input: _data._raw, record: _record)
|
|
35
|
+
Collection.new(raw, _data, _record)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def collection?
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def item?
|
|
44
|
+
false
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def raw_items
|
|
48
|
+
if _raw.is_a?(Array)
|
|
49
|
+
_raw
|
|
50
|
+
else
|
|
51
|
+
access(input: _raw, record: _record)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
protected
|
|
56
|
+
|
|
57
|
+
def method_missing(name, *args, **keyword_args, &block)
|
|
58
|
+
if _collection.respond_to?(name)
|
|
59
|
+
value = _collection.send(name, *args, **keyword_args, &block)
|
|
60
|
+
record = DHS::Record.for_url(value[:href]) if value.is_a?(Hash) && value[:href]
|
|
61
|
+
record ||= _record
|
|
62
|
+
value = enclose_item_in_data(value) if value.is_a?(Hash)
|
|
63
|
+
return value if METHOD_NAMES_EXLCUDED_FROM_WRAPPING.include?(name.to_s)
|
|
64
|
+
wrap_return(value, record, name, args)
|
|
65
|
+
elsif _data._raw.is_a?(Hash)
|
|
66
|
+
get(name, *args, **keyword_args)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def respond_to_missing?(name, _include_all = false)
|
|
71
|
+
# We accept every message that does not belong to set of keywords and is not a setter
|
|
72
|
+
!BLACKLISTED_KEYWORDS.include?(name.to_s) && !name.to_s[/=$/]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
# Encloses accessed collection item
|
|
78
|
+
# by wrapping it in an DHS::Item
|
|
79
|
+
def enclose_item_in_data(value)
|
|
80
|
+
data = DHS::Data.new(value, _data, _record)
|
|
81
|
+
item = DHS::Item.new(data)
|
|
82
|
+
DHS::Data.new(item, _data)
|
|
83
|
+
end
|
|
84
|
+
end
|
data/lib/dhs/complex.rb
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Complex is the main data structure for includes:
|
|
4
|
+
# Can be for example :place, [:place, :customer],
|
|
5
|
+
# [{ places: [:customer] }, { places: { customer: :contract }}]
|
|
6
|
+
# and so on
|
|
7
|
+
class DHS::Complex
|
|
8
|
+
attr_reader :data
|
|
9
|
+
|
|
10
|
+
def reduce!(data)
|
|
11
|
+
@data = if data.is_a?(DHS::Complex)
|
|
12
|
+
data.data
|
|
13
|
+
elsif data.is_a?(Array) && !data.empty?
|
|
14
|
+
data.inject(DHS::Complex.new.reduce!([])) { |acc, datum| acc.merge!(DHS::Complex.new.reduce!(datum)) }.data
|
|
15
|
+
elsif data.is_a?(Hash) && !data.empty?
|
|
16
|
+
data.map { |k, v| [k, DHS::Complex.new.reduce!(v)] }.to_h
|
|
17
|
+
else
|
|
18
|
+
data
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
self
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.reduce(data)
|
|
25
|
+
new.reduce!(data).unwrap
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def merge!(other)
|
|
29
|
+
if data.is_a?(Symbol)
|
|
30
|
+
merge_into_symbol!(other)
|
|
31
|
+
elsif data.is_a?(Array)
|
|
32
|
+
merge_into_array!(other)
|
|
33
|
+
elsif data.is_a?(Hash)
|
|
34
|
+
merge_into_hash!(other)
|
|
35
|
+
elsif unwrap != other.unwrap
|
|
36
|
+
raise ArgumentError, "Cannot merge #{unwrap} with #{other.unwrap}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def unwrap
|
|
43
|
+
if data.is_a?(Array)
|
|
44
|
+
result = data.map(&:unwrap)
|
|
45
|
+
result.empty? ? nil : result
|
|
46
|
+
elsif data.is_a?(Hash)
|
|
47
|
+
result = data.map { |k, v| [k, v.unwrap] }.to_h
|
|
48
|
+
result.empty? ? nil : result
|
|
49
|
+
else
|
|
50
|
+
data
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def ==(other)
|
|
55
|
+
unwrap == other.unwrap
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def merge_into_array!(other)
|
|
61
|
+
if data.empty?
|
|
62
|
+
@data = other.data
|
|
63
|
+
elsif other.data.is_a?(Symbol)
|
|
64
|
+
merge_symbol_into_array!(other)
|
|
65
|
+
elsif other.data.is_a?(Array)
|
|
66
|
+
merge_array_into_array!(other)
|
|
67
|
+
elsif other.data.is_a?(Hash)
|
|
68
|
+
merge_hash_into_array!(other)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def merge_symbol_into_array!(other)
|
|
73
|
+
return if data.include?(other)
|
|
74
|
+
data.push(other)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def merge_array_into_array!(other)
|
|
78
|
+
@data = other.data.inject(self) { |acc, datum| acc.merge!(datum) }.data
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def merge_hash_into_array!(other)
|
|
82
|
+
@data = [].tap do |new_data|
|
|
83
|
+
data.each do |element|
|
|
84
|
+
if element.data.is_a?(Symbol)
|
|
85
|
+
# remove keys that were in the hash
|
|
86
|
+
new_data << element unless other.data.key?(element.data)
|
|
87
|
+
elsif element.data.is_a?(Array)
|
|
88
|
+
new_data << element
|
|
89
|
+
elsif element.data.is_a?(Hash)
|
|
90
|
+
new_data << element.merge!(other)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# add it to the array if there was no hash to merge it
|
|
96
|
+
data.push(other) if data.none? { |element| element.data.is_a?(Hash) }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def merge_into_hash!(other)
|
|
100
|
+
if data.empty?
|
|
101
|
+
@data = other.data
|
|
102
|
+
elsif other.data.is_a?(Symbol)
|
|
103
|
+
merge_symbol_into_hash!(other)
|
|
104
|
+
elsif other.data.is_a?(Array)
|
|
105
|
+
merge_array_into_hash!(other)
|
|
106
|
+
elsif other.data.is_a?(Hash)
|
|
107
|
+
merge_hash_into_hash!(other)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def merge_symbol_into_hash!(other)
|
|
112
|
+
return if data.key?(other.data)
|
|
113
|
+
|
|
114
|
+
@data = [DHS::Complex.new.reduce!(data), other]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def merge_array_into_hash!(other)
|
|
118
|
+
@data = other.data.inject(self) { |acc, datum| acc.merge!(datum) }.data
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def merge_hash_into_hash!(other)
|
|
122
|
+
other.data.each do |k, v|
|
|
123
|
+
data[k] = if data.key?(k)
|
|
124
|
+
data[k].merge!(v)
|
|
125
|
+
else
|
|
126
|
+
v
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def merge_into_symbol!(other)
|
|
132
|
+
if other.data.is_a?(Symbol)
|
|
133
|
+
merge_symbol_into_symbol!(other)
|
|
134
|
+
elsif other.data.is_a?(Array)
|
|
135
|
+
merge_array_into_symbol!(other)
|
|
136
|
+
elsif other.data.is_a?(Hash)
|
|
137
|
+
merge_hash_into_symbol!(other)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def merge_symbol_into_symbol!(other)
|
|
142
|
+
return if other.data == data
|
|
143
|
+
|
|
144
|
+
@data = [DHS::Complex.new.reduce!(data), other]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def merge_array_into_symbol!(other)
|
|
148
|
+
@data = other.data.unshift(DHS::Complex.new.reduce!(data)).uniq { |a| a.unwrap }
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def merge_hash_into_symbol!(other)
|
|
152
|
+
@data = if other.data.key?(data)
|
|
153
|
+
other.data
|
|
154
|
+
else
|
|
155
|
+
[DHS::Complex.new.reduce!(data), other]
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
# Preload all the DHS::Records that are defined in app/models/*
|
|
6
|
+
# in order to collect record endpoints and to be able to identify records from hrefs
|
|
7
|
+
# and not only from model constant names (which is different to ActiveRecord)
|
|
8
|
+
module AutoloadRecords
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
included do
|
|
12
|
+
class Engine < Rails::Engine
|
|
13
|
+
initializer 'Load all DHS::Records from app/models/**' do |app|
|
|
14
|
+
Middleware.require_records
|
|
15
|
+
next if app.config.cache_classes
|
|
16
|
+
|
|
17
|
+
app.config.middleware.use Middleware
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Middleware
|
|
21
|
+
def initialize(app)
|
|
22
|
+
@app = app
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def call(env)
|
|
26
|
+
self.class.require_records
|
|
27
|
+
@app.call(env)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.model_files
|
|
31
|
+
Dir.glob(Rails.root.join('app', 'models', '**', '*.rb'))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.require_direct_inheritance
|
|
35
|
+
model_files.sort.map do |file|
|
|
36
|
+
next unless File.read(file).match('DHS::Record')
|
|
37
|
+
require_dependency file
|
|
38
|
+
file.split('models/').last.gsub('.rb', '').classify
|
|
39
|
+
end.compact
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.require_inheriting_records(parents)
|
|
43
|
+
model_files.each do |file|
|
|
44
|
+
file_content = File.read(file)
|
|
45
|
+
next if parents.none? { |parent| file_content.match(/\b#{parent}\b/) }
|
|
46
|
+
next if file_content.match?('extend ActiveSupport::Concern')
|
|
47
|
+
require_dependency file
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.require_records
|
|
52
|
+
require_inheriting_records(require_direct_inheritance)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Collection < DHS::Proxy
|
|
6
|
+
|
|
7
|
+
# Handles pontentially (deep-)nested collections
|
|
8
|
+
# Examples:
|
|
9
|
+
# [ { name: 'Steve '} ]
|
|
10
|
+
# { items: [ { name: 'Steve' } ] }
|
|
11
|
+
# { response: { business: [ { name: 'Steve' } ] } }
|
|
12
|
+
module HandleNested
|
|
13
|
+
extend ActiveSupport::Concern
|
|
14
|
+
|
|
15
|
+
delegate :access, :nest, :concat, to: :class
|
|
16
|
+
|
|
17
|
+
module ClassMethods
|
|
18
|
+
# Access potentially nested collection of items
|
|
19
|
+
def access(input:, record: nil)
|
|
20
|
+
input.dig(*items_key(record))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Initializes nested collection
|
|
24
|
+
def nest(input:, value: nil, record: nil)
|
|
25
|
+
input[items_key(record)] = value
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Concats existing nested collection of items
|
|
29
|
+
# with given items
|
|
30
|
+
def concat(input:, items:, record: nil)
|
|
31
|
+
input.dig(*items_key(record)).concat(items)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# Takes configured items key to access collection of items
|
|
37
|
+
# of falls back to the default key
|
|
38
|
+
def items_key(record)
|
|
39
|
+
record&.items_key || DHS::Record.items_key
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|