zero-rails_openapi 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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