bullet_train-api 1.2.22 → 1.2.23

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b698e3c1efb4baded431f9971fd5102a93b4a582b3c23626a4c287d1f2158a53
4
- data.tar.gz: 6e44423ed7d5f4698372f7def585fbb5cf81c5caf1be0e64b315a1d21f443a1d
3
+ metadata.gz: 52964332e89aebd4034e1a1d6da5f4e96065920023b79a002360787140845d2c
4
+ data.tar.gz: 969c41617e73866c1fca4658846bc95a425dfb86e608f9f1687dc295a24248b6
5
5
  SHA512:
6
- metadata.gz: 9a53a06ce3d7620876c38ff9b4ddd89c7c19c18f044faf4158f276369a42fd7e1eec06df2f8ad58a52affb30f3fd88ce2aacfb6c2c7c96c03a4c2ff267d90119
7
- data.tar.gz: 83b4321431b744891209b52754499e796fb64ae6a8a1466d5bcf4482c79aad6f3a733d8f83abea15b1e6d425e9f497543db9bd21886a4f40aa730aa3957ff93e
6
+ metadata.gz: 39313d6d4963ec35c2b606d5bd967b1f04668dfc47de6269271b80450b9e5c5de872f93fa0b4bc8f194fe3ebc25a5507b523d2bf512a09401c8f1bb62b131c95
7
+ data.tar.gz: 19b9778baedbea755ab32b48b192b7141408a9b4467447a49631d9b5ab550651da37cb31628c4792882c44e059e790db4d42e621d0f4fcb61b8e9b7e38de56ee
@@ -1,128 +1,5 @@
1
- module OpenApiHelper
2
- def indent(string, count)
3
- lines = string.lines
4
- first_line = lines.shift
5
- lines = lines.map { |line| (" " * count).to_s + line }
6
- lines.unshift(first_line).join.html_safe
7
- end
8
-
9
- # TODO: Remove this method? It's not being used anywhere
10
- def components_for(model)
11
- for_model model do
12
- indent(render("api/#{@version}/open_api/#{model.name.underscore.pluralize}/components"), 2)
13
- end
14
- end
15
-
16
- def current_model
17
- @model_stack.last
18
- end
19
-
20
- def for_model(model)
21
- @model_stack ||= []
22
- @model_stack << model
23
- result = yield
24
- @model_stack.pop
25
- result
26
- end
27
-
28
- def gem_paths
29
- @gem_paths ||= `bundle show --paths`.lines.map { |gem_path| gem_path.chomp }
30
- end
31
-
32
- def automatic_paths_for(model, parent, except: [])
33
- output = render("api/#{@version}/open_api/shared/paths", except: except)
34
- output = Scaffolding::Transformer.new(model.name, [parent&.name]).transform_string(output).html_safe
35
- indent(output, 1)
36
- end
37
-
38
- def automatic_components_for(model, locals: {})
39
- path = "app/views/api/#{@version}"
40
- paths = ([path] + gem_paths.map { |gem_path| "#{gem_path}/#{path}" })
41
- jbuilder = Jbuilder::Schema.renderer(paths, locals: {
42
- # If we ever get to the point where we need a real model here, we should implement an example team in seeds that we can source it from.
43
- model.name.underscore.split("/").last.to_sym => model.new,
44
- # Same here, if we ever need this to be a real object, this should be `test@example.com` with an `SecureRandom.hex` password.
45
- :current_user => User.new
46
- }.merge(locals))
47
-
48
- schema_json = jbuilder.json(
49
- model.new,
50
- title: I18n.t("#{model.name.underscore.pluralize}.label"),
51
- # TODO Improve this. We don't have a generic description for models we can use here.
52
- description: I18n.t("#{model.name.underscore.pluralize}.label"),
53
- )
54
-
55
- attributes_output = JSON.parse(schema_json)
56
-
57
- # Rails attachments aren't technically attributes in a model,
58
- # so we add the attributes manually to make them available in the API.
59
- if model.attachment_reflections.any?
60
- model.attachment_reflections.each do |reflection|
61
- attribute_name = reflection.first
62
-
63
- attributes_output["properties"][attribute_name] = {
64
- "type" => "object",
65
- "description" => attribute_name.titleize.to_s
66
- }
67
-
68
- attributes_output["example"].merge!({attribute_name.to_s => nil})
69
- end
70
- end
71
-
72
- if has_strong_parameters?("Api::#{@version.upcase}::#{model.name.pluralize}Controller".constantize)
73
- strong_params_module = "Api::#{@version.upcase}::#{model.name.pluralize}Controller::StrongParameters".constantize
74
- strong_parameter_keys = BulletTrain::Api::StrongParametersReporter.new(model, strong_params_module).report
75
- if strong_parameter_keys.last.is_a?(Hash)
76
- strong_parameter_keys += strong_parameter_keys.pop.keys
77
- end
78
-
79
- parameters_output = JSON.parse(schema_json)
80
- parameters_output["required"].select! { |key| strong_parameter_keys.include?(key.to_sym) }
81
- parameters_output["properties"].select! { |key, value| strong_parameter_keys.include?(key.to_sym) }
82
-
83
- (
84
- indent(attributes_output.to_yaml.gsub("---", "#{model.name.gsub("::", "")}Attributes:"), 3) +
85
- indent(" " + parameters_output.to_yaml.gsub("---", "#{model.name.gsub("::", "")}Parameters:"), 3)
86
- ).html_safe
87
- else
88
-
89
- indent(attributes_output.to_yaml.gsub("---", "#{model.name.gsub("::", "")}Attributes:"), 3)
90
- .html_safe
91
- end
92
- end
93
-
94
- def paths_for(model)
95
- for_model model do
96
- indent(render("api/#{@version}/open_api/#{model.name.underscore.pluralize}/paths"), 1)
97
- end
98
- end
99
-
100
- def attribute(attribute)
101
- heading = t("#{current_model.name.underscore.pluralize}.fields.#{attribute}.heading")
102
- attribute_data = current_model.columns_hash[attribute.to_s]
103
-
104
- # Default to `string` when the type returns nil.
105
- type = attribute_data.nil? ? "string" : attribute_data.type
106
-
107
- attribute_block = <<~YAML
108
- #{attribute}:
109
- description: "#{heading}"
110
- type: #{type}
111
- YAML
112
- indent(attribute_block.chomp, 2)
113
- end
114
- alias_method :parameter, :attribute
115
-
116
- private
117
-
118
- def has_strong_parameters?(controller)
119
- methods = controller.action_methods
120
- methods.include?("create") || methods.include?("update")
121
- end
122
- end
123
-
124
1
  class Api::OpenApiController < ApplicationController
