openapi-sourcetools 0.10.1 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b692fd4b41d1d925fc0a51d94faabe7ee1f5ec8ff26c7ee393e37cafd9b9dffe
4
- data.tar.gz: 19df615a73ec7f006fffd49f1474fb188dbe0f616c49739f0b28c692f7035ec5
3
+ metadata.gz: 830a477c8647ad883e5a6619767f19cfae7c2d9b9baa100b0e10bdd911ef0fc1
4
+ data.tar.gz: 9e4a89d44c344c0099f826bf08c459b2eaa448e4d8b76b982e7ee8b7146199b2
5
5
  SHA512:
6
- metadata.gz: d52cdb9cbdea83bbb3ff510c0b73f61d47eb13049b74e452f90eb597d5a3f697dd414b8f4ca6dd7215d8ea9ac3fd397864c8589365e2a295aa575f2cb3d18c7e
7
- data.tar.gz: 26b623377edc1c7cbf58721d1bc3a6a649d2bd79098c5b30502f7810678a09f27c6f401452f96020f4ddc8ff2a5546fce40c2904b63ad968421e7563730182ee
6
+ metadata.gz: eef01e1c3095d747213533d8ceeb4d0ba4107970b6541632b92b9ffaa0a0202d583ec6934f2af4af3dbf0dff4d0344e053bbf9201d8128cd474406fe11a8b308
7
+ data.tar.gz: 92fcbc4c9128e213ee4d67d7eebe69c5de9f5ef2576a0efdeae33b2f512a786d586e0eebe903fc932b43f59475ecbd780d925263adbd9f5039b113292db8ae97
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021-2024 Ismo Kärkkäinen
1
+ Copyright (c) 2021-2026 Ismo Kärkkäinen
2
2
 
3
3
  The Universal Permissive License (UPL), Version 1.0
4
4
 
@@ -8,30 +8,14 @@ require_relative '../lib/openapi/sourcetools/apiobjects'
8
8
  require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
10
  require 'yaml'
11
- include OpenAPISourceTools
12
11
 
13
12
 
14
- def replace_headers(obj, components)
15
- return unless obj.is_a?(Hash)
16
- obj.each do |k, v|
17
- if k == 'headers'
18
- v.keys.sort!.each do |name|
19
- r = v[name]
20
- next unless r.is_a?(Hash) # Could complain.
21
- next if r.key?('$ref')
22
- v[name] = { '$ref' => components.reference(r) }
23
- end
24
- else
25
- replace_headers(v, components)
26
- end
27
- end
28
- end
29
-
30
13
  def main
31
14
  input_name = nil
32
15
  output_name = nil
33
16
  path = %w[components headers]
34
- components = ApiObjects::Components.new(path, 'Header')
17
+ components = OpenAPISourceTools::ApiObjects::Components.new(path, 'Header')
18
+ replacer = OpenAPISourceTools::ApiObjects::ValueSubValueReplacer.new('headers', components)
35
19
 
36
20
  parser = OptionParser.new do |opts|
37
21
  opts.summary_indent = ' '
@@ -59,15 +43,15 @@ replaces the original with reference.
59
43
  end
60
44
  parser.order!
61
45
 
62
- doc = Common.load_source(input_name)
46
+ doc = OpenAPISourceTools::Common.load_source(input_name)
63
47
  return 2 if doc.nil?
64
48
 
65
49
  components.items = doc.dig(*path) || {}
66
- replace_headers(doc.dig('components', 'responses') || {}, components)
67
- replace_headers(doc.fetch('paths', {}), components)
68
- Common.bury(doc, path, components.items) unless components.items.empty?
50
+ replacer.replace(doc.dig('components', 'responses') || {})
51
+ replacer.replace(doc.fetch('paths', {}))
52
+ OpenAPISourceTools::Common.bury(doc, path, components.items) unless components.items.empty?
69
53
 
70
- Common.dump_result(output_name, doc, 3)
54
+ OpenAPISourceTools::Common.dump_result(output_name, doc, 3)
71
55
  end
72
56
 
73
57
  exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -7,12 +7,12 @@
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
8
8
  require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
- include OpenAPISourceTools
10
+
11
11
 
12
12
  def replace_parameter(p, components)
13
13
  return p unless p.is_a?(Hash) # Could complain.
14
14
  return p if p.key?('$ref')
15
- { '$ref' => components.reference(p) }
15
+ components.to_reference_object(p)
16
16
  end
17
17
 
18
18
  def replace_parameters(obj, components)
@@ -46,7 +46,7 @@ def add_operations_parameters(paths, referenced)
46
46
  # Below that are operations objects.
47
47
  paths.each_value do |item|
48
48
  top_nameloc2ref = nameloc2ref(item['parameters'] || [], referenced)
49
- oos = ApiObjects.operation_objects(item)
49
+ oos = OpenAPISourceTools::ApiObjects.operation_objects(item)
50
50
  oos.each_value do |operation|
