openapi-sourcetools 0.9.2 → 0.10.1

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: 625fca7f208b4a1e4c041265a1b5aba0d0685bbda6dcdd831af5db701aff4de0
4
- data.tar.gz: bfe98b2ef3fa42ca2edccdf7b57eda9d653637e23a6b6325e41297e00100e1b6
3
+ metadata.gz: b692fd4b41d1d925fc0a51d94faabe7ee1f5ec8ff26c7ee393e37cafd9b9dffe
4
+ data.tar.gz: 19df615a73ec7f006fffd49f1474fb188dbe0f616c49739f0b28c692f7035ec5
5
5
  SHA512:
6
- metadata.gz: 7895833d61f1954c4d6b056e2b350c72d767c7ec031222bcec9f8aa2820836eced6e5432f14465f567967bce674006e699bc65180d73951a1ff63b7d40c5fc57
7
- data.tar.gz: b86546e0d0cf07d19ba082e43f29b4f0c35bef6d05f6e678695f7d821bf38e1e761eaa95ecf10a7c0a00e0a41710fdf088eba13b8c3bd9f4b46a7bac7db49f49
6
+ metadata.gz: d52cdb9cbdea83bbb3ff510c0b73f61d47eb13049b74e452f90eb597d5a3f697dd414b8f4ca6dd7215d8ea9ac3fd397864c8589365e2a295aa575f2cb3d18c7e
7
+ data.tar.gz: 26b623377edc1c7cbf58721d1bc3a6a649d2bd79098c5b30502f7810678a09f27c6f401452f96020f4ddc8ff2a5546fce40c2904b63ad968421e7563730182ee
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024-2025 Ismo Kärkkäinen
4
+ # Copyright © 2024-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -70,4 +70,4 @@ replaces the original with reference.
70
70
  Common.dump_result(output_name, doc, 3)
71
71
  end
72
72
 
73
- exit(main) if defined?($unit_test).nil?
73
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024-2025 Ismo Kärkkäinen
4
+ # Copyright © 2024-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -87,7 +87,8 @@ replaces the original with reference.
87
87
 
88
88
  Optionally adds parameters to all operations objects by copying parameters
89
89
  from path item and replacing ones referred to in operations object. The
90
- path item parameters are left in place. Even empty arrays are added.
90
+ path item parameters are left in place. Even empty arrays are added. This
91
+ feature is intended to simplify code generation.
91
92
 
92
93
  #{components.help}
93
94
  )
@@ -109,4 +110,4 @@ path item parameters are left in place. Even empty arrays are added.
109
110
  Common.dump_result(output_name, doc, 3)
110
111
  end
111
112
 
112
- exit(main) unless defined?($unit_test)
113
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024-2025 Ismo Kärkkäinen
4
+ # Copyright © 2024-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -68,4 +68,4 @@ replaces the original with reference.
68
68
  Common.dump_result(output_name, doc, 3)
69
69
  end
70
70
 
71
- exit(main) if defined?($unit_test).nil?
71
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024-2025 Ismo Kärkkäinen
4
+ # Copyright © 2024-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -128,4 +128,4 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
128
128
  Common.dump_result(output_name, doc, 3)
129
129
  end
130
130
 
131
- exit(main) if defined?($unit_test).nil?
131
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2025 Ismo Kärkkäinen
4
+ # Copyright © 2025-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -105,4 +105,4 @@ replaces the original with reference.
105
105
  Common.dump_result(output_name, doc, 3)
106
106
  end
107
107
 
108
- exit(main) unless defined?($unit_test)
108
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024-2025 Ismo Kärkkäinen
4
+ # Copyright © 2024-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -214,4 +214,4 @@ input, as inlined types in requests, for example, are ignored.
214
214
  Common.dump_result(output_name, YAML.dump(report, line_width: 80), 3)
215
215
  end
216
216
 
