jekyll-openapi 0.2.0 → 0.3.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 +4 -4
- data/README.md +57 -9
- data/lib/jekyll_openapi/document.rb +40 -23
- data/lib/jekyll_openapi/parameters.rb +11 -3
- data/lib/jekyll_openapi/version.rb +1 -1
- metadata +15 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7c592a43f900f36f1afbfc4432c1dc6b9e55302ec6e481bc6284596a728c36ea
|
|
4
|
+
data.tar.gz: 047ef58c76751ad0cc91415d838dc367ea302f83b4f88fa95f430397db3563b3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9a2fe7b1a1ca251142a4592cc1222aed94895e1dd8dbe4d13b7106436e4a50812e08c0756bb5051c24f3918ea99c4e0e348bb46ad9158d89848187c5a9e75c9d
|
|
7
|
+
data.tar.gz: 93542f7e0c5bdafa05d21442d67044ab751642163571dd01671165a6af69a21fd94461dd96150ea1bbf49b9e3594686194dbca97f3525fe1d33ccec68717b705
|
data/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# jekyll-openapi
|
|
2
2
|
|
|
3
3
|
A (mostly) spec-compliant [OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.0) toolkit for
|
|
4
|
-
Liquid-based static site generators (Jekyll in particular)
|
|
4
|
+
Liquid-based static site generators (Jekyll in particular), with partial
|
|
5
|
+
[OpenAPI 3.2](https://spec.openapis.org/oas/v3.2.0) support (see
|
|
6
|
+
[OpenAPI 3.2 support](#openapi-32-support)).
|
|
5
7
|
|
|
6
8
|
It deliberately does **not** render HTML. The gem provides:
|
|
7
9
|
|
|
@@ -75,19 +77,20 @@ title: API Reference
|
|
|
75
77
|
operation, grouped by tag. That's a complete, working integration.
|
|
76
78
|
|
|
77
79
|
`oapi_operations` already does the tedious parts for you: it skips
|
|
78
|
-
non-operation path-item keys, handles `x-` extension methods
|
|
79
|
-
and merges path-level parameters into
|
|
80
|
+
non-operation path-item keys, handles `x-` extension methods and OpenAPI 3.2
|
|
81
|
+
`additionalOperations`, filters by tag, and merges path-level parameters into
|
|
82
|
+
each operation.
|
|
80
83
|
|
|
81
84
|
Each `op` in the loop is a plain Hash you can traverse further:
|
|
82
85
|
|
|
83
86
|
| key | content |
|
|
84
87
|
|------------------------|------------------------------------------------------|
|
|
85
88
|
| `"path"` | `"/pets/{petId}"` |
|
|
86
|
-
| `"method"` | normalized method, `x-` prefix stripped (`"mkcol"`)
|
|
87
|
-
| `"raw_method"` | the literal key (`"x-mkcol"`)
|
|
89
|
+
| `"method"` | normalized method, lowercase, `x-` prefix stripped (`"mkcol"`) |
|
|
90
|
+
| `"raw_method"` | the literal key (`"x-mkcol"`, `"MKCOL"`) |
|
|
88
91
|
| `"operation"` | the Operation object, dereferenced |
|
|
89
92
|
| `"parameters"` | path-level + operation-level parameters, merged (operation wins on same name/location) |
|
|
90
|
-
| `"grouped_parameters"` | same, grouped: `{"query" => [...], "path" => [...], "header" => [...], "cookie" => [...]}` |
|
|
93
|
+
| `"grouped_parameters"` | same, grouped: `{"query" => [...], "querystring" => [...], "path" => [...], "header" => [...], "cookie" => [...]}` |
|
|
91
94
|
|
|
92
95
|
### Going further
|
|
93
96
|
|
|
@@ -159,6 +162,51 @@ when followed; recursive schemas terminate (rendered as a link, or their name in
|
|
|
159
162
|
the text renderers); invalid schemas render as `""`. Your build never breaks on
|
|
160
163
|
a bad spec.
|
|
161
164
|
|
|
165
|
+
## OpenAPI 3.2 support
|
|
166
|
+
|
|
167
|
+
Partial. Because the model hands templates plain hashes, most new 3.2 *fields*
|
|
168
|
+
flow through untouched and are usable today; "supported" below means the
|
|
169
|
+
library actively understands the feature, "passthrough" means the raw data
|
|
170
|
+
reaches your template but no helper interprets it.
|
|
171
|
+
|
|
172
|
+
Supported:
|
|
173
|
+
|
|
174
|
+
- [x] `additionalOperations` — enumerated by `oapi_operations` like any other
|
|
175
|
+
operation, with path-level parameters merged; `method` is the lowercased
|
|
176
|
+
method name, `raw_method` the literal key (`"PROPFIND"`). Gives webDAV-style
|
|
177
|
+
APIs first-class treatment (previously only reachable via `x-` methods).
|
|
178
|
+
- [x] The `query` HTTP method — recognized as a first-class path-item key.
|
|
179
|
+
- [x] Tag `summary` — passes through `oapi_tags` (tested); use it as a short
|
|
180
|
+
display name where `description` is prose.
|
|
181
|
+
- [x] `in: querystring` parameters — grouped under their own `"querystring"`
|
|
182
|
+
key by `oapi_parameters` / `grouped_parameters` (the parameter is
|
|
183
|
+
`content`-based: render its media-type schema, not a name/value pair). An
|
|
184
|
+
operation-level querystring parameter overrides a path-level one regardless
|
|
185
|
+
of name, and mixing it with `in: query` parameters warns (the spec forbids
|
|
186
|
+
it) but keeps both.
|
|
187
|
+
|
|
188
|
+
Passthrough (data reaches templates, no helper logic):
|
|
189
|
+
|
|
190
|
+
- [ ] Tag `parent` / `kind` — the fields are readable, but `oapi_operations`
|
|
191
|
+
and `oapi_tags` treat tags as a flat list: no hierarchy building, no
|
|
192
|
+
filtering by kind.
|
|
193
|
+
- [ ] Response `summary`, Server `name` — readable on the raw objects.
|
|
194
|
+
- [ ] Security scheme additions (`deviceAuthorization` flow,
|
|
195
|
+
`oauth2MetadataUrl`, `deprecated`) — readable via `oapi_security_schemes`.
|
|
196
|
+
|
|
197
|
+
Not supported (TODO):
|
|
198
|
+
|
|
199
|
+
- [ ] Streaming / sequential media types — `itemSchema`, `itemEncoding` and
|
|
200
|
+
`prefixEncoding` are ignored by the schema renderers and `oapi_examples`.
|
|
201
|
+
- [ ] Example Object `dataValue` / `serializedValue` — `oapi_examples` only
|
|
202
|
+
reads `value`.
|
|
203
|
+
- [ ] `xml.nodeType` — the XML renderer still keys off the 3.1 `attribute` /
|
|
204
|
+
`wrapped` flags.
|
|
205
|
+
- [ ] `$self` and multi-document descriptions — consistent with the existing
|
|
206
|
+
local-`$ref`s-only policy.
|
|
207
|
+
- [ ] `components.mediaTypes` reuse — untested; generic local `$ref`
|
|
208
|
+
resolution may already handle it, but no guarantees.
|
|
209
|
+
|
|
162
210
|
## Compliance notes
|
|
163
211
|
|
|
164
212
|
Intentional simplifications, in the spirit of "readable docs over exhaustive
|
|
@@ -178,8 +226,8 @@ fidelity":
|
|
|
178
226
|
rake test # or: ruby -Ilib -Itest test/test_<name>.rb
|
|
179
227
|
```
|
|
180
228
|
|
|
181
|
-
Tests run against generic fixtures (`test/fixtures/petstore.yml
|
|
229
|
+
Tests run against generic fixtures (`test/fixtures/petstore.yml`, a pristine
|
|
230
|
+
OpenAPI 3.1 document, and `test/fixtures/filestore.yml`, a WebDAV-flavored
|
|
231
|
+
OpenAPI 3.2 one); when the gem
|
|
182
232
|
sources live inside the eCorpus_doc repository, an extra integration suite runs
|
|
183
233
|
the whole pipeline over the real eCorpus API definition.
|
|
184
|
-
</content>
|
|
185
|
-
</invoke>
|
|
@@ -14,7 +14,7 @@ module JekyllOpenAPI
|
|
|
14
14
|
# page needs. `$ref`s stay navigable but keep their names (see Reference), so
|
|
15
15
|
# templates can link named schemas instead of inlining them.
|
|
16
16
|
class Document
|
|
17
|
-
HTTP_METHODS = %w[get put post delete options head patch trace].freeze
|
|
17
|
+
HTTP_METHODS = %w[get put post delete options head patch trace query].freeze
|
|
18
18
|
PATH_ITEM_FIELDS = %w[summary description servers parameters $ref].freeze
|
|
19
19
|
|
|
20
20
|
attr_reader :data
|
|
@@ -116,32 +116,49 @@ module JekyllOpenAPI
|
|
|
116
116
|
# follow it so referenced operations are not silently dropped.
|
|
117
117
|
path_item = follow(path_item)
|
|
118
118
|
next [] unless path_item.is_a?(Hash)
|
|
119
|
-
path_item.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
119
|
+
path_item.flat_map do |key, value|
|
|
120
|
+
if key == "additionalOperations"
|
|
121
|
+
# OpenAPI 3.2: a map of custom HTTP method name => Operation Object.
|
|
122
|
+
value = follow(value)
|
|
123
|
+
next [] unless value.is_a?(Hash)
|
|
124
|
+
value.filter_map do |method, operation|
|
|
125
|
+
build_operation(path, path_item, method.downcase, method, operation)
|
|
126
|
+
end
|
|
127
|
+
else
|
|
128
|
+
next [] if PATH_ITEM_FIELDS.include?(key)
|
|
129
|
+
next [] unless HTTP_METHODS.include?(key) || key.start_with?("x-")
|
|
130
|
+
operation = follow(value)
|
|
131
|
+
# `x-` is OpenAPI's extension mechanism, not a method namespace: a
|
|
132
|
+
# path-item extension is only an operation when it actually carries an
|
|
133
|
+
# Operation Object. `operationId`/`responses` mark one; vendor metadata
|
|
134
|
+
# (x-internal, x-codegen, …) has neither and must not become a phantom
|
|
135
|
+
# method. Standard HTTP verbs are always operations.
|
|
136
|
+
next [] if operation.is_a?(Hash) && key.start_with?("x-") &&
|
|
137
|
+
!(operation.key?("operationId") || operation.key?("responses"))
|
|
138
|
+
|
|
139
|
+
[build_operation(path, path_item, key.delete_prefix("x-"), key, operation)].compact
|
|
140
|
+
end
|
|
141
141
|
end
|
|
142
142
|
end
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
+
# @return [Hash, nil] a normalized operation entry, or nil when `operation`
|
|
146
|
+
# is not an Operation Object
|
|
147
|
+
def build_operation(path, path_item, method, raw_method, operation)
|
|
148
|
+
operation = follow(operation)
|
|
149
|
+
return unless operation.is_a?(Hash)
|
|
150
|
+
|
|
151
|
+
params = Parameters.merge(path_item["parameters"], operation["parameters"])
|
|
152
|
+
{
|
|
153
|
+
"path" => path,
|
|
154
|
+
"method" => method,
|
|
155
|
+
"raw_method" => raw_method,
|
|
156
|
+
"operation" => operation,
|
|
157
|
+
"parameters" => params,
|
|
158
|
+
"grouped_parameters" => Parameters.group(params, logger: @logger),
|
|
159
|
+
}
|
|
160
|
+
end
|
|
161
|
+
|
|
145
162
|
# Resolve a $ref used where a mapping (path item / operation) is expected.
|
|
146
163
|
def follow(node)
|
|
147
164
|
node.is_a?(Reference) ? node.resolve : node
|
|
@@ -5,7 +5,9 @@ module JekyllOpenAPI
|
|
|
5
5
|
# Helpers for OpenAPI Parameter objects.
|
|
6
6
|
# @see https://spec.openapis.org/oas/v3.1.0.html#parameter-object
|
|
7
7
|
module Parameters
|
|
8
|
-
|
|
8
|
+
# "querystring" is OpenAPI 3.2: a single parameter describing the entire
|
|
9
|
+
# query string through `content` (its `name` is not used in serialization).
|
|
10
|
+
LOCATIONS = %w[query querystring path header cookie].freeze
|
|
9
11
|
|
|
10
12
|
# A parameter may arrive inline (Hash) or as a $ref (Reference). Both read
|
|
11
13
|
# like a mapping, so both are valid parameter objects here.
|
|
@@ -15,7 +17,7 @@ module JekyllOpenAPI
|
|
|
15
17
|
|
|
16
18
|
##
|
|
17
19
|
# Groups a parameter list by location ("in").
|
|
18
|
-
# Always returns all
|
|
20
|
+
# Always returns all five location keys so templates can test emptiness.
|
|
19
21
|
# @param params [Array<Hash>, nil]
|
|
20
22
|
# @return [Hash{String => Array<Hash>}]
|
|
21
23
|
def self.group(params, logger: JekyllOpenAPI.logger)
|
|
@@ -28,18 +30,24 @@ module JekyllOpenAPI
|
|
|
28
30
|
logger.warn("invalid parameter location #{location.inspect} in #{param.inspect}")
|
|
29
31
|
end
|
|
30
32
|
end
|
|
33
|
+
unless output["querystring"].empty? || output["query"].empty?
|
|
34
|
+
logger.warn("`in: querystring` must not be combined with `in: query` parameters")
|
|
35
|
+
end
|
|
31
36
|
output
|
|
32
37
|
end
|
|
33
38
|
|
|
34
39
|
##
|
|
35
40
|
# Merges path-item level and operation level parameter lists.
|
|
36
41
|
# An operation parameter overrides a path one with the same (name, in) pair.
|
|
42
|
+
# A querystring parameter overrides on location alone: its name is not used
|
|
43
|
+
# in serialization and only one may describe the query string.
|
|
37
44
|
# @return [Array<Hash>]
|
|
38
45
|
def self.merge(path_params, operation_params)
|
|
39
46
|
merged = {}
|
|
40
47
|
(Array(path_params) + Array(operation_params)).each do |param|
|
|
41
48
|
next unless mapping?(param)
|
|
42
|
-
|
|
49
|
+
name = param["in"] == "querystring" ? nil : param["name"]
|
|
50
|
+
merged[[name, param["in"]]] = param
|
|
43
51
|
end
|
|
44
52
|
merged.values
|
|
45
53
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-openapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sebastien Dumetz
|
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: base64
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: liquid
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|