125
- helper :open_api
2
+ helper "api/open_api"
126
3
 
127
4
  def set_default_response_format
128
5
  request.format = :yaml
@@ -0,0 +1,124 @@
1
+ module Api
2
+ module OpenApiHelper
3
+ def indent(string, count)
4
+ lines = string.lines
5
+ first_line = lines.shift
6
+ lines = lines.map { |line| (" " * count).to_s + line }
7
+ lines.unshift(first_line).join.html_safe
8
+ end
9
+
10
+ # TODO: Remove this method? It's not being used anywhere
11
+ def components_for(model)
12
+ for_model model do
13
+ indent(render("api/#{@version}/open_api/#{model.name.underscore.pluralize}/components"), 2)
14
+ end
15
+ end
16
+
17
+ def current_model
18
+ @model_stack.last
19
+ end
20
+
21
+ def for_model(model)
22
+ @model_stack ||= []
23
+ @model_stack << model
24
+ result = yield
25
+ @model_stack.pop
26
+ result
27
+ end
28
+
29
+ def gem_paths
30
+ @gem_paths ||= `bundle show --paths`.lines.map { |gem_path| gem_path.chomp }
31
+ end
32
+
33
+ def automatic_paths_for(model, parent, except: [])
34
+ output = render("api/#{@version}/open_api/shared/paths", except: except)
35
+ output = Scaffolding::Transformer.new(model.name, [parent&.name]).transform_string(output).html_safe
36
+ indent(output, 1)
37
+ end
38
+
39
+ def automatic_components_for(model, locals: {})
40
+ path = "app/views/api/#{@version}"
41
+ paths = ([path] + gem_paths.map { |gem_path| "#{gem_path}/#{path}" })
42
+ jbuilder = Jbuilder::Schema.renderer(paths, locals: {
43
+ # If we ever get to the point where we need a real model here, we should implement an example team in seeds that we can source it from.
44
+ model.name.underscore.split("/").last.to_sym => model.new,
45
+ # Same here, if we ever need this to be a real object, this should be `test@example.com` with an `SecureRandom.hex` password.
46
+ :current_user => User.new
47
+ }.merge(locals))
48
+
49
+ schema_json = jbuilder.json(
50
+ model.new,
51
+ title: I18n.t("#{model.name.underscore.pluralize}.label"),
52
+ # TODO Improve this. We don't have a generic description for models we can use here.
53
+ description: I18n.t("#{model.name.underscore.pluralize}.label"),
54
+ )
55
+
56
+ attributes_output = JSON.parse(schema_json)
57
+
58
+ # Rails attachments aren't technically attributes in a model,
59
+ # so we add the attributes manually to make them available in the API.
60
+ if model.attachment_reflections.any?
61
+ model.attachment_reflections.each do |reflection|
62
+ attribute_name = reflection.first
63
+
64
+ attributes_output["properties"][attribute_name] = {
65
+ "type" => "object",
66
+ "description" => attribute_name.titleize.to_s
67
+ }
68
+
69
+ attributes_output["example"].merge!({attribute_name.to_s => nil})
70
+ end
71
+ end
72
+
73
+ if has_strong_parameters?("Api::#{@version.upcase}::#{model.name.pluralize}Controller".constantize)
74
+ strong_params_module = "Api::#{@version.upcase}::#{model.name.pluralize}Controller::StrongParameters".constantize
75
+ strong_parameter_keys = BulletTrain::Api::StrongParametersReporter.new(model, strong_params_module).report
76
+ if strong_parameter_keys.last.is_a?(Hash)
77
+ strong_parameter_keys += strong_parameter_keys.pop.keys
78
+ end
79
+
80
+ parameters_output = JSON.parse(schema_json)
81
+ parameters_output["required"].select! { |key| strong_parameter_keys.include?(key.to_sym) }
82
+ parameters_output["properties"].select! { |key, value| strong_parameter_keys.include?(key.to_sym) }
83
+
84
+ (
85
+ indent(attributes_output.to_yaml.gsub("---", "#{model.name.gsub("::", "")}Attributes:"), 3) +
86
+ indent(" " + parameters_output.to_yaml.gsub("---", "#{model.name.gsub("::", "")}Parameters:"), 3)
87
+ ).html_safe
88
+ else
89
+
90
+ indent(attributes_output.to_yaml.gsub("---", "#{model.name.gsub("::", "")}Attributes:"), 3)
91
+ .html_safe
92
+ end
93
+ end
94
+
95
+ def paths_for(model)
96
+ for_model model do
97
+ indent(render("api/#{@version}/open_api/#{model.name.underscore.pluralize}/paths"), 1)
98
+ end
99
+ end
100
+
101
+ def attribute(attribute)
102
+ heading = t("#{current_model.name.underscore.pluralize}.fields.#{attribute}.heading")
103
+ attribute_data = current_model.columns_hash[attribute.to_s]
104
+
105
+ # Default to `string` when the type returns nil.
106
+ type = attribute_data.nil? ? "string" : attribute_data.type
107
+
108
+ attribute_block = <<~YAML
109
+ #{attribute}:
110
+ description: "#{heading}"
111
+ type: #{type}
112
+ YAML
113
+ indent(attribute_block.chomp, 2)
114
+ end
115
+ alias_method :parameter, :attribute
116
+
117
+ private
118
+
119
+ def has_strong_parameters?(controller)
120
+ methods = controller.action_methods
121
+ methods.include?("create") || methods.include?("update")
122
+ end
123
+ end
124
+ end
@@ -4,7 +4,7 @@
4
4
  <% unless except.include?(:index) %>
