yext-api 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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