From 3d11f60b2c78012ee76e8c66f59244c8d9953c84 Mon Sep 17 00:00:00 2001 From: Taylor Brooks Date: Sun, 4 Feb 2024 09:40:32 -0600 Subject: [PATCH] Initial commit --- .github/workflows/test.yml | 22 ++++ .gitignore | 4 + .ruby-version | 1 + .travis.yml | 1 + Gemfile | 3 + LICENSE | 22 ++++ README.md | 50 +++++++++ Rakefile | 14 +++ bin/rspec | 19 ++++ lib/shelby_arena.rb | 6 ++ lib/shelby_arena/client.rb | 101 ++++++++++++++++++ lib/shelby_arena/error.rb | 50 +++++++++ lib/shelby_arena/resources/batch.rb | 43 ++++++++ lib/shelby_arena/resources/contribution.rb | 72 +++++++++++++ lib/shelby_arena/resources/fund.rb | 23 ++++ lib/shelby_arena/resources/person.rb | 72 +++++++++++++ lib/shelby_arena/response/base.rb | 41 +++++++ lib/shelby_arena/response/batch.rb | 23 ++++ lib/shelby_arena/response/contribution.rb | 28 +++++ .../response/contribution_fund.rb | 20 ++++ lib/shelby_arena/response/fund.rb | 20 ++++ lib/shelby_arena/response/person.rb | 35 ++++++ lib/shelby_arena/version.rb | 3 + shelby_arena.gemspec | 33 ++++++ 24 files changed, 706 insertions(+) create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 .ruby-version create mode 100644 .travis.yml create mode 100644 Gemfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Rakefile create mode 100755 bin/rspec create mode 100644 lib/shelby_arena.rb create mode 100644 lib/shelby_arena/client.rb create mode 100644 lib/shelby_arena/error.rb create mode 100644 lib/shelby_arena/resources/batch.rb create mode 100644 lib/shelby_arena/resources/contribution.rb create mode 100644 lib/shelby_arena/resources/fund.rb create mode 100644 lib/shelby_arena/resources/person.rb create mode 100644 lib/shelby_arena/response/base.rb create mode 100644 lib/shelby_arena/response/batch.rb create mode 100644 lib/shelby_arena/response/contribution.rb create mode 100644 lib/shelby_arena/response/contribution_fund.rb create mode 100644 lib/shelby_arena/response/fund.rb create mode 100644 lib/shelby_arena/response/person.rb create mode 100644 lib/shelby_arena/version.rb create mode 100644 shelby_arena.gemspec diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..f17c84e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,22 @@ +name: Run specs + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + - name: Install dependencies + run: bundle install + - name: Run tests + run: bundle exec rspec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8e1ec1e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +shelby_arena-*.gem +.env +Gemfile.lock +.DS_Store diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..a4dd9db --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.7.4 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f819a51 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: ruby diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4a5d65a --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013 Taylor Brooks + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..025721d --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# Shelby Arena Ruby Client ![example workflow](https://github.com/taylorbrooks/shelby_arena/actions/workflows/test.yml/badge.svg) + +A Ruby wrapper for the Shelby Arena API + +### Installation +Add this line to your application's Gemfile: +````ruby + # in your Gemfile + gem 'shelby_arena', '~> 0.0.1' + + # then... + bundle install +```` + +### Usage +````ruby + # Authenticating with username and password + client = ShelbyArena::Client.new( + url: ..., + username: ..., + password: ..., + ) + + # Authenticating with authorization token + client = ShelbyArena::Client.new( + url: ..., + authorization_token: ..., + ) + + # Find a specific person + client.find_person_by_email('gob@bluthco.com') + client.find_person_by_name('Tobias Funke') +```` + +### History + +View the [changelog](https://github.com/taylorbrooks/shelby_arena/blob/master/CHANGELOG.md) +This gem follows [Semantic Versioning](http://semver.org/) + +### Contributing + +Everyone is encouraged to help improve this project. Here are a few ways you can help: + +- [Report bugs](https://github.com/taylorbrooks/shelby_arena/issues) +- Fix bugs and [submit pull requests](https://github.com/taylorbrooks/shelby_arena/pulls) +- Write, clarify, or fix documentation +- Suggest or add new features + +### Copyright +Copyright (c) 2023 Taylor Brooks. See LICENSE for details. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..6cdcbf8 --- /dev/null +++ b/Rakefile @@ -0,0 +1,14 @@ +require 'bundler/gem_tasks' +require 'rspec/core/rake_task' + +RSpec::Core::RakeTask.new(:spec) + +task default: :spec + +task :environment do + require 'dotenv' + Dotenv.load + + $LOAD_PATH.unshift File.expand_path('../lib', __FILE__) + require 'shelby_arena' +end diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000..d6327c1 --- /dev/null +++ b/bin/rspec @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path( + '../../Gemfile', + Pathname.new(__FILE__).realpath +) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rspec-core', 'rspec') diff --git a/lib/shelby_arena.rb b/lib/shelby_arena.rb new file mode 100644 index 0000000..ae30762 --- /dev/null +++ b/lib/shelby_arena.rb @@ -0,0 +1,6 @@ +require_relative 'shelby_arena/client' +require_relative 'shelby_arena/error' +require_relative 'shelby_arena/version' + +module ShelbyArena +end diff --git a/lib/shelby_arena/client.rb b/lib/shelby_arena/client.rb new file mode 100644 index 0000000..ef2a77c --- /dev/null +++ b/lib/shelby_arena/client.rb @@ -0,0 +1,101 @@ +require 'faraday' + +Dir[File.expand_path('../resources/*.rb', __FILE__)].each { |f| require f } +require File.expand_path('../response/base.rb', __FILE__) +Dir[File.expand_path('../response/*.rb', __FILE__)].each { |f| require f } + +module ShelbyArena + class Client + include ShelbyArena::Client::Batch + include ShelbyArena::Client::Fund + include ShelbyArena::Client::Person + include ShelbyArena::Client::Contribution + + attr_reader :url, :username, :password, :logger, :connection, :adapter, :ssl, :api_key, :api_secret, :api_session + + def initialize(url:, username:, password:, api_key:, api_secret:, logger: true, adapter: Faraday.default_adapter, ssl: nil) + if username.nil? && password.nil? + raise ArgumentError, 'either username and password' + end + + @url = "#{url}/api.svc/" + @username = username + @password = password + @api_key = api_key + @api_secret = api_secret + @logger = logger + @adapter = adapter + @ssl = ssl + @api_session = fetch_api_session + end + + def delete(path, options = {}) + connection.delete(path, options).body + end + + def get(path, options = {}) + connection.get(path, options).body + end + + def patch(path, options = {}) + connection.patch(path, options).body + end + + def post(path, options = {}) + connection.post(path, options).body + end + + def json_post(path, options = {}) + connection(true).post(path, options).body + end + + def put(path, options = {}) + connection.put(path, options).body + end + + private + + def fetch_api_session + params = { + username: username, + password: password, + api_key: api_key + } + + res = post('login', **params) + + res.dig('ApiSession', 'SessionID') + end + + def generate_api_sig(path, options = {}) + options[:api_session] = api_session + params = Faraday::FlatParamsEncoder.encode(options) + thing_to_hash = "#{api_secret}_#{path}?#{params}".downcase + Digest::MD5.hexdigest(thing_to_hash) + end + + def connection(json = false) + headers = { + accept: 'application/json', + 'User-Agent' => "shelby-arena-ruby-gem/v#{ShelbyArena::VERSION}" + } + + headers['Content-Type'] = 'application/json' if json + + client_opts = { + url: url, + headers: headers + } + + client_opts[:ssl] = ssl if ssl + + Faraday.new(client_opts) do |conn| + conn.request :url_encoded + conn.response :logger if logger + conn.response :xml + conn.use FaradayMiddleware::ShelbyArenaErrorHandler + conn.adapter adapter + end + end + end +end diff --git a/lib/shelby_arena/error.rb b/lib/shelby_arena/error.rb new file mode 100644 index 0000000..426a634 --- /dev/null +++ b/lib/shelby_arena/error.rb @@ -0,0 +1,50 @@ +module ShelbyArena + class Error < StandardError; end + class BadGateway < Error; end + class BadRequest < Error; end + class CloudflareError < Error; end + class Forbidden < Error; end + class GatewayTimeout < Error; end + class InternalServerError < Error; end + class NotFound < Error; end + class ServiceUnavailable < Error; end + class Unauthorized < Error; end +end + +require 'faraday' +module FaradayMiddleware + class ShelbyArenaErrorHandler < Faraday::Middleware + ERROR_STATUSES = 400..600 + + def on_complete(env) + case env[:status] + when 400 + raise ShelbyArena::BadRequest, error_message(env) + when 401 + raise ShelbyArena::Unauthorized, error_message(env) + when 403 + raise ShelbyArena::Forbidden, error_message(env) + when 404 + raise ShelbyArena::NotFound, error_message(env) + when 500 + raise ShelbyArena::InternalServerError, error_message(env) + when 502 + raise ShelbyArena::BadGateway, error_message(env) + when 503 + raise ShelbyArena::ServiceUnavailable, error_message(env) + when 504 + raise ShelbyArena::GatewayTimeout, error_message(env) + when 520 + raise ShelbyArena::CloudflareError, error_message(env) + when ERROR_STATUSES + raise ShelbyArena::Error, error_message(env) + end + end + + private + + def error_message(env) + "#{env[:status]}: #{env[:url]} #{env[:body]}" + end + end +end diff --git a/lib/shelby_arena/resources/batch.rb b/lib/shelby_arena/resources/batch.rb new file mode 100644 index 0000000..5a9dee7 --- /dev/null +++ b/lib/shelby_arena/resources/batch.rb @@ -0,0 +1,43 @@ +module ShelbyArena + class Client + module Batch + def list_batches(options = {}) + path = 'batch/list' + options[:api_sig] = generate_api_sig(path, options) + + res = get(path, options.sort) + Response::Batch.format(res.dig('BatchListResult', 'Batches', 'Batch')) + end + + def find_batch(id, options = {}) + path = "batch/#{id}" + options[:api_sig] = generate_api_sig(path, options) + + res = get(path, options.sort) + Response::Batch.format(res.dig('Batch')) + end + + def create_batch(name:, start_date:, end_date:) + path = 'batch/add' + body = { + BatchName: name, + BatchDate: start_date, + BatchDateEnd: end_date + } + + options = {} + options[:api_sig] = generate_api_sig(path, options) + json_body = body.to_json + + json_post("#{path}?api_session=#{options[:api_session]}&api_sig=#{options[:api_sig]}", json_body) + end + + def delete_batch(id, options = {}) + path = "batch/#{id}" + options[:api_sig] = generate_api_sig(path, options) + require 'pry'; binding.pry + delete(path, options.sort) + end + end + end +end diff --git a/lib/shelby_arena/resources/contribution.rb b/lib/shelby_arena/resources/contribution.rb new file mode 100644 index 0000000..9b2e091 --- /dev/null +++ b/lib/shelby_arena/resources/contribution.rb @@ -0,0 +1,72 @@ +module ShelbyArena + class Client + module Contribution + + def list_contributions(options = {}) + options[:api_sig] = generate_api_sig(contribution_path, options) + res = get(contribution_path, options.sort) + Response::Contribution.format(res.dig('ContributionListResult', 'Contributions', 'Contribution')) + end + + def find_contributions_by_batch_id(batch_id, options = {}) + path = "batch/#{batch_id}/contribution/list" + options[:api_sig] = generate_api_sig(path, options) + + res = get(path, options.sort) + Response::Contribution.format(res.dig('ContributionListResult', 'Contributions', 'Contribution')) + end + + def find_contribution(id, options = {}) + options[:api_sig] = generate_api_sig(contribution_path(id), options) + res = get(contribution_path(id), options.sort) + Response::Contribution.format(res.dig('Contribution')) + end + + def create_contribution( + batch_id, + person_id:, + date:, + currency_type_id:, + transaction_number:, + contribution_funds: + ) + path = "batch/#{batch_id}/contribution/add" + + body = { + 'BatchId' => batch_id, + 'CurrencyAmount' => sum_of_funds(contribution_funds), + 'TransactionNumber' => transaction_number, + 'ContributionDate' => date, + 'CurrencyTypeId' => currency_type_id, + 'PersonId' => person_id, + 'ContributionFunds' => translate_funds(contribution_funds) + } + + options = {} + options[:api_sig] = generate_api_sig(path, options) + + res = json_post("#{path}?api_session=#{options[:api_session]}&api_sig=#{options[:api_sig]}", body.to_json) + res.dig('ModifyResult', 'ObjectID') + end + + private + + def sum_of_funds(contribution_funds) + contribution_funds.map { |fund| fund[:amount] }.sum + end + + def translate_funds(contribution_funds) + contribution_funds.map do |fund| + { + 'FundId' => fund[:fund_id], + 'Amount' => fund[:amount] + } + end + end + + def contribution_path(id = nil) + id ? "contribution/#{id}" : 'contribution/list' + end + end + end +end diff --git a/lib/shelby_arena/resources/fund.rb b/lib/shelby_arena/resources/fund.rb new file mode 100644 index 0000000..50afbcd --- /dev/null +++ b/lib/shelby_arena/resources/fund.rb @@ -0,0 +1,23 @@ +module ShelbyArena + class Client + module Fund + def list_funds(options = {}) + options[:api_sig] = generate_api_sig(fund_path, options) + res = get(fund_path, options.sort) + Response::Fund.format(res.dig('FundListResult', 'Funds', 'Fund')) + end + + def find_fund(id, options = {}) + options[:api_sig] = generate_api_sig(fund_path(id), options) + res = get(fund_path(id), options.sort) + Response::Fund.format(res.dig('Fund')) + end + + private + + def fund_path(id = nil) + id ? "fund/#{id}" : 'fund/list' + end + end + end +end diff --git a/lib/shelby_arena/resources/person.rb b/lib/shelby_arena/resources/person.rb new file mode 100644 index 0000000..5417c2b --- /dev/null +++ b/lib/shelby_arena/resources/person.rb @@ -0,0 +1,72 @@ +module ShelbyArena + class Client + module Person + def list_people(options = {}) + options[:api_sig] = generate_api_sig(people_path, options) + res = get(people_path, options.sort) + Response::Person.format(res.dig('PersonListResult', 'Persons', 'Person')) + end + + def find_people_by_name_and_email(first_name, last_name, email) + list_people(firstName: first_name, lastName: last_name, email: email) + end + + def find_people_by_email(email) + list_people(email: email) + end + + def find_person(id, options = {}) + path = people_path(id) + options[:api_sig] = generate_api_sig(path, options) + res = get(path, options.sort) + Response::Person.format(res.dig('Person')) + end + + def create_person( + first_name:, + last_name:, + email: + ) + path = 'person/add' + + body = { + 'FirstName' => first_name, + 'LastName' => last_name, + 'Emails' => ['Address' => email] + } + + options = {} + options[:api_sig] = generate_api_sig(path, options) + res = json_post("#{path}?api_session=#{options[:api_session]}&api_sig=#{options[:api_sig]}", body.to_json) + res.dig('ModifyResult', 'ObjectID') + end + + def update_person( + id, + first_name: nil, + last_name: nil, + email: nil + ) + path = "#{people_path(id)}/update" + + body = {} + + body['FirstName'] = first_name if first_name + body['LastName'] = last_name if last_name + body['Emails'] = ['Address' => email] if email + + options = {} + options[:api_sig] = generate_api_sig(path, options) + + res = json_post("#{path}?api_session=#{options[:api_session]}&api_sig=#{options[:api_sig]}", body.to_json) + res.dig('ModifyResult', 'ObjectID') + end + + private + + def people_path(id = nil) + id ? "person/#{id}" : 'person/list' + end + end + end +end diff --git a/lib/shelby_arena/response/base.rb b/lib/shelby_arena/response/base.rb new file mode 100644 index 0000000..bcf7ea6 --- /dev/null +++ b/lib/shelby_arena/response/base.rb @@ -0,0 +1,41 @@ +module ShelbyArena + module Response + class Base + attr_reader :data + + def self.format(data) + new(data).format + end + + def initialize(data) + @data = data + end + + def format + if data.is_a?(Array) + data.map { |item| format_single(item) } + else + format_single(data) + end + end + + def to_h(dict, data) + return {} if data.nil? + + dict.each_with_object({}) do |(l, r), object| + object[l] = data[r] + end + end + + def to_boolean(string) + string.downcase == 'true' + end + + def date_parse(string) + return DateTime.parse(string) if string + + nil + end + end + end +end diff --git a/lib/shelby_arena/response/batch.rb b/lib/shelby_arena/response/batch.rb new file mode 100644 index 0000000..3432782 --- /dev/null +++ b/lib/shelby_arena/response/batch.rb @@ -0,0 +1,23 @@ +module ShelbyArena + module Response + class Batch < Base + MAP = { + name: 'BatchName', + id: 'BatchId', + start_date: 'BatchDate', + end_date: 'BatchDateEnd', + verify_amount: 'VerifyAmount', + finalized: 'Finalized' + }.freeze + + def format_single(data) + response = to_h(MAP, data) + response[:start_date] = date_parse(response[:start_date]) + response[:end_date] = date_parse(response[:end_date]) + response[:verify_amount] = response[:verify_amount].to_f + response[:finalized] = to_boolean(response[:finalized]) + response + end + end + end +end diff --git a/lib/shelby_arena/response/contribution.rb b/lib/shelby_arena/response/contribution.rb new file mode 100644 index 0000000..29fe5a4 --- /dev/null +++ b/lib/shelby_arena/response/contribution.rb @@ -0,0 +1,28 @@ +module ShelbyArena + module Response + class Contribution < Base + MAP = { + id: 'ContributionId', + batch_id: 'BatchId', + amount: 'CurrencyAmount', + date: 'ContributionDate', + memo: 'Memo', + person_id: 'PersonId', + person: 'PersonInformation', + transaction_number: 'TransactionNumber', + currency_type_id: 'CurrencyTypeId', + currency_type_value: 'CurrencyTypeValue', + contribution_funds: 'ContributionFunds' + }.freeze + + + def format_single(data) + response = to_h(MAP, data) + response[:contribution_funds] = ContributionFund.format(response[:contribution_funds].dig('ContributionFund')) if response[:contribution_funds] + response[:person] = Person.format(response[:person]) + response[:amount] = response[:amount].to_f + response + end + end + end +end diff --git a/lib/shelby_arena/response/contribution_fund.rb b/lib/shelby_arena/response/contribution_fund.rb new file mode 100644 index 0000000..c20ffc0 --- /dev/null +++ b/lib/shelby_arena/response/contribution_fund.rb @@ -0,0 +1,20 @@ +module ShelbyArena + module Response + class ContributionFund < Base + MAP = { + id: 'ContributionFundId', + contribution_id: 'ContributionId', + amount: 'Amount', + fund: 'Fund', + fund_id: 'FundId' + }.freeze + + def format_single(data) + response = to_h(MAP, data) + response[:fund] = Fund.format(response[:fund]) + response[:amount] = response[:amount].to_f + response + end + end + end +end diff --git a/lib/shelby_arena/response/fund.rb b/lib/shelby_arena/response/fund.rb new file mode 100644 index 0000000..5af7eab --- /dev/null +++ b/lib/shelby_arena/response/fund.rb @@ -0,0 +1,20 @@ +module ShelbyArena + module Response + class Fund < Base + MAP = { + id: 'FundId', + active: 'Active', + name: 'FundName', + online_name: 'OnlineName', + description: 'FundDescription', + is_tax_deductible: 'TaxDeductible', + start_date: 'StartDate', + end_date: 'EndDate' + }.freeze + + def format_single(data) + to_h(MAP, data) + end + end + end +end diff --git a/lib/shelby_arena/response/person.rb b/lib/shelby_arena/response/person.rb new file mode 100644 index 0000000..c9a9521 --- /dev/null +++ b/lib/shelby_arena/response/person.rb @@ -0,0 +1,35 @@ +module ShelbyArena + module Response + class Person < Base + MAP = { + age: 'Age', + first_name: 'FirstName', + last_name: 'LastName', + person_id: 'PersonID', + person_link: 'PersonLink', + gender: 'Gender' + }.freeze + + def format_single(data) + response = to_h(MAP, data) + response[:email] = set_email(data) + response[:emails] = set_emails(data) + response + end + + private + + def set_email(raw_response) + # find_person returns an array of `Emails` + # list_person return `FirstActiveEmail` + raw_response.dig('FirstActiveEmail') || raw_response.dig('Emails', 'Email', 0, 'Address') + end + + def set_emails(raw_response) + # find_person returns an array of `Emails` + # list_person return `FirstActiveEmail` + raw_response.dig('Emails', 'Email')&.map { |email| email.dig('Address') } || [] + end + end + end +end diff --git a/lib/shelby_arena/version.rb b/lib/shelby_arena/version.rb new file mode 100644 index 0000000..518e0cc --- /dev/null +++ b/lib/shelby_arena/version.rb @@ -0,0 +1,3 @@ +module ShelbyArena + VERSION = '0.0.1'.freeze +end diff --git a/shelby_arena.gemspec b/shelby_arena.gemspec new file mode 100644 index 0000000..0ef4392 --- /dev/null +++ b/shelby_arena.gemspec @@ -0,0 +1,33 @@ +$:.push File.expand_path('../lib', __FILE__) +require 'shelby_arena/version' +require 'base64' + +Gem::Specification.new do |s| + s.name = 'shelby_arena' + s.version = ShelbyArena::VERSION + s.authors = ['Taylor Brooks'] + s.email = ['dGJyb29rc0BnbWFpbC5jb20='].map { |e| Base64.decode64(e) } + s.homepage = 'https://github.com/taylorbrooks/shelby_arena' + s.summary = 'A Ruby wrapper for the Shelby Arena API' + s.description = 'A Ruby wrapper for the Shelby Arena API -- a church management platform.' + s.license = 'MIT' + + s.files = `git ls-files`.split($/) + s.executables = s.files.grep(%r{^bin/}).map { |f| File.basename(f) } + s.test_files = s.files.grep(%r{^(test)/}) + + s.required_ruby_version = '>= 2.7' + + s.require_paths = ['lib'] + + s.add_runtime_dependency 'faraday', '> 2.0' + s.add_runtime_dependency 'faraday-multipart' + + s.add_development_dependency 'bundler', '~> 2.3' + s.add_development_dependency 'dotenv' + s.add_development_dependency 'pry' + s.add_development_dependency 'rake', '~> 12.3.3' + s.add_development_dependency 'rspec', '~> 3.7' + s.add_development_dependency 'sinatra', '~> 2.0' + s.add_development_dependency 'webmock', '~> 3.1' +end