gemfather-stable 2.2.2

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/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