51
51
  nl2r = nameloc2ref(operation['parameters'] || [], referenced)
52
52
  params = top_nameloc2ref.merge(nl2r)
@@ -61,7 +61,7 @@ def main
61
61
  output_name = nil
62
62
  add2operations = false
63
63
  path = %w[components parameters]
64
- components = ApiObjects::Components.new(path, 'Parameter')
64
+ components = OpenAPISourceTools::ApiObjects::Components.new(path, 'Parameter')
65
65
 
66
66
  parser = OptionParser.new do |opts|
67
67
  opts.summary_indent = ' '
@@ -97,17 +97,17 @@ feature is intended to simplify code generation.
97
97
  end
98
98
  parser.order!
99
99
 
100
- doc = Common.load_source(input_name)
100
+ doc = OpenAPISourceTools::Common.load_source(input_name)
101
101
  return 2 if doc.nil?
102
102
 
103
103
  components.items = doc.dig(*path) || {}
104
104
  replace_parameters(doc.fetch('paths', {}), components)
105
- Common.bury(doc, path, components.items) unless components.items.empty?
105
+ OpenAPISourceTools::Common.bury(doc, path, components.items) unless components.items.empty?
106
106
  # If nothing has parameters, this adds empty arrays.
107
107
  # Consistency might be desired for code generation templates.
108
108
  add_operations_parameters(doc.fetch('paths', {}), components.items) if add2operations
109
109
 
110
- Common.dump_result(output_name, doc, 3)
110
+ OpenAPISourceTools::Common.dump_result(output_name, doc, 3)
111
111
  end
112
112
 
113
113
  exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -7,30 +7,14 @@
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
8
8
  require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
- include OpenAPISourceTools
11
10
 
12
11
 
13
- def replace_responses(obj, components)
14
- return unless obj.is_a?(Hash)
15
- obj.each do |k, v|
16
- if k == 'responses'
17
- v.keys.sort!.each do |code|
18
- r = v[code]
19
- next unless r.is_a?(Hash) # Could complain.
20
- next if r.key?('$ref')
21
- v[code] = { '$ref' => components.reference(r) }
22
- end
23
- else
24
- replace_responses(v, components)
25
- end
26
- end
27
- end
28
-
29
12
  def main
30
13
  input_name = nil
31
14
  output_name = nil
32
15
  path = %w[components responses]
33
- components = ApiObjects::Components.new(path, 'Response')
16
+ components = OpenAPISourceTools::ApiObjects::Components.new(path, 'Response')
17
+ replacer = OpenAPISourceTools::ApiObjects::ValueSubValueReplacer.new('responses', components)
34
18
 
35
19
  parser = OptionParser.new do |opts|
36
20
  opts.summary_indent = ' '
@@ -58,14 +42,14 @@ replaces the original with reference.
58
42
  end
59
43
  parser.order!
60
44
 
61
- doc = Common.load_source(input_name)
45
+ doc = OpenAPISourceTools::Common.load_source(input_name)
62
46
  return 2 if doc.nil?
63
47
 
64
48
  components.items = doc.dig(*path) || {}
65
- replace_responses(doc.fetch('paths', {}), components)
66
- Common.bury(doc, path, components.items) unless components.items.empty?
49
+ replacer.replace(doc.fetch('paths', {}))
50
+ OpenAPISourceTools::Common.bury(doc, path, components.items) unless components.items.empty?
67
51
 
68
- Common.dump_result(output_name, doc, 3)
52
+ OpenAPISourceTools::Common.dump_result(output_name, doc, 3)
69
53
  end
70
54
 
71
55
  exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -7,7 +7,6 @@
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
8
8
  require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
- include OpenAPISourceTools
11
10
 
12
11
 
13
12
  def remove_subitem(obj, path)
@@ -27,38 +26,45 @@ def replace_inlines(obj, components, top_level_name = nil)
27
26
  return true unless obj.is_a?(Hash)
28
27
  if obj.key?('$ref')
29
28
  components.store_anchor(obj)
30
- # Here would be the place to get rid of other keys if so desired.
31
29
  return true
32
30
  end
33
31
  # Is inlined, process parts recursively.