5
5
  get:
6
6
  tags:
7
- - "Scaffolding/Completely Concrete/Tangible Things"
7
+ - Scaffolding::CompletelyConcrete::TangibleThing
8
8
  summary: "List Tangible Things"
9
9
  operationId: listScaffoldingCompletelyConcreteTangibleThings
10
10
  parameters:
@@ -30,11 +30,13 @@
30
30
  type: array
31
31
  items:
32
32
  $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
33
+ example:
34
+ <%= FactoryBot.get_example(:scaffolding_completely_concrete_tangible_thing, version: @version) %>
33
35
  <% end %>
34
36
  <% unless except.include?(:create) %>
35
37
  post:
36
38
  tags:
37
- - "Scaffolding/Completely Concrete/Tangible Things"
39
+ - Scaffolding::CompletelyConcrete::TangibleThing
38
40
  summary: "Create Tangible Thing"
39
41
  operationId: createScaffoldingCompletelyConcreteTangibleThings
40
42
  parameters:
@@ -54,6 +56,8 @@
54
56
  scaffolding_completely_concrete_tangible_thing:
55
57
  type: object
56
58
  $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingParameters"
59
+ example:
60
+ <%= FactoryBot.post_parameters(:scaffolding_completely_concrete_tangible_thing, version: @version) %>
57
61
  responses:
