lhs 24.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/.bundler-version +1 -0
- data/.gitignore +39 -0
- data/.rubocop.localch.yml +325 -0
- data/.rubocop.yml +52 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Gemfile.activesupport4 +5 -0
- data/Gemfile.activesupport5 +4 -0
- data/LICENSE +674 -0
- data/README.md +2836 -0
- data/Rakefile +25 -0
- data/cider-ci.yml +6 -0
- data/cider-ci/bin/bundle +51 -0
- data/cider-ci/bin/ruby_install +8 -0
- data/cider-ci/bin/ruby_version +25 -0
- data/cider-ci/jobs/rspec-activesupport-4.yml +27 -0
- data/cider-ci/jobs/rspec-activesupport-5.yml +26 -0
- data/cider-ci/jobs/rspec-activesupport-latest.yml +24 -0
- data/cider-ci/jobs/rubocop.yml +18 -0
- data/cider-ci/task_components/bundle.yml +22 -0
- data/cider-ci/task_components/rspec.yml +37 -0
- data/cider-ci/task_components/rubocop.yml +29 -0
- data/cider-ci/task_components/ruby.yml +15 -0
- data/friday.yml +2 -0
- data/lhs.gemspec +43 -0
- data/lib/lhs.rb +100 -0
- data/lib/lhs/collection.rb +84 -0
- data/lib/lhs/complex.rb +158 -0
- data/lib/lhs/concerns/autoload_records.rb +55 -0
- data/lib/lhs/concerns/collection/handle_nested.rb +43 -0
- data/lib/lhs/concerns/collection/internal_collection.rb +49 -0
- data/lib/lhs/concerns/configuration.rb +20 -0
- data/lib/lhs/concerns/data/becomes.rb +18 -0
- data/lib/lhs/concerns/data/equality.rb +14 -0
- data/lib/lhs/concerns/data/json.rb +14 -0
- data/lib/lhs/concerns/data/to_hash.rb +14 -0
- data/lib/lhs/concerns/inspect.rb +70 -0
- data/lib/lhs/concerns/is_href.rb +15 -0
- data/lib/lhs/concerns/item/destroy.rb +38 -0
- data/lib/lhs/concerns/item/endpoint_lookup.rb +27 -0
- data/lib/lhs/concerns/item/save.rb +55 -0
- data/lib/lhs/concerns/item/update.rb +50 -0
- data/lib/lhs/concerns/item/validation.rb +61 -0
- data/lib/lhs/concerns/o_auth.rb +25 -0
- data/lib/lhs/concerns/option_blocks.rb +26 -0
- data/lib/lhs/concerns/proxy/accessors.rb +132 -0
- data/lib/lhs/concerns/proxy/create.rb +45 -0
- data/lib/lhs/concerns/proxy/link.rb +25 -0
- data/lib/lhs/concerns/proxy/problems.rb +27 -0
- data/lib/lhs/concerns/record/attribute_assignment.rb +25 -0
- data/lib/lhs/concerns/record/batch.rb +40 -0
- data/lib/lhs/concerns/record/chainable.rb +465 -0
- data/lib/lhs/concerns/record/configuration.rb +103 -0
- data/lib/lhs/concerns/record/create.rb +24 -0
- data/lib/lhs/concerns/record/custom_setters.rb +22 -0
- data/lib/lhs/concerns/record/destroy.rb +18 -0
- data/lib/lhs/concerns/record/endpoints.rb +108 -0
- data/lib/lhs/concerns/record/equality.rb +14 -0
- data/lib/lhs/concerns/record/find.rb +86 -0
- data/lib/lhs/concerns/record/find_by.rb +38 -0
- data/lib/lhs/concerns/record/first.rb +20 -0
- data/lib/lhs/concerns/record/href_for.rb +19 -0
- data/lib/lhs/concerns/record/last.rb +27 -0
- data/lib/lhs/concerns/record/mapping.rb +25 -0
- data/lib/lhs/concerns/record/merge.rb +26 -0
- data/lib/lhs/concerns/record/model.rb +23 -0
- data/lib/lhs/concerns/record/pagination.rb +47 -0
- data/lib/lhs/concerns/record/provider.rb +23 -0
- data/lib/lhs/concerns/record/relations.rb +26 -0
- data/lib/lhs/concerns/record/request.rb +620 -0
- data/lib/lhs/concerns/record/scope.rb +25 -0
- data/lib/lhs/concerns/record/tracing.rb +24 -0
- data/lib/lhs/concerns/record/update.rb +17 -0
- data/lib/lhs/config.rb +24 -0
- data/lib/lhs/data.rb +165 -0
- data/lib/lhs/endpoint.rb +12 -0
- data/lib/lhs/interceptors/auto_oauth/interceptor.rb +33 -0
- data/lib/lhs/interceptors/auto_oauth/thread_registry.rb +18 -0
- data/lib/lhs/interceptors/extended_rollbar/handler.rb +40 -0
- data/lib/lhs/interceptors/extended_rollbar/interceptor.rb +20 -0
- data/lib/lhs/interceptors/extended_rollbar/thread_registry.rb +19 -0
- data/lib/lhs/interceptors/request_cycle_cache/interceptor.rb +41 -0
- data/lib/lhs/interceptors/request_cycle_cache/thread_registry.rb +18 -0
- data/lib/lhs/item.rb +59 -0
- data/lib/lhs/pagination/base.rb +90 -0
- data/lib/lhs/pagination/link.rb +21 -0
- data/lib/lhs/pagination/offset.rb +22 -0
- data/lib/lhs/pagination/page.rb +18 -0
- data/lib/lhs/pagination/start.rb +22 -0
- data/lib/lhs/problems/base.rb +113 -0
- data/lib/lhs/problems/errors.rb +69 -0
- data/lib/lhs/problems/nested/base.rb +54 -0
- data/lib/lhs/problems/nested/errors.rb +16 -0
- data/lib/lhs/problems/nested/warnings.rb +15 -0
- data/lib/lhs/problems/warnings.rb +24 -0
- data/lib/lhs/proxy.rb +68 -0
- data/lib/lhs/railtie.rb +34 -0
- data/lib/lhs/record.rb +112 -0
- data/lib/lhs/rspec.rb +10 -0
- data/lib/lhs/test/stubbable_records.rb +34 -0
- data/lib/lhs/unprocessable.rb +6 -0
- data/lib/lhs/version.rb +5 -0
- data/script/ci/build.sh +18 -0
- data/spec/auto_oauth_spec.rb +169 -0
- data/spec/autoloading_spec.rb +48 -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 +57 -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/dummy_customer.rb +6 -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/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 +33 -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 +30 -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 +28 -0
- data/spec/item/partial_update_spec.rb +170 -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 +52 -0
- data/spec/option_blocks/ensure_reset_between_requests_spec.rb +23 -0
- data/spec/option_blocks/main_spec.rb +55 -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 +46 -0
- data/spec/pagination/offset/pages_left_spec.rb +26 -0
- data/spec/pagination/parameters_spec.rb +61 -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 +78 -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 +45 -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 +52 -0
- data/spec/record/endpoint_priorities_spec.rb +26 -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 +41 -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 +104 -0
- data/spec/record/first_spec.rb +39 -0
- data/spec/record/force_merge_spec.rb +56 -0
- data/spec/record/handle_includes_errors_spec.rb +32 -0
- data/spec/record/has_many_spec.rb +120 -0
- data/spec/record/has_one_spec.rb +116 -0
- data/spec/record/href_for_spec.rb +25 -0
- data/spec/record/ignore_errors_spec.rb +139 -0
- data/spec/record/immutable_chains_spec.rb +22 -0
- data/spec/record/includes_first_page_spec.rb +737 -0
- data/spec/record/includes_spec.rb +693 -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 +68 -0
- data/spec/record/loading_twice_spec.rb +19 -0
- data/spec/record/mapping_spec.rb +102 -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 +26 -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 +41 -0
- data/spec/record/references_spec.rb +53 -0
- data/spec/record/relation_caching_spec.rb +121 -0
- data/spec/record/reload_by_id_spec.rb +43 -0
- data/spec/record/reload_spec.rb +65 -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 +154 -0
- data/spec/record/update_spec.rb +62 -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_lhs_spec.rb +9 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/stubs/all_spec.rb +72 -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 +776 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class LHS::Record
|
|
6
|
+
|
|
7
|
+
# Scopes allow you to reuse common where queries
|
|
8
|
+
module Scope
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
module ClassMethods
|
|
12
|
+
def scope(name, block)
|
|
13
|
+
scopes[name] = block
|
|
14
|
+
define_singleton_method(name) do |*args|
|
|
15
|
+
block.call(*args)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def scopes
|
|
20
|
+
@scopes ||= {}
|
|
21
|
+
@scopes
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class LHS::Record
|
|
6
|
+
|
|
7
|
+
module Tracing
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
module ClassMethods
|
|
11
|
+
# Needs to be called directly from the first method (level) within LHS
|
|
12
|
+
def trace!(options = {})
|
|
13
|
+
return options unless LHS.config.trace
|
|
14
|
+
|
|
15
|
+
(options || {}).tap do |options|
|
|
16
|
+
source = caller.detect do |source|
|
|
17
|
+
!source.match?(%r{/lib/lhs})
|
|
18
|
+
end
|
|
19
|
+
options[:source] = source
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
class LHS::Record
|
|
6
|
+
|
|
7
|
+
module Update
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
class <<self
|
|
12
|
+
alias_method :update, :create
|
|
13
|
+
alias_method :update!, :create!
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/lhs/config.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'singleton'
|
|
4
|
+
|
|
5
|
+
class LHS::Config
|
|
6
|
+
include Singleton
|
|
7
|
+
|
|
8
|
+
attr_accessor :request_cycle_cache_enabled, :request_cycle_cache, :trace, :auto_oauth
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
self.request_cycle_cache_enabled ||= true
|
|
12
|
+
self.trace ||= false
|
|
13
|
+
if defined?(ActiveSupport::Cache::MemoryStore)
|
|
14
|
+
self.request_cycle_cache ||= ActiveSupport::Cache::MemoryStore.new
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def reset
|
|
19
|
+
self.request_cycle_cache_enabled = nil
|
|
20
|
+
self.trace = nil
|
|
21
|
+
self.request_cycle_cache = nil
|
|
22
|
+
initialize
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/lhs/data.rb
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Data provides functionalities to accesses information
|
|
4
|
+
class LHS::Data
|
|
5
|
+
autoload :Becomes,
|
|
6
|
+
'lhs/concerns/data/becomes'
|
|
7
|
+
autoload :Equality,
|
|
8
|
+
'lhs/concerns/data/equality'
|
|
9
|
+
autoload :Json,
|
|
10
|
+
'lhs/concerns/data/json'
|
|
11
|
+
autoload :ToHash,
|
|
12
|
+
'lhs/concerns/data/to_hash'
|
|
13
|
+
|
|
14
|
+
include Becomes
|
|
15
|
+
include Equality
|
|
16
|
+
include Json
|
|
17
|
+
include ToHash
|
|
18
|
+
include LHS::Inspect
|
|
19
|
+
|
|
20
|
+
delegate :instance_methods, :items_key, :limit_key, :total_key, :pagination_key, to: :class
|
|
21
|
+
|
|
22
|
+
# prevent clashing with attributes of underlying data
|
|
23
|
+
attr_accessor :_proxy, :_parent, :_record, :_request, :_endpoint
|
|
24
|
+
attr_reader :_raw
|
|
25
|
+
|
|
26
|
+
def initialize(input, parent = nil, record = nil, request = nil, endpoint = nil)
|
|
27
|
+
self._raw = raw_from_input(input)
|
|
28
|
+
self._parent = parent
|
|
29
|
+
self._record = record
|
|
30
|
+
self._proxy = proxy_from_input(input)
|
|
31
|
+
self._request = request
|
|
32
|
+
self._endpoint = endpoint
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# merging data
|
|
36
|
+
# e.g. when loading remote data via link
|
|
37
|
+
def merge_raw!(data)
|
|
38
|
+
return false if data.blank? || !data._raw.is_a?(Hash)
|
|
39
|
+
_raw.merge! data._raw
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Unwraps data for certain use cases
|
|
43
|
+
# like items_created_key for CREATE, UPDATED etc.
|
|
44
|
+
# like item_key for GET etc.
|
|
45
|
+
def unwrap(usecase)
|
|
46
|
+
nested_path = record.send(usecase) if record
|
|
47
|
+
return LHS::Data.new(dig(*nested_path) || _raw, nil, self.class) if nested_path
|
|
48
|
+
self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def _root
|
|
52
|
+
root = self
|
|
53
|
+
root = root._parent while root&._parent
|
|
54
|
+
root
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def parent
|
|
58
|
+
if _parent&._record
|
|
59
|
+
_parent._record.new(_parent, false)
|
|
60
|
+
else
|
|
61
|
+
_parent
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def class
|
|
66
|
+
_record || _root._record
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# enforce internal data structure to have deep symbolized keys
|
|
70
|
+
def _raw=(raw)
|
|
71
|
+
raw.to_hash.deep_symbolize_keys! if raw&.respond_to?(:to_hash)
|
|
72
|
+
@_raw = raw
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def root_item?
|
|
76
|
+
root_item == self
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def collection?
|
|
80
|
+
_proxy.is_a? LHS::Collection
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def item?
|
|
84
|
+
_proxy.is_a? LHS::Item
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
protected
|
|
88
|
+
|
|
89
|
+
def method_missing(name, *args, &block)
|
|
90
|
+
_proxy.send(name, *args, &block)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def respond_to_missing?(name, include_all = false)
|
|
94
|
+
(root_item? && instance_methods.include?(name)) ||
|
|
95
|
+
_proxy.respond_to?(name, include_all)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def collection_proxy?(input)
|
|
101
|
+
(input.is_a?(Hash) && LHS::Collection.access(input: input, record: _record)) ||
|
|
102
|
+
input.is_a?(Array) ||
|
|
103
|
+
_raw.is_a?(Array)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def root_item
|
|
107
|
+
return if _proxy.class != LHS::Item
|
|
108
|
+
root = root_item = self
|
|
109
|
+
loop do
|
|
110
|
+
root = root._parent
|
|
111
|
+
root_item = root if root && root._proxy.is_a?(LHS::Item)
|
|
112
|
+
if !(root && root._parent)
|
|
113
|
+
break
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
root_item
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def root?
|
|
120
|
+
_root == self
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def proxy_from_input(input)
|
|
124
|
+
if input.is_a? LHS::Proxy
|
|
125
|
+
input
|
|
126
|
+
elsif collection_proxy?(raw_from_input(input))
|
|
127
|
+
LHS::Collection.new(self)
|
|
128
|
+
else
|
|
129
|
+
LHS::Item.new(self)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def raw_from_input(input)
|
|
134
|
+
if json?(input)
|
|
135
|
+
raw_from_json_string(input)
|
|
136
|
+
elsif defined?(input._raw)
|
|
137
|
+
input._raw
|
|
138
|
+
elsif defined?(input._data)
|
|
139
|
+
input._data._raw
|
|
140
|
+
else
|
|
141
|
+
raw_from_anything_else(input)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def json?(input)
|
|
146
|
+
input.is_a?(String) && !input.empty? && !!input.match(/^("|\[|'|\{)/)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def raw_from_json_string(input)
|
|
150
|
+
json = JSON.parse(input)
|
|
151
|
+
if json.is_a?(Hash)
|
|
152
|
+
json.deep_symbolize_keys
|
|
153
|
+
elsif json.is_a?(Array)
|
|
154
|
+
json.map { |item| item.is_a?(Hash) ? item.deep_symbolize_keys : item }
|
|
155
|
+
else
|
|
156
|
+
json
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def raw_from_anything_else(input)
|
|
161
|
+
input = input.to_hash if input.class != Hash && input.respond_to?(:to_hash)
|
|
162
|
+
input.deep_symbolize_keys! if input.is_a?(Hash)
|
|
163
|
+
input
|
|
164
|
+
end
|
|
165
|
+
end
|
data/lib/lhs/endpoint.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# An endpoint is used as source to fetch objects
|
|
4
|
+
class LHS::Endpoint
|
|
5
|
+
|
|
6
|
+
def self.for_url(url)
|
|
7
|
+
template, record = LHS::Record::Endpoints.all.dup.detect do |template, _record|
|
|
8
|
+
LHC::Endpoint.match?(url, template)
|
|
9
|
+
end
|
|
10
|
+
record&.endpoints&.detect { |endpoint| endpoint.url == template }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module LHS
|
|
6
|
+
module Interceptors
|
|
7
|
+
module AutoOauth
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
class Interceptor < LHC::Interceptor
|
|
11
|
+
|
|
12
|
+
def before_request
|
|
13
|
+
request.options[:auth] = { bearer: token }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def tokens
|
|
17
|
+
@tokens ||= LHS::Interceptors::AutoOauth::ThreadRegistry.access_token
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def token
|
|
21
|
+
if tokens.is_a?(Hash)
|
|
22
|
+
tokens.dig(
|
|
23
|
+
request.options[:oauth] ||
|
|
24
|
+
request.options[:record]&.auto_oauth
|
|
25
|
+
)
|
|
26
|
+
else
|
|
27
|
+
tokens
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require 'active_support/per_thread_registry'
|
|
5
|
+
|
|
6
|
+
module LHS
|
|
7
|
+
module Interceptors
|
|
8
|
+
module AutoOauth
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
class ThreadRegistry
|
|
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 :access_token
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LHS
|
|
4
|
+
module Interceptors
|
|
5
|
+
module ExtendedRollbar
|
|
6
|
+
class Handler
|
|
7
|
+
|
|
8
|
+
def self.init
|
|
9
|
+
proc do |options|
|
|
10
|
+
# as handlers cant influence what actually is reported to rollbar
|
|
11
|
+
# this just makes sure that Rollbar is already loaded when this class is loaded,
|
|
12
|
+
# so that we can extend rollbar loging
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module ExtendedLogging
|
|
17
|
+
def log(level, *args)
|
|
18
|
+
args[2] = {} if args[2].nil?
|
|
19
|
+
args[2][:lhs] = LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log.map do |entry|
|
|
20
|
+
{
|
|
21
|
+
request: entry[:request].options,
|
|
22
|
+
response: {
|
|
23
|
+
code: entry[:response].code,
|
|
24
|
+
body: entry[:response].body
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
end.to_json
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module ::Rollbar
|
|
33
|
+
class Notifier
|
|
34
|
+
prepend LHS::Interceptors::ExtendedRollbar::Handler::ExtendedLogging
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module LHS
|
|
6
|
+
module Interceptors
|
|
7
|
+
module ExtendedRollbar
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
class Interceptor < LHC::Interceptor
|
|
11
|
+
def after_response
|
|
12
|
+
return unless LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log
|
|
13
|
+
LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log.push(request: request, response: response)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
const_set('ExtendedRollbar', LHS::Interceptors::ExtendedRollbar::Interceptor)
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require 'active_support/per_thread_registry'
|
|
5
|
+
|
|
6
|
+
module LHS
|
|
7
|
+
module Interceptors
|
|
8
|
+
module ExtendedRollbar
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
class ThreadRegistry
|
|
12
|
+
# Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
|
|
13
|
+
# Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v4.
|
|
14
|
+
extend ActiveSupport::PerThreadRegistry
|
|
15
|
+
attr_accessor :log
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module LHS
|
|
6
|
+
module Interceptors
|
|
7
|
+
module RequestCycleCache
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
class Interceptor < LHC::Interceptor
|
|
11
|
+
|
|
12
|
+
VERSION = 1
|
|
13
|
+
CACHED_METHODS = [:get].freeze
|
|
14
|
+
|
|
15
|
+
def before_request
|
|
16
|
+
request.options = {
|
|
17
|
+
cache: {
|
|
18
|
+
expires_in: 5.minutes,
|
|
19
|
+
race_condition_ttl: 5.seconds,
|
|
20
|
+
key: cache_key_for(request),
|
|
21
|
+
methods: CACHED_METHODS,
|
|
22
|
+
use: LHS.config.request_cycle_cache
|
|
23
|
+
}
|
|
24
|
+
}.merge(request.options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def cache_key_for(request)
|
|
30
|
+
[
|
|
31
|
+
"LHS_REQUEST_CYCLE_CACHE(v#{VERSION})",
|
|
32
|
+
request.method.upcase,
|
|
33
|
+
[request.url, request.params.presence].compact.join('?'),
|
|
34
|
+
"REQUEST=#{LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id}",
|
|
35
|
+
"HEADERS=#{request.headers.hash}"
|
|
36
|
+
].join(' ')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|