34
- items = obj['allOf']
35
- items = obj['anyOf'] if items.nil?
36
- items = obj['oneOf'] if items.nil?
37
- # All above need special treatment in code generation templates.
38
- return replace_inlines(items, components) unless items.nil?
39
- t = obj['type']
40
- if t.nil? # Some kind of intermediate-level object.
32
+ %w[allOf anyOf oneOf items prefixItems additionalProperties unevaluatedItems
33
+ unevaluatedProperties if then else not
34
+ ].each do |prop_name|
35
+ return false unless replace_inlines(obj[prop_name], components)
36
+ end
37
+ %w[properties patternProperties dependentSchemas].each do |prop_name|
38
+ props = obj[prop_name]
39
+ next if props.nil?
40
+ props.keys.sort!.each do |name|
41
+ return false unless replace_inlines(props[name], components)
42
+ end
43
+ end
44
+ looks_like_type = false
45
+ # required is omitted since it is in schema and in parameters.
46
+ %w[type items prefixItems properties patternProperties additionalProperties
47
+ unevaluatedItems unevaluatedProperties enum const minimum maximum multipleOf
48
+ exclusiveMinimum exclusiveMaximum maxLength minLength pattern maxItems minItems
49
+ uniqueItems maxContains minContains maxProperties minProperties propertyNames
50
+ dependentRequired format contentEncoding contentMediaType contentSchema
51
+ ].each do |kw|
52
+ if obj.key?(kw)
53
+ looks_like_type = true
54
+ break
55
+ end
56
+ end
57
+ unless looks_like_type
58
+ # Some kind of intermediate-level object.
41
59
  (obj.keys.sort! { |a, b| a.to_s <=> b.to_s }).each do |key|
42
60
  next if key == 'securitySchemes'
43
61
  return false unless replace_inlines(obj[key], components)
44
62
  end
45
63
  return true
46
64
  end
47
- case t
48
- when 'array'
49
- return false unless replace_inlines(obj['items'], components)
50
- when 'object'
51
- %w[properties patternProperties].each do |prop_name|
52
- props = obj.fetch(prop_name, {})
53
- props.keys.sort!.each do |name|
54
- return false unless replace_inlines(props[name], components)
55
- end
56
- end
57
- return false unless replace_inlines(obj['additionalProperties'], components)
58
- end
59
65
  r = components.ref_string(top_level_name) || components.reference(obj)
60
66
  components.store_anchor(obj, r)
61
- obj.replace({ '$ref' => r }) if top_level_name.nil?
67
+ components.to_reference_object(obj, r) if top_level_name.nil?
62
68
  true
63
69
  end
64
70
 
@@ -82,7 +88,7 @@ def main
82
88
  input_name = nil
83
89
  output_name = nil
84
90
  path = %w[components schemas]
85
- components = ApiObjects::Components.new(path, 'Schema')
91
+ components = OpenAPISourceTools::ApiObjects::Components.new(path, 'Schema')
86
92
 
87
93
  parser = OptionParser.new do |opts|
88
94
  opts.summary_indent = ' '
@@ -109,7 +115,7 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
109
115
  end
110
116
  parser.order!
111
117
 
112
- doc = Common.load_source(input_name)
118
+ doc = OpenAPISourceTools::Common.load_source(input_name)
113
119
  return 2 if doc.nil?
114
120
 
115
121
  # Find schema object and remove it temporarily to prevent being
@@ -122,10 +128,10 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
122
128
  end
123
129
  return 4 unless replace_inlines(doc, components)
124
130
  components.alter_anchors
125
- Common.bury(doc, path, components.items) unless components.items.empty?
131
+ OpenAPISourceTools::Common.bury(doc, path, components.items) unless components.items.empty?
126
132
  replace_anchor_refs(doc, components)
127
133
 
128
- Common.dump_result(output_name, doc, 3)
134
+ OpenAPISourceTools::Common.dump_result(output_name, doc, 3)
129
135
  end
130
136
 
131
137
  exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright © 2026 Ismo Kärkkäinen
5
+ # Licensed under Universal Permissive License. See LICENSE.txt.
6
+
7
+ require_relative '../lib/openapi/sourcetools/apiobjects'
8
+ require_relative '../lib/openapi/sourcetools/common'
9
+ require 'optparse'
10
+ require 'yaml'
11
+
12
+
13
+ def main
14
+ input_name = nil
15
+ output_name = nil
16
+ retainer = OpenAPISourceTools::ApiObjects::ValueRetainer.new('$ref')
17
+
18
+ parser = OptionParser.new do |opts|
19
+ opts.summary_indent = ' '
20
+ opts.summary_width = 26
21
+ opts.banner = 'Usage: openapi-clearrefs [options]'
22
+ opts.separator ''
23
+ opts.separator 'Options:'
24
+ opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
25
+ input_name = f
26
+ end
27
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
28
+ output_name = f
29
+ end
30
+ opts.on('-h', '--help', 'Print this help and exit.') do
31
+ $stdout.puts %(#{opts}
32
+ Loads API document in OpenAPI format and from objects with '$ref' key, deletes
33
+ all other keys.
34
+ )
35
+ exit 0
36
+ end
37
+ end
38
+ parser.order!
39
+
40
+ doc = OpenAPISourceTools::Common.load_source(input_name)
41
+ return 2 if doc.nil?
42
+ retainer.process(doc)
43
+ OpenAPISourceTools::Common.dump_result(output_name, doc, 3)
44
+ end
45
+
46
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)