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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Item < DHS::Proxy
|
|
6
|
+
autoload :EndpointLookup,
|
|
7
|
+
'dhs/concerns/item/endpoint_lookup'
|
|
8
|
+
|
|
9
|
+
module Update
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
include EndpointLookup
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def update(params, options = nil, partial_update = false)
|
|
17
|
+
update!(params, options, partial_update)
|
|
18
|
+
rescue DHC::Error => e
|
|
19
|
+
self.errors = DHS::Problems::Errors.new(e.response, record)
|
|
20
|
+
false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def partial_update(params, options = nil)
|
|
24
|
+
update(params, options, true)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def partial_update!(params, options = nil)
|
|
28
|
+
update!(params, options, true)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def update!(params, options = {}, partial_update = false)
|
|
32
|
+
options = options.present? ? options.dup : {}
|
|
33
|
+
partial_record = _record.new(DHS::Data.new(params, _data.parent, _record))
|
|
34
|
+
_data.merge_raw!(partial_record._data)
|
|
35
|
+
data = _data._raw.dup
|
|
36
|
+
partial_data = partial_record._data._raw.dup
|
|
37
|
+
url = url_for_persistance!(data, options)
|
|
38
|
+
data_sent = partial_update ? partial_data.extract!(*data.keys) : data
|
|
39
|
+
response_data = record.request(
|
|
40
|
+
options.merge(
|
|
41
|
+
method: options.fetch(:method, :post),
|
|
42
|
+
url: url,
|
|
43
|
+
body: data_sent
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
_data.merge_raw!(response_data.unwrap(:item_created_key))
|
|
47
|
+
true
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Item < DHS::Proxy
|
|
6
|
+
|
|
7
|
+
module Validation
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
def valid?(options = {})
|
|
11
|
+
options ||= {}
|
|
12
|
+
errors.clear
|
|
13
|
+
endpoint = validation_endpoint
|
|
14
|
+
raise 'No endpoint found to perform validations! See here: https://github.com/DePayFi/dhs#validation' unless endpoint
|
|
15
|
+
record = DHS::Record.for_url(endpoint.url)
|
|
16
|
+
params = merge_validation_params!(endpoint).merge options.fetch(:params, {})
|
|
17
|
+
url = validation_url(endpoint)
|
|
18
|
+
run_validation!(record, options, url, params)
|
|
19
|
+
true
|
|
20
|
+
rescue DHC::Error => e
|
|
21
|
+
self.errors = DHS::Problems::Errors.new(e.response, record)
|
|
22
|
+
false
|
|
23
|
+
end
|
|
24
|
+
alias validate valid?
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def validation_url(endpoint)
|
|
29
|
+
url = endpoint.url
|
|
30
|
+
action = endpoint.options[:validates][:path].presence
|
|
31
|
+
url = "#{url}/#{action}" if action.present?
|
|
32
|
+
url
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def merge_validation_params!(endpoint)
|
|
36
|
+
validates_params = endpoint.options[:validates].reject { |key, _| key.to_sym == :path }
|
|
37
|
+
params = endpoint.options.fetch(:params, {}).merge(params_from_link)
|
|
38
|
+
params = params.merge(validates_params) if validates_params.is_a?(Hash)
|
|
39
|
+
params
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def run_validation!(record, options, url, params)
|
|
43
|
+
record.request(
|
|
44
|
+
options.merge(
|
|
45
|
+
url: url,
|
|
46
|
+
method: :post,
|
|
47
|
+
params: params,
|
|
48
|
+
body: _data
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def validation_endpoint
|
|
54
|
+
endpoint = endpoint_from_link if _data.href # take embeded first
|
|
55
|
+
endpoint ||= record.find_endpoint(_data._raw)
|
|
56
|
+
validates = endpoint.options&.fetch(:validates, false)
|
|
57
|
+
raise 'Endpoint does not support validations!' unless validates
|
|
58
|
+
endpoint
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module DHS
|
|
6
|
+
module OAuth
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
prepend_before_action :dhs_store_oauth_access_token
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def dhs_store_oauth_access_token
|
|
16
|
+
dhs_check_auto_oauth_enabled!
|
|
17
|
+
DHS::Interceptors::AutoOauth::ThreadRegistry.access_token = instance_exec(&DHS.config.auto_oauth)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def dhs_check_auto_oauth_enabled!
|
|
21
|
+
return if DHS.config.auto_oauth.present? && DHS.config.auto_oauth.is_a?(Proc)
|
|
22
|
+
raise 'You have to enable DHS.config.auto_oauth by passing a proc returning an access token!'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require 'active_support/per_thread_registry'
|
|
5
|
+
|
|
6
|
+
module DHS
|
|
7
|
+
module OptionBlocks
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
class CurrentOptionBlock
|
|
11
|
+
# Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
|
|
12
|
+
# Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v4.
|
|
13
|
+
extend ActiveSupport::PerThreadRegistry
|
|
14
|
+
attr_accessor :options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module ClassMethods
|
|
18
|
+
def options(options, &block)
|
|
19
|
+
CurrentOptionBlock.options = options
|
|
20
|
+
block.call
|
|
21
|
+
ensure
|
|
22
|
+
CurrentOptionBlock.options = nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Proxy
|
|
6
|
+
module Accessors
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
# Keywords that would not be forwarded via method missing
|
|
10
|
+
# FIXME: Extend the set of keywords
|
|
11
|
+
BLACKLISTED_KEYWORDS = %w(new proxy_association).freeze
|
|
12
|
+
|
|
13
|
+
delegate :dig, :fetch, to: :_raw, allow_nil: true
|
|
14
|
+
|
|
15
|
+
def clear_cache!
|
|
16
|
+
@cache = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def set(name, args)
|
|
22
|
+
clear_cache!
|
|
23
|
+
return set_attribute_directly(name, args.try(:first)) if name != :[]=
|
|
24
|
+
key = args[0]
|
|
25
|
+
value = args[1]
|
|
26
|
+
_data._raw[key.to_sym] = value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def set_attribute_directly(name, value)
|
|
30
|
+
key = name.to_s.gsub(/=$/, '')
|
|
31
|
+
_data._raw[key.to_sym] = value
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get(name, *args)
|
|
35
|
+
name = args.first if name == :[]
|
|
36
|
+
value = _data._raw[name.to_s] if _data._raw
|
|
37
|
+
if value.nil? && _data._raw.present? && _data._raw.is_a?(Hash)
|
|
38
|
+
value = _data._raw[name.to_sym]
|
|
39
|
+
value = _data._raw[name.to_s.classify.to_sym] if value.nil?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
record = DHS::Record.for_url(value[:href]) if value.is_a?(Hash) && value[:href]
|
|
43
|
+
access_item(value, record, name) ||
|
|
44
|
+
access_collection(value, record, name) ||
|
|
45
|
+
convert(value)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def accessing_item?(value, record)
|
|
49
|
+
return false unless value.is_a?(Hash)
|
|
50
|
+
return false if record && access(input: value, record: record).present?
|
|
51
|
+
return false if !record && value[:items].present?
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def accessing_collection?(value, record)
|
|
56
|
+
return true if value.is_a?(Array)
|
|
57
|
+
return true if value.is_a?(Hash) && record && access(input: value, record: record).present?
|
|
58
|
+
return true if value.is_a?(Hash) && !record && value[:items].present?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def convert(value)
|
|
62
|
+
return value unless value.is_a?(String)
|
|
63
|
+
if date_time?(value)
|
|
64
|
+
Time.zone.parse(value)
|
|
65
|
+
elsif date?(value)
|
|
66
|
+
Date.parse(value)
|
|
67
|
+
else
|
|
68
|
+
value
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def access_item(value, record, name)
|
|
73
|
+
return unless accessing_item?(value, record)
|
|
74
|
+
wrap_return(value, record, name)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def access_collection(value, record, name)
|
|
78
|
+
return unless accessing_collection?(value, record)
|
|
79
|
+
collection_data = DHS::Data.new(value, _data)
|
|
80
|
+
collection = DHS::Collection.new(collection_data)
|
|
81
|
+
wrap_return(collection, record, name)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Wraps the return value with a record class.
|
|
85
|
+
# Adds errors and warnings if existing.
|
|
86
|
+
# Returns plain data if no record class was found.
|
|
87
|
+
def wrap_return(value, record, name, args = nil)
|
|
88
|
+
name = args.first if name == :[]
|
|
89
|
+
return value unless worth_wrapping?(value)
|
|
90
|
+
data = (value.is_a?(DHS::Data) || value.is_a?(DHS::Record)) ? value : DHS::Data.new(value, _data, record, _request)
|
|
91
|
+
data.errors = DHS::Problems::Nested::Errors.new(errors, name) if errors.any?
|
|
92
|
+
data.warnings = DHS::Problems::Nested::Warnings.new(warnings, name) if warnings.any?
|
|
93
|
+
if _record && _record._relations[name]
|
|
94
|
+
klass = _record._relations[name][:record_class_name].constantize
|
|
95
|
+
return cache.compute_if_absent(klass) do
|
|
96
|
+
data.becomes(klass, errors: data.errors, warnings: data.warnings)
|
|
97
|
+
end
|
|
98
|
+
elsif record && !value.is_a?(DHS::Record)
|
|
99
|
+
return data.becomes(record, errors: data.errors, warnings: data.warnings)
|
|
100
|
+
end
|
|
101
|
+
data
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def worth_wrapping?(value)
|
|
105
|
+
value.is_a?(DHS::Proxy) ||
|
|
106
|
+
value.is_a?(DHS::Data) ||
|
|
107
|
+
value.is_a?(DHS::Record) ||
|
|
108
|
+
value.is_a?(Hash) ||
|
|
109
|
+
value.is_a?(Array)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def date?(value)
|
|
113
|
+
value[date_time_regex, :date].presence
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def time?(value)
|
|
117
|
+
value[date_time_regex, :time].presence
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def date_time?(value)
|
|
121
|
+
date?(value) && time?(value)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def date_time_regex
|
|
125
|
+
/(?<date>\d{4}-\d{2}-\d{2})?(?<time>T\d{2}:\d{2}(:\d{2}(\.\d*.\d{2}:\d{2})*)?)?/
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def cache
|
|
129
|
+
@cache ||= Concurrent::Map.new
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Proxy
|
|
6
|
+
|
|
7
|
+
module Create
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
def create(data = {}, options = nil)
|
|
11
|
+
record_creation!(options) do
|
|
12
|
+
record_from_link.create(
|
|
13
|
+
data,
|
|
14
|
+
options_for_creation(options)
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def create!(data = {}, options = nil)
|
|
20
|
+
record_creation!(options) do
|
|
21
|
+
record_from_link.create!(
|
|
22
|
+
data,
|
|
23
|
+
options_for_creation(options)
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def record_creation!(options)
|
|
31
|
+
raise(ArgumentError, 'Record already exists') if _raw.keys != [:href] && item?
|
|
32
|
+
|
|
33
|
+
record = yield
|
|
34
|
+
# Needed to handle unexpanded collection which looks the same as item
|
|
35
|
+
reload!(options) if record.errors.empty?
|
|
36
|
+
record
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def options_for_creation(options)
|
|
40
|
+
return options if params_from_link.blank?
|
|
41
|
+
options = {} if options.blank?
|
|
42
|
+
options.deep_merge(params: params_from_link)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Proxy
|
|
6
|
+
|
|
7
|
+
module Link
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def record_from_link
|
|
13
|
+
DHS::Record.for_url(_data.href)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def endpoint_from_link
|
|
17
|
+
DHS::Endpoint.for_url(_data.href)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def params_from_link
|
|
21
|
+
return {} if !_data.href || !endpoint_from_link
|
|
22
|
+
DHC::Endpoint.values_as_params(endpoint_from_link.url, _data.href)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Proxy
|
|
6
|
+
|
|
7
|
+
module Problems
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
attr_writer :errors, :warnings
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(data)
|
|
15
|
+
super(data)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def errors
|
|
19
|
+
response = (_raw.present? && _raw.is_a?(Hash) && _raw[:field_errors]) ? OpenStruct.new(body: _raw.to_json) : nil
|
|
20
|
+
@errors ||= DHS::Problems::Errors.new(response, record)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def warnings
|
|
24
|
+
@warnings ||= DHS::Problems::Warnings.new(_raw, record)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class DHS::Record
|
|
4
|
+
|
|
5
|
+
module AttributeAssignment
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
def assign_attributes(new_attributes)
|
|
9
|
+
unless new_attributes.respond_to?(:stringify_keys)
|
|
10
|
+
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument, #{new_attributes.class} passed."
|
|
11
|
+
end
|
|
12
|
+
return if new_attributes.empty?
|
|
13
|
+
|
|
14
|
+
_assign_attributes(new_attributes)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def _assign_attributes(attributes)
|
|
20
|
+
attributes.each do |key, value|
|
|
21
|
+
public_send(:"#{key}=", value)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class DHS::Record
|
|
6
|
+
|
|
7
|
+
module Batch
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
module ClassMethods
|
|
11
|
+
# Process single entries fetched in batches
|
|
12
|
+
def find_each(options = {})
|
|
13
|
+
find_in_batches(options) do |records|
|
|
14
|
+
records.each do |record|
|
|
15
|
+
item = DHS::Item.new(record)
|
|
16
|
+
yield new(DHS::Data.new(item, records._data, self))
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Process batches of entries
|
|
22
|
+
def find_in_batches(options = {})
|
|
23
|
+
raise 'No block given' unless block_given?
|
|
24
|
+
options = options.dup
|
|
25
|
+
start = options.delete(:start) || 1
|
|
26
|
+
batch_size = options.delete(:batch_size) || DHS::Pagination::Base::DEFAULT_LIMIT
|
|
27
|
+
loop do # as suggested by Matz
|
|
28
|
+
options = options.dup
|
|
29
|
+
options[:params] = (options[:params] || {}).merge(limit_key(:parameter) => batch_size, pagination_key(:parameter) => start)
|
|
30
|
+
data = request(options)
|
|
31
|
+
batch_size = data._raw.dig(*limit_key(:body))
|
|
32
|
+
left = data._raw.dig(*total_key).to_i - data._raw.dig(*pagination_key(:body)).to_i - data._raw.dig(*limit_key(:body)).to_i
|
|
33
|
+
yield new(data)
|
|
34
|
+
break if left <= 0
|
|
35
|
+
start += batch_size
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|