gemfather-stable 2.2.2

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 (60) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +145 -0
  3. data/bin/gemfather +6 -0
  4. data/gem_template/%app_name%.gemspec.tt +32 -0
  5. data/gem_template/.gitignore.tt +26 -0
  6. data/gem_template/.rubocop-rspec.yml.tt +38 -0
  7. data/gem_template/.rubocop-ruby.yml.tt +54 -0
  8. data/gem_template/.rubocop.yml.tt +11 -0
  9. data/gem_template/Gemfile.tt +17 -0
  10. data/gem_template/Makefile.tt +21 -0
  11. data/gem_template/README.md.tt +180 -0
  12. data/gem_template/Rakefile.tt +6 -0
  13. data/gem_template/bin/console.tt +21 -0
  14. data/gem_template/bin/generate.tt +6 -0
  15. data/gem_template/bin/rubocop.tt +29 -0
  16. data/gem_template/lib/%app_name%.rb.tt +25 -0
  17. data/gem_template/lib/%app_short_name%/client.rb.tt +18 -0
  18. data/gem_template/lib/%app_short_name%/http_errors.rb.tt +20 -0
  19. data/gem_template/lib/%app_short_name%/railtie.rb.tt +5 -0
  20. data/gem_template/lib/%app_short_name%/version.rb.tt +5 -0
  21. data/gem_template/log/.keep.tt +0 -0
  22. data/gem_template/spec/spec_helper.rb.tt +35 -0
  23. data/lib/api_generator/client/config.rb +57 -0
  24. data/lib/api_generator/client/connection.rb +149 -0
  25. data/lib/api_generator/commands/generate.rb +56 -0
  26. data/lib/api_generator/helpers/utils.rb +56 -0
  27. data/lib/api_generator/middleware/error_code_middleware.rb +43 -0
  28. data/lib/api_generator/middleware/error_handler_middleware.rb +26 -0
  29. data/lib/api_generator/middleware/handle_unsuccessful_request_middleware.rb +36 -0
  30. data/lib/api_generator/middleware/http_errors.rb +21 -0
  31. data/lib/api_generator/middleware/raise_error_base.rb +11 -0
  32. data/lib/api_generator/middleware/raise_error_dsl.rb +36 -0
  33. data/lib/api_generator/middleware.rb +4 -0
  34. data/lib/api_generator/models/base.rb +15 -0
  35. data/lib/api_generator/models/data.rb +16 -0
  36. data/lib/api_generator/pagination/dsl.rb +32 -0
  37. data/lib/api_generator/pagination/limit_offset_relation.rb +24 -0
  38. data/lib/api_generator/pagination/page_relation.rb +21 -0
  39. data/lib/api_generator/pagination/relation.rb +114 -0
  40. data/lib/api_generator/pagination.rb +2 -0
  41. data/lib/api_generator/railtie.rb +24 -0
  42. data/lib/api_generator/services/base_create.rb +56 -0
  43. data/lib/api_generator/services/create_api.rb +87 -0
  44. data/lib/api_generator/services/create_model.rb +69 -0
  45. data/lib/api_generator/services/create_scaffold.rb +53 -0
  46. data/lib/api_generator/services/gemfather.rb +81 -0
  47. data/lib/api_generator/version.rb +3 -0
  48. data/lib/api_generator.rb +18 -0
  49. data/templates/api/action.erb +10 -0
  50. data/templates/api/action_paginate.erb +10 -0
  51. data/templates/api/api_module.erb +11 -0
  52. data/templates/api/include_helpers.erb +9 -0
  53. data/templates/api/include_namespace.erb +1 -0
  54. data/templates/api/path.erb +1 -0
  55. data/templates/models/request.erb +11 -0
  56. data/templates/models/response.erb +11 -0
  57. data/templates/specs/api_spec.erb +15 -0
  58. data/templates/specs/request_spec.erb +12 -0
  59. data/templates/specs/response_spec.erb +12 -0
  60. metadata +229 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 73b2704a7a26751dddda94278a37d81fd0ed4a411c622e3b189212d25f7357f0