58
62
  "404":
59
63
  description: "Not Found"
@@ -63,6 +67,8 @@
63
67
  application/json:
64
68
  schema:
65
69
  $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
70
+ example:
71
+ <%= FactoryBot.post_examples(:scaffolding_completely_concrete_tangible_thing, version: @version) %>
66
72
  <% end %>
67
73
  <% end %>
68
74
  <% unless except.include?(:show) && except.include?(:update) && except.include?(:destroy) %>
@@ -70,7 +76,7 @@
70
76
  <% unless except.include?(:show) %>
71
77
  get:
72
78
  tags:
73
- - "Scaffolding/Completely Concrete/Tangible Things"
79
+ - Scaffolding::CompletelyConcrete::TangibleThing
74
80
  summary: "Fetch Tangible Thing"
75
81
  operationId: getScaffoldingCompletelyConcreteTangibleThings
76
82
  parameters:
@@ -84,11 +90,13 @@
84
90
  application/json:
85
91
  schema:
86
92
  $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
93
+ example:
94
+ <%= FactoryBot.get_example(:scaffolding_completely_concrete_tangible_thing, version: @version) %>
87
95
  <% end %>
88
96
  <% unless except.include?(:update) %>
89
97
  put:
90
98
  tags:
91
- - "Scaffolding/Completely Concrete/Tangible Things"
99
+ - Scaffolding::CompletelyConcrete::TangibleThing
92
100
  summary: "Update Tangible Thing"
93
101
  operationId: updateScaffoldingCompletelyConcreteTangibleThings
94
102
  parameters:
@@ -104,6 +112,8 @@
104
112
  scaffolding_completely_concrete_tangible_thing:
105
113
  type: object
106
114
  $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingParameters"
115
+ example:
116
+ <%= FactoryBot.put_parameters(:scaffolding_completely_concrete_tangible_thing, version: @version) %>
107
117
  responses:
108
118
  "404":
109
119
  description: "Not Found"
@@ -113,11 +123,13 @@
113
123
  application/json:
114
124
  schema:
115
125
  $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
126
+ example:
127
+ <%= FactoryBot.put_example(:scaffolding_completely_concrete_tangible_thing, version: @version) %>
116
128
  <% end %>
117
129
  <% unless except.include?(:destroy) %>
118
130
  delete:
119
131
  tags:
120
- - "Scaffolding/Completely Concrete/Tangible Things"
132
+ - Scaffolding::CompletelyConcrete::TangibleThing
121
133
  summary: "Remove Tangible Thing"
122
134
  operationId: removeScaffoldingCompletelyConcreteTangibleThings
123
135
  parameters:
@@ -1,7 +1,7 @@
1
1
  /teams:
2
2
  get:
3
3
  tags:
4
- - Teams
4
+ - Team
5
5
  summary: "List Teams"
6
6
  operationId: listTeams
7
7
  parameters:
@@ -22,10 +22,13 @@
22
22
  type: array
23
23
  items:
24
24
  $ref: "#/components/schemas/TeamAttributes"
25
+ example:
26
+ <%= FactoryBot.get_examples(:team, version: @version) %>
27
+
25
28
  /teams/{id}:
26
29
  get:
27
30
  tags:
28
- - Teams
31
+ - Team
29
32
  summary: "Fetch Team"
30
33
  operationId: fetchTeam
31
34
  parameters:
@@ -39,9 +42,11 @@
39
42
  application/json:
40
43
  schema:
41
44
  $ref: "#/components/schemas/TeamAttributes"
45
+ example:
46
+ <%= FactoryBot.get_example(:team, version: @version) %>
42
47
  put:
43
48
  tags:
44
- - Teams
49
+ - Team
45
50
  summary: "Update Team"
46
51
  operationId: updateTeam
47
52
  parameters:
@@ -57,6 +62,8 @@
57
62
  team:
58
63
  type: object
59
64
  $ref: "#/components/schemas/TeamParameters"
65
+ example:
66
+ <%= FactoryBot.put_parameters(:team, version: @version) %>
60
67
  responses:
61
68
  "404":