217
- exit(main) if defined?($unit_test).nil?
217
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021-2025 Ismo Kärkkäinen
4
+ # Copyright © 2021-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -73,4 +73,4 @@ into each path object matching count as "x-openapi-sourcetools-freq".
73
73
  Common.dump_result(output_name, doc, 3)
74
74
  end
75
75
 
76
- exit(main) unless defined?($unit_test)
76
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
data/bin/openapi-generate CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021-2025 Ismo Kärkkäinen
4
+ # Copyright © 2021-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/common'
@@ -58,4 +58,4 @@ After all generators have loaded succesfully, tasks are run.
58
58
  gen.run
59
59
  end
60
60
 
61
- exit(main) unless defined?($unit_test)
61
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
data/bin/openapi-merge CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021-2025 Ismo Kärkkäinen
4
+ # Copyright © 2021-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/common'
@@ -34,18 +34,23 @@ def add_missing(existing, incoming, field)
34
34
  end
35
35
  end
36
36
 
37
- def add_undefined(merged, incoming, filename, path, max_depths)
37
+ def add_undefined(merged, incoming, filename, path, max_depths, firsts, lasts)
38
38
  incoming.each_pair do |key, value|
39
39
  unless merged.key? key
40
40
  merged[key] = value
41
41
  next
42
42
  end
43
+ next if firsts.member?(key) # When key appears the second or more times.
44
+ if lasts.member?(key) # If last is kept, always copy value.
45
+ merged[key] = value
46
+ next
47
+ end
43
48
  m = merged[key]
44
49
  raise_se("Path #{path_combo(path, false)} merged type #{m.class} differs from type #{value.class} in #{filename}") unless m.instance_of?(value.class)
45
50
  raise_se("Re-definition of #{key} #{path_combo(path)} in #{filename}") if too_deep(path, max_depths)
46
51
  if m.is_a? Hash # paths or similar
47
52
  path.push key
48
- add_undefined(m, value, filename, path, max_depths)
53
+ add_undefined(m, value, filename, path, max_depths, firsts, lasts)
49
54
  path.pop
50
55
  elsif m.is_a? Array
51
56
  case key
@@ -121,6 +126,8 @@ end
121
126
  def main
122
127
  output_file = nil
123
128
  keep = false
129
+ firsts = Set.new
130
+ lasts = Set.new
124
131
 
125
132
  parser = OptionParser.new do |opts|
126
133
  opts.summary_indent = ' '
@@ -137,6 +144,12 @@ def main
137
144
  opts.on('-p', '--prune', 'Prune all unreferenced objects under components (default).') do
138
145
  keep = false
139
146
  end
147
+ opts.on('-f', '--first KEY', 'Keep only the first occurrence of top-level KEY.') do |key|
148
+ firsts.add(key)
149
+ end
150
+ opts.on('-l', '--last KEY', 'Keep only the last occurrence of top-level KEY.') do |key|
151
+ lasts.add(key)
152
+ end
140
153
  opts.on('-h', '--help', 'Print this help and exit.') do
