From 27b6baf5af0688e6bda055c8f5eae307db159cad Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Mon, 14 Nov 2022 16:04:57 -0500 Subject: [PATCH 01/12] Make some changes to produce valid JSON - Change shape of parameters - Default description to empty string when there is no comment --- .../swagger/templates/swagger.json.erb | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 6793887..652c258 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -40,30 +40,27 @@ parameters = { name: :data, in: :body, - type: :object, - properties: { - data: { - type: :object, - properties: { - type: { type: :string, default: route_resouces }, - attributes: { - type: :object, - properties: properties(attrs: creatable_fields) - } + schema: { + type: :object, + properties: { + type: { type: :string, default: route_resouces }, + attributes: { + type: :object, + properties: properties(attrs: creatable_fields) } - }, + } }, description: tt(:request_body) } - parameters[:properties][:data][:properties][:relationships] ||= {} - parameters[:properties][:data][:properties][:relationships] = { type: :object, properties: create_relationships_properties } + parameters[:schema][:properties][:relationships] ||= {} + parameters[:schema][:properties][:relationships] = { type: :object, properties: create_relationships_properties } parameters end def patch_resource_parameters patch_parameters = create_resource_parameters.dup - patch_parameters[:properties][:data][:properties][:id] ||= {} - patch_parameters[:properties][:data][:properties][:id].merge!({ type: :integer, description: 'ID' }) + patch_parameters[:schema][:properties][:id] ||= {} + patch_parameters[:schema][:properties][:id].merge!({ type: :integer, description: 'ID' }) parameters = [{ name: :id, in: :path, type: :integer, description: 'ID', required: true }] parameters << patch_parameters parameters @@ -80,7 +77,7 @@ props[attr][:type] = columns[attr][:type] props[attr][:items] = { type: columns[attr][:items_type] } if columns[attr][:is_array] props[attr][:'x-nullable'] = columns[attr][:nullable] - props[attr][:description] = columns[attr][:comment] + props[attr][:description] = columns[attr][:comment] || '' end end end From 6827c9ad5961b3c38dc582850463c87d5302accd Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Mon, 21 Nov 2022 11:24:17 -0500 Subject: [PATCH 02/12] Add host --- lib/generators/jsonapi/swagger/swagger_generator.rb | 8 ++++++++ .../jsonapi/swagger/templates/swagger.json.erb | 2 ++ lib/jsonapi/swagger.rb | 10 +++++++++- lib/jsonapi/swagger/json.rb | 4 ++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/generators/jsonapi/swagger/swagger_generator.rb b/lib/generators/jsonapi/swagger/swagger_generator.rb index ddc9e4a..3c00e38 100644 --- a/lib/generators/jsonapi/swagger/swagger_generator.rb +++ b/lib/generators/jsonapi/swagger/swagger_generator.rb @@ -41,10 +41,18 @@ def swagger_info JSON.pretty_generate(Jsonapi::Swagger.info) end + def swagger_host + Jsonapi::Swagger.host + end + def swagger_base_path Jsonapi::Swagger.base_path end + def swagger_security_definitions + JSON.pretty_generate(Jsonapi::Swagger.security_definitions) + end + def swagger_file_path Jsonapi::Swagger.file_path end diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 652c258..4bff1a6 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -1,7 +1,9 @@ { "swagger": "<%= swagger_version %>", "info": <%= swagger_info %>, + "host": "<%= swagger_host %>", "basePath" : "<%= swagger_base_path %>", + "securityDefinitions": <%= swagger_security_definitions %>, <%- def list_resource_parameters [].tap do |parameters| diff --git a/lib/jsonapi/swagger.rb b/lib/jsonapi/swagger.rb index 9c0c689..5e4d503 100644 --- a/lib/jsonapi/swagger.rb +++ b/lib/jsonapi/swagger.rb @@ -10,7 +10,7 @@ module Swagger class Error < StandardError; end class << self - attr_accessor :version, :info, :file_path, :base_path, :use_rswag + attr_accessor :version, :info, :file_path, :base_path, :host, :use_rswag def config yield self @@ -32,6 +32,14 @@ def base_path @base_path end + def host + @host + end + + def security_definitions + @security_definitions ||= { BasicAuth: { type: 'basic' } } + end + def use_rswag @use_rswag ||= false end diff --git a/lib/jsonapi/swagger/json.rb b/lib/jsonapi/swagger/json.rb index b23c3e9..ce0b17b 100644 --- a/lib/jsonapi/swagger/json.rb +++ b/lib/jsonapi/swagger/json.rb @@ -12,6 +12,10 @@ def parse_doc @doc ||= JSON.parse(load) rescue Hash.new{ |h, k| h[k]= {} } end + def host + Jsonapi::Swagger.host + end + def base_path Jsonapi::Swagger.base_path end From bbdec802297ef2337b848f8f5793586f85a541df Mon Sep 17 00:00:00 2001 From: Katrina Date: Mon, 21 Nov 2022 13:18:06 -0800 Subject: [PATCH 03/12] dasherized attributes --- .../jsonapi/swagger/templates/swagger.json.erb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 4bff1a6..6d01a79 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -75,11 +75,13 @@ def properties(attrs: []) Hash.new{|h, k| h[k] = {}} .tap do |props| attrs.each do |attr| - columns = columns_with_comment(need_encoding: false) - props[attr][:type] = columns[attr][:type] - props[attr][:items] = { type: columns[attr][:items_type] } if columns[attr][:is_array] - props[attr][:'x-nullable'] = columns[attr][:nullable] - props[attr][:description] = columns[attr][:comment] || '' + # We dasherize the attribute key because JSONApiResources needs attributes to be dasherized + dasherizedAttr = attr.to_s.gsub("_", "-") + columns = columns_with_comment(need_encoding: false) + props[dasherizedAttr][:type] = columns[attr][:type] + props[dasherizedAttr][:items] = { type: columns[attr][:items_type] } if columns[attr][:is_array] + props[dasherizedAttr][:'x-nullable'] = columns[attr][:nullable] + props[dasherizedAttr][:description] = columns[attr][:comment] || '' end end end From 3eba8e51359c42e1031b33c770dad542aee5c7b0 Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Mon, 21 Nov 2022 16:19:10 -0500 Subject: [PATCH 04/12] Modify the shape to avoid duplicate 'data's and add security sections --- .../swagger/templates/swagger.json.erb | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 6d01a79..5101075 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -43,26 +43,30 @@ name: :data, in: :body, schema: { - type: :object, properties: { - type: { type: :string, default: route_resouces }, - attributes: { + data: { type: :object, - properties: properties(attrs: creatable_fields) + properties: { + type: { type: :string, default: route_resouces }, + attributes: { + type: :object, + properties: properties(attrs: creatable_fields) + } + } } } }, description: tt(:request_body) } - parameters[:schema][:properties][:relationships] ||= {} - parameters[:schema][:properties][:relationships] = { type: :object, properties: create_relationships_properties } + parameters[:schema][:properties][:data][:properties][:relationships] ||= {} + parameters[:schema][:properties][:data][:properties][:relationships] = { type: :object, properties: create_relationships_properties } parameters end def patch_resource_parameters patch_parameters = create_resource_parameters.dup - patch_parameters[:schema][:properties][:id] ||= {} - patch_parameters[:schema][:properties][:id].merge!({ type: :integer, description: 'ID' }) + patch_parameters[:schema][:properties][:data][:properties][:id] ||= {} + patch_parameters[:schema][:properties][:data][:properties][:id].merge!({ type: :integer, description: 'ID' }) parameters = [{ name: :id, in: :path, type: :integer, description: 'ID', required: true }] parameters << patch_parameters parameters @@ -263,6 +267,7 @@ summary: "#{route_resouces} #{tt(:list)}", tags: [route_resouces], produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], parameters: list_resource_parameters, responses: list_resource_responses } @@ -273,6 +278,7 @@ summary: "#{route_resouces} #{tt(:detail)}", tags: [route_resouces], produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], parameters: show_resource_parameters, responses: show_resource_responses } @@ -285,6 +291,7 @@ if mutable? tags: [route_resouces], consumes: ['application/vnd.api+json'], produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], parameters: [create_resource_parameters], responses: create_resource_responses } @@ -296,6 +303,7 @@ if mutable? tags: [route_resouces], consumes: ['application/vnd.api+json'], produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], parameters: patch_resource_parameters, responses: show_resource_responses } @@ -306,6 +314,7 @@ if mutable? summary: "#{route_resouces} #{tt(:delete)}", tags: [route_resouces], produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], parameters: delete_resource_parameters, responses: delete_resource_responses } From 8140a0826f614c804367193c26f214d31fbe3c0b Mon Sep 17 00:00:00 2001 From: Katrina Date: Tue, 29 Nov 2022 14:06:25 -0800 Subject: [PATCH 05/12] modified swagger.json.erb such that the generated swagger.json file contains only the enabled methods for a given resource --- .../swagger/templates/swagger.json.erb | 75 +++++++++++-------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 5101075..394e835 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -285,40 +285,51 @@ } if mutable? - doc['paths']["/#{route_resouces}"].merge!({ - post: { - summary: "#{route_resouces} #{tt(:create)}", - tags: [route_resouces], - consumes: ['application/vnd.api+json'], - produces: ['application/vnd.api+json'], - security: [{ BasicAuth: [] }], - parameters: [create_resource_parameters], - responses: create_resource_responses - } - }) + if Rails.application.routes.recognize_path("#{route_resouces}", method: :post)[:action] != 'error' + doc['paths']["/#{route_resouces}"].merge!({ + post: { + summary: "#{route_resouces} #{tt(:create)}", + tags: [route_resouces], + consumes: ['application/vnd.api+json'], + produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], + parameters: [create_resource_parameters], + responses: create_resource_responses + } + }) + end - doc['paths']["/#{route_resouces}/{id}"].merge!({ - patch: { - summary: "#{route_resouces} #{tt(:patch)}", - tags: [route_resouces], - consumes: ['application/vnd.api+json'], - produces: ['application/vnd.api+json'], - security: [{ BasicAuth: [] }], - parameters: patch_resource_parameters, - responses: show_resource_responses - } - }) + current_resource = file_name.pluralize + # the db query returns a hash that is then converted into an array (length 1) from which we grab the value stored under id + id = ActiveRecord::Base.connection.exec_query("SELECT id FROM #{current_resource} LIMIT 1").to_a[0]["id"] + + if Rails.application.routes.recognize_path("#{route_resouces}/#{id}", method: :patch)[:action] != 'error' + doc['paths']["/#{route_resouces}/{id}"].merge!({ + patch: { + summary: "#{route_resouces} #{tt(:patch)}", + tags: [route_resouces], + consumes: ['application/vnd.api+json'], + produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], + parameters: patch_resource_parameters, + responses: show_resource_responses + } + }) + end + + if Rails.application.routes.recognize_path("#{route_resouces}/#{id}", method: :delete)[:action] != 'error' + doc['paths']["/#{route_resouces}/{id}"].merge!({ + delete: { + summary: "#{route_resouces} #{tt(:delete)}", + tags: [route_resouces], + produces: ['application/vnd.api+json'], + security: [{ BasicAuth: [] }], + parameters: delete_resource_parameters, + responses: delete_resource_responses + } + }) + end - doc['paths']["/#{route_resouces}/{id}"].merge!({ - delete: { - summary: "#{route_resouces} #{tt(:delete)}", - tags: [route_resouces], - produces: ['application/vnd.api+json'], - security: [{ BasicAuth: [] }], - parameters: delete_resource_parameters, - responses: delete_resource_responses - } - }) else doc['paths']["/#{route_resouces}"].delete(:post) doc['paths']["/#{route_resouces}/{id}"].delete(:patch) From e90310c92327c7e78766baa533492fa037e7c835 Mon Sep 17 00:00:00 2001 From: Katrina Date: Thu, 1 Dec 2022 11:35:20 -0800 Subject: [PATCH 06/12] refactored swagger.json.erb --- .../swagger/templates/swagger.json.erb | 99 ++++++------------- 1 file changed, 31 insertions(+), 68 deletions(-) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 394e835..4785d58 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -25,7 +25,7 @@ end end - def show_resource_parameters + def detail_resource_parameters [].tap do |parameters| parameters << { name: :id, in: :path, type: :integer, description: 'ID', required: true } if relationships.present? @@ -204,7 +204,7 @@ } end - def show_resource_responses + def detail_resource_responses { '200' => { description: tt(:get_detail), @@ -213,6 +213,8 @@ } end + alias patch_resource_responses detail_resource_responses + def create_resource_responses { '201' => { @@ -262,79 +264,40 @@ } end - doc['paths']["/#{route_resouces}"] = { - get: { - summary: "#{route_resouces} #{tt(:list)}", - tags: [route_resouces], - produces: ['application/vnd.api+json'], - security: [{ BasicAuth: [] }], - parameters: list_resource_parameters, - responses: list_resource_responses - } - } + current_resource = file_name.pluralize + id = ActiveRecord::Base.connection.exec_query("SELECT id FROM #{current_resource} LIMIT 1").to_a[0]["id"] - doc['paths']["/#{route_resouces}/{id}"] = { - get: { - summary: "#{route_resouces} #{tt(:detail)}", - tags: [route_resouces], - produces: ['application/vnd.api+json'], - security: [{ BasicAuth: [] }], - parameters: show_resource_parameters, - responses: show_resource_responses - } - } + doc['paths']["/#{route_resouces}"] = {} + doc['paths']["/#{route_resouces}/{id}"] = {} -if mutable? - if Rails.application.routes.recognize_path("#{route_resouces}", method: :post)[:action] != 'error' - doc['paths']["/#{route_resouces}"].merge!({ - post: { - summary: "#{route_resouces} #{tt(:create)}", - tags: [route_resouces], - consumes: ['application/vnd.api+json'], - produces: ['application/vnd.api+json'], - security: [{ BasicAuth: [] }], - parameters: [create_resource_parameters], - responses: create_resource_responses - } - }) - end - - current_resource = file_name.pluralize - # the db query returns a hash that is then converted into an array (length 1) from which we grab the value stored under id - id = ActiveRecord::Base.connection.exec_query("SELECT id FROM #{current_resource} LIMIT 1").to_a[0]["id"] - - if Rails.application.routes.recognize_path("#{route_resouces}/#{id}", method: :patch)[:action] != 'error' - doc['paths']["/#{route_resouces}/{id}"].merge!({ - patch: { - summary: "#{route_resouces} #{tt(:patch)}", - tags: [route_resouces], - consumes: ['application/vnd.api+json'], - produces: ['application/vnd.api+json'], - security: [{ BasicAuth: [] }], - parameters: patch_resource_parameters, - responses: show_resource_responses - } - }) - end + [:list, :detail, :create, :patch, :delete].each do |action| + method = action + if action == :list || action == :detail + method = :get + elsif action == :create + method = :post + end - if Rails.application.routes.recognize_path("#{route_resouces}/#{id}", method: :delete)[:action] != 'error' - doc['paths']["/#{route_resouces}/{id}"].merge!({ - delete: { - summary: "#{route_resouces} #{tt(:delete)}", + path_hash = Hash.new + path_hash[method] = { + summary: "#{route_resouces} #{tt(action)}", tags: [route_resouces], produces: ['application/vnd.api+json'], security: [{ BasicAuth: [] }], - parameters: delete_resource_parameters, - responses: delete_resource_responses + parameters: send("#{action.to_s}_resource_parameters"), + responses: send("#{action.to_s}_resource_responses") } - }) - end -else - doc['paths']["/#{route_resouces}"].delete(:post) - doc['paths']["/#{route_resouces}/{id}"].delete(:patch) - doc['paths']["/#{route_resouces}/{id}"].delete(:delete) -end --%> + if action == :list || action == :create + if Rails.application.routes.recognize_path("#{route_resouces}", method: method)[:action] != 'error' + doc['paths']["/#{route_resouces}"].merge!(path_hash) + end + else + if Rails.application.routes.recognize_path("#{route_resouces}/#{id}", method: method)[:action] != 'error' + doc['paths']["/#{route_resouces}/{id}"].merge!(path_hash) + end + end + end + -%> "paths": <%= JSON.pretty_generate(doc['paths'] ) %> } \ No newline at end of file From 32f513e1cc4cb892849a277f5753c8c81a46c64f Mon Sep 17 00:00:00 2001 From: Katrina Date: Mon, 5 Dec 2022 08:46:00 -0800 Subject: [PATCH 07/12] fixed the post paramarers array in swagger.json.erb --- lib/generators/jsonapi/swagger/swagger_generator.rb | 10 +++++----- .../jsonapi/swagger/templates/swagger.json.erb | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/generators/jsonapi/swagger/swagger_generator.rb b/lib/generators/jsonapi/swagger/swagger_generator.rb index 3c00e38..daf6417 100644 --- a/lib/generators/jsonapi/swagger/swagger_generator.rb +++ b/lib/generators/jsonapi/swagger/swagger_generator.rb @@ -74,11 +74,11 @@ def resouces_name end def route_resouces - resouces_name.tableize + resouces_name.tableize.dasherize end def model_class_name - (class_path + [file_name]).map!(&:camelize).join("::") + (class_path + [file_name]).map!(&:camelize).join('::') end def sortable_fields_desc @@ -141,7 +141,7 @@ def columns_with_comment(need_encoding: true) model_klass.columns.each do |col| col_name = transform_method ? col.name.send(transform_method) : col.name is_array = col.respond_to?(:array) ? col.array : false - clos[col_name.to_sym] = { type: swagger_type(col), items_type: col.type, is_array: is_array, nullable: col.null, comment: col.comment } + clos[col_name.to_sym] = { type: swagger_type(col), items_type: col.type, is_array: is_array, nullable: col.null, comment: col.comment } clos[col_name.to_sym][:comment] = safe_encode(col.comment) if need_encoding end end @@ -162,12 +162,12 @@ def relation_table_name(relation) return relation.name if relation.respond_to?(:name) end - def t(key, options={}) + def t(key, options = {}) content = tt(key, options) safe_encode(content) end - def tt(key, options={}) + def tt(key, options = {}) options[:scope] = :jsonapi_swagger options[:default] = key.to_s.humanize I18n.t(key, options) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 4785d58..2f73e42 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -288,6 +288,10 @@ responses: send("#{action.to_s}_resource_responses") } + if action == :create + path_hash[method][:parameters] = [path_hash[method][:parameters]] + end + if action == :list || action == :create if Rails.application.routes.recognize_path("#{route_resouces}", method: method)[:action] != 'error' doc['paths']["/#{route_resouces}"].merge!(path_hash) From e95f0c63523ff50023984c9ee55eb42654cdeb75 Mon Sep 17 00:00:00 2001 From: Katrina Date: Mon, 5 Dec 2022 12:48:41 -0800 Subject: [PATCH 08/12] added line in swagger.json.erb to include 'consumes' in generated swagger.json --- lib/generators/jsonapi/swagger/templates/swagger.json.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 2f73e42..9b4890f 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -282,6 +282,7 @@ path_hash[method] = { summary: "#{route_resouces} #{tt(action)}", tags: [route_resouces], + consumes: ['application/vnd.api+json'], produces: ['application/vnd.api+json'], security: [{ BasicAuth: [] }], parameters: send("#{action.to_s}_resource_parameters"), From 9c96b9aea010aee69cdff619796fd3758576df4c Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Mon, 5 Dec 2022 16:38:24 -0500 Subject: [PATCH 09/12] introduce swagger_all --- lib/generators/jsonapi/swagger_all/USAGE | 5 + .../swagger_all/swagger_all_generator.rb | 169 ++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 lib/generators/jsonapi/swagger_all/USAGE create mode 100644 lib/generators/jsonapi/swagger_all/swagger_all_generator.rb diff --git a/lib/generators/jsonapi/swagger_all/USAGE b/lib/generators/jsonapi/swagger_all/USAGE new file mode 100644 index 0000000..d62252d --- /dev/null +++ b/lib/generators/jsonapi/swagger_all/USAGE @@ -0,0 +1,5 @@ +Description: + Create a JSONAPI Swagger for all resources + +Example: + rails generate jsonapi:swagger_all diff --git a/lib/generators/jsonapi/swagger_all/swagger_all_generator.rb b/lib/generators/jsonapi/swagger_all/swagger_all_generator.rb new file mode 100644 index 0000000..f495823 --- /dev/null +++ b/lib/generators/jsonapi/swagger_all/swagger_all_generator.rb @@ -0,0 +1,169 @@ +module Jsonapi + class SwaggerAllGenerator < Rails::Generators::Base + desc 'Create JSONAPI Swaggers for all Resources.' + source_root File.expand_path('../swagger/templates', __dir__) + + def create_swagger_all_file + ["V0::Admin", "V0::Batch"].each do |resource| + template 'swagger.json.erb', json_file + end + end + + private + + def doc + @doc ||= swagger_json.parse_doc + end + + def json_file + @json_file ||= File.join( + 'swagger', + swagger_file_path + ) + end + + def swagger_version + Jsonapi::Swagger.version + end + + def swagger_info + JSON.pretty_generate(Jsonapi::Swagger.info) + end + + def swagger_host + Jsonapi::Swagger.host + end + + def swagger_base_path + Jsonapi::Swagger.base_path + end + + def swagger_security_definitions + JSON.pretty_generate(Jsonapi::Swagger.security_definitions) + end + + def swagger_file_path + Jsonapi::Swagger.file_path + end + + def swagger_json + @swagger_json ||= Jsonapi::Swagger::Json.new(json_file) + end + + def spec_file_name + "#{file_name.downcase.pluralize}_spec.rb" + end + + def model_name + file_name.downcase.singularize + end + + def resouces_name + model_class_name.pluralize + end + + def route_resouces + resouces_name.tableize + end + + def model_class_name + (class_path + [file_name]).map!(&:camelize).join("::") + end + + def sortable_fields_desc + t(:sortable_fields) + ': (-)' + sortable_fields.join(',') + end + + def ori_sortable_fields_desc + tt(:sortable_fields) + ': (-)' + sortable_fields.join(',') + end + + def model_klass + file_name.camelize.safe_constantize + end + + def resource_klass + @resource_klass ||= Jsonapi::Swagger::Resource.with(model_class_name) + end + + def attributes + resource_klass.attributes.except(:id) + end + + def relationships + resource_klass.relationships + end + + def sortable_fields + resource_klass.sortable_fields + end + + def creatable_fields + resource_klass.creatable_fields - relationships.keys + end + + def updatable_fields + resource_klass.updatable_fields - relationships.keys + end + + def filters + resource_klass.filters + end + + def mutable? + resource_klass.mutable? + end + + def attribute_default + Jsonapi::Swagger.attribute_default + end + + def transform_method + @transform_method ||= resource_klass.transform_method if resource_klass.respond_to?(:transform_method) + end + + def columns_with_comment(need_encoding: true) + @columns_with_comment ||= {}.tap do |clos| + clos.default_proc = proc do |h, k| + h[k] = attribute_default + end + model_klass.columns.each do |col| + col_name = transform_method ? col.name.send(transform_method) : col.name + is_array = col.respond_to?(:array) ? col.array : false + clos[col_name.to_sym] = { type: swagger_type(col), items_type: col.type, is_array: is_array, nullable: col.null, comment: col.comment } + clos[col_name.to_sym][:comment] = safe_encode(col.comment) if need_encoding + end + end + end + + def swagger_type(column) + return 'array' if column.respond_to?(:array) && column.array + + case column.type + when :bigint, :integer then 'integer' + when :boolean then 'boolean' + else 'string' + end + end + + def relation_table_name(relation) + return relation.class_name.tableize if relation.respond_to?(:class_name) + return relation.name if relation.respond_to?(:name) + end + + def t(key, options={}) + content = tt(key, options) + safe_encode(content) + end + + def tt(key, options={}) + options[:scope] = :jsonapi_swagger + options[:default] = key.to_s.humanize + I18n.t(key, options) + end + + def safe_encode(content) + content&.force_encoding('ASCII-8BIT') + end + end +end From a6884580a220d8424c7ea0294fa898a42cf686a0 Mon Sep 17 00:00:00 2001 From: Katrina Date: Mon, 19 Dec 2022 09:11:04 -0600 Subject: [PATCH 10/12] modified swagger.json.erb to produce valid swagger.json --- .../jsonapi/swagger/templates/swagger.json.erb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 9b4890f..5fd0360 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -22,6 +22,10 @@ relationships.each_value do |relation| parameters << { name: :"fields[#{relation_table_name(relation)}]", in: :query, type: :string, description: tt(:display_field), required: false } end + duplicate = parameters.detect{ |el| parameters.count(el) > 1 } + if duplicate + parameters.delete_at(parameters.find_index(duplicate)) + end end end @@ -35,6 +39,10 @@ relationships.each_value do |relation| parameters << { name: :"fields[#{relation_table_name(relation)}]", in: :query, type: :string, description: tt(:display_field), required: false } end + duplicate = parameters.detect{ |el| parameters.count(el) > 1 } + if duplicate + parameters.delete_at(parameters.find_index(duplicate)) + end end end @@ -303,6 +311,14 @@ end end end + + if doc['paths']["/#{route_resouces}"] == {} + doc['paths'].delete("/#{route_resouces}") + end + + if doc['paths']["/#{route_resouces}/{id}"] == {} + doc['paths'].delete("/#{route_resouces}/{id}") + end -%> "paths": <%= JSON.pretty_generate(doc['paths'] ) %> } \ No newline at end of file From 194c0f7c0c562d86a7341c1aaad1d1979d39007e Mon Sep 17 00:00:00 2001 From: Katrina Date: Mon, 19 Dec 2022 13:17:29 -0600 Subject: [PATCH 11/12] Revert "introduce swagger_all" This reverts commit 9c96b9aea010aee69cdff619796fd3758576df4c. --- lib/generators/jsonapi/swagger_all/USAGE | 5 - .../swagger_all/swagger_all_generator.rb | 169 ------------------ 2 files changed, 174 deletions(-) delete mode 100644 lib/generators/jsonapi/swagger_all/USAGE delete mode 100644 lib/generators/jsonapi/swagger_all/swagger_all_generator.rb diff --git a/lib/generators/jsonapi/swagger_all/USAGE b/lib/generators/jsonapi/swagger_all/USAGE deleted file mode 100644 index d62252d..0000000 --- a/lib/generators/jsonapi/swagger_all/USAGE +++ /dev/null @@ -1,5 +0,0 @@ -Description: - Create a JSONAPI Swagger for all resources - -Example: - rails generate jsonapi:swagger_all diff --git a/lib/generators/jsonapi/swagger_all/swagger_all_generator.rb b/lib/generators/jsonapi/swagger_all/swagger_all_generator.rb deleted file mode 100644 index f495823..0000000 --- a/lib/generators/jsonapi/swagger_all/swagger_all_generator.rb +++ /dev/null @@ -1,169 +0,0 @@ -module Jsonapi - class SwaggerAllGenerator < Rails::Generators::Base - desc 'Create JSONAPI Swaggers for all Resources.' - source_root File.expand_path('../swagger/templates', __dir__) - - def create_swagger_all_file - ["V0::Admin", "V0::Batch"].each do |resource| - template 'swagger.json.erb', json_file - end - end - - private - - def doc - @doc ||= swagger_json.parse_doc - end - - def json_file - @json_file ||= File.join( - 'swagger', - swagger_file_path - ) - end - - def swagger_version - Jsonapi::Swagger.version - end - - def swagger_info - JSON.pretty_generate(Jsonapi::Swagger.info) - end - - def swagger_host - Jsonapi::Swagger.host - end - - def swagger_base_path - Jsonapi::Swagger.base_path - end - - def swagger_security_definitions - JSON.pretty_generate(Jsonapi::Swagger.security_definitions) - end - - def swagger_file_path - Jsonapi::Swagger.file_path - end - - def swagger_json - @swagger_json ||= Jsonapi::Swagger::Json.new(json_file) - end - - def spec_file_name - "#{file_name.downcase.pluralize}_spec.rb" - end - - def model_name - file_name.downcase.singularize - end - - def resouces_name - model_class_name.pluralize - end - - def route_resouces - resouces_name.tableize - end - - def model_class_name - (class_path + [file_name]).map!(&:camelize).join("::") - end - - def sortable_fields_desc - t(:sortable_fields) + ': (-)' + sortable_fields.join(',') - end - - def ori_sortable_fields_desc - tt(:sortable_fields) + ': (-)' + sortable_fields.join(',') - end - - def model_klass - file_name.camelize.safe_constantize - end - - def resource_klass - @resource_klass ||= Jsonapi::Swagger::Resource.with(model_class_name) - end - - def attributes - resource_klass.attributes.except(:id) - end - - def relationships - resource_klass.relationships - end - - def sortable_fields - resource_klass.sortable_fields - end - - def creatable_fields - resource_klass.creatable_fields - relationships.keys - end - - def updatable_fields - resource_klass.updatable_fields - relationships.keys - end - - def filters - resource_klass.filters - end - - def mutable? - resource_klass.mutable? - end - - def attribute_default - Jsonapi::Swagger.attribute_default - end - - def transform_method - @transform_method ||= resource_klass.transform_method if resource_klass.respond_to?(:transform_method) - end - - def columns_with_comment(need_encoding: true) - @columns_with_comment ||= {}.tap do |clos| - clos.default_proc = proc do |h, k| - h[k] = attribute_default - end - model_klass.columns.each do |col| - col_name = transform_method ? col.name.send(transform_method) : col.name - is_array = col.respond_to?(:array) ? col.array : false - clos[col_name.to_sym] = { type: swagger_type(col), items_type: col.type, is_array: is_array, nullable: col.null, comment: col.comment } - clos[col_name.to_sym][:comment] = safe_encode(col.comment) if need_encoding - end - end - end - - def swagger_type(column) - return 'array' if column.respond_to?(:array) && column.array - - case column.type - when :bigint, :integer then 'integer' - when :boolean then 'boolean' - else 'string' - end - end - - def relation_table_name(relation) - return relation.class_name.tableize if relation.respond_to?(:class_name) - return relation.name if relation.respond_to?(:name) - end - - def t(key, options={}) - content = tt(key, options) - safe_encode(content) - end - - def tt(key, options={}) - options[:scope] = :jsonapi_swagger - options[:default] = key.to_s.humanize - I18n.t(key, options) - end - - def safe_encode(content) - content&.force_encoding('ASCII-8BIT') - end - end -end From 3cf9d62222992b98fa87e679e1cc2c0909eba144 Mon Sep 17 00:00:00 2001 From: Katrina Date: Mon, 19 Dec 2022 09:11:04 -0600 Subject: [PATCH 12/12] modified swagger.json.erb to produce valid swagger.json --- .../jsonapi/swagger/templates/swagger.json.erb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/generators/jsonapi/swagger/templates/swagger.json.erb b/lib/generators/jsonapi/swagger/templates/swagger.json.erb index 9b4890f..5fd0360 100644 --- a/lib/generators/jsonapi/swagger/templates/swagger.json.erb +++ b/lib/generators/jsonapi/swagger/templates/swagger.json.erb @@ -22,6 +22,10 @@ relationships.each_value do |relation| parameters << { name: :"fields[#{relation_table_name(relation)}]", in: :query, type: :string, description: tt(:display_field), required: false } end + duplicate = parameters.detect{ |el| parameters.count(el) > 1 } + if duplicate + parameters.delete_at(parameters.find_index(duplicate)) + end end end @@ -35,6 +39,10 @@ relationships.each_value do |relation| parameters << { name: :"fields[#{relation_table_name(relation)}]", in: :query, type: :string, description: tt(:display_field), required: false } end + duplicate = parameters.detect{ |el| parameters.count(el) > 1 } + if duplicate + parameters.delete_at(parameters.find_index(duplicate)) + end end end @@ -303,6 +311,14 @@ end end end + + if doc['paths']["/#{route_resouces}"] == {} + doc['paths'].delete("/#{route_resouces}") + end + + if doc['paths']["/#{route_resouces}/{id}"] == {} + doc['paths'].delete("/#{route_resouces}/{id}") + end -%> "paths": <%= JSON.pretty_generate(doc['paths'] ) %> } \ No newline at end of file