yext-api 0.1.1 → 0.1.3

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -1
  3. data/Gemfile.lock +16 -8
  4. data/PULL_REQUEST_TEMPLATE.md +11 -0
  5. data/README.md +25 -7
  6. data/app/controllers/yext/api/agreements/add_request_controller.rb +78 -0
  7. data/app/controllers/yext/api/application_controller.rb +1 -3
  8. data/config/initializers/memoist.rb +3 -0
  9. data/config/routes.rb +3 -0
  10. data/lib/config/api.yml +95 -230
  11. data/lib/yext/api/administrative_api/account.rb +37 -27
  12. data/lib/yext/api/administrative_api/add_request.rb +87 -3
  13. data/lib/yext/api/administrative_api/service.rb +26 -4
  14. data/lib/yext/api/concerns/account_child.rb +37 -8
  15. data/lib/yext/api/concerns/account_relations.rb +16 -1
  16. data/lib/yext/api/concerns/default_scopes.rb +8 -2
  17. data/lib/yext/api/concerns/faraday_connection.rb +21 -7
  18. data/lib/yext/api/concerns/rate_limits.rb +8 -1
  19. data/lib/yext/api/enumerations/add_request_status.rb +19 -0
  20. data/lib/yext/api/enumerations/location_type.rb +18 -0
  21. data/lib/yext/api/knowledge_api/account_settings/account.rb +0 -2
  22. data/lib/yext/api/knowledge_api/account_settings/role.rb +24 -0
  23. data/lib/yext/api/knowledge_api/account_settings/user.rb +81 -0
  24. data/lib/yext/api/knowledge_api/health_check/health.rb +0 -1
  25. data/lib/yext/api/knowledge_api/knowledge_manager/category.rb +0 -1
  26. data/lib/yext/api/knowledge_api/knowledge_manager/location.rb +18 -6
  27. data/lib/yext/api/live_api/location.rb +0 -4
  28. data/lib/yext/api/utils/api_base.rb +8 -0
  29. data/lib/yext/api/utils/api_finder.rb +100 -0
  30. data/lib/yext/api/utils/configuration.rb +93 -0
  31. data/lib/yext/api/utils/middleware/api_rate_limits.rb +35 -0
  32. data/lib/yext/api/utils/middleware/default_parameters.rb +138 -0
  33. data/lib/yext/api/utils/middleware/response_parser.rb +111 -0
  34. data/lib/yext/api/utils/middleware/uri_cleanup.rb +48 -0
  35. data/lib/yext/api/utils/params.rb +69 -0
  36. data/lib/yext/api/version.rb +1 -1
  37. data/yext-api.gemspec +6 -7
  38. metadata +56 -31
  39. data/.travis.yml +0 -5
  40. data/app/assets/config/yext_api_manifest.js +0 -2
  41. data/app/assets/images/yext/api/.keep +0 -0
  42. data/app/assets/javascripts/yext/api/application.js +0 -13
  43. data/app/assets/stylesheets/yext/api/application.css +0 -15
  44. data/app/docs/notes.txt +0 -45
  45. data/app/helpers/yext/api/application_helper.rb +0 -11
  46. data/app/jobs/yext/api/application_job.rb +0 -8
  47. data/app/mailers/yext/api/application_mailer.rb +0 -11
  48. data/app/models/yext/api/application_record.rb +0 -10
  49. data/app/views/layouts/yext/api/application.html.erb +0 -14
  50. data/lib/tasks/yext/api_tasks.rake +0 -6
  51. data/lib/yext/api/concerns/api_finder.rb +0 -61
  52. data/lib/yext/api/utils/api_rate_limits.rb +0 -36
  53. data/lib/yext/api/utils/default_parameters.rb +0 -57
  54. data/lib/yext/api/utils/response_parser.rb +0 -84
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.16.0
@@ -1,2 +0,0 @@
1
- //= link_directory ../javascripts/yext/api .js
2
- //= link_directory ../stylesheets/yext/api .css
File without changes
@@ -1,13 +0,0 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
- //
10
- // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
- // about supported directives.
12
- //
13
- //= require_tree .
@@ -1,15 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
- * files in this directory. Styles in this file should be added after the last require_* statement.
11
- * It is generally better to create a new file per style scope.
12
- *
13
- *= require_tree .
14
- *= require_self
15
- */
@@ -1,45 +0,0 @@
1
- Other
2
- Date/time: Time.now.iso8601
3
- Date: Time.now.to_date.iso8601
4
-
5
- Classes examples:
6
- AdministrativeApi::Account
7
- AdministrativeApi::AddRequest
8
- AdministrativeApi::Service
9
- KnowledgeApi::HealthCheck::Health
10
- KnowledgeApi::KnowledgeManager::Location
11
- KnowledgeApi::KnowledgeManager::Folder
12
- KnowledgeApi::KnowledgeManager::Menu
13
- KnowledgeApi::KnowledgeManager::Bio
14
- KnowledgeApi::KnowledgeManager::Product
15
- KnowledgeApi::KnowledgeManager::Event
16
- KnowledgeApi::KnowledgeManager::Category
17
- KnowledgeApi::KnowledgeManager::GoogleField
18
- KnowledgeApi::KnowledgeManager::CustomField
19
- KnowledgeApi::KnowledgeManager::LanguageProfile
20
- KnowledgeApi::KnowledgeManager::Asset
21
- KnowledgeApi::PowerListings::Publisher
22
- KnowledgeApi::PowerListings::Listing
23
- KnowledgeApi::PowerListings::PublisherSuggestion
24
- KnowledgeApi::Analytics::MaxDate
25
- KnowledgeApi::Analytics::Report
26
- KnowledgeApi::Analytics::Activity
27
- KnowledgeApi::Reviews::Review
28
- KnowledgeApi::Reviews::Comment
29
- KnowledgeApi::Reviews::ReviewInvitation
30
- KnowledgeApi::Reviews::ReviewGenerationSetting
31
- KnowledgeApi::Social::Post
32
- KnowledgeApi::Social::Comment
33
- KnowledgeApi::Social::LinkedAccount
34
- KnowledgeApi::AccountSettings::Role
35
- KnowledgeApi::AccountSettings::User
36
- KnowledgeApi::AccountSettings::Account
37
- KnowledgeApi::OptimizationTasks::OptimizationTask
38
- LiveApi::Menu
39
- LiveApi::Bio
40
- LiveApi::Product
41
- LiveApi::Event
42
- LiveApi::LanguageProfile
43
- LiveApi::LanguageProfileSchema
44
- LiveApi::Location
45
- LiveApi::LocationSchema
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # :nocov:
4
- module Yext
5
- module Api
6
- # The base module for the Engines helpers.
7
- module ApplicationHelper
8
- end
9
- end
10
- end
11
- # :nocov:
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # module Yext
4
- # module Api
5
- # class ApplicationJob < ActiveJob::Base
6
- # end
7
- # end
8
- # end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # module Yext
4
- # module Api
5
- # # The base class for mailers in the Engine.
6
- # class ApplicationMailer < ActionMailer::Base
7
- # default from: "from@example.com"
8
- # layout "mailer"
9
- # end
10
- # end
11
- # end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Unused
4
- # module Yext
5
- # module Api
6
- # class ApplicationRecord < ActiveRecord::Base
7
- # self.abstract_class = true
8
- # end
9
- # end
10
- # end
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Yext Api</title>
5
- <%= stylesheet_link_tag "yext/api/application", media: "all" %>
6
- <%= javascript_include_tag "yext/api/application" %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
10
-
11
- <%= yield %>
12
-
13
- </body>
14
- </html>
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # desc "Explaining what the task does"
4
- # task :yext_api do
5
- # # Task goes here
6
- # end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Yext
4
- module Api
5
- module Concerns
6
- # This module add the `find_api` method to a class to allow the searching of the base
7
- # api category module for a particular route.
8
- module ApiFinder
9
- def find_api(url, method)
10
- return if url.nil? || method.nil?
11
- return Yext::Api::LiveApi if url.host.include?("liveapi")
12
-
13
- hash = YAML.load_file(Yext::Api::Engine.root.join("lib/config/api.yml"))
14
-
15
- hash.each_key do |hash_key|
16
- guess_api = api_from_key(hash_key)
17
-
18
- next if guess_api.blank?
19
-
20
- return guess_api if found_route?(hash[hash_key], url.path, method.to_s)
21
- end
22
-
23
- nil
24
- end
25
-
26
- private
27
-
28
- def found_route?(hash, path, method)
29
- hash.each do |key_name, sub_hash|
30
- if sub_hash.is_a?(Hash)
31
- return true if found_route?(sub_hash, path, method)
32
- elsif key_name == :actions
33
- return true if found_action?(sub_hash, path, method)
34
- end
35
- end
36
-
37
- false
38
- end
39
-
40
- def found_action?(actions, path, method)
41
- actions.each do |action|
42
- next if action[:path_regex].blank?
43
- next if action[:method].to_s != method
44
-
45
- return true if Regexp.new("#{action[:path_regex]}$").match(path)
46
- end
47
-
48
- false
49
- end
50
-
51
- def api_from_key(hash_key)
52
- "Yext::Api::#{hash_key.to_s.classify}".constantize
53
- rescue NameError
54
- # :nocov:
55
- nil
56
- # :nocov:
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Yext
4
- module Api
5
- module Utils
6
- # Faraday Middleware for extracting API limits from call responses.
7
- class ApiRateLimits < Faraday::Response::Middleware
8
- include Yext::Api::Concerns::ApiFinder
9
-
10
- def call(env)
11
- @app.call(env).on_complete do |environment|
12
- save_rates(environment, find_api(env[:url], env[:method].to_s))
13
-
14
- env.response
15
- end
16
- end
17
-
18
- private
19
-
20
- def save_rates(environment, api_module)
21
- return if api_module.blank?
22
-
23
- api_module.last_status = environment[:status]
24
-
25
- response_headers = environment[:response_headers]
26
-
27
- return unless response_headers.key?("rate-limit-remaining")
28
-
29
- api_module.update_rates(remaining: response_headers["rate-limit-remaining"].to_i,
30
- limit: response_headers["rate-limit-limit"].to_i,
31
- reset_at: Time.at(response_headers["rate-limit-reset"].to_i))
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Yext
4
- module Api
5
- module Utils
6
- # Faraday Middleware for adding Configuration default values to API calls as needed.
7
- #
8
- # Most options can be set via scopes and the soped values will be kept if they are used.
9
- #
10
- # The following configuration options are defaulted:
11
- # validation_level: Added to query parameters if not already there and is not nil
12
- # api_key: Added to query parameters if not already there
13
- # api_version: Added to qeury parameters if not already there
14
- # account_id: Inserted into the path if the path includes the Account default URI and no
15
- # account_id was specified.
16
- class DefaultParameters < Faraday::Response::Middleware
17
- attr_reader :configuration
18
-
19
- def call(request_env)
20
- @configuration = Yext::Api.configuration
21
- url = request_env[:url]
22
- params = Rack::Utils.parse_nested_query(url.query).with_indifferent_access
23
-
24
- add_username_headers(request_env, configuration, params)
25
- add_default_query_params(configuration, params)
26
- save_query_params(url, params)
27
-
28
- @app.call(request_env)
29
- end
30
-
31
- private
32
-
33
- def add_default_query_params(configuration, params)
34
- params.reverse_merge!(api_key: configuration.api_key,
35
- v: configuration.api_version || "20161012")
36
-
37
- params[:validation] ||= configuration.validation_level if configuration.validation_level.present?
38
- end
39
-
40
- def save_query_params(url, params)
41
- url.query = params.to_query
42
- end
43
-
44
- def add_username_headers(request_env, configuration, params)
45
- username = params.delete(:yext_username) || configuration.yext_username
46
- user_id = params.delete(:yext_user_id) || configuration.yext_user_id
47
-
48
- return unless %w[put post patch delete].include?(request_env[:method].to_s)
49
-
50
- request_headers = request_env[:request_headers]
51
- request_headers["Yext-Username"] = username if username.present?
52
- request_headers["Yext-User-Id"] = user_id if user_id.present?
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Yext
4
- module Api
5
- module Utils
6
- # The default response parser for Faraday to get the results from Yext into the structure
7
- # that is needed by Spyke.
8
- class ResponseParser < Faraday::Response::Middleware
9
- include Yext::Api::Concerns::ApiFinder
10
-
11
- def call(env)
12
- @parse_env = env
13
-
14
- @app.call(env).on_complete do |environment|
15
- on_complete(environment)
16
- end
17
- end
18
-
19
- def parse(body)
20
- # Yext Response:
21
- # http://developer.yext.com/docs/api-reference/#section/Policies-and-Conventions
22
- #
23
- # Example response format:
24
- # {
25
- # "meta": {
26
- # "uuid": "bb0c7e19-4dc3-4891-bfa5-8593b1f124ad",
27
- # "errors": [
28
- # {
29
- # "code": ...error code...,
30
- # "type": ...error, fatal error, non fatal error, or warning...,
31
- # "message": ...explanation of the issue...
32
- # }
33
- # ]
34
- # },
35
- # "response": {
36
- # ...results...
37
- # }
38
- # }
39
- #
40
- # Spyke Expected Response Format:
41
- # https://github.com/balvig/spyke#configuration
42
- #
43
- # { data: { id: 1, name: 'Bob' }, metadata: {}, errors: {} }
44
- #
45
- # Errors:
46
- # https://github.com/balvig/spyke#api-side-validations
47
- #
48
- # { title: [{ error: 'blank'}, { error: 'too_short', count: 10 }]}
49
-
50
- # yext_response_json = MultiJson.load(body, symbolize_keys: true)
51
- return {} if body.starts_with?("<html")
52
- return { data: [{ response_string: body }], metadata: {}, errors: {} } unless body.starts_with?("{")
53
-
54
- yext_response_json = JSON.parse(body, symbolize_names: true)
55
-
56
- data = extract_data_value(yext_response_json)
57
-
58
- save_meta_data(find_api(parse_env[:url], parse_env[:method].to_s), yext_response_json[:meta])
59
-
60
- { data: data,
61
- metadata: yext_response_json[:meta],
62
- errors: {} }
63
- end
64
-
65
- private
66
-
67
- def extract_data_value(yext_response_json)
68
- data = yext_response_json[:response]
69
- data = data[(data.keys - [:count]).first] if data.is_a?(Hash) && (data.key?(:count) || data.length <= 2)
70
-
71
- data
72
- end
73
-
74
- attr_reader :parse_env
75
-
76
- def save_meta_data(api_module, metadata)
77
- return if api_module.blank?
78
-
79
- api_module.last_meta = metadata
80
- end
81
- end
82
- end
83
- end
84
- end