62
69
  description: "Not Found"
@@ -66,3 +73,5 @@
66
73
  application/json:
67
74
  schema:
68
75
  $ref: "#/components/schemas/TeamAttributes"
76
+ example:
77
+ <%= FactoryBot.put_example(:team, version: @version) %>
@@ -1,7 +1,7 @@
1
1
  /users:
2
2
  get:
3
3
  tags:
4
- - Users
4
+ - User
5
5
  summary: "List Users"
6
6
  operationId: listUsers
7
7
  parameters:
@@ -22,10 +22,12 @@
22
22
  type: array
23
23
  items:
24
24
  $ref: "#/components/schemas/UserAttributes"
25
+ example:
26
+ <%= FactoryBot.get_examples(:user, version: @version) %>
25
27
  /users/{id}:
26
28
  get:
27
29
  tags:
28
- - Users
30
+ - User
29
31
  summary: "Fetch User"
30
32
  operationId: fetchUser
31
33
  parameters:
@@ -39,9 +41,11 @@
39
41
  application/json:
40
42
  schema:
41
43
  $ref: "#/components/schemas/UserAttributes"
44
+ example:
45
+ <%= FactoryBot.get_example(:user, version: @version) %>
42
46
  put:
43
47
  tags:
44
- - Users
48
+ - User
45
49
  summary: "Update User"
46
50
  operationId: updateUser
47
51
  parameters:
@@ -57,6 +61,8 @@
57
61
  user:
58
62
  type: object
59
63
  $ref: "#/components/schemas/UserParameters"
64
+ example:
65
+ <%= FactoryBot.put_parameters(:user, version: @version) %>
60
66
  responses:
61
67
  "404":
62
68
  description: "Not Found"
@@ -66,3 +72,5 @@
66
72
  application/json:
67
73
  schema:
68
74
  $ref: "#/components/schemas/UserAttributes"
