swagger23 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +125 -0
- data/bin/swagger23 +113 -0
- data/lib/swagger23/converter.rb +71 -0
- data/lib/swagger23/converters/components.rb +79 -0
- data/lib/swagger23/converters/info.rb +16 -0
- data/lib/swagger23/converters/paths.rb +274 -0
- data/lib/swagger23/converters/security.rb +99 -0
- data/lib/swagger23/converters/servers.rb +37 -0
- data/lib/swagger23/error.rb +8 -0
- data/lib/swagger23/ref_rewriter.rb +72 -0
- data/lib/swagger23/schema_processor.rb +93 -0
- data/lib/swagger23/version.rb +5 -0
- data/lib/swagger23.rb +112 -0
- data/sig/swagger23.rbs +71 -0
- data/swagger23.gemspec +48 -0
- metadata +111 -0
data/lib/swagger23.rb
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "swagger23/version"
|
|
5
|
+
require_relative "swagger23/error"
|
|
6
|
+
require_relative "swagger23/ref_rewriter"
|
|
7
|
+
require_relative "swagger23/schema_processor"
|
|
8
|
+
require_relative "swagger23/converters/info"
|
|
9
|
+
require_relative "swagger23/converters/servers"
|
|
10
|
+
require_relative "swagger23/converters/paths"
|
|
11
|
+
require_relative "swagger23/converters/components"
|
|
12
|
+
require_relative "swagger23/converters/security"
|
|
13
|
+
require_relative "swagger23/converter"
|
|
14
|
+
|
|
15
|
+
module Swagger23
|
|
16
|
+
# Parse a JSON or YAML string into a Ruby Hash.
|
|
17
|
+
#
|
|
18
|
+
# Detection strategy: inspect the first non-whitespace byte.
|
|
19
|
+
# '{' or '[' → JSON (the only two valid JSON document starters)
|
|
20
|
+
# anything else → YAML
|
|
21
|
+
#
|
|
22
|
+
# This avoids trying to JSON-parse a UTF-8 YAML string, which raises
|
|
23
|
+
# Encoding::InvalidByteSequenceError when the Ruby process is running with
|
|
24
|
+
# an ASCII locale.
|
|
25
|
+
#
|
|
26
|
+
# @param source [String] raw JSON or YAML content
|
|
27
|
+
# @return [Hash] parsed document
|
|
28
|
+
# @raise [Swagger23::Error] if the source cannot be parsed as either format
|
|
29
|
+
def self.parse(source)
|
|
30
|
+
# Ensure we always work with a UTF-8 string regardless of how the caller
|
|
31
|
+
# obtained it (File.read without encoding:, STDIN.read, etc.).
|
|
32
|
+
source = source.dup.force_encoding("UTF-8") unless source.encoding == Encoding::UTF_8
|
|
33
|
+
|
|
34
|
+
first = source.lstrip[0]
|
|
35
|
+
|
|
36
|
+
if first == "{" || first == "["
|
|
37
|
+
begin
|
|
38
|
+
JSON.parse(source)
|
|
39
|
+
rescue JSON::ParserError => e
|
|
40
|
+
raise Swagger23::Error, "JSON parse error: #{e.message}"
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
require "yaml"
|
|
44
|
+
begin
|
|
45
|
+
result = YAML.safe_load(source)
|
|
46
|
+
rescue Psych::SyntaxError => e
|
|
47
|
+
raise Swagger23::Error, "Could not parse input as YAML: #{e.message}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if result.nil?
|
|
51
|
+
raise Swagger23::Error, "Could not parse input: document is empty or null"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
unless result.is_a?(Hash)
|
|
55
|
+
raise Swagger23::Error, "Input parsed to #{result.class}, expected a Hash"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
result
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Convert a Swagger 2.0 Hash to an OpenAPI 3.0 Hash.
|
|
63
|
+
#
|
|
64
|
+
# @param swagger [Hash] parsed Swagger 2.0 document
|
|
65
|
+
# @return [Hash] OpenAPI 3.0 document
|
|
66
|
+
def self.convert(swagger)
|
|
67
|
+
Converter.new(swagger).convert
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Parse a JSON or YAML string and return the converted OpenAPI 3.0 document
|
|
71
|
+
# as a pretty-printed JSON string.
|
|
72
|
+
#
|
|
73
|
+
# @param source [String] Swagger 2.0 document as JSON or YAML
|
|
74
|
+
# @return [String] OpenAPI 3.0 document as JSON
|
|
75
|
+
def self.convert_string(source)
|
|
76
|
+
JSON.pretty_generate(convert(parse(source)))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Parse a JSON or YAML string and return the converted OpenAPI 3.0 document
|
|
80
|
+
# as a YAML string.
|
|
81
|
+
#
|
|
82
|
+
# @param source [String] Swagger 2.0 document as JSON or YAML
|
|
83
|
+
# @return [String] OpenAPI 3.0 document as YAML
|
|
84
|
+
def self.convert_to_yaml(source)
|
|
85
|
+
require "yaml"
|
|
86
|
+
YAML.dump(stringify_keys_deep(convert(parse(source))))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @deprecated Use {convert_string} instead (identical behaviour, clearer name).
|
|
90
|
+
def self.convert_json(source)
|
|
91
|
+
convert_string(source)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# ── Internal helpers ──────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
# YAML.dump can emit symbols as keys if the hash was built with symbol keys.
|
|
97
|
+
# Our converter always uses string keys (coming from JSON.parse), but we
|
|
98
|
+
# normalise just in case a caller passes in a symbolised hash.
|
|
99
|
+
def self.stringify_keys_deep(obj)
|
|
100
|
+
case obj
|
|
101
|
+
in Hash
|
|
102
|
+
obj.each_with_object({}) do |(k, v), h|
|
|
103
|
+
h[k.to_s] = stringify_keys_deep(v)
|
|
104
|
+
end
|
|
105
|
+
in Array
|
|
106
|
+
obj.map { |item| stringify_keys_deep(item) }
|
|
107
|
+
else
|
|
108
|
+
obj
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
private_class_method :stringify_keys_deep
|
|
112
|
+
end
|
data/sig/swagger23.rbs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Type signatures for the swagger23 gem public API.
|
|
2
|
+
# Compatible with Steep, Sorbet (via rbs), and IDEs such as RubyMine / VS Code + ruby-lsp.
|
|
3
|
+
|
|
4
|
+
module Swagger23
|
|
5
|
+
VERSION: String
|
|
6
|
+
|
|
7
|
+
class Error < StandardError
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class InvalidSwaggerError < Error
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Parse a JSON or YAML string into a Ruby Hash.
|
|
14
|
+
def self.parse: (String source) -> Hash[String, untyped]
|
|
15
|
+
|
|
16
|
+
# Convert a Swagger 2.0 Hash to an OpenAPI 3.0 Hash.
|
|
17
|
+
def self.convert: (Hash[String, untyped] swagger) -> Hash[String, untyped]
|
|
18
|
+
|
|
19
|
+
# Parse and convert, returning a pretty-printed JSON string.
|
|
20
|
+
def self.convert_string: (String source) -> String
|
|
21
|
+
|
|
22
|
+
# Parse and convert, returning a YAML string.
|
|
23
|
+
def self.convert_to_yaml: (String source) -> String
|
|
24
|
+
|
|
25
|
+
# @deprecated Use convert_string instead.
|
|
26
|
+
def self.convert_json: (String source) -> String
|
|
27
|
+
|
|
28
|
+
class Converter
|
|
29
|
+
SUPPORTED_SWAGGER_VERSION: String
|
|
30
|
+
TARGET_OPENAPI_VERSION: String
|
|
31
|
+
|
|
32
|
+
def initialize: (Hash[String, untyped] swagger) -> void
|
|
33
|
+
def convert: () -> Hash[String, untyped]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
module RefRewriter
|
|
37
|
+
REF_MAP: Hash[String, String]
|
|
38
|
+
|
|
39
|
+
def self.rewrite: (untyped obj) -> untyped
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module SchemaProcessor
|
|
43
|
+
def self.process: (untyped obj) -> untyped
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module Converters
|
|
47
|
+
module Info
|
|
48
|
+
def self.convert: (Hash[String, untyped] swagger) -> Hash[String, untyped]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
module Servers
|
|
52
|
+
def self.convert: (Hash[String, untyped] swagger) -> Array[Hash[String, untyped]]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
module Paths
|
|
56
|
+
HTTP_METHODS: Array[String]
|
|
57
|
+
|
|
58
|
+
def self.convert: (Hash[String, untyped] swagger) -> Hash[String, untyped]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
module Components
|
|
62
|
+
def self.convert: (Hash[String, untyped] swagger) -> Hash[String, untyped]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
module Security
|
|
66
|
+
def self.convert: (Hash[String, untyped] swagger) -> Hash[String, untyped]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
ParameterConverter: singleton(Paths)
|
|
70
|
+
end
|
|
71
|
+
end
|
data/swagger23.gemspec
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/swagger23/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "swagger23"
|
|
7
|
+
spec.version = Swagger23::VERSION
|
|
8
|
+
spec.authors = ["Maxim Veysgeym"]
|
|
9
|
+
spec.email = []
|
|
10
|
+
spec.summary = "Convert Swagger 2.0 to OpenAPI 3.0 — Ruby library and CLI"
|
|
11
|
+
spec.description = <<~DESC
|
|
12
|
+
swagger23 converts Swagger 2.0 (OAS 2) API specifications into OpenAPI 3.0.3 (OAS 3)
|
|
13
|
+
specifications. Accepts JSON or YAML input, produces JSON or YAML output.
|
|
14
|
+
Works as a Ruby library (Swagger23.convert) or a standalone CLI tool (swagger23).
|
|
15
|
+
Handles paths, parameters, requestBody, components/schemas, securitySchemes,
|
|
16
|
+
servers, $ref rewriting, collectionFormat, x-nullable, discriminator, OAuth2 flows,
|
|
17
|
+
and file uploads. No external runtime dependencies. Safe for large specs.
|
|
18
|
+
DESC
|
|
19
|
+
spec.license = "MIT"
|
|
20
|
+
spec.homepage = "https://github.com/Qew7/swagger23"
|
|
21
|
+
|
|
22
|
+
spec.metadata = {
|
|
23
|
+
"homepage_uri" => spec.homepage,
|
|
24
|
+
"source_code_uri" => spec.homepage,
|
|
25
|
+
"bug_tracker_uri" => "#{spec.homepage}/issues",
|
|
26
|
+
"documentation_uri" => "#{spec.homepage}/blob/main/README.md"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
spec.required_ruby_version = ">= 3.2.0"
|
|
30
|
+
|
|
31
|
+
spec.files = Dir[
|
|
32
|
+
"lib/**/*.rb",
|
|
33
|
+
"sig/**/*.rbs",
|
|
34
|
+
"bin/*",
|
|
35
|
+
"swagger23.gemspec",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
spec.bindir = "bin"
|
|
41
|
+
spec.executables = ["swagger23"]
|
|
42
|
+
spec.require_paths = ["lib"]
|
|
43
|
+
|
|
44
|
+
spec.add_dependency "json", ">= 2.0"
|
|
45
|
+
|
|
46
|
+
spec.add_development_dependency "rspec", "~> 3.12"
|
|
47
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
48
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: swagger23
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Maxim Veysgeym
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-03-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: json
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rspec
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.12'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.12'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '13.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '13.0'
|
|
55
|
+
description: |
|
|
56
|
+
swagger23 converts Swagger 2.0 (OAS 2) API specifications into OpenAPI 3.0.3 (OAS 3)
|
|
57
|
+
specifications. Accepts JSON or YAML input, produces JSON or YAML output.
|
|
58
|
+
Works as a Ruby library (Swagger23.convert) or a standalone CLI tool (swagger23).
|
|
59
|
+
Handles paths, parameters, requestBody, components/schemas, securitySchemes,
|
|
60
|
+
servers, $ref rewriting, collectionFormat, x-nullable, discriminator, OAuth2 flows,
|
|
61
|
+
and file uploads. No external runtime dependencies. Safe for large specs.
|
|
62
|
+
email: []
|
|
63
|
+
executables:
|
|
64
|
+
- swagger23
|
|
65
|
+
extensions: []
|
|
66
|
+
extra_rdoc_files: []
|
|
67
|
+
files:
|
|
68
|
+
- LICENSE
|
|
69
|
+
- README.md
|
|
70
|
+
- bin/swagger23
|
|
71
|
+
- lib/swagger23.rb
|
|
72
|
+
- lib/swagger23/converter.rb
|
|
73
|
+
- lib/swagger23/converters/components.rb
|
|
74
|
+
- lib/swagger23/converters/info.rb
|
|
75
|
+
- lib/swagger23/converters/paths.rb
|
|
76
|
+
- lib/swagger23/converters/security.rb
|
|
77
|
+
- lib/swagger23/converters/servers.rb
|
|
78
|
+
- lib/swagger23/error.rb
|
|
79
|
+
- lib/swagger23/ref_rewriter.rb
|
|
80
|
+
- lib/swagger23/schema_processor.rb
|
|
81
|
+
- lib/swagger23/version.rb
|
|
82
|
+
- sig/swagger23.rbs
|
|
83
|
+
- swagger23.gemspec
|
|
84
|
+
homepage: https://github.com/Qew7/swagger23
|
|
85
|
+
licenses:
|
|
86
|
+
- MIT
|
|
87
|
+
metadata:
|
|
88
|
+
homepage_uri: https://github.com/Qew7/swagger23
|
|
89
|
+
source_code_uri: https://github.com/Qew7/swagger23
|
|
90
|
+
bug_tracker_uri: https://github.com/Qew7/swagger23/issues
|
|
91
|
+
documentation_uri: https://github.com/Qew7/swagger23/blob/main/README.md
|
|
92
|
+
post_install_message:
|
|
93
|
+
rdoc_options: []
|
|
94
|
+
require_paths:
|
|
95
|
+
- lib
|
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - ">="
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: 3.2.0
|
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - ">="
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '0'
|
|
106
|
+
requirements: []
|
|
107
|
+
rubygems_version: 3.4.19
|
|
108
|
+
signing_key:
|
|
109
|
+
specification_version: 4
|
|
110
|
+
summary: Convert Swagger 2.0 to OpenAPI 3.0 — Ruby library and CLI
|
|
111
|
+
test_files: []
|