yext-api 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +100 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +10 -0
  9. data/Gemfile.lock +187 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +206 -0
  12. data/Rakefile +30 -0
  13. data/app/assets/config/yext_api_manifest.js +2 -0
  14. data/app/assets/images/yext/api/.keep +0 -0
  15. data/app/assets/javascripts/yext/api/application.js +13 -0
  16. data/app/assets/stylesheets/yext/api/application.css +15 -0
  17. data/app/controllers/yext/api/application_controller.rb +12 -0
  18. data/app/docs/notes.txt +45 -0
  19. data/app/helpers/yext/api/application_helper.rb +11 -0
  20. data/app/jobs/yext/api/application_job.rb +8 -0
  21. data/app/mailers/yext/api/application_mailer.rb +11 -0
  22. data/app/models/yext/api/application_record.rb +10 -0
  23. data/app/views/layouts/yext/api/application.html.erb +14 -0
  24. data/bin/console +16 -0
  25. data/bin/rails +16 -0
  26. data/bin/setup +8 -0
  27. data/config/initializers/spyke.rb +3 -0
  28. data/config/routes.rb +4 -0
  29. data/lib/config/api.yml +1100 -0
  30. data/lib/tasks/yext/api_tasks.rake +6 -0
  31. data/lib/yext/api.rb +33 -0
  32. data/lib/yext/api/administrative_api.rb +12 -0
  33. data/lib/yext/api/administrative_api/account.rb +62 -0
  34. data/lib/yext/api/administrative_api/add_request.rb +34 -0
  35. data/lib/yext/api/administrative_api/service.rb +38 -0
  36. data/lib/yext/api/concerns/account_child.rb +92 -0
  37. data/lib/yext/api/concerns/account_relations.rb +25 -0
  38. data/lib/yext/api/concerns/api_finder.rb +61 -0
  39. data/lib/yext/api/concerns/default_scopes.rb +37 -0
  40. data/lib/yext/api/concerns/enum_all.rb +18 -0
  41. data/lib/yext/api/concerns/faraday_connection.rb +45 -0
  42. data/lib/yext/api/concerns/rate_limits.rb +31 -0
  43. data/lib/yext/api/engine.rb +13 -0
  44. data/lib/yext/api/enumerations/validation.rb +16 -0
  45. data/lib/yext/api/knowledge_api.rb +12 -0
  46. data/lib/yext/api/knowledge_api/account_settings/account.rb +33 -0
  47. data/lib/yext/api/knowledge_api/health_check/health.rb +25 -0
  48. data/lib/yext/api/knowledge_api/knowledge_manager/category.rb +25 -0
  49. data/lib/yext/api/knowledge_api/knowledge_manager/location.rb +59 -0
  50. data/lib/yext/api/live_api.rb +12 -0
  51. data/lib/yext/api/live_api/location.rb +37 -0
  52. data/lib/yext/api/utils/api_base.rb +13 -0
  53. data/lib/yext/api/utils/api_rate_limits.rb +36 -0
  54. data/lib/yext/api/utils/configuration.rb +97 -0
  55. data/lib/yext/api/utils/default_parameters.rb +57 -0
  56. data/lib/yext/api/utils/response_parser.rb +84 -0
  57. data/lib/yext/api/version.rb +7 -0
  58. data/lib/yext/include_rails.rb +31 -0
  59. data/yext-api.gemspec +51 -0
  60. metadata +271 -0
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # desc "Explaining what the task does"
4
+ # task :yext_api do
5
+ # # Task goes here
6
+ # end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yext/api/engine"
4
+
5
+ module Yext
6
+ # API interface for Yext
7
+ module Api
8
+ # Allows you to configure global settings for the Yext::Api.
9
+ #
10
+ # See Yext::Api::Utils::Configuration for details on the configuration options.
11
+ #
12
+ # Usage:
13
+ #
14
+ # Yext::Api.configure do |config|
15
+ # config.account_id = "my account_id"
16
+ # config.api_key = "my api key"
17
+ # end
18
+ def self.configure
19
+ yield configuration if block_given?
20
+ end
21
+
22
+ # Gets the configuration object for configuring a single item.
23
+ #
24
+ # See Yext::Api::Utils::Configuration for details on the configuration options.
25
+ #
26
+ # Usage:
27
+ #
28
+ # Yext::Api.configuration.api_key = "my api key"
29
+ def self.configuration
30
+ Yext::Api::Utils::Configuration.instance
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ # http://developer.yext.com/docs/administrative-api
6
+ #
7
+ # Yext Administrative API
8
+ module AdministrativeApi
9
+ extend Yext::Api::Concerns::RateLimits
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module AdministrativeApi
6
+ # :administrative_api:
7
+ # :account:
8
+ # :actions:
9
+ # - :action: :create
10
+ # :method: :post
11
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/newlocationaddrequests
12
+ # :path_regex: v2/accounts/\w+/newlocationaddrequests
13
+ # :default_version: 20161012
14
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/createNewLocationAddRequest
15
+ # :comment: Request that a new location be added and services added to it. The location is created only if the request succeeds.
16
+ # :sandbox_only: false
17
+ # - :action: :add_services
18
+ # :method: :post
19
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/existinglocationaddrequests
20
+ # :path_regex: v2/accounts/\w+/existinglocationaddrequests
21
+ # :default_version: 20161012
22
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/createExistingLocationAddRequest
23
+ # :comment: Request that one or more available services be added to an existing location.
24
+ # :sandbox_only: false
25
+ # - :action: :change_status
26
+ # :method: :post
27
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/processaddrequest
28
+ # :path_regex: v2/accounts/\w+/processaddrequest
29
+ # :default_version: 20161012
30
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/createProcessReviewAddRequest
31
+ # :comment: Request that an add request in REVIEW be processed to COMPLETE, CANCELED, or FAILED.
32
+ # :sandbox_only: true
33
+ # - :action: :index
34
+ # :method: :get
35
+ # :endpoint: https://api.yext.com/v2/accounts
36
+ # :path_regex: v2/accounts
37
+ # :default_version: 20161012
38
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/listAccounts
39
+ # :comment: List all accounts that you have access to. Unless you are in Partner Portal mode, this will only be your own account.
40
+ # :sandbox_only: false
41
+ # - :action: :show
42
+ # :method: :get
43
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}
44
+ # :path_regex: v2/accounts/\w+
45
+ # :default_version: 20161012
46
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/getAccount
47
+ # :comment: Get details for an account.
48
+ # :sandbox_only: false
49
+ # - :action: :update
50
+ # :method: :put
51
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}
52
+ # :path_regex: v2/accounts/\w+
53
+ # :default_version: 20161012
54
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/updateAccount
55
+ # :comment: Update an account's name or ID.
56
+ # :sandbox_only: false
57
+ class Account < Yext::Api::Utils::ApiBase
58
+ include Yext::Api::Concerns::AccountRelations
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TODO: Complete and test. Untested initial framework class.
4
+ module Yext
5
+ module Api
6
+ module AdministrativeApi
7
+ # :administrative_api:
8
+ # :add_request:
9
+ # :actions:
10
+ # - :action: :index
11
+ # :method: :get
12
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/addrequests
13
+ # :path_regex: v2/accounts/[^/]+?/addrequests
14
+ # :default_version: 20161012
15
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/listAddRequests
16
+ # :comment: Get all of the add requests in the account. The response includes both New Location
17
+ # Add Requests and Existing Location Add Requests.
18
+ # :sandbox_only: false
19
+ # - :action: :show
20
+ # :method: :get
21
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/addrequests/{addRequestId}
22
+ # :path_regex: v2/accounts/[^/]+?/addrequests/[^/]+??
23
+ # :default_version: 20161012
24
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/getAddRequest
25
+ # :comment: Get status information about an add request previously created.
26
+ # :sandbox_only: false
27
+ class AddRequest < Yext::Api::Utils::ApiBase
28
+ uri("addrequests/(:id)")
29
+
30
+ include Yext::Api::Concerns::AccountChild
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module AdministrativeApi
6
+ # :administrative_api:
7
+ # :service:
8
+ # :actions:
9
+ # - :action: :available
10
+ # :method: :get
11
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/availableservices
12
+ # :default_version: 20161012
13
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/listAvailableServices
14
+ # :comment: Return list of services available to you under your agreements.
15
+ # :sandbox_only: false
16
+ # - :action: :index
17
+ # :method: :get
18
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/services
19
+ # :default_version: 20161012
20
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/listServices
21
+ # :comment: Retrieve a list of all services provisioned through this account.
22
+ # :sandbox_only: false
23
+ # - :action: :destroy
24
+ # :method: :post
25
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/cancelservices
26
+ # :default_version: 20161012
27
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/cancelServices
28
+ # :comment: Cancel one or more active services.
29
+ # :sandbox_only: false
30
+ class Service < Yext::Api::Utils::ApiBase
31
+ include Yext::Api::Concerns::AccountChild
32
+
33
+ scope :available, -> { with(Yext::Api::Concerns::AccountChild.with_account_path("availableservices")) }
34
+ scope :cancel_services, -> { with(Yext::Api::Concerns::AccountChild.with_account_path("cancelservices")) }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Concerns
6
+ # This concern prepends the `accounts/:account_id/` path to the URI for classes which require it.
7
+ #
8
+ # The account_id can be set in the following ways:
9
+ # * Global configuration:
10
+ # * Yext::Api.configuration.account_id = new_account_id
11
+ # * For an individual call:
12
+ # * SpykeClass.with_account(new_account_id)
13
+ # * SpykeClass.where(account_id: new_account_id)
14
+ #
15
+ # NOTE: This will not work if the DefaultParameters middleware is not being used.
16
+ #
17
+ # If the class that this is included in uses a custom URI, the `uri` call must be made before this
18
+ # module is included.
19
+ module AccountChild
20
+ extend ActiveSupport::Concern
21
+
22
+ class << self
23
+ def with_account_path(path)
24
+ File.join("accounts/:account_id", path)
25
+ end
26
+
27
+ def ensure_relation(klass)
28
+ [Yext::Api::KnowledgeApi::AccountSettings::Account, Yext::Api::AdministrativeApi::Account].each do |account_class|
29
+ next if account_class.instance_methods.include?("#{klass.model_name.element}_ids".to_sym)
30
+
31
+ klass_uri = klass.instance_variable_get(:@uri)
32
+ helper_warnings(account_class, klass, klass_uri)
33
+ klass_uri ||= klass.send(:default_uri)
34
+
35
+ add_has_many_relation(account_class, klass, klass_uri)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def add_has_many_relation(account_class, klass, klass_uri)
42
+ account_class.class_eval do
43
+ has_many klass.model_name.element.pluralize.to_sym,
44
+ class_name: klass.name,
45
+ uri: Yext::Api::Concerns::AccountChild.with_account_path(klass_uri)
46
+ end
47
+ end
48
+
49
+ def helper_warnings(account_class, klass, klass_uri)
50
+ klass_name = klass.name
51
+ relation_name = klass.model_name.element.pluralize
52
+
53
+ puts "WARNING! #{account_class.name} does not include the relationship for #{klass_name}"
54
+ puts " Add the following line to Yext::Api::Concerns::AccountRelations:"
55
+
56
+ if klass_uri && klass_uri != klass.send(:default_uri)
57
+ puts " has_many :#{relation_name}, class_name: \"#{klass_name}\", " \
58
+ "uri: Yext::Api::Concerns::AccountChild.with_account_path(\"#{klass_uri}\")"
59
+ else
60
+ puts " has_many :#{relation_name}, class_name: \"#{klass_name}\""
61
+ end
62
+ end
63
+ end
64
+
65
+ included do
66
+ scope(:with_account, lambda do |account_or_id|
67
+ if account_or_id.is_a?(Yext::Api::KnowledgeApi::AccountSettings::Account) ||
68
+ account_or_id.is_a?(Yext::Api::AdministrativeApi::Account)
69
+ account_or_id
70
+ else
71
+ Yext::Api::KnowledgeApi::AccountSettings::Account.new(id: account_or_id)
72
+ end.public_send(model_name.element.pluralize)
73
+ end)
74
+
75
+ Yext::Api::Concerns::AccountChild.ensure_relation(self)
76
+ end
77
+
78
+ class_methods do
79
+ def all
80
+ if current_scope.nil?
81
+ Yext::Api::KnowledgeApi::AccountSettings::Account.
82
+ new(id: Yext::Api.configuration.account_id || "me").
83
+ public_send(model_name.element.pluralize)
84
+ else
85
+ current_scope
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Concerns
6
+ # Because the Account is listed in the API documentation in two locations, there are two
7
+ # different but somewhat identical Account objects.
8
+ #
9
+ # This module includes the shared code between the two.
10
+ module AccountRelations
11
+ extend ActiveSupport::Concern
12
+
13
+ # The module AccountChild will add these relations if they are missing, but if they are
14
+ # listed explicitly it is more efficient.
15
+ included do
16
+ has_many :add_requests,
17
+ class_name: "Yext::Api::AdministrativeApi::AddRequest",
18
+ uri: Yext::Api::Concerns::AccountChild.with_account_path("addrequests/(:id)")
19
+ has_many :locations, class_name: "Yext::Api::KnowledgeApi::KnowledgeManager::Location"
20
+ has_many :services, class_name: "Yext::Api::AdministrativeApi::Service"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,61 @@
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
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Concerns
6
+ # This module adds default scopes that will specify configurations to be overridden for a
7
+ # particular call.
8
+ #
9
+ # If these scopes are used, the values passed in will be used in the API call, if the scope
10
+ # is not used, then the DefaultParameters middleware will insert the default values.
11
+ module DefaultScopes
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ scope(:with_version, ->(version) { where(v: version) })
16
+ scope(:with_application, ->(app_id) { where(api_key: app_id) })
17
+ scope(:yext_username, ->(username) { where(yext_username: username) })
18
+ scope(:yext_user_id, ->(user_id) { where(yext_user_id: user_id) })
19
+
20
+ scope(:validate, lambda do |validation = Yext::Api::Enumerations::Validation::STRICT|
21
+ if validation.is_a?(String)
22
+ validation = Yext::Api::Enumerations::Validation::STRICT unless Yext::Api::Enumerations::Validation.all.include?(validation)
23
+ else
24
+ validation = if validation
25
+ Yext::Api::Enumerations::Validation::STRICT
26
+ else
27
+ Yext::Api::Enumerations::Validation::LENIENT
28
+ end
29
+ end
30
+
31
+ where(validation: validation)
32
+ end)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Concerns
6
+ # This concern adds an `all` method to an enumeration class to list all constants in that class.
7
+ module EnumAll
8
+ extend ActiveSupport::Concern
9
+
10
+ class_methods do
11
+ def all
12
+ (constants - %i[ClassMethods]).map { |c| const_get(c) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Concerns
6
+ # This module defines methods that set the connection for a Spyke class.
7
+ #
8
+ # The default connection is to the sandbox or the API based on the value of the configuration
9
+ # sandbox setting.
10
+ #
11
+ # A class function live_api is provided to allow LiveApi module classes to use the live endpoint.
12
+ module FaradayConnection
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ url = if Yext::Api.configuration.sandbox
17
+ "https://sandbox.yext.com/v2"
18
+ else
19
+ "https://api.yext.com/v2"
20
+ end
21
+
22
+ self.connection = Yext::Api::Concerns::FaradayConnection.faraday_connection(url)
23
+ end
24
+
25
+ class_methods do
26
+ def live_api
27
+ self.connection = Yext::Api::Concerns::FaradayConnection.faraday_connection("https://live.yext.com/v2")
28
+ end
29
+ end
30
+
31
+ def self.faraday_connection(url)
32
+ Faraday.new(url: url) do |c|
33
+ c.request :json
34
+
35
+ c.use Yext::Api::Utils::ResponseParser
36
+ c.use Yext::Api::Utils::DefaultParameters
37
+ c.use Yext::Api::Utils::ApiRateLimits
38
+
39
+ c.adapter Faraday.default_adapter
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end