75
+ example:
76
+ <%= FactoryBot.put_example(:user, version: @version) %>
@@ -0,0 +1,146 @@
1
+ require_relative "../../../app/helpers/api/open_api_helper"
2
+
3
+ module FactoryBot
4
+ module ExampleBot
5
+ attr_accessor :tables_to_reset
6
+
7
+ def example(model, **options)
8
+ @tables_to_reset = [model.to_s.pluralize]
9
+
10
+ object = nil
11
+
12
+ ActiveRecord::Base.transaction do
13
+ instance = FactoryBot.create(factory(model), **options)
14
+ object = deep_clone(instance)
15
+
16
+ raise ActiveRecord::Rollback
17
+ end
18
+
19
+ reset_tables!
20
+ object
21
+ end
22
+
23
+ def example_list(model, quantity, **options)
24
+ @tables_to_reset = [model.to_s.pluralize]
25
+
26
+ objects = []
27
+
28
+ ActiveRecord::Base.transaction do
29
+ instances = FactoryBot.create_list(factory(model), quantity, **options)
30
+
31
+ instances.each do |instance|
32
+ objects << deep_clone(instance)
33
+ end
34
+
35
+ raise ActiveRecord::Rollback
36
+ end
37
+
38
+ reset_tables!
39
+ objects
40
+ end
41
+
42
+ %i[get_examples get_example post_examples post_parameters put_example put_parameters patch_example patch_parameters].each do |method|
43
+ define_method(method) do |model, **options|
44
+ _path_examples(method.to_s, model, **options)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def factory(model)
51
+ factories = FactoryBot.factories.instance_variable_get(:@items).keys
52
+ factories.include?("#{model}_example") ? "#{model}_example" : model
53
+ end
54
+
55
+ def reset_tables!
56
+ @tables_to_reset.each do |name|
57
+ ActiveRecord::Base.connection.reset_pk_sequence!(name) if ActiveRecord::Base.connection.table_exists?(name)
58
+ end
59
+ end
60
+
61
+ def deep_clone(instance)
62
+ clone = instance.clone
63
+
64
+ instance.class.reflections.each do |name, reflection|
65
+ if reflection.macro == :has_many
66
+ associations = instance.send(name).map { |association| association.clone }
67
+ clone.send("#{name}=", associations)
68
+ @tables_to_reset << name
69
+ elsif %i[belongs_to has_one].include?(reflection.macro)
70
+ clone.send("#{name}=", instance.send(name).clone)
71
+ @tables_to_reset << name.pluralize
72
+ end
73
+ end
74
+
75
+ clone
76
+ end
77
+
78
+ include ::Api::OpenApiHelper
79
+ def _path_examples(method, model, **options)
80
+ version = options.delete(:version) || "v1"
81
+
82
+ case method.split("_").first
83
+ when "get"
84
+ count = (options.delete(:count) || method == "get_examples") ? 2 : 1
85
+ template, class_name, var_name, values = _set_values(method, model, count)
86
+ else
87
+ template, class_name, var_name, values = _set_values("get_example", model)
88
+
89
+ unless %w[example examples].include?(method.split("_").last)
90
+ if has_strong_parameters?("::Api::#{version.upcase}::#{class_name.pluralize}Controller".constantize)
91
+ strong_params_module = "::Api::#{version.upcase}::#{class_name.pluralize}Controller::StrongParameters".constantize
92
+ strong_parameter_keys = BulletTrain::Api::StrongParametersReporter.new(class_name.constantize, strong_params_module).report
93
+ if strong_parameter_keys.last.is_a?(Hash)
94
+ strong_parameter_keys += strong_parameter_keys.pop.keys
95
+ end
96
+
97
+ output = _json_output(template, version, class_name, var_name, values)
98
+
99
+ parameters_output = JSON.parse(output)
100
+ parameters_output&.select! { |key| strong_parameter_keys.include?(key.to_sym) }
101
+
102
+ return indent(parameters_output.to_yaml.delete_prefix("---\n"), 6).html_safe
103
+ end
104
+ return nil
105
+ end
106
+ end
107
+
108
+ _yaml_output(template, version, class_name, var_name, values)
109
+ end
110
+
111
+ def _set_values(method, model, count = 1)
112
+ if count > 1
113
+ values = FactoryBot.example_list(model, count)
114
+ class_name = values.first.class.name
115
+ var_name = class_name.demodulize.underscore.pluralize
116
+ else
117
+ values = FactoryBot.example(model)
118
+ class_name = values.class.name
119
+ var_name = class_name.demodulize.underscore
120
+ end
121
+
122
+ template = (method == "get_examples") ? "index" : "show"
123
+
124
+ [template, class_name, var_name, values]
125
+ end
126
+
127
+ def _json_output(template, version, class_name, var_name, values)
128
+ ActionController::Base.render(
129
+ template: "api/#{version}/#{class_name.underscore.pluralize}/#{template}",
130
+ assigns: {"#{var_name}": values},
131
+ formats: :json
132
+ )
133
+ end
134
+
135
+ def _yaml_output(template, version, class_name, var_name, values)
136
+ indent(
137
+ JSON.parse(
138
+ _json_output(template, version, class_name, var_name, values)
139
+ ).to_yaml
140
+ .delete_prefix("---\n"), 7
141
+ ).html_safe
142
+ end
143
+ end
144
+
145
+ extend ExampleBot
146
+ end
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module Api
3
- VERSION = "1.2.22"
3
+ VERSION = "1.2.23"
4
4
  end
5
5
  end
@@ -1,6 +1,7 @@
1
1
  require "bullet_train/api/version"
2
2
  require "bullet_train/api/engine"
3
3
  require "bullet_train/api/strong_parameters_reporter"
4
+ require "bullet_train/api/example_bot"
4
5
  require "bullet_train/platform/connection_workflow"
5
6
 
6
7
  # require "wine_bouncer"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.22
4
+ version: 1.2.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-24 00:00:00.000000000 Z
11
+ date: 2023-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 2.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: factory_bot
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: bullet_train
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -141,6 +155,7 @@ files:
141
155
  - app/controllers/concerns/api/controllers/base.rb
142
156
  - app/controllers/concerns/api/v1/teams/controller_base.rb
143
157
  - app/controllers/concerns/api/v1/users/controller_base.rb
158
+ - app/helpers/api/open_api_helper.rb
144
159
  - app/models/platform/access_token.rb
145
160
  - app/models/platform/application.rb
146
161
  - app/views/account/platform/access_tokens/_breadcrumbs.html.erb
@@ -188,6 +203,7 @@ files:
188
203
  - config/routes.rb
189
204
  - lib/bullet_train/api.rb
190
205
  - lib/bullet_train/api/engine.rb
206
+ - lib/bullet_train/api/example_bot.rb
191
207
  - lib/bullet_train/api/strong_parameters_reporter.rb
192
208
  - lib/bullet_train/api/version.rb
193
209
  - lib/bullet_train/platform.rb