4
+ data.tar.gz: f2513f818f206125c3752aeea49f308efb33aabbe3a17cc33d054ffc946ce6f5
5
+ SHA512:
6
+ metadata.gz: 83ee29716ac671380b04d80903f6bf85c29c5af4c9922f746de54faee854dc421195e7a68076028d12ec53bdc978cebe6a3f60b77fbda17f16096fc9311bd8cd
7
+ data.tar.gz: f5309abbd86c427b9d573f9a1d7f0d48d75b3585cc2b8138de0d371c868f54a824195edd5029645d54685330232891e74b7a9fbcbd81ea1744e5dc2610c739e3
data/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # Gemfather
2
+
3
+ ![Gemfather image](/docs/gemfather.png?raw=true)
4
+
5
+ ### Гем для генерации API-гемов
6
+
7
+ Установка
8
+
9
+ `gem install gemfather`
10
+
11
+ После установки гем добавляет в путь `$PATH` исполняемый скрипт `gemfather`, который позволит запускать `gemfather` из командной строки
12
+
13
+ `gemfather GEM_NAME` создает в текущем каталоге папку GEM_NAME c базовой структурой для гема API
14
+
15
+ Описание нового проекта и документация по его конфигурированию и работе также будет сгененрирована в файле `GEM_NAME/README.md`
16
+
17
+ Пример:
18
+ ```
19
+ ./gemfather domclick_new_api
20
+
21
+ create domclick_new_api
22
+ create domclick_new_api/domclick_new_api.gemspec
23
+ create domclick_new_api/Dockerfile.test
24
+ create domclick_new_api/Gemfile
25
+ create domclick_new_api/Makefile
26
+ create domclick_new_api/README.md
27
+ create domclick_new_api/Rakefile
28
+ create domclick_new_api/bin/console
29
+ create domclick_new_api/bin/dc
30
+ create domclick_new_api/bin/generate
31
+ create domclick_new_api/lib/domclick_new_api.rb
32
+ create domclick_new_api/lib/domclick_new_api/client.rb
33
+ create domclick_new_api/lib/domclick_new_api/railtie.rb
34
+ create domclick_new_api/lib/domclick_new_api/version.rb
35
+ create domclick_new_api/spec/spec_helper.rb
36
+ create domclick_new_api/log
37
+ chmod domclick_new_api/bin/dc
38
+ chmod domclick_new_api/bin/generate
39
+ chmod domclick_new_api/bin/console
40
+ run bundle binstubs rspec-core from "./domclick_new_api"
41
+ run bin/rspec from "./domclick_new_api"
42
+ ```
43
+
44
+ Внутри каталога есть исполняемый скрипт generate, который генерирует в проекте скаффолд для ручки сервиса
45
+
46
+ Генерация скаффолда (api, model, specs) происходит следующим образом:
47
+ `bin/generate namespace:action:post`
48
+
49
+ Пример: `bin/generate deals:create:post`
50
+
51
+ Будет добавлена следующая структура каталогов и файлов
52
+ ```
53
+ create ./lib/domclick_api/api
54
+ create ./lib/domclick_api/api/deals.rb
55
+ create ./lib/domclick_api/model/deals/create
56
+ create ./lib/domclick_api/model/deals/create/request.rb
57
+ create ./lib/domclick_api/model/deals/create/response.rb
58
+ create ./spec/api
59
+ create ./spec/api/deals_spec.rb
60
+ create ./spec/model/deals/create
61
+ create ./spec/model/deals/create/request_spec.rb
62
+ create ./spec/model/deals/create/response_spec.rb
63
+ ```
64
+ Таким образом, будет создана ручка, вызывающая путь `/create`, модели `request` и `response`, а также тесты для этой ручки
65
+
66
+ ## Пагинация
67
+
68
+ Опционально, если добавить параметр `--paginate` - то ручка будет поддерживать пагинацию. Для конфигурации пагинации используется DSL:
69
+
70
+ ```ruby
71
+ paginate :find_offers,
72
+ with: :limit_offset,
73
+ on_request: lambda { |req, limit: nil, offset: nil, sort: nil|
74
+ req.params[:limit] = limit if limit.present?
75
+ req.params[:offset] = offset if offset.present?
76
+ req.params[:sort] = sort if sort.present?
77
+ },
78
+ data_key: :offers,
79
+ limit: :limit.to_proc,
80
+ offset: :offset.to_proc,
81
+ total: :total.to_proc
82
+ ```
83
+
84
+ ```ruby
85
+ paginate :find_offers,
86
+ with: :page,
87
+ on_request: lambda { |req, page: nil, per_page: nil, sort: nil|
88
+ req.params[:page] = page if page.present?
89
+ req.params[:per_page] = per_page if per_page.present?
90
+ req.params[:sort] = sort if sort.present?
91
+ },
92
+ data_key: :offers,
93
+ per_page: :per_page.to_proc,
94
+ total: :total.to_proc
95
+ ```
96
+
97
+ Таким образом, метод `find_offers` будет возвращать объект relation, реализующий `Enumerable`.
98
+ Данные при этом не будут загружены до тех пор, пока доступ к ним не понадобится (например, метод `#to_a`).
99
+
100
+ ## Опции DSL
101
+
102
+ `with` - стратегия пагинации, стандартно поддерживаются `:page` и `:limit_offset`.
103
+ `on_request` - коллбэк вызываемый при инициализации запроса. Позволяет нужным образом передать параметры (например, в теле или в хедерах).
104
+ `data_key` - ключ, по которому можно получить массив данных из ответа.
105
+ Может быть пустым, если данные лежат в корне, или массивом, если данные находятся в многоуровневой структуре (например, `[:data, :offers]`).
106
+ `total` - коллбэк, по которому можно получить из ответа общее количество элементов на всех страницах (не обязательная опция).
107
+
108
+ Опции, индивидуальные для стратегий пагинации:
109
+
110
+ ### Стратегия :page
111
+
112
+ `per_page` - коллбэк, по которому можно получить из ответа количество элементов на одной странице (не обязательная опция).
113
+
114
+ ### Стратегия :limit_offset
115
+
116
+ `limit` - коллбэк, по которому можно получить из ответа количество элементов на одной странице (не обязательная опция).
117
+ `offset` - коллбэк, по которому можно получить из ответа текущее смещение (не обязательная опция).
118
+
119
+ ## Использование метода с пагинацией
120
+
121
+ ```ruby
122
+ # Получение 100 записей, упорядоченных по id, начиная с 50-го элемента
123
+ client.find_offers(company_id: 1).limit(100).offset(50).order(id: 'desc').to_a
124
+
125
+ # Получение всех записей начиная с 50-го элемента
126
+ client.find_offers(company_id: 1).limit(100).offset(50).all_remaining.to_a
127
+
128
+ # Получение 10 записей на второй странице
129
+ client.find_offers(company_id: 1).page(2).per_page(10).to_a
130
+
131
+ # Получение всех записей начиная со второй страницы
132
+ client.find_offers(company_id: 1).page(2).all_remaining.to_a
133
+
134
+ # Получение первого элемента со второй страницы
135
+ client.find_offers(company_id: 1).page(2).first
136
+
137
+ # Получение полного ответа со второй страницы
138
+ client.find_offers(company_id: 1).page(2).response
139
+
140
+ # Получение общего количество элементов на всех страницах в сумме
141
+ client.find_offers(company_id: 1).page(2).total
142
+
143
+ # Получение общего количество элементов на всех страницах в сумме (сначала загрузит все страницы)
144
+ client.find_offers(company_id: 1).page(2).total!
145
+ ```
data/bin/gemfather ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bundler/setup'
3
+ require_relative '../lib/api_generator'
4
+
5
+ ApiGenerator::Services::Gemfather.new.generate_client(ARGV[0])
6
+
@@ -0,0 +1,32 @@
1
+ require_relative './lib/<%= app_short_name %>/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = '<%= app_name %>'
5
+ spec.version = <%= app_name_class %>::Version::VERSION
6
+ spec.authors = ['<%= author %>']
7
+ spec.email = ['<%= email %>']
8
+
9
+ spec.summary = 'API client for <%= app_name %> service'
10
+ spec.homepage = 'https://TODO.INSERT/YOUR_REPO/HERE/'
11
+ spec.required_ruby_version = '>= 2.7'
12
+
13
+ spec.metadata = {
14
+ 'bug_tracker_uri' => "#{spec.homepage}/issues",
15
+ 'changelog_uri' => "#{spec.homepage}/blob/main/CHANGELOG.md",
16
+ 'documentation_uri' => "#{spec.homepage}/blob/main/README.md",
17
+ 'homepage_uri' => spec.homepage,
18
+ 'source_code_uri' => spec.homepage,
19
+ 'rubygems_mfa_required' => 'true'
20
+ }
21
+
22
+ spec.files = Dir['lib/**/*', 'README.md']
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency 'addressable', '~> 2.3'
26
+ spec.add_dependency 'dry-configurable', '~> 0.11'
27
+ spec.add_dependency 'gemfather', '~> <%= version %>'
28
+ spec.add_dependency 'faraday', '>= 0.17', '< 2'
29
+ spec.add_dependency 'faraday_middleware', '>= 0.13', '< 2'
30
+ spec.add_dependency 'hashie', '>= 3.0', '< 5'
31
+ spec.add_dependency 'zeitwerk', '>= 2.2.2'
32
+ end
@@ -0,0 +1,26 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore all logfiles and tempfiles.
11
+ /log/*
12
+ !/log/.keep
13
+
14
+ # Local environments file by gem 'dotenv'
15
+ .env
16
+
17
+ # Ingore all builded gems
18
+ *.gem
19
+
20
+ # Ignore local lock for gem developing
21
+ Gemfile.lock
22
+
23
+ coverage
24
+ .rspec_status
25
+ .rspec
26
+ .yardoc
@@ -0,0 +1,38 @@
1
+ require: rubocop-rspec
2
+
3
+ Metrics/BlockLength:
4
+ Exclude:
5
+ - app/admin/**/*.rb
6
+ - spec/**/*.rb
7
+
8
+ Metrics/ModuleLength:
9
+ Exclude:
10
+ - spec/**/*.rb
11
+
12
+ Style/SymbolProc:
13
+ Exclude:
14
+ - spec/factories/**/*.rb
15
+
16
+ RSpec/ExampleLength:
17
+ Enabled: false
18
+
19
+ RSpec/HookArgument:
20
+ Enabled: false
21
+
22
+ RSpec/MultipleExpectations:
23
+ Enabled: false
24
+
25
+ RSpec/NestedGroups:
26
+ Max: 4
27
+
28
+ RSpec/FilePath:
29
+ Exclude:
30
+ - spec/requests/**/*.rb
31
+
32
+ RSpec/DescribeClass:
33
+ Exclude:
34
+ - spec/lib/tasks/**/*.rb
35
+ - spec/config/*.rb
36
+
37
+ RSpec/MultipleMemoizedHelpers:
38
+ Enabled: false
@@ -0,0 +1,54 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ Exclude:
4
+ - 'bin/**/*'
5
+ NewCops: enable
6
+
7
+ Layout/LineLength:
8
+ Max: 100
9
+
10
+ Bundler/OrderedGems:
11
+ Enabled: false
12
+
13
+ Layout/FirstHashElementIndentation:
14
+ EnforcedStyle: consistent
15
+
16
+ Layout/ClassStructure:
17
+ Enabled: true
18
+
19
+ Style/ClassAndModuleChildren:
20
+ Enabled: false
21
+
22
+ Style/Documentation:
23
+ Enabled: true
24
+ Include:
25
+ - 'app/services/**/*'
26
+
27
+ Style/FrozenStringLiteralComment:
28
+ Enabled: false
29
+
30
+ Style/AsciiComments:
31
+ Enabled: false
32
+
33
+ Style/Send:
34
+ Enabled: true
35
+
36
+ Style/HashEachMethods:
37
+ Enabled: true
38
+
39
+ Style/HashTransformKeys:
40
+ Enabled: true
41
+
42
+ Style/HashTransformValues:
43
+ Enabled: true
44
+
45
+ Style/TrailingCommaInArguments:
46
+ EnforcedStyleForMultiline: consistent_comma
47
+
48
+ Style/TrailingCommaInArrayLiteral:
49
+ EnforcedStyleForMultiline: consistent_comma
50
+
51
+ Style/TrailingCommaInHashLiteral:
52
+ EnforcedStyleForMultiline: consistent_comma
53
+
54
+
@@ -0,0 +1,11 @@
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+
5
+ inherit_from:
6
+ - .rubocop-ruby.yml
7
+ - .rubocop-rspec.yml
8
+
9
+ inherit_mode:
10
+ merge:
11
+ - Exclude
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://repo.sberned.ru/repository/rubygems-public/'
4
+
5
+ # Specify your gem's dependencies in <%= app_name %>.gemspec
6
+ gemspec
7
+
8
+ gem 'bundler', '~> 2.0'
9
+ gem 'rubocop', '~> 1.8'
10
+ gem 'rubocop-performance'
11
+ gem 'rubocop-rspec', '~> 2.1'
12
+ gem 'rubocop-rake'
13
+ gem 'dotenv', '~> 2.7'
14
+ gem 'pry', '~> 0.13'
15
+ gem 'rake', '~> 12.0'
16
+ gem 'rspec', '~> 3.9'
17
+ gem 'vcr', '~> 4.0'
@@ -0,0 +1,21 @@
1
+ default: lint test
2
+
3
+ setup:
4
+ bundle install
5
+
6
+ test:
7
+ bin/rspec
8
+
9
+ lint:
10
+ bin/rubocop
11
+
12
+ cleanup:
13
+ rm -f <%= app_name %>-*.gem
14
+
15
+ build:
16
+ gem build <%= app_name %>.gemspec
17
+
18
+ publish:
19
+ gem push <%= app_name %>-*.gem
20
+
21
+ deploy: build publish cleanup
@@ -0,0 +1,180 @@
1
+ # <%= app_name_class %>
2
+
3
+ Ruby клиент для взаимодейтсвия с API сервиса [<%= app_name_class %> API](https://<%= app_name %>.dev/)
4
+
5
+ ## Установка
6
+
7
+ Добавьте эту строку в Gemfile:
8
+
9
+ ```ruby
10
+ gem '<%= app_name %>'
11
+ ```
12
+
13
+ Выполните:
14
+
15
+ ```console
16
+ $ bundle
17
+ ```
18
+
19
+ Или установите из командной строки:
20
+
21
+ ```console
22
+ $ gem install <%= app_name %>
23
+ ```
24
+
25
+ ## Конфигурация
26
+
27
+ ```ruby
28
+ <%= app_name_class %>::Client.configure do |config|
29
+ config.api_endpoint = 'https://<%= app_name %>.dev/'
30
+ config.api_user = 'user'
31
+ config.api_password = 'password'
32
+ config.open_timeout = 5
33
+ config.read_timeout = 5
34
+ config.user_agent = 'info for debugging' # default is `Ruby <%= app_name_class %> API Client`
35
+ config.logger = Logger.new(STDERR) # по дефолту `Rails.logger` в development окружении, в других - nil
36
+ end
37
+ ```
38
+
39
+ ## Авторизация
40
+
41
+ Из коробки есть:
42
+ - По токену
43
+
44
+ Для конфигурации в config нужно передать заголовок и сам токен
45
+ ```ruby
46
+ config.api_token
47
+ config.api_header
48
+ ```
49
+ - Basic auth
50
+
51
+ Для конфигурации в config нужно передать логин и пароль
52
+ ```ruby
53
+ config.api_user
54
+ config.api_password
55
+ ```
56
+ - Для прочих кастомных настроек соединения при инициализации клиента передается блок
57
+
58
+ ```ruby
59
+ <%= app_name_class %>::Client.new do |connection|
60
+ # кастомные настройки
61
+ end
62
+ ```
63
+
64
+ ## Обработка ошибок
65
+ Обработка ошибок реализована через DSL в клиенте вида
66
+
67
+ `on_status 4XX, error: :error_name`
68
+
69
+ При появлении статуса `4ХХ`, будет выброшено исключение `ErrorName`
70
+
71
+
72
+ ## Использование
73
+
74
+ В папке `bin` существует скрипт `generate`, который генерирует в проекте скаффолд для ручки сервиса
75
+
76
+ Генерация скаффолда (api, model, specs) происходит следующим образом:
77
+ `bin/generate namespace:action:post`
78
+
79
+ Пример: `bin/generate deals:create:post`
80
+
81
+ Будет добавлена следующая структура каталогов и файлов
82
+ ```console
83
+ create ./lib/domclick_api/api
84
+ create ./lib/domclick_api/api/deals.rb
85
+ create ./lib/domclick_api/model/deals/create
86
+ create ./lib/domclick_api/model/deals/create/request.rb
87
+ create ./lib/domclick_api/model/deals/create/response.rb
88
+ create ./spec/api
89
+ create ./spec/api/deals_spec.rb
90
+ create ./spec/model/deals/create
91
+ create ./spec/model/deals/create/request_spec.rb
92
+ create ./spec/model/deals/create/response_spec.rb
93
+ ```
94
+ Таким образом, будет создана ручка, вызывающая путь `/create`, модели `request` и `response`, а также тесты для этой ручки
95
+
96
+ Вызов ручки:
97
+
98
+ ```ruby
99
+ client = <%= app_name_class %>.client
100
+ client.create(params)
101
+ ```
102
+ Опционально, если добавить параметр `--paginate` - то ручка будет поддерживать пагинацию. Для конфигурации пагинации используется DSL:
103
+
104
+ ```ruby
105
+ paginate :find_offers,
106
+ with: :limit_offset,
107
+ on_request: lambda { |req, limit: nil, offset: nil, sort: nil|
108
+ req.params[:limit] = limit if limit.present?
109
+ req.params[:offset] = offset if offset.present?
110
+ req.params[:sort] = sort if sort.present?
111
+ },
112
+ data_key: :offers,
113
+ limit: :limit.to_proc,
114
+ offset: :offset.to_proc,
115
+ total: :total.to_proc
116
+ ```
117
+
118
+ ```ruby
119
+ paginate :find_offers,
120
+ with: :page,
121
+ on_request: lambda { |req, page: nil, per_page: nil, sort: nil|
122
+ req.params[:page] = page if page.present?
123
+ req.params[:per_page] = per_page if per_page.present?
124
+ req.params[:sort] = sort if sort.present?
125
+ },
126
+ data_key: :offers,
127
+ per_page: :per_page.to_proc,
128
+ total: :total.to_proc
129
+ ```
130
+
131
+ Таким образом, метод `find_offers` будет возвращать объект relation, реализующий `Enumerable`.
132
+ Данные при этом не будут загружены до тех пор, пока доступ к ним не понадобится (например, метод `#to_a`).
133
+
134
+ ```ruby
135
+ client.find_offers(company_id: 1).limit(100).offset(50).order(id: 'desc').map(&:id)
136
+ ```
137
+
138
+ ## Разработка
139
+
140
+ Установка:
141
+
142
+ ```console
143
+ make setup
144
+ ```
145
+
146
+ Тесты:
147
+
148
+ ```console
149
+ make test
150
+ ```
151
+
152
+ Рубокоп:
153
+
154
+ ```console
155
+ make lint
156
+ ```
157
+
158
+ Очистка:
159
+
160
+ ```console
161
+ make cleanup
162
+ ```
163
+
164
+ Создать docker образ:
165
+
166
+ ```console
167
+ make build
168
+ ```
169
+
170
+ Поставка гема в RubyGems:
171
+
172
+ ```console
173
+ make publish
174
+ ```
175
+
176
+ Деплой:
177
+
178
+ ```console
179
+ make deploy
180
+ ```
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'dotenv/load'
5
+ require 'irb'
6
+ require_relative '../lib/<%= app_name %>'
7
+
8
+ <%= app_name_class %>::Client.configure do |configuration|
9
+ configuration.api_endpoint = 'http://server.dev'
10
+ configuration.api_token = 'TOKEN'
11
+
12
+ configuration.logger = Logger.new(STDOUT)
13
+ end
14
+
15
+ begin
16
+ # Put your test code here
17
+ rescue StandardError => e
18
+ pp e
19
+ end
20
+
21
+ binding.irb
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bundler/setup'
3
+ require 'api_generator'
4
+ require 'fileutils'
5
+
6
+ ApiGenerator::Commands::Generate.new(ARGV[0..1]).call
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rubocop", "rubocop")
@@ -0,0 +1,25 @@
1
+ require 'addressable'
2
+ require 'bundler/setup'
3
+ require 'api_generator'
4
+ require 'dry-configurable'
5
+ require 'faraday'
6
+ require 'faraday_middleware'
7
+ require 'hashie'
8
+ require 'time'
9
+ require 'zeitwerk'
10
+
11
+ require '<%= app_short_name %>/railtie' if defined?(Rails)
12
+
13
+ module <%= app_short_name_class %>
14
+ def self.client
15
+ return @client if defined?(@client) && @client.class.same_config?(Client.config)
16
+
17
+ @client = Client.new(**Client.config.to_h)
18
+ end
19
+ end
20
+
21
+ loader = Zeitwerk::Loader.new
22
+ loader.tag = File.basename(__FILE__, '.rb')
23
+ loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
24
+ loader.push_dir("#{__dir__}/<%= app_short_name %>", namespace: <%= app_name_class %>)
25
+ loader.setup
@@ -0,0 +1,18 @@
1
+ module <%= app_short_name_class %>
2
+ class Client < ApiGenerator::Client::Connection
3
+ # INCLUDES
4
+
5
+ # ERROR_HANDLING
6
+ on_status 400, error: :invalid_request_error
7
+ on_status 401, error: :unauthorized_error
8
+ on_status 403, error: :forbidden_error
9
+ on_status 404, error: :resource_not_found_error
10
+ on_status 405, error: :method_not_allowed_error
11
+ on_status 413, error: :payload_too_large_error
12
+ on_status 422, error: :unprocessable_entity
13
+
14
+ def customize_connection!(connection)
15
+ # set custom authorization here if needed
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module <%= app_short_name_class %>
2
+ module HttpErrors
3
+ class ConnectionError < StandardError; end
4
+
5
+ class BaseError < StandardError
6
+ attr_reader :body
7
+
8
+ def initialize(msg = nil, body = nil)
9
+ @body = body if body
10
+ super(msg)
11
+ end
12
+ end
13
+
14
+ class ServerError < BaseError; end
15
+
16
+ class ClientError < BaseError; end
17
+
18
+ class UnsuccessfulRequestError < ClientError; end
19
+ end
20
+ end