zero-rails_openapi 1.1.1 → 1.2.0

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
  SHA1:
3
- metadata.gz: 5c0a2065e4a332132fafda9c0b20dc1f10a87ba0
4
- data.tar.gz: 8e232f1841f6489ec5fba6e9c3aaf56e0314e416
3
+ metadata.gz: ade759189024d01051f73655ca7f55d14264598c
4
+ data.tar.gz: f97aa2a93a2b88af05e8326e5d1ef894a205cc47
5
5
  SHA512:
6
- metadata.gz: 24baf84b60c4e2b4a846d5284b34fef596444d1ee90f35fa537d2de87af6b7e35999b44e780db9fbd1a8450675bfe558d9b2d77a51774f120d8133d2fef08f8a
7
- data.tar.gz: c238aa68acdc0be8a9d7c3482828ab7feedc69088161622bace745b801111bc28184a9a0612ccb774b5c6accf630e3258c86c88cf160a0e2ee9534544ddc2655
6
+ metadata.gz: 8b9ba73d3704dff23f9e5fc9d515a87ad2e822b7fd08aa9207e9e47d0e47e5ece4ba66bed8514e3465e87ddf761060ed73c2f6cfb8c79be7438a4f7ebe5452eb
7
+ data.tar.gz: eb6048d787fbc7f3001e2fe7b47b999e404282b801741c07248ee0a6516c64a24b8790f5093383aa5f816a902178752fd8f830977ba4ee55dc4fc36f5b7e4fdc
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zero-rails_openapi (1.1.1)
4
+ zero-rails_openapi (1.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # ZRO: OpenApi 3 DocGenerator for Rails
2
2
 
3
- Provide concise DSL for you to generate the OpenAPI Specification 3 (**OAS3**, formerly Swagger3) JSON file for Rails application,
3
+ [![Gem Version](https://badge.fury.io/rb/zero-rails_openapi.svg)](https://badge.fury.io/rb/zero-rails_openapi)
4
+ [![Build Status](https://travis-ci.org/zhandao/zero-rails_openapi.svg?branch=master)](https://travis-ci.org/zhandao/zero-rails_openapi)
5
+
6
+ Provide concise DSL for generating the OpenAPI Specification 3 (**OAS3**, formerly Swagger3) documentation JSON file for Rails application,
4
7
  then you can use Swagger UI 3.2.0+ to show the documentation.
5
8
 
6
9
  ## Contributing
@@ -22,7 +25,9 @@ but I dont have enough time now = ▽ =
22
25
  - [Generate JSON Documentation File](#generate-json-documentation-file)
23
26
  - [Use Swagger UI(very beautiful web page) to show your Documentation](#use-swagger-uivery-beautiful-web-page-to-show-your-documentation)
24
27
  - [Tricks](#tricks)
25
- - [Write the DSL Somewhere Else](#write-the-dsl-somewhere-else)
28
+ - [Write DSL Somewhere Else](#trick1-write-the-dsl-somewhere-else)
29
+ - [DRYing](#trick2-drying)
30
+ - [Auto Generate Description](#trick3-auto-generate-description)
26
31
  - [Troubleshooting](#troubleshooting)
27
32
 
28
33
  ## About OAS
@@ -65,7 +70,7 @@ OpenApi.configure do |c|
65
70
  # [REQUIRED] The output location where .json doc file will be written to.
66
71
  c.file_output_path = 'public/open_api'
67
72
 
68
- c.register_apis = {
73
+ c.register_docs = {
69
74
  homepage_api: {
70
75
  # [REQUIRED] ZRO will scan all the descendants of root_controller, then generate their docs.
71
76
  root_controller: Api::V1::BaseController,
@@ -89,7 +94,7 @@ end
89
94
  You can also set the *global configuration(/component)* of OAS:
90
95
  Server Object / Security Scheme Object / Security Requirement Object ...
91
96
 
92
- For more detailed configuration: [open_api.rb](https://github.com/zhandao/zero-rails_openapi/blob/masterdocumentation/examples/open_api.rb)
97
+ For more detailed configuration: [open_api.rb](https://github.com/zhandao/zero-rails_openapi/blob/master/documentation/examples/open_api.rb)
93
98
 
94
99
  ## Usage
95
100
 
@@ -108,17 +113,18 @@ class ApplicationController < ActionController::API
108
113
 
109
114
  #### \> [DSL Usage Example](https://github.com/zhandao/zero-rails_openapi/blob/masterdocumentation/examples/examples_controller.rb)
110
115
 
116
+ (TODO: I consider that, here should be put in a the simplest case.)
111
117
  ```ruby
112
118
  class Api::V1::ExamplesController < Api::V1::BaseController
113
119
  apis_set 'ExamplesController\'s APIs' do
114
- schema :Dog => [ { id!: Integer, name: String }, dft: { id: 1, name: 'pet' } ]
120
+ schema :Dog => [ String, must_be: 'doge' ]
115
121
  query! :QueryCompUuid => [ :product_uuid, String, desc: 'product uuid' ]
116
122
  path! :PathCompId => [ :id, Integer, desc: 'user id' ]
117
123
  resp :RespComp => [ 'bad request', :json ]
118
124
  body! :RqBodyComp => [ :form ]
119
125
  end
120
126
 
121
- open_api_set %i[index show], 'common response' do
127
+ api_dry %i[index show], 'common response' do
122
128
  response '567', 'query result export', :pdf, type: File
123
129
  end
124
130
 
@@ -178,17 +184,17 @@ end
178
184
  desc and external_doc_url will be output to the tags[the current tag] (tag defaults to controller_name ), but are optional.
179
185
  the focus is on the block, the DSL methods in the block will generate components.
180
186
 
181
- - `open_api_set` [Optional]
187
+ - `api_dry` [Optional]
182
188
 
183
189
  this method is for DRYing.
184
190
 
185
191
  ```ruby
186
192
  # method signature
187
- open_api_set method = :all, desc = '', &block
193
+ api_dry method = :all, desc = '', &block
188
194
  # usage
189
- open_api_set :all, 'common response' do; end
190
- open_api_set :index do; end
191
- open_api_set [:index, :show] do; end
195
+ api_dry :all, 'common response' do; end
196
+ api_dry :index do; end
197
+ api_dry [:index, :show] do; end
192
198
  ```
193
199
 
194
200
  As you think, the DSL methods in the block will be executed to each API that you set by method.
@@ -205,7 +211,7 @@ end
205
211
  ```
206
212
 
207
213
 
208
- #### \>\> DSL methods inside *open_api* and *open_api_set*'s block ([source code](https://github.com/zhandao/zero-rails_openapi/blob/master/lib/open_api/dsl_inside_block.rb):: ApiInfoObj)
214
+ #### \>\> DSL methods inside *open_api* and *api_dry*'s block ([source code](https://github.com/zhandao/zero-rails_openapi/blob/master/lib/open_api/dsl_inside_block.rb):: ApiInfoObj)
209
215
 
210
216
  These methods in the block describe the specified API(s): description, valid?,
211
217
  parameters, request body, responses, securities, servers.
@@ -237,6 +243,8 @@ parameters, request body, responses, securities, servers.
237
243
 
238
244
  You can of course describe the input in it's DSL method (like `query! :done` [this line](https://github.com/zhandao/zero-rails_openapi#-dsl-usage-example)),
239
245
  but that will make it long and ugly. We recommend that unite descriptions in this place.
246
+
247
+ In addition, when you want to dry the same parameters (each with a different description), it will be of great use.
240
248
 
241
249
  - param family methods (OAS - [Parameter Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#parameterObject))
242
250
  - `param`
@@ -300,7 +308,21 @@ parameters, request body, responses, securities, servers.
300
308
  def form desc = '', schema_hash = { }
301
309
  body :form, desc, schema_hash
302
310
  end
311
+ # usage
312
+ form! 'register', data: {
313
+ name: String,
314
+ password: String,
315
+ password_confirmation: String
316
+ }
317
+ # advance usage
318
+ form 'for creating a user', data: {
319
+ :name! => { type: String, desc: 'user name' },
320
+ :password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
321
+ # optional
322
+ :remarks => { type: String, desc: 'remarks' },
323
+ }
303
324
 
325
+ # method implement
304
326
  def file! media_type, desc = '', schema_hash = { type: File }
305
327
  body! media_type, desc, schema_hash
306
328
  end
@@ -371,9 +393,16 @@ The DSL methods used to generate the components in this block are:
371
393
  schema component_key, type, schema_hash
372
394
  # usage
373
395
  schema :Dog => [ { id!: Integer, name: String }, dft: { id: 1, name: 'pet' } ]
396
+ # advance usage
397
+ schema :Dog => [{
398
+ id!: Integer,
399
+ name: { type: String, must_be: 'zhandao', desc: 'name' }
400
+ }, # this is schema type*
401
+ dft: { id: 1, name: 'pet' }]
374
402
  # or (unrecommended)
375
403
  schema :Dog, { id!: Integer, name: String }, dft: { id: 1, name: 'pet' }
376
404
  ```
405
+ *: see: [Type](https://github.com/zhandao/zero-rails_openapi/blob/master/documentation/parameter.md#type)
377
406
 
378
407
  ### Generate JSON Documentation File
379
408
 
@@ -395,9 +424,9 @@ In order to use it, you may have to enable CORS, [see](https://github.com/swagge
395
424
 
396
425
  ### Tricks
397
426
 
398
- #### Write the DSL Somewhere Else
427
+ #### Trick1 - Write the DSL Somewhere Else
399
428
 
400
- Does your documentation take too mant lines?
429
+ Does your documentation take too many lines?
401
430
  Do you want to separate documentation from business controller to simplify both?
402
431
  Very easy! Just use `ctrl_path`.
403
432
 
@@ -425,6 +454,45 @@ end
425
454
 
426
455
  Notes: convention is the file name ends with `_doc.rb`
427
456
 
457
+ #### Trick2 - DRYing
458
+
459
+ To be written.
460
+
461
+ You can look at this [file](https://github.com/zhandao/zero-rails_openapi/blob/masterdocumentation/examples/auto_gen_dsl.rb) at the moment.
462
+ In general is to use method `api_dry`.
463
+ The implementation of the file is: do `api_dry` when inherits the base controller inside `inherited` method.
464
+
465
+ #### Trick3 - Auto Generate Description
466
+
467
+ ```ruby
468
+ desc 'api desc',
469
+ search_type!: 'search field, allows:<br/>'
470
+ query :search_type, String, enum: %w[name creator category price]
471
+
472
+ # or
473
+
474
+ query :search_type, String, desc!: 'search field, allows:<br/>',
475
+ enum: %w[name creator category price]
476
+ ```
477
+
478
+ Notice `!` use (`search_type!`, `desc!`), it tells ZRO to append
479
+ information that analyzed from definitions (enum, must_be ..) to description automatically.
480
+
481
+ Any one of above will generate:
482
+ `search field, allows:<br/>1/ name<br/>2/ creator,<br/>3/ category<br/>4/ price<br/>`
483
+
484
+ ZRO also allows you use Hash to define `enum`:
485
+ ```ruby
486
+ query :view, String, enum: {
487
+ 'all goods (default)': :all,
488
+ 'only online': :online,
489
+ 'only offline': :offline,
490
+ 'expensive goods': :get,
491
+ 'cheap goods': :borrow,
492
+ }
493
+ ```
494
+ Read this [file](https://github.com/zhandao/zero-rails_openapi/blob/masterdocumentation/examples/auto_gen_desc.rb) to learn more.
495
+
428
496
  ## Troubleshooting
429
497
 
430
498
  - **You wrote document of the current API, but not find in the generated json file?**
@@ -0,0 +1,28 @@
1
+ class V1::GoodsDoc < BaseDoc
2
+
3
+ open_api :index, 'Get list of Goods.' do
4
+ desc 'listing Goods',
5
+ view!: 'search view, allows::<br/>',
6
+ # '1/ all goods (default):all<br/>' \
7
+ # '2/ only online:online<br/>' \
8
+ # '3/ only offline:offline<br/>' \
9
+ # '4/ expensive goods:expensive<br/>' \
10
+ # '5/ cheap goods:cheap<br/>',
11
+ search_type!: 'search field, allows:<br/>'
12
+ # '1/ name<br/>2/ creator,<br/>3/ category<br/>4/ price<br/>'
13
+
14
+ # query :view, String, enum: %w[all online offline get borrow]
15
+ query :view, String, enum: {
16
+ 'all goods (default)': :all,
17
+ 'only online': :online,
18
+ 'only offline': :offline,
19
+ 'expensive goods': :get,
20
+ 'cheap goods': :borrow,
21
+ }
22
+ query :search_type, String, enum: %w[name creator category price]
23
+ # Same as:
24
+ # query :search_type, String, desc!: 'search field, allows:<br/>',
25
+ # enum: %w[name creator category price]
26
+ end
27
+
28
+ end
@@ -0,0 +1,42 @@
1
+ require 'open_api/generator'
2
+
3
+ # Usage: add `include AutoGenDSL` to base controller.
4
+ module AutoGenDSL
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def inherited(subclass)
11
+ super
12
+ subclass.class_eval do
13
+ break unless self.name.match? /sController|sDoc/
14
+ ctrl_path "api/#{self.name.sub('Doc', '').downcase.gsub('::', '/')}" if self.name.match? /sDoc/
15
+ open_api_dry
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def open_api_dry
22
+ ctrl_path = try(:controller_path) || instance_variable_get('@_ctrl_path')
23
+ ::OpenApi::Generator.get_actions_by_ctrl_path(ctrl_path)&.each do |action|
24
+ api_dry action do
25
+ # Token in Header
26
+ if !action_path.match?(/NoVerificationController/) && !%w[create login].include?(action)
27
+ header! 'Token', String, desc: 'user token'
28
+ end
29
+
30
+ # Common :index parameters
31
+ if !action_path.match?(/NotDRYController/) && action == 'index'
32
+ query :page, Integer, desc: 'page'
33
+ query :per_page, Integer, desc: 'per'
34
+ end
35
+
36
+ # OAS require at least one response on each api.
37
+ default_response 'default response', :json
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,13 +1,18 @@
1
1
  class Api::V1::ExamplesController < Api::V1::BaseController
2
2
  apis_set 'ExamplesController\'s APIs' do
3
- schema :Dog => [ { id!: Integer, name: String }, dft: { id: 1, name: 'pet' } ]
3
+ schema :Dog => [{
4
+ id!: Integer,
5
+ name: { type: String, must_be: 'zhandao', desc: 'name' }
6
+ }, # this is schema type, see:
7
+ dft: { id: 1, name: 'pet' }]
8
+ # schema :Dog => [ String, dft: { id: 1, name: 'pet' } ]
4
9
  query! :QueryCompUuid => [ :product_uuid, String, desc: 'product uuid' ]
5
10
  path! :PathCompId => [ :id, Integer, desc: 'user id' ]
6
11
  resp :RespComp => [ 'bad request', :json ]
7
12
  body! :RqBodyComp => [ :form ]
8
13
  end
9
14
 
10
- open_api_set %i[index show], 'common response' do
15
+ api_dry %i[index show], 'common response' do
11
16
  response '567', 'query result export', :pdf, type: File
12
17
  end
13
18
 
@@ -21,7 +26,7 @@ class Api::V1::ExamplesController < Api::V1::BaseController
21
26
  query! :id, Integer, enum: 0..5, length: [1, 2], pattern: /^[0-9]$/, range: {gt:0, le:5}
22
27
  query! :done, Boolean, must_be: false, default: true, desc: 'must be false'
23
28
  query :email_addr, String, lth: :ge_3, default: email # is_a: :email
24
- # form! 'form', type: { id!: Integer, name: String }
29
+
25
30
  file :pdf, 'desc: the media type is application/pdf'
26
31
 
27
32
  response :success, 'success response', :json, type: :Dog
@@ -33,4 +38,13 @@ class Api::V1::ExamplesController < Api::V1::BaseController
33
38
  param_ref :PathCompId, :QueryCompUuid
34
39
  response_ref '123' => :RespComp, '223' => :RespComp
35
40
  end
41
+
42
+ open_api :create do
43
+ form 'for creating a user', data: {
44
+ :name! => { type: String, desc: 'user name' },
45
+ :password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
46
+ # optional
47
+ :remarks => { type: String, desc: 'remarks' },
48
+ }
49
+ end
36
50
  end
@@ -6,7 +6,7 @@ OpenApi.configure do |c|
6
6
 
7
7
  # Everything about OAS3 is on https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md
8
8
  # Getting started: https://swagger.io/docs/specification/basic-structure/
9
- c.register_apis = {
9
+ c.register_docs = {
10
10
  homepage_api: {
11
11
  # [REQUIRED] ZRO will scan all the descendants of the root_controller, then generate their docs.
12
12
  root_controller: Api::V1::BaseController,
@@ -54,11 +54,11 @@ OpenApi.configure do |c|
54
54
  # This URL supports Server Variables and MAY be relative,
55
55
  # to indicate that the host location is relative to the location where
56
56
  # the OpenAPI document is being served.
57
- url: 'http://localhost:2333',
57
+ url: 'http://localhost:3000',
58
58
  # An optional string describing the host designated by the URL.
59
59
  description: 'Optional server description, e.g. Main (production) server'
60
60
  },{
61
- url: 'http://localhost:3332',
61
+ url: 'http://localhost:3001',
62
62
  description: 'Optional server description, e.g. Internal staging server for testing'
63
63
  }
64
64
  ],
@@ -1,12 +1,15 @@
1
1
  ### More Explanation of Param()
2
2
 
3
- - [param_type] OpenAPI 3.0 distinguishes between the following parameter types based on the parameter location:
3
+ #### param_type
4
+ OpenAPI 3.0 distinguishes between the following parameter types based on the parameter location:
4
5
  **header, path, query, cookie**. [more](https://swagger.io/docs/specification/describing-parameters/)
5
6
 
6
- - [name] parameter name. If param_type is :path, it must correspond to the associated path segment form
7
+ #### name
8
+ parameter name. If param_type is :path, it must correspond to the associated path segment form
7
9
  the routing path, for example: the path is `/good/:id`, then you have to declare a path parameter with name `id`.
8
10
 
9
- - [type] parameter (schema) type. Support all [data types](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#dataTypes) defined in OAS.
11
+ #### type
12
+ parameter (schema) type. Support all [data types](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#dataTypes) defined in OAS.
10
13
  In addition, you can use `format` in schema_hash to define in fine detail the data type being used, like:
11
14
  int32, float, date ...
12
15
  All the types you can use are:
@@ -27,22 +30,25 @@ All the types you can use are:
27
30
  You can use `Object.const_set()` to define a constant that does not exist, but note that
28
31
  the value you set could not be a Symbol (it will be explained as a Ref Object), should be a String.
29
32
 
30
- - [required] :opt or :req
33
+ #### required
34
+ :opt or :req
31
35
 
32
- - The [[schema]](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#schemaObject) defining the type used for the parameter.
36
+ #### Schema Hash
37
+
38
+ The [[schema]](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#schemaObject) defining the type used for the parameter.
33
39
  schema_hash(optional) will be used to generate Schema Object inside Parameter Object.
34
40
  [source code](https://github.com/zhandao/zero-rails_openapi/blob/master/lib/oas_objs/schema_obj.rb)
35
41
  You can set the schema by following keys (all are optional), the words in parentheses are available aliases of the keys:
36
- - enum (values, allowable_values)
42
+ - **enum (values, allowable_values)**
37
43
  Must be Array or Range(will be converted to Array)
38
- - value (must_be, allowable_value)
44
+ - **must_be (value, allowable_value)**
39
45
  Single value, could be a String, Array ...
40
- - range (number_range)
46
+ - **range (number_range)**
41
47
  Allow value in this continuous range. Set this field like this: `{ gt: 0, le: 5 }`
42
- - length (lth)
48
+ - **length (lth)**
43
49
  Must be an Integer, Integer Array, Integer Range, or the following format Symbol: `:gt_`, `:ge_`, `:lt_`, `:le_`, examples: :ge_5 means "greater than or equal 5"; :lt_9 means "lower than 9".
44
- - format (fmt)
45
- - is (is_a)
50
+ - **format (fmt)**
51
+ - **is (is_a)**
46
52
  1. It's not in OAS, just an addition field for better express.You can see it as `format`, but in fact they are quite different.
47
53
  2. Look at this example: the `format` is set to "int32", but you also want to express that this
48
54
  schema is an "id" format —— this cannot be expressed in the current OAS version.
@@ -51,5 +57,5 @@ You can set the schema by following keys (all are optional), the words in parent
51
57
  for example the parameter name "user_email" will generate "is: email". Default `is` options are:
52
58
  [email phone password uuid uri url time date], to overwrite it you can set it in initializer `c.is_options = %w[]`.
53
59
  5. If type is Object, for describing each property's schema, the only way is use ref type, like: `{ id: :Id, name: :Name }`
54
- - pattern (regexp, pr, reg)
55
- - default (dft, default_value)
60
+ - **pattern (regexp, pr, reg)**
61
+ - **default (dft, default_value)**
@@ -7,22 +7,22 @@ module OpenApi
7
7
  end
8
8
 
9
9
  def value_present
10
- Proc.new { |_, v| truly_present? v }
10
+ proc { |_, v| truly_present? v }
11
11
  end
12
12
 
13
13
  def assign(value)
14
- @assign = value.is_a?(Symbol)? self.send("_#{value}") : value
14
+ @assign = value.is_a?(Symbol) ? send("_#{value}") : value
15
15
  self
16
16
  end
17
17
 
18
- def all(*values)
18
+ def reduceee(*values)
19
19
  @assign = values.compact.reduce({ }, :merge).keep_if &value_present
20
20
  self
21
21
  end
22
22
 
23
23
  def to_processed(who)
24
24
  if who.is_a?(Symbol)
25
- self.send("#{who}=", @assign)
25
+ send("#{who}=", @assign)
26
26
  else
27
27
  processed[who.to_sym] = @assign
28
28
  end if truly_present?(@assign)
@@ -34,7 +34,7 @@ module OpenApi
34
34
  self[who.to_sym] = @assign if truly_present?(@assign)
35
35
  end
36
36
 
37
- def for_merge # to_processed
37
+ def then_merge! # to_processed
38
38
  processed.tap { |it| it.merge! @assign if truly_present?(@assign) }
39
39
  end
40
40
  end
@@ -7,13 +7,13 @@ module OpenApi
7
7
  attr_accessor :media_type, :schema
8
8
  def initialize(media_type, schema_hash)
9
9
  self.media_type = media_type_mapping media_type
10
- self.schema = SchemaObj.new(schema_hash[:type], schema_hash)
10
+ self.schema = SchemaObj.new(schema_hash[:type] || schema_hash[:data], schema_hash)
11
11
  end
12
12
 
13
13
  def process
14
- schema_processed = self.schema.process
14
+ schema_processed = schema.process
15
15
  schema = schema_processed.values.join.blank? ? { } : { schema: schema_processed }
16
- media_type.nil? ? { } : { media_type => schema }
16
+ media_type.nil? ? { } : { media_type => schema }
17
17
  end
18
18
 
19
19
  # https://swagger.io/docs/specification/media-types/
@@ -23,32 +23,32 @@ module OpenApi
23
23
  def media_type_mapping(media_type)
24
24
  return media_type if media_type.is_a? String
25
25
  case media_type
26
- when :app; 'application/*'
27
- when :json; 'application/json'
28
- when :xml; 'application/xml'
29
- when :xwww; 'application/x-www-form-urlencoded'
30
- when :pdf; 'application/pdf'
31
- when :zip; 'application/zip'
32
- when :gzip; 'application/gzip'
33
- when :doc; 'application/msword'
34
- when :docx; 'application/application/vnd.openxmlformats-officedocument.wordprocessingml.document'
35
- when :xls; 'application/vnd.ms-excel'
36
- when :xlsx; 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
37
- when :ppt; 'application/vnd.ms-powerpoint'
38
- when :pptx; 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
39
- # when :pdf; 'application/pdf'
40
- when :form; 'multipart/form-data'; when :form_data; 'multipart/form-data'
41
- when :text; 'text/*'
42
- when :plain; 'text/plain; charset=utf-8'
43
- when :html; 'text/html'
44
- when :csv; 'text/csv'
45
- when :image; 'image/*'
46
- when :png; 'image/png'
47
- when :jpeg; 'image/jpeg'
48
- when :gif; 'image/gif'
49
- when :audio; 'audio/*'
50
- when :video; 'video/*'
51
- else; nil
26
+ when :app then 'application/*'
27
+ when :json then 'application/json'
28
+ when :xml then 'application/xml'
29
+ when :xwww then 'application/x-www-form-urlencoded'
30
+ when :pdf then 'application/pdf'
31
+ when :zip then 'application/zip'
32
+ when :gzip then 'application/gzip'
33
+ when :doc then 'application/msword'
34
+ when :docx then 'application/application/vnd.openxmlformats-officedocument.wordprocessingml.document'
35
+ when :xls then 'application/vnd.ms-excel'
36
+ when :xlsx then 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
37
+ when :ppt then 'application/vnd.ms-powerpoint'
38
+ when :pptx then 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
39
+ # when :pdf then 'application/pdf'
40
+ when :form then 'multipart/form-data'; when :form_data then 'multipart/form-data'
41
+ when :text then 'text/*'
42
+ when :plain then 'text/plain then charset=utf-8'
43
+ when :html then 'text/html'
44
+ when :csv then 'text/csv'
45
+ when :image then 'image/*'
46
+ when :png then 'image/png'
47
+ when :jpeg then 'image/jpeg'
48
+ when :gif then 'image/gif'
49
+ when :audio then 'audio/*'
50
+ when :video then 'video/*'
51
+ else nil
52
52
  end
53
53
  end
54
54
  end
@@ -11,15 +11,23 @@ module OpenApi
11
11
  self.processed = {
12
12
  name: name,
13
13
  in: param_type,
14
- required: "#{required}".match?(/req/),
14
+ required: required.to_s.match?(/req/),
15
15
  }
16
16
  self.schema = SchemaObj.new(type, schema_hash)
17
- self.merge! schema_hash
17
+ merge! schema_hash
18
18
  end
19
19
 
20
20
  def process
21
- assign(_desc).to_processed 'description'
22
- processed.tap { |it| it[:schema] = schema.process_for self[:name] }
21
+ assign(desc).to_processed 'description'
22
+ processed.tap { |it| it[:schema] = schema.process_for self.processed[:name] }
23
+ end
24
+
25
+ def desc
26
+ if __desc.present?
27
+ schema.preprocess_with_desc __desc, self[:name]
28
+ else
29
+ _desc
30
+ end
23
31
  end
24
32
 
25
33
 
@@ -27,9 +35,10 @@ module OpenApi
27
35
  # This mapping allows user to select the aliases in DSL writing,
28
36
  # without increasing the complexity of the implementation.
29
37
  { # SELF_MAPPING
30
- _range: %i[range number_range],
31
- _length: %i[length lth ],
32
- _desc: %i[desc description ],
38
+ _range: %i[ range number_range ],
39
+ _length: %i[ length lth ],
40
+ _desc: %i[ desc description ],
41
+ __desc: %i[ desc! description! ],
33
42
  }.each do |key, aliases|
34
43
  define_method key do
35
44
  aliases.each { |alias_name| self[key] ||= self[alias_name] } if self[key].nil?
@@ -10,7 +10,7 @@ module OpenApi
10
10
  attr_accessor :processed
11
11
  def initialize(ref_to, component_key)
12
12
  self.processed = {
13
- '$ref': "#components/#{ref_to}s/#{component_key}"
13
+ '$ref': "#components/#{ref_to.to_s.pluralize}/#{component_key}"
14
14
  }
15
15
  end
16
16
 
@@ -11,7 +11,7 @@ module OpenApi
11
11
  attr_accessor :processed, :media_type
12
12
  def initialize(required, media_type, desc, schema_hash)
13
13
  self.media_type = MediaTypeObj.new(media_type, schema_hash)
14
- self.processed = { required: "#{required}".match?(/req/), description: desc }
14
+ self.processed = { required: required.to_s.match?(/req/), description: desc }
15
15
  end
16
16
 
17
17
  def process
@@ -31,7 +31,7 @@ A request body with a referenced model definition.
31
31
  {
32
32
  "description": "user to add to the system",
33
33
  "content": {
34
- "application/json": {
34
+ "multipart/form-data": {
35
35
  "schema": {
36
36
  "$ref": "#/components/schemas/User"
37
37
  },
@@ -9,7 +9,7 @@ module OpenApi
9
9
 
10
10
  attr_accessor :processed, :code, :media_type
11
11
  def initialize(code, desc, media_type, schema_hash)
12
- self.code = "#{code}"
12
+ self.code = code.to_s
13
13
  self.media_type = MediaTypeObj.new(media_type, schema_hash)
14
14
  self.processed = { description: desc }
15
15
  end
@@ -18,25 +18,66 @@ module OpenApi
18
18
  # However, user can decide how to write --
19
19
  # `type: number, format: double`, or `type: double`
20
20
  self.type = type
21
- self.merge! schema_hash
21
+ merge! schema_hash
22
22
  end
23
23
 
24
24
 
25
- def process_for(param_name = nil)
25
+ def process_for(param_name = nil, options = { desc_inside: false })
26
+ return processed if @preprocessed
27
+
26
28
  processed.merge! processed_type
27
- all(processed_enum_and_length,
28
- processed_range,
29
- processed_is_and_format(param_name),
30
- { pattern: _pattern&.inspect&.delete('/'),
31
- default: _default }
32
- ).for_merge
29
+ reduceee processed_enum_and_length,
30
+ processed_range,
31
+ processed_is_and_format(param_name),
32
+ {
33
+ pattern: _pattern&.inspect&.delete('/'),
34
+ default: _default,
35
+ }
36
+ then_merge!
37
+
38
+ assign(processed_desc options).then_merge!
33
39
  end
34
40
  alias_method :process, :process_for
35
41
 
42
+ def preprocess_with_desc desc, param_name = nil
43
+ self.__desc = desc
44
+ process_for param_name
45
+ @preprocessed = true
46
+ __desc
47
+ end
48
+
49
+ def processed_desc(options)
50
+ result = __desc ? self.__desc = process_desc : _desc
51
+ options[:desc_inside] ? { description: result } : nil
52
+ end
53
+
54
+ def process_desc
55
+ if processed[:enum].present?
56
+ if @enum_info.present?
57
+ @enum_info.each_with_index do |(info, value), index|
58
+ __desc.concat "#{index + 1}/ #{info}: #{value}<br/>"
59
+ end
60
+ else
61
+ processed[:enum].each_with_index do |value, index|
62
+ __desc.concat "#{index + 1}/ #{value}<br/>"
63
+ end
64
+ end
65
+ end
66
+ __desc
67
+ end
68
+
36
69
  def processed_type(type = self.type)
37
70
  t = type.class.in?([Hash, Array, Symbol]) ? type : "#{type}".downcase
38
71
  if t.is_a? Hash
39
- recursive_obj_type t
72
+ # For support writing:
73
+ # form 'desc', data: {
74
+ # id!: { type: Integer, enum: 0..5, desc: 'user id' }
75
+ # }
76
+ if t.key? :type
77
+ SchemaObj.new(t[:type], t).process_for @prop_name, desc_inside: true
78
+ else
79
+ recursive_obj_type t
80
+ end
40
81
  elsif t.is_a? Array
41
82
  recursive_array_type t
42
83
  elsif t.is_a? Symbol
@@ -47,12 +88,14 @@ module OpenApi
47
88
  { type: 'string', format: t}
48
89
  elsif t.eql? 'file'
49
90
  { type: 'string', format: OpenApi.config.dft_file_format }
91
+ elsif t.eql? 'datetime'
92
+ { type: 'string', format: 'date-time' }
50
93
  else # other string
51
94
  { type: t }
52
95
  end
53
96
  end
54
97
  def recursive_obj_type(t) # DSL use { prop_name: prop_type } to represent object structure
55
- return processed_type(t) unless t.is_a? Hash
98
+ return processed_type(t) if !t.is_a?(Hash) || t.key?(:type)
56
99
 
57
100
  _schema = {
58
101
  type: 'object',
@@ -60,6 +103,7 @@ module OpenApi
60
103
  required: [ ]
61
104
  }
62
105
  t.each do |prop_name, prop_type|
106
+ @prop_name = prop_name
63
107
  _schema[:required] << "#{prop_name}".delete('!') if "#{prop_name}".match? '!'
64
108
  _schema[:properties]["#{prop_name}".delete('!').to_sym] = recursive_obj_type prop_type
65
109
  end
@@ -78,6 +122,16 @@ module OpenApi
78
122
  end
79
123
 
80
124
  def processed_enum_and_length
125
+ # Support this writing for auto generating desc from enum.
126
+ # enum: {
127
+ # 'all_data': :all,
128
+ # 'one_page': :one
129
+ # }
130
+ if _enum.is_a? Hash
131
+ @enum_info = _enum
132
+ self._enum = _enum.values
133
+ end
134
+
81
135
  %i[_enum _length].each do |key|
82
136
  value = self.send(key)
83
137
  self[key] = value.to_a if value.present? && value.is_a?(Range)
@@ -85,7 +139,7 @@ module OpenApi
85
139
 
86
140
  # generate_enums_by_enum_array
87
141
  values = _enum || _value
88
- self._enum = (values.is_a?(Array) ? values : [values]) if truly_present?(values)
142
+ self._enum = Array(values) if truly_present?(values)
89
143
 
90
144
  # generate length range fields by _lth array
91
145
  lth = _length || [ ]
@@ -124,21 +178,23 @@ module OpenApi
124
178
  def recognize_is_options_in(name)
125
179
  # identify whether `is` patterns matched the name, if so, generate `is`.
126
180
  OpenApi.config.is_options.each do |pattern|
127
- self._is = pattern or break if "#{name}".match? /#{pattern}/
181
+ self._is = pattern or break if name.match? /#{pattern}/
128
182
  end if _is.nil?
129
183
  self.delete :_is if _is.in?([:x, :we])
130
184
  end
131
185
 
132
186
 
133
187
  { # SELF_MAPPING
134
- _enum: %i[enum values allowable_values],
135
- _value: %i[must_be value allowable_value ],
136
- _range: %i[range number_range ],
137
- _length: %i[length lth ],
138
- _is: %i[is_a is ], # NOT OAS Spec, just an addition
139
- _format: %i[format fmt ],
140
- _pattern: %i[pattern regexp pr reg ],
141
- _default: %i[default dft default_value ],
188
+ _enum: %i[ enum values allowable_values ],
189
+ _value: %i[ must_be value allowable_value ],
190
+ _range: %i[ range number_range ],
191
+ _length: %i[ length lth ],
192
+ _is: %i[ is_a is ], # NOT OAS Spec, just an addition
193
+ _format: %i[ format fmt ],
194
+ _pattern: %i[ pattern regexp pr reg ],
195
+ _default: %i[ default dft default_value ],
196
+ _desc: %i[ desc description ],
197
+ __desc: %i[ desc! description! ],
142
198
  }.each do |key, aliases|
143
199
  define_method key do
144
200
  aliases.each do |alias_name|
@@ -7,7 +7,7 @@ module OpenApi
7
7
  DEFAULT_CONFIG = {
8
8
  is_options: %w[email phone password uuid uri url time date],
9
9
  dft_file_format: 'binary'
10
- }
10
+ }.freeze
11
11
 
12
12
  module ClassMethods
13
13
  def config
@@ -19,15 +19,15 @@ module OpenApi
19
19
  end
20
20
 
21
21
  ### config options
22
- # register_apis = {
23
- # version: {
22
+ # register_docs = {
23
+ # doc_name: {
24
24
  # :file_output_path, :root_controller
25
25
  # info: {}
26
26
  # }}
27
27
  # is_options = %w[]
28
28
 
29
29
  def apis
30
- @apis ||= @config.register_apis
30
+ @apis ||= @config.register_docs
31
31
  end
32
32
  end
33
33
  end
data/lib/open_api/dsl.rb CHANGED
@@ -29,24 +29,29 @@ module OpenApi
29
29
 
30
30
  # select the routing info (corresponding to the current method) from the routing list.
31
31
  action_path = "#{@_ctrl_path ||= controller_path}##{method}"
32
- routes_info = ctrl_routes_list.select { |api| api[:action_path].match? /^#{action_path}$/ }.first
32
+ routes_info = ctrl_routes_list&.select { |api| api[:action_path].match? /^#{action_path}$/ }&.first
33
33
  puts "[zero-rails_openapi] Routing mapping failed: #{@_ctrl_path}##{method}" or return if routes_info.nil?
34
34
 
35
35
  # structural { path: { http_method:{ } } }, for Paths Object.
36
36
  path = (@_api_infos ||= { })[routes_info[:path]] ||= { }
37
37
  current_api = path[routes_info[:http_verb]] =
38
- ApiInfoObj.new(action_path).merge! summary: summary, operationId: method, tags: [@_apis_tag]
38
+ ApiInfoObj.new(action_path)
39
+ .merge! description: '', summary: summary, operationId: method, tags: [@_apis_tag],
40
+ parameters: [ ], requestBody: '', responses: { },
41
+ security: [ ], servers: [ ]
39
42
 
40
43
  current_api.tap do |it|
41
- it.instance_eval &block if block_given?
42
44
  [method, :all].each do |key| # blocks_store_key
43
45
  @_apis_blocks&.[](key)&.each { |blk| it.instance_eval &blk }
44
46
  end
47
+ it.instance_eval &block if block_given?
48
+ it.instance_eval { process_params }
49
+ it.delete_if { |_, v| v.blank? }
45
50
  end
46
51
  end
47
52
 
48
53
  # For DRY; method could be symbol array
49
- def open_api_set method = :all, desc = '', &block
54
+ def api_dry method = :all, desc = '', &block
50
55
  @_apis_blocks ||= { }
51
56
  if method.is_a? Array
52
57
  method.each { |m| (@_apis_blocks[m.to_sym] ||= [ ]) << block }
@@ -8,7 +8,7 @@ module OpenApi
8
8
  module DSL
9
9
  module CommonDSL
10
10
  def arrow_writing_support
11
- Proc.new do |args, executor|
11
+ proc do |args, executor|
12
12
  if args.count == 1 && args.first.is_a?(Hash)
13
13
  send(executor, args[0].keys.first, *args[0].values.first)
14
14
  else
@@ -45,9 +45,9 @@ module OpenApi
45
45
  end
46
46
 
47
47
  { # alias_methods mapping
48
- response: %i[error_response resp ],
49
- default_response: %i[dft_resp dft_response ],
50
- error_response: %i[other_response oth_resp error err_resp],
48
+ response: %i[ error_response resp ],
49
+ default_response: %i[ dft_resp dft_response ],
50
+ error_response: %i[ other_response oth_resp error err_resp ],
51
51
  }.each do |original_name, aliases|
52
52
  aliases.each do |alias_name|
53
53
  alias_method alias_name, original_name
@@ -61,7 +61,7 @@ module OpenApi
61
61
  class CtrlInfoObj < Hash
62
62
  include DSL::CommonDSL
63
63
 
64
- def _schema component_key, type, schema_hash
64
+ def _schema component_key, type, schema_hash = { }
65
65
  (self[:schemas] ||= { }).merge! component_key => SchemaObj.new(type, schema_hash).process
66
66
  end
67
67
  def schema *args
@@ -115,12 +115,42 @@ module OpenApi
115
115
 
116
116
  def desc desc, inputs_descs = { }
117
117
  @inputs_descs = inputs_descs
118
+ merge_desc_for_dryed_param
118
119
  self[:description] = desc
119
120
  end
120
121
 
122
+ # TODO: HACK
123
+ def merge_desc_for_dryed_param
124
+ @inputs_descs.each do |param_name, desc|
125
+ self[:parameters].each do |param|
126
+ if param_name.match?(?!) && param.processed[:name].to_s == param_name.to_s.delete(?!)
127
+ param.merge!(desc!: desc).process
128
+ end
129
+ end
130
+ end
131
+ end
132
+
121
133
  def param param_type, name, type, required, schema_hash = { }
122
- schema_hash[:desc] = @inputs_descs[name] if @inputs_descs&.[](name).present?
123
- (self[:parameters] ||= [ ]) << ParamObj.new(name, param_type, type, required, schema_hash).process
134
+ if @inputs_descs&.[](name).present?
135
+ schema_hash[:desc] = @inputs_descs[name]
136
+ elsif @inputs_descs&.[]("#{name}!".to_sym).present?
137
+ schema_hash[:desc!] = @inputs_descs["#{name}!".to_sym]
138
+ end
139
+
140
+ param_obj = ParamObj.new(name, param_type, type, required, schema_hash)
141
+ # The definition of the same name parameter will be overwritten
142
+ index = self[:parameters].map { |p_obj| p_obj.processed[:name] }.index name
143
+ if index.present?
144
+ self[:parameters][index] = param_obj
145
+ else
146
+ self[:parameters] << param_obj
147
+ end
148
+ end
149
+
150
+ def process_params
151
+ self[:parameters].each_with_index do |param_obj, index|
152
+ self[:parameters][index] = param_obj.process
153
+ end
124
154
  end
125
155
 
126
156
  def _param_agent name, type, schema_hash = { }
@@ -128,7 +158,7 @@ module OpenApi
128
158
  end
129
159
 
130
160
  def param_ref component_key, *keys
131
- (self[:parameters] ||= [ ]).concat [component_key].concat(keys).map { |key| RefObj.new(:parameter, key).process }
161
+ self[:parameters].concat [component_key].concat(keys).map { |key| RefObj.new(:parameter, key).process }
132
162
  end
133
163
 
134
164
  def request_body required, media_type, desc = '', schema_hash = { }
@@ -140,16 +170,16 @@ module OpenApi
140
170
  end
141
171
 
142
172
  def body_ref component_key
143
- self[:requestBody] = RefObj.new(:parameter, component_key).process
173
+ self[:requestBody] = RefObj.new(:requestBody, component_key).process
144
174
  end
145
175
 
146
176
  def response_ref code_compkey_hash
147
177
  code_compkey_hash.each do |code, component_key|
148
- (self[:responses] ||= { }).merge! code => RefObj.new(:response, component_key).process
178
+ self[:responses].merge! code => RefObj.new(:response, component_key).process
149
179
  end
150
180
  end
151
181
 
152
- # 注意同时只能写一句 request body,包括 form 和 file
182
+ # TODO: 目前只能写一句 request body,包括 form 和 file, 需要同时支持一下扁平化
153
183
  def form desc = '', schema_hash = { }
154
184
  body :form, desc, schema_hash
155
185
  end
@@ -164,11 +194,11 @@ module OpenApi
164
194
  end
165
195
 
166
196
  def security scheme_name, requirements = [ ]
167
- (self[:security] ||= [ ]) << { scheme_name => requirements }
197
+ self[:security] << { scheme_name => requirements }
168
198
  end
169
199
 
170
200
  def server url, desc
171
- (self[:servers] ||= [ ]) << { url: url, description: desc }
201
+ self[:servers] << { url: url, description: desc }
172
202
  end
173
203
  end # ----------------------------------------- end of ApiInfoObj
174
204
  end
@@ -1,5 +1,3 @@
1
- require 'active_support/hash_with_indifferent_access'
2
-
3
1
  module OpenApi
4
2
  module Generator
5
3
  def self.included(base)
@@ -9,33 +7,35 @@ module OpenApi
9
7
  module ClassMethods
10
8
  def generate_docs(api_name = nil)
11
9
  Dir['./app/controllers/**/*.rb'].each { |file| require file }
10
+ # TODO: _doc should be configured
12
11
  Dir['./app/**/*_doc.rb'].each { |file| require file }
13
12
  if api_name.present?
14
13
  [{ api_name => generate_doc(api_name) }]
15
14
  else
16
- OpenApi.apis.keys.map { |api_key| { api_key => generate_doc(api_key)} }.reduce({ }, :merge)
15
+ OpenApi.apis.keys.map { |api_key| { api_key => generate_doc(api_key) } }.reduce({ }, :merge)
17
16
  end
18
17
  end
19
18
 
20
19
  def generate_doc(api_name)
21
20
  settings = OpenApi.apis[api_name]
22
- doc = { openapi: '3.0.0' }.merge(settings.slice :info, :servers).merge({
21
+ doc = { openapi: '3.0.0' }.merge(settings.slice :info, :servers).merge(
23
22
  security: settings[:global_security], tags: [ ], paths: { },
24
23
  components: {
25
24
  securitySchemes: settings[:global_security_schemes],
26
25
  schemas: { }
27
26
  }
28
- })
27
+ )
29
28
 
30
29
  settings[:root_controller].descendants.each do |ctrl|
31
30
  ctrl_infos = ctrl.instance_variable_get('@_ctrl_infos')
32
31
  next if ctrl_infos.nil?
33
- doc[:paths].merge! ctrl.instance_variable_get('@_api_infos')
32
+ doc[:paths].merge! ctrl.instance_variable_get('@_api_infos') || { }
34
33
  doc[:tags] << ctrl_infos[:tag]
35
- doc[:components].merge! ctrl_infos[:components]
34
+ doc[:components].merge! ctrl_infos[:components] || { }
36
35
  end
37
- doc[:components].delete_if { |_,v| v.blank? }
38
- ($open_apis ||= { })[api_name] ||= HashWithIndifferentAccess.new(doc.delete_if { |_,v| v.blank? })
36
+ doc[:components].delete_if { |_, v| v.blank? }
37
+ ($open_apis ||= { })[api_name] ||=
38
+ ActiveSupport::HashWithIndifferentAccess.new(doc.delete_if { |_, v| v.blank? })
39
39
  end
40
40
 
41
41
  def write_docs
@@ -64,13 +64,13 @@ module OpenApi
64
64
  item.match?(/:/) ? "{#{item[1..-1]}}" : item
65
65
  end.join('/'), # => "/api/v1/examples/{id}"
66
66
  action_path: infos[2] # => "api/v1/examples#index"
67
- }
68
- end.group_by {|api| api[:action_path].split('#').first } # => { "api/v1/examples" => [..] }, group by paths
67
+ } rescue next
68
+ end.compact.group_by {|api| api[:action_path].split('#').first } # => { "api/v1/examples" => [..] }, group by paths
69
69
  end
70
70
 
71
71
  def self.get_actions_by_ctrl_path(path)
72
72
  @routes_list ||= generate_routes_list
73
- @routes_list[path].map do |action_info|
73
+ @routes_list[path]&.map do |action_info|
74
74
  action_info[:action_path].split('#').last
75
75
  end
76
76
  end
@@ -1,3 +1,3 @@
1
1
  module OpenApi
2
- VERSION = '1.1.1'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -9,9 +9,10 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["zhandao"]
10
10
  spec.email = ["x@skippingcat.com"]
11
11
 
12
- spec.summary = %q{Generate the OpenAPI Specification JSON file for Rails application.}
13
- spec.description = %q{Provide concise DSL for you to generate the OpenAPI Specification 3 (Swagger 3)
14
- JSON file for Rails application, then you can use Swagger-UI 3.2.0+ to show the documentation.}
12
+ spec.summary = %q{Generate the OpenAPI Specification 3 documentation for Rails application.}
13
+ spec.description = %q{Provide concise DSL for generating the OpenAPI Specification 3 (OAS3)
14
+ documentation JSON file for Rails application,
15
+ then you can use Swagger-UI 3.2.0+ to show the documentation.}
15
16
  spec.homepage = "https://github.com/zhandao/zero-rails_openapi"
16
17
  spec.license = "MIT"
17
18
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zero-rails_openapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zhandao
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-30 00:00:00.000000000 Z
11
+ date: 2017-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,8 +53,9 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
55
  description: |-
56
- Provide concise DSL for you to generate the OpenAPI Specification 3 (Swagger 3)
57
- JSON file for Rails application, then you can use Swagger-UI 3.2.0+ to show the documentation.
56
+ Provide concise DSL for generating the OpenAPI Specification 3 (OAS3)
57
+ documentation JSON file for Rails application,
58
+ then you can use Swagger-UI 3.2.0+ to show the documentation.
58
59
  email:
59
60
  - x@skippingcat.com
60
61
  executables: []
@@ -73,6 +74,8 @@ files:
73
74
  - Rakefile
74
75
  - bin/console
75
76
  - bin/setup
77
+ - documentation/examples/auto_gen_desc.rb
78
+ - documentation/examples/auto_gen_dsl.rb
76
79
  - documentation/examples/examples_controller.rb
77
80
  - documentation/examples/open_api.rb
78
81
  - documentation/parameter.md
@@ -89,7 +92,6 @@ files:
89
92
  - lib/open_api/dsl_inside_block.rb
90
93
  - lib/open_api/generator.rb
91
94
  - lib/open_api/version.rb
92
- - lib/takes/open_api.rake
93
95
  - zero-rails_openapi.gemspec
94
96
  homepage: https://github.com/zhandao/zero-rails_openapi
95
97
  licenses:
@@ -111,8 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
113
  version: '0'
112
114
  requirements: []
113
115
  rubyforge_project:
114
- rubygems_version: 2.6.12
116
+ rubygems_version: 2.6.13
115
117
  signing_key:
116
118
  specification_version: 4
117
- summary: Generate the OpenAPI Specification JSON file for Rails application.
119
+ summary: Generate the OpenAPI Specification 3 documentation for Rails application.
118
120
  test_files: []
@@ -1,6 +0,0 @@
1
- namespace :openapi do
2
- desc 'Generate OpenApi documentation files'
3
- task :api => [:environment] do |t, args|
4
- OpenApi.write_docs
5
- end
6
- end