141
154
  $stdout.puts %(#{opts}
142
155
 
@@ -148,20 +161,27 @@ allowed only to append to the merged document, not re-define anything in it.
148
161
  end
149
162
  parser.order!
150
163
 
151
- max_depths = Hash.new(0)
152
- max_depths['openapi'] = 1
153
- max_depths['info'] = 1
154
- max_depths['servers'] = 1
155
- max_depths['paths'] = 2 # Allows get, post, etc. from different files.
156
- max_depths['webhooks'] = 2
157
- max_depths['components'] = 2
158
- max_depths['security'] = 1
159
- max_depths['tags'] = 1
164
+ overlap = firsts & lasts
165
+ unless overlap.empty?
166
+ return Common.aargh("Key can only be in first or last, not both: #{overlap.to_a.sort!.join(' ')}", 1)
167
+ end
168
+
169
+ max_depths = Hash.new(0).merge!({
170
+ 'openapi' => 1,
171
+ 'info' => 1,
172
+ 'servers' => 1,
173
+ 'paths' => 2, # Allows get, post, etc. from different files.
174
+ 'webhooks' => 2,
175
+ 'components' => 2,
176
+ 'security' => 1,
177
+ 'tags' => 1
178
+ })
179
+
160
180
  merged = {}
161
181
  ARGV.each do |filename|
162
182
  s = Common.load_source(filename)
163
183
  return 2 if s.nil?
164
- add_undefined(merged, s, filename, [], max_depths)
184
+ add_undefined(merged, s, filename, [], max_depths, firsts, lasts)
165
185
  rescue StandardError => e
166
186
  return Common.aargh(e.to_s, 4)
167
187
  end
@@ -171,4 +191,4 @@ allowed only to append to the merged document, not re-define anything in it.
171
191
  Common.dump_result(output_file, merged, 3)
172
192
  end
173
193
 
174
- exit(main) if defined?($unit_test).nil?
194
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024-2025 Ismo Kärkkäinen
4
+ # Copyright © 2024-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/common'
@@ -121,4 +121,4 @@ STR and PREFIX are expected to be parts of a path surrounded by /.
121
121
  Common.dump_result(output_name, doc, 3)
122
122
  end
123
123
 
124
- exit(main) if defined?($unit_test).nil?
124
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2025 Ismo Kärkkäinen
4
+ # Copyright © 2025-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/common'
@@ -163,4 +163,4 @@ strings for testing generated code.
163
163
  Common.dump_result(output_name, ex, 3)
164
164
  end
165
165
 
166
- exit(main) if defined?($unit_test).nil?
166
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021-2025 Ismo Kärkkäinen
4
+ # Copyright © 2021-2026 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/openapi/sourcetools/apiobjects'
@@ -70,4 +70,4 @@ key. Checks for paths that may be ambiguous.
70
70
  Common.dump_result(output_name, doc, 3)
71
71
  end
72
72
 
73
- exit(main) unless defined?($unit_test)
73
+ exit(main) if File.basename(__FILE__) == File.basename($PROGRAM_NAME)
@@ -251,5 +251,83 @@ module OpenAPISourceTools
251
251
  @servers <=> other.servers
252
252
  end
253
253
  end
254
+
255
+ # Simple holder if security scheme objects.
256
+ class SecurityScheme
257
+ include Comparable
258
+
259
+ attr_reader :name, :scheme
260
+
261
+ def initialize(name, scheme)
262
+ @name = name
263
+ @scheme = scheme
264
+ end
265
+
266
+ def <=>(other)
267
+ @name <=> other.name
268
+ end
269
+ end
270
+
271
+ # Simple holder that determines where parameters are placed.
272
+ class SecurityRequirementObject
273
+ include Comparable
274
+
275
+ attr_reader :reqs, :extras
276
+
277
+ def initialize(reqs, schemes)
278
+ @reqs = reqs
279
+ @extras = {}
280
+ @reqs.each do |name, scopes|
281
+ scheme = schemes[name].scheme
282
+ case scheme['type']
283
+ when 'apiKey'
284
+ if scheme['in'] == 'header'
285
+ h = @extras[:headers] || {}
286
+ h[scheme['name']] = scopes
287
+ @extras[:headers] = h
288
+ elsif scheme['in'] == 'query'
289
+ q = @extras[:query] || {}
290
+ q[scheme['name']] = scopes
291
+ @extras[:query] = q
292
+ end
293
+ when 'http', 'oauth2', 'openIdConnect'
294
+ h = @extras[:headers] || {}
295
+ h['authorization'] = scopes
296
+ @extras[:headers] = h
297
+ else
298
+ raise "Unknown security type: #{scheme['type']} for #{name}"
299
+ end
300
+ end
301
+ end
302
+
303
+ def <=>(other)
304
+ d = @reqs.size <=> other.reqs.size
305
+ return d unless d.zero?
306
+ d = @reqs.keys.sort! <=> other.reqs.keys.sort!
307
+ return d unless d.zero?
308
+ @reqs.keys.sort!.each do |name|
309
+ d = @reqs[name].sort <=> other.reqs[name].sort
310
+ return d unless d.zero?
311
+ end
312
+ 0
313
+ end
314
+ end
315
+
316
+ # Available possibilities.
317
+ class SecurityAlternatives
318
+ include Comparable
319
+
320
+ attr_reader :sros, :schemes
321
+ attr_accessor :set_id
322
+
323
+ def initialize(sros, schemes)
324
+ @sros = sros
325
+ @schemes = schemes
326
+ end
327
+
328
+ def <=>(other)
329
+ @sros.sort <=> other.sros.sort
330
+ end
331
+ end
254
332
  end
255
333
  end
@@ -4,6 +4,7 @@
4
4
  # Copyright © 2024-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
+ require 'fileutils'
7
8
  require_relative 'common'
8
9
  require_relative 'loaders'
9
10
  require_relative 'gen'
@@ -1,21 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright © 2024-2025 Ismo Kärkkäinen
3
+ # Copyright © 2024-2026 Ismo Kärkkäinen
4
4
  # Licensed under Universal Permissive License. See LICENSE.txt.
5
5
 
6
+ require 'json'
7
+ require 'yaml'
8
+
6
9
 
7
10
  module OpenAPISourceTools
8
11
  # Output configuration settings for easy storage.
9
12
  # You can have it in configuration and pass hash to initialize.
10
13
  class OutputConfiguration
11
14
  attr_reader :indent_character, :indent_step
12
- attr_reader :tab, :tab_replaces_count
15
+ attr_reader :tab, :tab_replaces_count, :prettified_json
13
16
 
14
17
  def initialize(cfg = {})
15
18
  @indent_character = cfg['indent_character'] || ' '
16
19
  @indent_step = cfg['indent_step'] || 4
17
20
  @tab = cfg['tab'] || "\t"
18
21
  @tab_replaces_count = cfg['tab_replaces_count'] || 0
22
+ @prettified_json = {
23
+ array_nl: "\n",
24
+ object_nl: "\n",
25
+ indent: ' ',
26
+ space: ' '
27
+ }.merge(cfg['prettified_json'] || {})
19
28
  end
20
29
  end
21
30
 
@@ -81,5 +90,17 @@ module OpenAPISourceTools
81
90
  @last_indent = indent
82
91
  indented.join(separator)
83
92
  end
93
+
94
+ def yaml(something)
95
+ YAML.dump(something)
96
+ end
97
+
98
+ def json(something)
99
+ JSON.generate(something)
100
+ end
101
+
102
+ def pretty_json(something)
103
+ JSON.generate(something, @config.prettified_json)
104
+ end
84
105
  end
85
106
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright © 2025 Ismo Kärkkäinen
3
+ # Copyright © 2025-2026 Ismo Kärkkäinen
4
4
  # Licensed under Universal Permissive License. See LICENSE.txt.
5
5
 
6
6
  module OpenAPISourceTools
7
7
  NAME = 'openapi-sourcetools'
8
- VERSION = '0.9.2'
8
+ VERSION = '0.10.1'
9
9
 
10
10
  def self.info(separator = ': ')
11
11
  "#{NAME}#{separator}#{VERSION}"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi-sourcetools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismo Kärkkäinen
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-05-07 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: deep_merge
@@ -82,7 +81,6 @@ licenses:
82
81
  - UPL-1.0
83
82
  metadata:
84
83
  rubygems_mfa_required: 'true'
85
- post_install_message:
86
84
  rdoc_options: []
87
85
  require_paths:
88
86
  - lib
@@ -97,8 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
95
  - !ruby/object:Gem::Version
98
96
  version: '0'
99
97
  requirements: []
100
- rubygems_version: 3.4.19
101
- signing_key:
98
+ rubygems_version: 3.6.9
102
99
  specification_version: 4
103
100
  summary: Tools for creating source code from API specification.
104
101
  test_files: []