jdoc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d6199475826180211b7537e2b602a2fc83defb0e
4
+ data.tar.gz: 60b7fb0b6bd29b358c7d8962156cabb0bd528cd3
5
+ SHA512:
6
+ metadata.gz: 4d3fbe63ce3402525682b739a24bab0ff0b35fbfd8ae8339502a23a22311ca9d15d819da570d5813e1bb237923060d5f73b231529e28fc46b2048f2397e19c85
7
+ data.tar.gz: 89abc59441bdc661a499a3e87f4484b50e6268db4162fcbe86898d4d6bba0b34b3935932f937ca3ea3475114f23e85f84c4ab9712a6d064b9101607b1a013a85
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jdoc.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ryo Nakamura
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # Jdoc
2
+ Generate API documentation from JSON Schema.
3
+
4
+ ## Usage
5
+ See [example-api-documentation.md](example-api-documentation.md) generated by the following command.
6
+
7
+ ```sh
8
+ $ jdoc spec/fixtures/schema.json > example-api-documentation.md
9
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/jdoc ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
+ require "jdoc"
4
+ require "yaml"
5
+
6
+ unless path = ARGV[0]
7
+ puts "usage: #{$0} <schema.json or schema.yml>"
8
+ exit
9
+ end
10
+
11
+ case File.extname(path)
12
+ when ".yml", ".yaml"
13
+ schema = YAML.load_file(path)
14
+ else
15
+ str = File.read(path)
16
+ schema = MultiJson.decode(str)
17
+ end
18
+
19
+ puts Jdoc::Generator.call(schema)
@@ -0,0 +1,125 @@
1
+ # Example API
2
+ * [App](#app)
3
+ * [GET /apps](#get-apps)
4
+ * [POST /apps](#post-apps)
5
+ * [GET /apps/:id](#get-appsid)
6
+ * [PATCH /apps/:id](#patch-appsid)
7
+ * [DELETE /apps/:id](#delete-appsid)
8
+
9
+ ## App
10
+ An app is a program to be deployed.
11
+
12
+ ### Properties
13
+ * id - unique identifier of app
14
+ * Example: `01234567-89ab-cdef-0123-456789abcdef`
15
+ * Type: string
16
+ * Format: uuid
17
+ * ReadOnly: true
18
+ * name - unique name of app
19
+ * Example: `example`
20
+ * Type: string
21
+ * Patern: `(?-mix:^[a-z][a-z0-9-]{3,50}$)`
22
+
23
+ ### GET /apps
24
+ List existing apps.
25
+
26
+ ```
27
+ GET /apps HTTP/1.1
28
+ Content-Type: application/json
29
+ Host: api.example.com
30
+ ```
31
+
32
+ ```
33
+ HTTP/1.1 200
34
+ Content-Type: application/json
35
+
36
+ {
37
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
38
+ "name": "example"
39
+ }
40
+ ```
41
+
42
+ ### POST /apps
43
+ Create a new app.
44
+
45
+ ```
46
+ POST /apps HTTP/1.1
47
+ Content-Type: application/json
48
+ Host: api.example.com
49
+
50
+ {
51
+ "name": "example"
52
+ }
53
+ ```
54
+
55
+ ```
56
+ HTTP/1.1 201
57
+ Content-Type: application/json
58
+
59
+ {
60
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
61
+ "name": "example"
62
+ }
63
+ ```
64
+
65
+ ### GET /apps/:id
66
+ Info for existing app.
67
+
68
+ ```
69
+ GET /apps/:id HTTP/1.1
70
+ Content-Type: application/json
71
+ Host: api.example.com
72
+ ```
73
+
74
+ ```
75
+ HTTP/1.1 200
76
+ Content-Type: application/json
77
+
78
+ {
79
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
80
+ "name": "example"
81
+ }
82
+ ```
83
+
84
+ ### PATCH /apps/:id
85
+ Update an existing app.
86
+
87
+ ```
88
+ PATCH /apps/:id HTTP/1.1
89
+ Content-Type: application/json
90
+ Host: api.example.com
91
+
92
+ {
93
+ "name": "example"
94
+ }
95
+ ```
96
+
97
+ ```
98
+ HTTP/1.1 200
99
+ Content-Type: application/json
100
+
101
+ {
102
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
103
+ "name": "example"
104
+ }
105
+ ```
106
+
107
+ ### DELETE /apps/:id
108
+ Delete an existing app.
109
+
110
+ ```
111
+ DELETE /apps/:id HTTP/1.1
112
+ Content-Type: application/json
113
+ Host: api.example.com
114
+ ```
115
+
116
+ ```
117
+ HTTP/1.1 200
118
+ Content-Type: application/json
119
+
120
+ {
121
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
122
+ "name": "example"
123
+ }
124
+ ```
125
+
data/jdoc.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "jdoc/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "jdoc"
7
+ spec.version = Jdoc::VERSION
8
+ spec.authors = ["Ryo Nakamura"]
9
+ spec.email = ["r7kamura@gmail.com"]
10
+ spec.summary = "Generate API documentation from JSON Schema."
11
+ spec.homepage = "https://github.com/r7kamura/jdoc"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_dependency "multi_json"
20
+ spec.add_dependency "rack-spec", ">= 0.1.7"
21
+ spec.add_development_dependency "activesupport"
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "erubis"
24
+ spec.add_development_dependency "json_schema"
25
+ spec.add_development_dependency "pry"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec", "2.14.1"
28
+ end
data/lib/jdoc.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "cgi"
2
+ require "erubis"
3
+ require "json_schema"
4
+ require "multi_json"
5
+ require "rack/spec"
6
+
7
+ require "jdoc/generator"
8
+ require "jdoc/link"
9
+ require "jdoc/property"
10
+ require "jdoc/resource"
11
+ require "jdoc/schema"
12
+ require "jdoc/version"
@@ -0,0 +1,45 @@
1
+ module Jdoc
2
+ class Generator
3
+ TEMPLATE_PATH = File.expand_path("../../../template.md.erb", __FILE__)
4
+
5
+ # Utility wrapper for Jdoc::Generator#call
6
+ # @return [String]
7
+ def self.call(*args)
8
+ new(*args).call
9
+ end
10
+
11
+ # @param schema [Hash] JSON Schema represented as a Hash
12
+ def initialize(schema)
13
+ @raw_schema = schema
14
+ end
15
+
16
+ # Generates documentation in Markdown format from JSON schema
17
+ # @return [String] Text of generated markdown document
18
+ def call
19
+ eruby.result(context)
20
+ end
21
+
22
+ private
23
+
24
+ # @return [Hash] Context object used as a set of local variables for rendering template
25
+ def context
26
+ { schema: schema }
27
+ end
28
+
29
+ # @return [Jdoc::Schema]
30
+ # @raise [JsonSchema::SchemaError] Raises if given invalid JSON Schema
31
+ def schema
32
+ @schema ||= Jdoc::Schema.new(@raw_schema)
33
+ end
34
+
35
+ # @return [Erubis::Eruby]
36
+ def eruby
37
+ Erubis::Eruby.new(template)
38
+ end
39
+
40
+ # @return [String] ERB template
41
+ def template
42
+ File.read(TEMPLATE_PATH)
43
+ end
44
+ end
45
+ end
data/lib/jdoc/link.rb ADDED
@@ -0,0 +1,150 @@
1
+ module Jdoc
2
+ class Link
3
+ # @param link [JsonSchema::Schema::Link]
4
+ def initialize(link: nil)
5
+ @raw_link = link
6
+ end
7
+
8
+ # @return [String] method + path
9
+ # @example
10
+ # link.endpoint #=> "GET /apps"
11
+ def endpoint
12
+ "#{method} #{path}"
13
+ end
14
+
15
+ # Responds to .sort method
16
+ # @return [Fixnum]
17
+ def <=>(schema)
18
+ sort_key <=> schema.sort_key
19
+ end
20
+
21
+ # For #<=> method
22
+ # @return [String]
23
+ def sort_key
24
+ "#{path} #{method_order_score}"
25
+ end
26
+
27
+ # @return [String] Description for this endpoint, defined in description property
28
+ # @example
29
+ # link.description #=> "List existing apps."
30
+ def description
31
+ @raw_link.description
32
+ end
33
+
34
+ # @return [String] Href anchor for putting link in ToC
35
+ # @example
36
+ # link.anchor #=> "#get-apps"
37
+ def anchor
38
+ "#" + endpoint.gsub(" ", "-").gsub(/[:\/]/, "").downcase
39
+ end
40
+
41
+ # @return [String] Markdown styled link text for endpoint
42
+ # @example
43
+ # link.hyperlink #=> "[GET /apps](#get-apps)"
44
+ def hyperlink
45
+ "[#{endpoint}](#{anchor})"
46
+ end
47
+
48
+ # @return [String] Upper cased HTTP request method name
49
+ # @example
50
+ # link.method #=> "GET"
51
+ def method
52
+ @method ||= @raw_link.method.to_s.upcase
53
+ end
54
+
55
+ # @return [String] Request path name, defined at href property
56
+ # @note URI Template is replaced with placeholder
57
+ # @example
58
+ # link.path #=> "GET /apps/:id"
59
+ def path
60
+ @path ||= @raw_link.href.gsub(/{(.+)}/) do |matched|
61
+ ":" + CGI.unescape($1).gsub(/[()]/, "").split("/").last
62
+ end
63
+ end
64
+
65
+ # @return [String, nil] Example request body in JSON format
66
+ def request_body
67
+ MultiJson.encode(RequestBodyGenerator.call(schema), pretty: true) + "\n"
68
+ end
69
+
70
+ # @return [true, false] True if this endpoint must have request body
71
+ def has_request_body?
72
+ ["PATCH", "POST", "PUT"].include?(method)
73
+ end
74
+
75
+ # @return [String] JSON response body generated from example properties
76
+ def response_body
77
+ MultiJson.encode(response_hash, pretty: true)
78
+ end
79
+
80
+ # @return [Fixnum] Preferred respone status code for this endpoint
81
+ def response_status
82
+ method == "POST" ? 201 : 200
83
+ end
84
+
85
+ # @return [JsonSchema::Schema] Schema for this link, specified by targetSchema or parent schema
86
+ def schema
87
+ @raw_link.target_schema || @raw_link.parent
88
+ end
89
+
90
+ # @return [Json::Link::Resource]
91
+ # @note Resource means each property of top-level properties in this context
92
+ def resource
93
+ @resource ||= Resource.new(schema)
94
+ end
95
+
96
+ private
97
+
98
+ # @return [Hash]
99
+ # @raise [Rack::Spec::Mock::ExampleNotFound]
100
+ def response_hash
101
+ Rack::Spec::Mock::ResponseGenerator.call(schema)
102
+ end
103
+
104
+ # @return [Fixnum] Order score, used to sort links by preferred method order
105
+ def method_order_score
106
+ case method
107
+ when "GET"
108
+ 1
109
+ when "POST"
110
+ 2
111
+ when "PUT"
112
+ 3
113
+ when "PATCH"
114
+ 4
115
+ when "DELETE"
116
+ 5
117
+ else
118
+ 6
119
+ end
120
+ end
121
+
122
+ class RequestBodyGenerator
123
+ # Generates example request body from given schema
124
+ # @note Not includes properties that have readOnly property
125
+ # @return [Hash]
126
+ # @example
127
+ # Jdoc::Link::RequestBodyGenerator(schema) #=> { "name" => "example", "description" => "foo bar." }
128
+ def self.call(schema)
129
+ schema.properties.inject({}) do |result, (key, value)|
130
+ if value.data["readOnly"]
131
+ result
132
+ else
133
+ result.merge(
134
+ key => case
135
+ when !value.properties.empty?
136
+ call(value)
137
+ when !value.data["example"].nil?
138
+ value.data["example"]
139
+ when value.type.include?("null")
140
+ nil
141
+ else
142
+ raise ExampleNotFound, "No example found for #{schema.pointer}/#{key}"
143
+ end
144
+ )
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,59 @@
1
+ module Jdoc
2
+ class Property
3
+ attr_reader :name
4
+
5
+ # @param name [String]
6
+ # @param schema [JsonSchema::Schema]
7
+ def initialize(name: nil, schema: nil)
8
+ @name = name
9
+ @schema = schema
10
+ end
11
+
12
+ # @return [Hash] Key-Value pair of metadata of this property
13
+ def options
14
+ {
15
+ Example: example,
16
+ Type: type,
17
+ Format: format,
18
+ Patern: pattern,
19
+ ReadOnly: read_only,
20
+ }.reject {|key, value| value.nil? }
21
+ end
22
+
23
+ # @return [String, nil] Description text, defined in description property
24
+ def description
25
+ @schema.description
26
+ end
27
+
28
+ # @return [String, nil] Example value, defined in example property
29
+ def example
30
+ if str = @schema.data["example"]
31
+ "`#{str}`"
32
+ end
33
+ end
34
+
35
+ # @return [String, nil] Pattern constraint, defined in pattern property
36
+ def pattern
37
+ if str = @schema.pattern
38
+ "`#{str}`"
39
+ end
40
+ end
41
+
42
+ # @return [Stirng, nil] Format constraint, defined in format property
43
+ def format
44
+ @schema.format
45
+ end
46
+
47
+ # @return [true, nil] True if readOnly property is defined and it's true
48
+ def read_only
49
+ true if @schema.read_only == true
50
+ end
51
+
52
+ # @return [String, nil] Possible types defined in type property
53
+ def type
54
+ if @schema.type
55
+ @schema.type.join(", ")
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,55 @@
1
+ module Jdoc
2
+ class Resource
3
+ attr_reader :schema
4
+
5
+ # @param schema [JsonSchema::Schema]
6
+ def initialize(schema)
7
+ @schema = schema
8
+ end
9
+
10
+ # @return [String] Description for this schema, defined in description property
11
+ # @example
12
+ # resource.description #=> "An app is a program to be deployed."
13
+ def description
14
+ @schema.description
15
+ end
16
+
17
+ # @return [String] Href anchor for putting link in ToC
18
+ # @example
19
+ # resource.anchor #=> "#app"
20
+ def anchor
21
+ "#" + title.gsub(" ", "-").gsub(/[:\/]/, "").downcase
22
+ end
23
+
24
+ # @return [String] Markdown styled link text for this resource
25
+ # @example
26
+ # resource.hyperlink #=> "[App](#apps)"
27
+ def hyperlink
28
+ "[#{title}](#{anchor})"
29
+ end
30
+
31
+ # @return [String] Title defined in title property
32
+ # @example
33
+ # resource.title #=> "App"
34
+ def title
35
+ @schema.title
36
+ end
37
+
38
+ # @return [Array<Jdoc::Property>]
39
+ def properties
40
+ @schema.properties.map do |name, schema|
41
+ Property.new(name: name, schema: schema)
42
+ end
43
+ end
44
+
45
+ # Defined to change uniqueness in Hash key
46
+ def hash
47
+ @schema.hash
48
+ end
49
+
50
+ # Defined to change uniqueness in Hash key
51
+ def eql?(other)
52
+ @schema.eql?(other.schema)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,35 @@
1
+ module Jdoc
2
+ class Schema
3
+ # @param schema [Hash] JSON Schema
4
+ def initialize(schema)
5
+ @raw_schema = schema
6
+ end
7
+
8
+ # @return [Hash{Jdoc::Schema => Array}] Linkes table indexed by their schemata
9
+ def links_indexed_by_resource
10
+ @links_indexed_by_schema ||= links.inject(Hash.new {|h, k| h[k] = [] }) do |result, link|
11
+ result[link.resource] << link
12
+ result
13
+ end
14
+ end
15
+
16
+ # @return [String, nil] Title property of this schema
17
+ # @example
18
+ # schema.title #=> "app"
19
+ def title
20
+ @raw_schema["title"]
21
+ end
22
+
23
+ private
24
+
25
+ # @return [Array<Jdoc::Schema::Link>] Sorted links
26
+ def links
27
+ rack_schema.links.map {|link| Link.new(link: link) }.sort
28
+ end
29
+
30
+ # @return [Rack::Spec::Schema]
31
+ def rack_schema
32
+ @rack_schema ||= Rack::Spec::Schema.new(@raw_schema)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Jdoc
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,80 @@
1
+ ---
2
+ "$schema": http://json-schema.org/draft-04/hyper-schema
3
+ definitions:
4
+ app:
5
+ "$schema": http://json-schema.org/draft-04/hyper-schema
6
+ description: An app is a program to be deployed.
7
+ id: schemata/app
8
+ title: App
9
+ type:
10
+ - object
11
+ required:
12
+ - id
13
+ definitions:
14
+ id:
15
+ description: unique identifier of app
16
+ example: 01234567-89ab-cdef-0123-456789abcdef
17
+ format: uuid
18
+ readOnly: true
19
+ type:
20
+ - string
21
+ name:
22
+ description: unique name of app
23
+ example: example
24
+ pattern: "^[a-z][a-z0-9-]{3,50}$"
25
+ readOnly: false
26
+ type:
27
+ - string
28
+ links:
29
+ - description: Create a new app.
30
+ href: "/apps"
31
+ method: POST
32
+ rel: create
33
+ schema:
34
+ properties:
35
+ name:
36
+ "$ref": "#/definitions/app/definitions/name"
37
+ type:
38
+ - object
39
+ title: Create
40
+ - description: Delete an existing app.
41
+ href: "/apps/{(%23%2Fdefinitions%2Fapp%2Fdefinitions%2Fid)}"
42
+ method: DELETE
43
+ rel: destroy
44
+ title: Delete
45
+ - description: Info for existing app.
46
+ href: "/apps/{(%23%2Fdefinitions%2Fapp%2Fdefinitions%2Fid)}"
47
+ method: GET
48
+ rel: self
49
+ title: Info
50
+ - description: List existing apps.
51
+ href: "/apps"
52
+ method: GET
53
+ rel: instances
54
+ title: List
55
+ - description: Update an existing app.
56
+ href: "/apps/{(%23%2Fdefinitions%2Fapp%2Fdefinitions%2Fid)}"
57
+ method: PATCH
58
+ rel: update
59
+ schema:
60
+ properties:
61
+ name:
62
+ "$ref": "#/definitions/app/definitions/name"
63
+ type:
64
+ - object
65
+ title: Update
66
+ properties:
67
+ id:
68
+ "$ref": "#/definitions/app/definitions/id"
69
+ name:
70
+ "$ref": "#/definitions/app/definitions/name"
71
+ properties:
72
+ app:
73
+ "$ref": "#/definitions/app"
74
+ type:
75
+ - object
76
+ description: A schema for a small example API.
77
+ links:
78
+ - href: http://localhost:5000
79
+ rel: self
80
+ title: Example API
@@ -0,0 +1,149 @@
1
+ require "spec_helper"
2
+ require "active_support/core_ext/string/strip"
3
+ require "yaml"
4
+
5
+ describe Jdoc::Generator do
6
+ describe ".call" do
7
+ subject do
8
+ described_class.call(schema)
9
+ end
10
+
11
+ let(:schema) do
12
+ YAML.load_file(schema_path)
13
+ end
14
+
15
+ let(:schema_path) do
16
+ File.expand_path("../../fixtures/schema.yml", __FILE__)
17
+ end
18
+
19
+ it "returns a String of API documentation in Markdown from given JSON Schema" do
20
+ should == <<-EOS.strip_heredoc
21
+ # Example API
22
+ * [App](#app)
23
+ * [GET /apps](#get-apps)
24
+ * [POST /apps](#post-apps)
25
+ * [GET /apps/:id](#get-appsid)
26
+ * [PATCH /apps/:id](#patch-appsid)
27
+ * [DELETE /apps/:id](#delete-appsid)
28
+
29
+ ## App
30
+ An app is a program to be deployed.
31
+
32
+ ### Properties
33
+ * id - unique identifier of app
34
+ * Example: `01234567-89ab-cdef-0123-456789abcdef`
35
+ * Type: string
36
+ * Format: uuid
37
+ * ReadOnly: true
38
+ * name - unique name of app
39
+ * Example: `example`
40
+ * Type: string
41
+ * Patern: `(?-mix:^[a-z][a-z0-9-]{3,50}$)`
42
+
43
+ ### GET /apps
44
+ List existing apps.
45
+
46
+ ```
47
+ GET /apps HTTP/1.1
48
+ Content-Type: application/json
49
+ Host: api.example.com
50
+ ```
51
+
52
+ ```
53
+ HTTP/1.1 200
54
+ Content-Type: application/json
55
+
56
+ {
57
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
58
+ "name": "example"
59
+ }
60
+ ```
61
+
62
+ ### POST /apps
63
+ Create a new app.
64
+
65
+ ```
66
+ POST /apps HTTP/1.1
67
+ Content-Type: application/json
68
+ Host: api.example.com
69
+
70
+ {
71
+ "name": "example"
72
+ }
73
+ ```
74
+
75
+ ```
76
+ HTTP/1.1 201
77
+ Content-Type: application/json
78
+
79
+ {
80
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
81
+ "name": "example"
82
+ }
83
+ ```
84
+
85
+ ### GET /apps/:id
86
+ Info for existing app.
87
+
88
+ ```
89
+ GET /apps/:id HTTP/1.1
90
+ Content-Type: application/json
91
+ Host: api.example.com
92
+ ```
93
+
94
+ ```
95
+ HTTP/1.1 200
96
+ Content-Type: application/json
97
+
98
+ {
99
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
100
+ "name": "example"
101
+ }
102
+ ```
103
+
104
+ ### PATCH /apps/:id
105
+ Update an existing app.
106
+
107
+ ```
108
+ PATCH /apps/:id HTTP/1.1
109
+ Content-Type: application/json
110
+ Host: api.example.com
111
+
112
+ {
113
+ "name": "example"
114
+ }
115
+ ```
116
+
117
+ ```
118
+ HTTP/1.1 200
119
+ Content-Type: application/json
120
+
121
+ {
122
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
123
+ "name": "example"
124
+ }
125
+ ```
126
+
127
+ ### DELETE /apps/:id
128
+ Delete an existing app.
129
+
130
+ ```
131
+ DELETE /apps/:id HTTP/1.1
132
+ Content-Type: application/json
133
+ Host: api.example.com
134
+ ```
135
+
136
+ ```
137
+ HTTP/1.1 200
138
+ Content-Type: application/json
139
+
140
+ {
141
+ "id": "01234567-89ab-cdef-0123-456789abcdef",
142
+ "name": "example"
143
+ }
144
+ ```
145
+
146
+ EOS
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,7 @@
1
+ require "jdoc"
2
+
3
+ RSpec.configure do |config|
4
+ config.treat_symbols_as_metadata_keys_with_true_values = true
5
+ config.run_all_when_everything_filtered = true
6
+ config.filter_run :focus
7
+ end
data/template.md.erb ADDED
@@ -0,0 +1,40 @@
1
+ # <%= schema.title %>
2
+ <% schema.links_indexed_by_resource.each do |resource, links| %>
3
+ * <%= resource.hyperlink %>
4
+ <% links.each do |link| %>
5
+ * <%= link.hyperlink %>
6
+ <% end %>
7
+ <% end %>
8
+
9
+ <% schema.links_indexed_by_resource.each do |resource, links| %>
10
+ ## <%= resource.title %>
11
+ <%= resource.description %>
12
+
13
+ ### Properties
14
+ <% resource.properties.each do |property| %>
15
+ * <%= property.name %> - <%= property.description %>
16
+ <% property.options.each do |key, value| %>
17
+ * <%= key %>: <%= value %>
18
+ <% end %>
19
+ <% end %>
20
+
21
+ <% links.each do |link| %>
22
+ ### <%= link.endpoint %>
23
+ <%= link.description %>
24
+
25
+ ```
26
+ <%= link.method %> <%= link.path %> HTTP/1.1
27
+ Content-Type: application/json
28
+ Host: api.example.com
29
+ <%= "\n" + link.request_body if link.has_request_body? -%>
30
+ ```
31
+
32
+ ```
33
+ HTTP/1.1 <%= link.response_status %>
34
+ Content-Type: application/json
35
+
36
+ <%= link.response_body %>
37
+ ```
38
+
39
+ <% end %>
40
+ <% end %>
metadata ADDED
@@ -0,0 +1,194 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jdoc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryo Nakamura
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multi_json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack-spec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.7
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: erubis
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: json_schema
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 2.14.1
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 2.14.1
139
+ description:
140
+ email:
141
+ - r7kamura@gmail.com
142
+ executables:
143
+ - jdoc
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - Gemfile
149
+ - LICENSE.txt
150
+ - README.md
151
+ - Rakefile
152
+ - bin/jdoc
153
+ - example-api-documentation.md
154
+ - jdoc.gemspec
155
+ - lib/jdoc.rb
156
+ - lib/jdoc/generator.rb
157
+ - lib/jdoc/link.rb
158
+ - lib/jdoc/property.rb
159
+ - lib/jdoc/resource.rb
160
+ - lib/jdoc/schema.rb
161
+ - lib/jdoc/version.rb
162
+ - spec/fixtures/schema.yml
163
+ - spec/jdoc/generator_spec.rb
164
+ - spec/spec_helper.rb
165
+ - template.md.erb
166
+ homepage: https://github.com/r7kamura/jdoc
167
+ licenses:
168
+ - MIT
169
+ metadata: {}
170
+ post_install_message:
171
+ rdoc_options: []
172
+ require_paths:
173
+ - lib
174
+ required_ruby_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ required_rubygems_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ requirements: []
185
+ rubyforge_project:
186
+ rubygems_version: 2.2.2
187
+ signing_key:
188
+ specification_version: 4
189
+ summary: Generate API documentation from JSON Schema.
190
+ test_files:
191
+ - spec/fixtures/schema.yml
192
+ - spec/jdoc/generator_spec.rb
193
+ - spec/spec_helper.rb
194
+ has_rdoc: