open_api_2_json_schema 0.1.2 → 0.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
  SHA256:
3
- metadata.gz: 8f25b393383b6694b23d0306c5a48f91762ba658afbd488c15fa16c40cbfa246
4
- data.tar.gz: 5bc71e2ab8ff4019428686c39b17cc46f8ea5445d4d181af6fca65aa41b8cdd1
3
+ metadata.gz: b098b4e80aac6152b1a1623aa380b89b54e8c4a0c1e9c00c7e94f1f3063da1f8
4
+ data.tar.gz: bed62b780a77c06f4aa3d1576f57bff01926fd913b353b8a5c33cd41a3a971ff
5
5
  SHA512:
6
- metadata.gz: 3263c6c3f5372ff6e6cc93a812ce429ce1ab03d64b1d7eb5cfb23e9291f48b162accca973247dfca2fbc1da1b851089d5a4b21d663cfd0a300fe4fb368f69c1c
7
- data.tar.gz: 828d603767e21eab7b4197d4e3c8217b0cd816464e1726916c9e42571b09c0bcfdff8e1e3622f0f07928f74b67f6d54c87c752ec890dc0902119343181518ce8
6
+ metadata.gz: '03495227e0657a9d7fbb15827fd8cf6089f0d00ba6b3693de0544af09ce053239fe77c98712a34b5713511ce67fdeee580c96bb325c2ff7f53c4b55c98f79f31'
7
+ data.tar.gz: 3c8bcf6d521c462e49d6911f6a374e097140af0f6b6e969a4ceca1a5eae37df6fc20ce2806cac0da2e44fe331e7505a3730ff99fb73e2f960493defa41d41d51
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.2.0] - 2022-12-21
2
+
3
+ - Parsing & deferencing ref using `oas_parser`
4
+
1
5
  ## [0.1.2] - 2022-10-19
2
6
 
3
7
  - Support `discriminator`
data/README.md CHANGED
@@ -34,46 +34,6 @@ schema = {
34
34
  OpenApi2JsonSchema.convert(schema)
35
35
  ```
36
36
 
37
- ### Discriminator
38
-
39
- ```yaml
40
- # Sample YAML file
41
- schema:
42
- discriminator:
43
- propertyName: key
44
- mapping:
45
- value1: 'path-to-file-2.yml'
46
- value2: 'path-to-file-2.yml'
47
- properties:
48
- key:
49
- type: string
50
- enum:
51
- - value1
52
- - value2
53
- ```
54
-
55
- ```json
56
- "schema": {
57
- "properties": {
58
- "key": {
59
- "type": "string",
60
- "enum": ["value1", "value2"]
61
- }
62
- },
63
- "discriminator": {
64
- "propertyName": "name",
65
- "mapping": {
66
- "value1": {
67
- "type": "object"
68
- },
69
- "value2": {
70
- "type": "array"
71
- }
72
- }
73
- }
74
- }
75
- ```
76
-
77
37
  ## Development
78
38
 
79
39
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,121 @@
1
+ module OpenApi2JsonSchema
2
+ class Converter
3
+ NOT_SUPPORTED = [
4
+ 'nullable', 'readOnly',
5
+ 'writeOnly', 'xml', 'externalDocs',
6
+ 'example', 'deprecated'
7
+ ]
8
+ STRUCTS = ['allOf', 'anyOf', 'oneOf', 'not', 'items', 'additionalProperties', 'schema', 'discriminator']
9
+ VALID_TYPES = ['integer', 'number', 'string', 'boolean', 'object', 'array', 'null']
10
+ VALID_FORMATS = ['date-time', 'email', 'hostname', 'ipv4', 'ipv6', 'uri', 'uri-reference']
11
+
12
+ MIN_INT_32 = 0 - 2 ** 31
13
+ MAX_INT_32 = 2 ** 31 - 1
14
+ MIN_INT_64 = 0 - 2 ** 63
15
+ MAX_INT_64 = 2 ** 63 - 1
16
+ MIN_FLOAT = 0 - 2 ** 128
17
+ MAX_FLOAT = 2 ** 128 - 1
18
+ MAX_DOUBLE = 1.7976931348623157e+308
19
+ MIN_DOUBLE = 0 - MAX_DOUBLE
20
+ BYTE_PATTERN = '^[\\w\\d+\\/=]*$'
21
+
22
+ def convert(schema)
23
+ convert_schema(schema).tap do |json_schema|
24
+ json_schema['$schema'] = 'http://json-schema.org/draft-04/schema#'
25
+ end.to_json
26
+ end
27
+
28
+ private
29
+
30
+ def convert_schema(schema)
31
+ json_schema = schema.except(*NOT_SUPPORTED)
32
+
33
+ if schema.key?('properties')
34
+ new_properties = convert_properties(schema['properties'])
35
+
36
+ if schema['required'].is_a?(Array)
37
+ new_required = clean_required(schema['required'], schema['properties'])
38
+ json_schema['required'] = new_required if new_required.any?
39
+ end
40
+
41
+ json_schema['properties'] = new_properties if new_properties.any?
42
+ end
43
+
44
+ validate_type(schema['type'])
45
+
46
+ json_schema.merge!(convert_types(schema))
47
+ json_schema.merge!(convert_format(schema))
48
+
49
+ json_schema
50
+ end
51
+
52
+ def validate_type(type)
53
+ unless type.nil? || VALID_TYPES.include?(type)
54
+ raise InvalidTypeError.build(type)
55
+ end
56
+ end
57
+
58
+ def convert_properties(properties)
59
+ return {} unless properties.is_a?(Hash)
60
+
61
+ properties.reduce({}) do |result, (key, property)|
62
+ next result unless property.is_a?(Hash)
63
+
64
+ result.merge(key => convert_schema(property))
65
+ end
66
+ end
67
+
68
+ def convert_types(schema)
69
+ if schema['type'] && schema['nullable'] == true
70
+ type = [schema['type'], 'null']
71
+
72
+ if schema['enum'].is_a?(Array)
73
+ {
74
+ 'type' => type,
75
+ 'enum' => schema['enum'].append(nil)
76
+ }
77
+ else
78
+ { 'type' => type }
79
+ end
80
+ else
81
+ {}
82
+ end
83
+ end
84
+
85
+ def convert_format(schema)
86
+ case schema['format']
87
+ when 'int32'
88
+ {
89
+ 'minimum' => [MIN_INT_32, schema['minimum'] || MIN_INT_32].max,
90
+ 'maximum' => [MAX_INT_32, schema['maximum'] || MAX_INT_32].min
91
+ }
92
+ when 'int64'
93
+ {
94
+ 'minimum' => [MIN_INT_64, schema['minimum'] || MIN_INT_64].max,
95
+ 'maximum' => [MAX_INT_64, schema['maximum'] || MAX_INT_64].min
96
+ }
97
+ when 'float'
98
+ {
99
+ 'minimum' => [MIN_FLOAT, schema['minimum'] || MIN_FLOAT].max,
100
+ 'maximum' => [MAX_FLOAT, schema['maximum'] || MAX_FLOAT].min
101
+ }
102
+ when 'double'
103
+ {
104
+ 'minimum' => [MIN_DOUBLE, schema['minimum'] || MIN_DOUBLE].max,
105
+ 'maximum' => [MAX_DOUBLE, schema['maximum'] || MAX_DOUBLE].min
106
+ }
107
+ when 'byte'
108
+ { 'pattern' => BYTE_PATTERN }
109
+ else
110
+ {}
111
+ end
112
+ end
113
+
114
+ def clean_required(required, properties)
115
+ required ||= []
116
+ properties ||= {}
117
+
118
+ properties.slice(*required).keys
119
+ end
120
+ end
121
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenApi2JsonSchema
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -2,32 +2,13 @@
2
2
 
3
3
  require 'json'
4
4
  require 'yaml'
5
+ require 'oas_parser'
6
+ require_relative "open_api_2_json_schema/converter"
5
7
  require_relative "open_api_2_json_schema/version"
6
- require_relative 'attribute_handlers/all_of'
7
- require_relative 'attribute_handlers/discriminator'
8
8
 
9
9
  module OpenApi2JsonSchema
10
10
  module_function
11
11
 
12
- STRUCTS = ['allOf', 'anyOf', 'oneOf', 'not', 'items', 'additionalProperties', 'schema', 'discriminator']
13
- NOT_SUPPORTED = [
14
- 'nullable', 'readOnly',
15
- 'writeOnly', 'xml', 'externalDocs',
16
- 'example', 'deprecated'
17
- ]
18
- VALID_TYPES = ['integer', 'number', 'string', 'boolean', 'object', 'array', 'null']
19
- VALID_FORMATS = ['date-time', 'email', 'hostname', 'ipv4', 'ipv6', 'uri', 'uri-reference']
20
-
21
- MIN_INT_32 = 0 - 2 ** 31
22
- MAX_INT_32 = 2 ** 31 - 1
23
- MIN_INT_64 = 0 - 2 ** 63
24
- MAX_INT_64 = 2 ** 63 - 1
25
- MIN_FLOAT = 0 - 2 ** 128
26
- MAX_FLOAT = 2 ** 128 - 1
27
- MAX_DOUBLE = 1.7976931348623157e+308
28
- MIN_DOUBLE = 0 - MAX_DOUBLE
29
- BYTE_PATTERN = '^[\\w\\d+\\/=]*$'
30
-
31
12
  class Error < StandardError; end
32
13
  class InvalidTypeError < Error
33
14
  def self.build(type)
@@ -36,125 +17,10 @@ module OpenApi2JsonSchema
36
17
  end
37
18
 
38
19
  def convert_from_file(path)
39
- data = File.read(path)
40
- convert(YAML.load(data))
20
+ convert(OasParser::Definition.resolve(path).raw)
41
21
  end
42
22
 
43
23
  def convert(schema)
44
- convert_schema(schema).tap do |json_schema|
45
- json_schema['$schema'] = 'http://json-schema.org/draft-04/schema#'
46
- end.to_json
47
- end
48
-
49
- def convert_schema(schema)
50
- json_schema = schema.except(*NOT_SUPPORTED)
51
-
52
- schema.slice(*STRUCTS).each do |struct, data|
53
- case data
54
- when Array
55
- if struct == 'allOf'
56
- json_schema[struct] = AttributeHandlers::AllOf.new.call(data)
57
- else
58
- json_schema[struct] = data.map do |item|
59
- convert_schema(item)
60
- end
61
- end
62
- when Hash
63
- if struct == 'discriminator'
64
- json_schema[struct] = AttributeHandlers::Discriminator.new.call(data)
65
- else
66
- json_schema[struct] = convert_schema(data)
67
- end
68
- else
69
- # ignore
70
- end
71
- end
72
-
73
- if schema.key?('properties')
74
- new_properties = convert_properties(schema['properties'])
75
-
76
- if schema['required'].is_a?(Array)
77
- new_required = clean_required(schema['required'], schema['properties'])
78
- json_schema['required'] = new_required if new_required.any?
79
- end
80
-
81
- json_schema['properties'] = new_properties if new_properties.any?
82
- end
83
-
84
- validate_type(schema['type'])
85
-
86
- json_schema.merge!(convert_types(schema))
87
- json_schema.merge!(convert_format(schema))
88
-
89
- json_schema
90
- end
91
-
92
- def validate_type(type)
93
- unless type.nil? || VALID_TYPES.include?(type)
94
- raise InvalidTypeError.build(type)
95
- end
96
- end
97
-
98
- def convert_properties(properties)
99
- return {} unless properties.is_a?(Hash)
100
-
101
- properties.reduce({}) do |result, (key, property)|
102
- next result unless property.is_a?(Hash)
103
-
104
- result.merge(key => convert_schema(property))
105
- end
106
- end
107
-
108
- def convert_types(schema)
109
- if schema['type'] && schema['nullable'] == true
110
- type = [schema['type'], 'null']
111
-
112
- if schema['enum'].is_a?(Array)
113
- {
114
- 'type' => type,
115
- 'enum' => schema['enum'].append(nil)
116
- }
117
- else
118
- { 'type' => type }
119
- end
120
- else
121
- {}
122
- end
123
- end
124
-
125
- def convert_format(schema)
126
- case schema['format']
127
- when 'int32'
128
- {
129
- 'minimum' => [MIN_INT_32, schema['minimum'] || MIN_INT_32].max,
130
- 'maximum' => [MAX_INT_32, schema['maximum'] || MAX_INT_32].min
131
- }
132
- when 'int64'
133
- {
134
- 'minimum' => [MIN_INT_64, schema['minimum'] || MIN_INT_64].max,
135
- 'maximum' => [MAX_INT_64, schema['maximum'] || MAX_INT_64].min
136
- }
137
- when 'float'
138
- {
139
- 'minimum' => [MIN_FLOAT, schema['minimum'] || MIN_FLOAT].max,
140
- 'maximum' => [MAX_FLOAT, schema['maximum'] || MAX_FLOAT].min
141
- }
142
- when 'double'
143
- {
144
- 'minimum' => [MIN_DOUBLE, schema['minimum'] || MIN_DOUBLE].max,
145
- 'maximum' => [MAX_DOUBLE, schema['maximum'] || MAX_DOUBLE].min
146
- }
147
- when 'byte'
148
- { 'pattern' => BYTE_PATTERN }
149
- else
150
- {}
151
- end
152
- end
153
-
154
- def clean_required(required, properties)
155
- required ||= []
156
- properties ||= {}
157
-
158
- properties.slice(*required).keys
24
+ Converter.new.convert(schema)
159
25
  end
160
26
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open_api_2_json_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hieuk09
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-19 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2022-12-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oas_parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.25'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.25'
13
27
  description: 'Due to the OpenAPI v3.0 and JSON Schema discrepancy, you can use this
14
28
  JS library to convert OpenAPI Schema objects to proper JSON Schema. '
15
29
  email:
@@ -27,11 +41,9 @@ files:
27
41
  - Rakefile
28
42
  - bin/console
29
43
  - bin/setup
30
- - lib/attribute_handlers/all_of.rb
31
- - lib/attribute_handlers/discriminator.rb
32
44
  - lib/open_api_2_json_schema.rb
45
+ - lib/open_api_2_json_schema/converter.rb
33
46
  - lib/open_api_2_json_schema/version.rb
34
- - lib/ref_schema_parser.rb
35
47
  homepage: https://github.com/hieuk09/open_api_2_json_schema
36
48
  licenses:
37
49
  - MIT
@@ -46,14 +58,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
46
58
  requirements:
47
59
  - - ">="
48
60
  - !ruby/object:Gem::Version
49
- version: 2.6.0
61
+ version: 2.7.0
50
62
  required_rubygems_version: !ruby/object:Gem::Requirement
51
63
  requirements:
52
64
  - - ">="
53
65
  - !ruby/object:Gem::Version
54
66
  version: '0'
55
67
  requirements: []
56
- rubygems_version: 3.0.8
68
+ rubygems_version: 3.3.7
57
69
  signing_key:
58
70
  specification_version: 4
59
71
  summary: OpenAPI v3.0 schema to JSON Schema draft 4 converter
@@ -1,21 +0,0 @@
1
- require_relative '../ref_schema_parser'
2
-
3
- module OpenApi2JsonSchema
4
- module AttributeHandlers
5
- class AllOf
6
- def call(all_of_schemas)
7
- raise 'allOf schema must be an Array' unless all_of_schemas.is_a?(Array)
8
-
9
- all_of_schemas.each_with_index.map do |schema, index|
10
- raise "Invalid schema: allOf[#{index}]" unless schema.is_a?(Hash)
11
-
12
- if schema['$ref']
13
- OpenApi2JsonSchema::RefSchemaParser.new.call(schema['$ref'])
14
- else
15
- schema
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,18 +0,0 @@
1
- require_relative "../ref_schema_parser"
2
-
3
- module OpenApi2JsonSchema
4
- module AttributeHandlers
5
- class Discriminator
6
- def call(discriminator_schema)
7
- raise "discriminator schema must be a Hash" unless discriminator_schema.is_a?(Hash)
8
-
9
- mapping = discriminator_schema.fetch("mapping")
10
- mapping.each do |key, file_path|
11
- mapping[key] = OpenApi2JsonSchema::RefSchemaParser.new.call(file_path)
12
- end
13
-
14
- discriminator_schema
15
- end
16
- end
17
- end
18
- end
@@ -1,35 +0,0 @@
1
- require 'yaml'
2
-
3
- module OpenApi2JsonSchema
4
- class RefSchemaParser
5
- def call(ref_path)
6
- file_path, fragments = normalize_path(ref_path)
7
- ref_schema = load_file(file_path)
8
- fragment_schema = ref_schema
9
-
10
- if fragments
11
- fragments.split('/').each do |fragment|
12
- if fragment && fragment != '' && fragment_schema[fragment]
13
- fragment_schema = fragment_schema[fragment]
14
- end
15
- end
16
- end
17
-
18
- fragment_schema
19
- end
20
-
21
- private
22
-
23
- def normalize_path(path)
24
- temp_path = path.split('#')
25
- raise 'Invalid reference path' if temp_path.size > 2
26
-
27
- temp_path
28
- end
29
-
30
- def load_file(path)
31
- data = File.read(path)
32
- YAML.safe_load(data)
33
- end
34
- end
35
- end