openapi-sourcetools 0.5.0 → 0.6.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: 23e0cd1aefa69559d35171e477d8b749ec61251b67c51040b1130ce48fb57725
4
- data.tar.gz: 1fa4a40b88aa863d3eed153db455aed0bd4d9b9b88a4aa9ca8f92874e07613f5
3
+ metadata.gz: 9320a1d6d4202c453fb7065f00bc534206b1c780560ae443cd30293f27827595
4
+ data.tar.gz: af45eabe9a8f392c705398957cf276acb39923655207ffda12ee8d93e1c072a0
5
5
  SHA512:
6
- metadata.gz: c56924c74979a016aeb8789bd7071f0d54e3c1de746c7bd92d9166cf0a03001f76f5b7b772d128f3e278bbc7835f52f7f139e4c71fe814032c49a252c24f6ece
7
- data.tar.gz: f7c87b497a0c154d99b7cbd33da06cce91e9a7aa8d6b8d72bc6b64f86a50fa1f93a93a0e96f922dab1fdb0c189989cd197f48d12ee5399254fe78120e286ddd4
6
+ metadata.gz: 1f81cae3adb06d42d3bf5361615a0a21ca42346d08b1f8b83462116668d2ad61ec05ac707e723d910bbe55eb29699129ba13570b44504581e92597242ab3d810
7
+ data.tar.gz: 656959f866321cd68814fed2ef1c9121fe1db36674cb7fbd49f9f2a652e5f43a29d6b1d491a2197278577084d1328e01f99fd1eff8fca1c7ef7d6299ed512b17
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright © 2024 Ismo Kärkkäinen
5
+ # Licensed under Universal Permissive License. See LICENSE.txt.
6
+
7
+ require_relative '../lib/apiobjects'
8
+ require_relative '../lib/common'
9
+ require 'optparse'
10
+ require 'yaml'
11
+
12
+ def replace_parameter(p, components)
13
+ return p unless p.is_a?(Hash) # Could complain.
14
+ return p if p.key?('$ref')
15
+ { '$ref' => components.reference(p) }
16
+ end
17
+
18
+ def replace_parameters(obj, components)
19
+ return unless obj.is_a?(Hash)
20
+ obj.each do |k, v|
21
+ if k == 'parameters'
22
+ obj[k] = v.map { |p| replace_parameter(p, components) }
23
+ else
24
+ replace_parameters(v, components)
25
+ end
26
+ end
27
+ end
28
+
29
+ def main
30
+ input_name = nil
31
+ output_name = nil
32
+ path = %w[components parameters]
33
+ components = Components.new(path, 'Parameter')
34
+
35
+ ENV['POSIXLY_CORRECT'] = '1'
36
+ parser = OptionParser.new do |opts|
37
+ opts.summary_indent = ' '
38
+ opts.summary_width = 26
39
+ opts.banner = 'Usage: openapi-addparameters [options]'
40
+ opts.separator ''
41
+ opts.separator 'Options:'
42
+ opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
43
+ input_name = f
44
+ end
45
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout .') do |f|
46
+ output_name = f
47
+ end
48
+ components.add_options(opts)
49
+ opts.on('-h', '--help', 'Print this help and exit.') do
50
+ $stdout.puts %(#{opts}
51
+
52
+ Loads API document in OpenAPI format and moves parameters under components and
53
+ replaces the original with reference.
54
+
55
+ #{components.help}
56
+ )
57
+ exit 0
58
+ end
59
+ end
60
+ parser.parse!
61
+
62
+ doc = load_source(input_name)
63
+ return 2 if doc.nil?
64
+
65
+ components.items = doc.dig(*path) || {}
66
+ replace_parameters(doc.fetch('paths', {}), components)
67
+ bury(doc, path, components.items) unless components.items.empty?
68
+
69
+ dump_result(output_name, YAML.dump(doc, line_width: 1_000_000), 3)
70
+ end
71
+
72
+ exit(main) if defined?($unit_test).nil?
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright © 2021-2024 Ismo Kärkkäinen
5
+ # Licensed under Universal Permissive License. See LICENSE.txt.
6
+
7
+ require_relative '../lib/common'
8
+ require_relative '../lib/loaders'
9
+ require_relative '../lib/gen'
10
+ require_relative '../lib/generate'
11
+ require 'optparse'
12
+ require 'yaml'
13
+
14
+
15
+ def main
16
+ input_name = nil
17
+ output_dir = nil
18
+
19
+ ENV['POSIXLY_CORRECT'] = '1'
20
+ parser = OptionParser.new do |opts|
21
+ opts.summary_indent = ' '
22
+ opts.summary_width = 26
23
+ opts.banner = 'Usage: openapi-generate [options] generator-names...'
24
+ opts.separator ''
25
+ opts.separator 'Options:'
26
+ opts.on('-i', '--input FILE', 'Read processed API from FILE, not stdin.') do |f|
27
+ input_name = f
28
+ end
29
+ opts.on('-o', '--outdir DIR', 'Output directory.') do |d|
30
+ output_dir = d
31
+ end
32
+ opts.on('-h', '--help', 'Print this help and exit.') do
33
+ $stdout.puts %(#{opts}
34
+ Loads API document in OpenAPI format and generator names. Built-in generator
35
+ loaders accept the following:
36
+ #{Loaders.document.strip}
37
+
38
+ During load each generator can add and modify tasks via Gen module:
39
+ #{Gen.document.strip}
40
+
41
+ After all generators have loaded succesfully, tasks are run.
42
+ )
43
+ exit 0
44
+ end
45
+ end
46
+ parser.parse!
47
+
48
+ return aargh('Generator names must be given.', 1) if ARGV.empty?
49
+
50
+ a = load_source(input_name)
51
+ return 2 if a.nil?
52
+ return aargh("Not a directory: #{output_dir}", 3) unless File.directory?(output_dir)
53
+ gen = Generator.new(a, input_name, output_dir)
54
+ ec = gen.load(ARGV)
55
+ return ec unless ec.zero?
56
+ gen.run
57
+ end
58
+
59
+ exit(main) if defined?($unit_test).nil?
data/lib/apiobjects.rb CHANGED
@@ -85,11 +85,7 @@ class PathOperation
85
85
  attr_accessor :summary, :description
86
86
  end
87
87
 
88
- # Should mapping JSON schema types to native types be a separate step?
89
- # Just add x-openapi-sourcetools-native: nativetype
90
- # Separate program that can pipe modified spec out to code generation?
91
-
92
- # JSON schema is way too complex to simplify here. One could have a convenience
88
+ # One could have a convenience
93
89
  # method that determines how many bytes the value needs, and if it needs to be
94
90
  # signed.
95
91
 
@@ -302,3 +298,36 @@ class SchemaOrderer
302
298
  chosen
303
299
  end
304
300
  end
301
+
302
+ class HeaderOrderer
303
+ end
304
+
305
+ class ResponseOrderer
306
+ end
307
+
308
+ class PathOrderer
309
+ end
310
+
311
+ class Tasker
312
+ attr_reader :doc
313
+ def initialize(doc)
314
+ @doc = doc
315
+ end
316
+ end
317
+
318
+ class SchemaTasker < Tasker
319
+ # initialize with doc
320
+ # Orderer set somehow.
321
+ # Method ot create one task per schema.
322
+ # Method to create one task for all schemas.
323
+ end
324
+
325
+ class HeaderTasker < Tasker
326
+ # initialize with doc
327
+ # Orderer set somehow.
328
+ # Method ot create one task per schema.
329
+ # Method to create one task for all schemas.
330
+ end
331
+
332
+
333
+
data/lib/common.rb CHANGED
@@ -21,7 +21,7 @@ def bury(doc, path, value)
21
21
  doc[path.last] = value
22
22
  end
23
23
 
24
- module Output
24
+ module Out
25
25
  attr_reader :count
26
26
 
27
27
  def put(message)
data/lib/gen.rb ADDED
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright © 2024 Ismo Kärkkäinen
4
+ # Licensed under Universal Permissive License. See LICENSE.txt.
5
+
6
+ require_relative 'task'
7
+ require_relative 'helper'
8
+
9
+
10
+ module Gen
11
+ def self.mod_attr_reader(symbol, docstr = nil)
12
+ attr_reader(symbol)
13
+ module_function(symbol)
14
+ return if docstr.nil?
15
+ @docsrc = [] unless Gen.instance_variable_defined?('@docsrc')
16
+ @docsrc.push("- #{symbol.to_s} : #{docstr}")
17
+ end
18
+
19
+ def self.mod_attr_accessor(symbol, docstr = nil)
20
+ attr_accessor(symbol)
21
+ module_function(symbol)
22
+ s = symbol.to_s
23
+ module_function((s + '=').to_sym)
24
+ return if docstr.nil?
25
+ @docsrc = [] unless Gen.instance_variable_defined?('@docsrc')
26
+ @docsrc.push("- #{s} : #{docstr}")
27
+ end
28
+
29
+ mod_attr_reader :doc, 'OpenAPI document.'
30
+ mod_attr_reader :outdir, 'Output directory name.'
31
+ mod_attr_accessor :in_name, 'OpenAPI document name, nil if stdin.'
32
+ mod_attr_accessor :in_basename, 'OpenAPI document basename, nil if stdin.'
33
+ mod_attr_accessor :tasks, 'Tasks array.'
34
+ mod_attr_accessor :g, 'Hash for storing values visible to all tasks.'
35
+ mod_attr_accessor :a, 'Intended for instance with defined attributes.'
36
+ mod_attr_accessor :h, 'Instance of class with helper methods.'
37
+ mod_attr_accessor :t, 'Current task instance.'
38
+ mod_attr_accessor :task_index, 'Current task index.'
39
+ mod_attr_accessor :loaders, 'Array of generator loader methods.'
40
+
41
+ def self.setup(document_content, input_name, output_directory)
42
+ @doc = document_content
43
+ @outdir = output_directory
44
+ if input_name.nil?
45
+ @in_name = nil
46
+ @in_basename = nil
47
+ else
48
+ @in_name = File.basename(input_name)
49
+ @in_basename = File.basename(input_name, '.*')
50
+ end
51
+ @tasks = []
52
+ @g = {}
53
+ @a = nil
54
+ @h = nil
55
+ @t = nil
56
+ @task_index = nil
57
+ @loaders = []
58
+ add_task(task: HelperTask.new)
59
+ end
60
+
61
+ def self.add_task(task:, name: nil, executable: false, x: nil)
62
+ @tasks.push(task)
63
+ # Since this method allows the user to pass their own task type instance,
64
+ # assign optional values with defaults only when clearly given.
65
+ @tasks.last.name = name unless name.nil?
66
+ @tasks.last.executable = executable unless executable == false
67
+ @tasks.last.x = x unless x.nil?
68
+ end
69
+
70
+ def self.add_write_content(name:, content:, executable: false)
71
+ add_task(task: WriteTask.new(name, content, executable))
72
+ end
73
+
74
+ def self.add(source:, template: nil, template_name: nil, name: nil, executable: false, x: nil)
75
+ add_task(task: Task.new(source, template, template_name), name: name, executable: executable, x: x)
76
+ end
77
+
78
+ def self.document
79
+ @docsrc.join("\n") + %(
80
+ - add_task(task:, name: nil, executable: false, x: nil) : Adds task object.
81
+ - add_write_content(name:, content:, executable: false) : Add file write task.
82
+ - add(source:, template: nil, template_name: nil, name: nil,
83
+ executable: false, x: nil) :
84
+ Adds template task with source as object to process.
85
+ )
86
+ end
87
+ end
data/lib/generate.rb ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright © 2024 Ismo Kärkkäinen
5
+ # Licensed under Universal Permissive License. See LICENSE.txt.
6
+
7
+ require_relative 'common'
8
+ require_relative 'loaders'
9
+ require_relative 'gen'
10
+
11
+ def executable_bits_on(mode)
12
+ mode = mode.to_s(8).split('')
13
+ mode.size.times do |k|
14
+ m = mode[k].to_i(8)
15
+ # Applies to Unix-likes. Other system, check and handle.
16
+ m += 1 unless 3 < mode.size - k || m.zero? || m % 2 == 1
17
+ mode[k] = m
18
+ end
19
+ m = 0
20
+ mode.each do |v|
21
+ m = 8 * m + v
22
+ end
23
+ m
24
+ end
25
+
26
+ class Generator
27
+ def initialize(document_content, input_name, output_directory)
28
+ Gen.setup(document_content, input_name, output_directory)
29
+ Gen.loaders = Loaders.loaders
30
+ end
31
+
32
+ def context_binding
33
+ binding
34
+ end
35
+
36
+ def load(generator_names)
37
+ generator_names.each do |name|
38
+ idx = Gen.loaders.index { |loader| loader.call(name) }
39
+ return aargh("No loader could handle #{name}", 2) if idx.nil?
40
+ end
41
+ 0
42
+ rescue StandardError => e
43
+ aargh(e.to_s, 2)
44
+ end
45
+
46
+ def generate(t)
47
+ t.generate(context_binding)
48
+ rescue Exception => e
49
+ aargh(e.to_s, 4)
50
+ end
51
+
52
+ def output_name(t, index)
53
+ name = t.output_name
54
+ name = "#{index}.txt" if name.nil?
55
+ File.join(Gen.outdir, name)
56
+ end
57
+
58
+ def save(name, contents, executable)
59
+ f = File.new(name, File::WRONLY | File::CREAT | File::TRUNC)
60
+ s = executable ? f.stat : nil
61
+ f.write(contents)
62
+ f.close
63
+ return unless executable
64
+ mode = executable_bits_on(s.mode)
65
+ File.chmod(mode, name) unless mode == s.mode
66
+ end
67
+
68
+ def run
69
+ # This allows tasks to be added while processing.
70
+ # Not intended to be done but might prove handy.
71
+ # Also exposes current task index in case new task is added in the middle.
72
+ Gen.task_index = 0
73
+ while Gen.task_index < Gen.tasks.size
74
+ Gen.t = Gen.tasks[Gen.task_index]
75
+ out = generate(Gen.t)
76
+ Gen.task_index += 1
77
+ next if Gen.t.discard # Check first to ignore result if no output.
78
+ return out if out.is_a?(Integer)
79
+ next if out.empty? # Allows no output but return value still checked.
80
+ name = output_name(Gen.t, Gen.task_index - 1)
81
+ begin
82
+ save(name, out, Gen.t.executable)
83
+ rescue StandardError => e
84
+ return aargh("Error writing output file: #{name}\n#{e}", 3)
85
+ end
86
+ end
87
+ 0
88
+ end
89
+ end
data/lib/helper.rb ADDED
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright © 2024 Ismo Kärkkäinen
4
+ # Licensed under Universal Permissive License. See LICENSE.txt.
5
+
6
+ require_relative 'task'
7
+
8
+
9
+ class Helper
10
+ attr_reader :doc, :parents
11
+ attr_accessor :parent_parameters
12
+
13
+ # Stores the nearesh Hash for each Hash.
14
+ def store_parents(obj, parent = nil)
15
+ if obj.is_a?(Hash)
16
+ @parents[obj.object_id] = parent
17
+ obj.each do |k, v|
18
+ store_parents(v, obj)
19
+ end
20
+ elsif obj.is_a?(Array)
21
+ obj.each do |v|
22
+ store_parents(v, parent)
23
+ end
24
+ end
25
+ end
26
+
27
+ def initialize(doc)
28
+ @doc = doc
29
+ # For each hash in doc, set parent?
30
+ # Build an object_id to parent object mapping and use parent method?
31
+ @parents = {}
32
+ store_parents(@doc)
33
+ end
34
+
35
+ def parent(object)
36
+ @parents[object.object_id]
37
+ end
38
+
39
+ COMPONENTS = '#/components/'
40
+
41
+ def category_and_name(ref_or_obj)
42
+ ref = ref_or_obj.is_a?(Hash) ? ref_or_obj['$ref'] : ref_or_obj
43
+ return nil unless ref.is_a?(String)
44
+ return nil unless ref.start_with?(Helper::COMPONENTS)
45
+ idx = ref.index('/', Helper::COMPONENTS.size)
46
+ return nil if idx.nil?
47
+ category = ref[Helper::COMPONENTS.size...idx]
48
+ [ category, ref[(idx + 1)...ref.size] ]
49
+ end
50
+
51
+ def dereference(ref_or_obj)
52
+ cn = category_and_name(ref_or_obj)
53
+ return nil if cn.nil?
54
+ cs = @doc.dig('components', cn.first) || {}
55
+ cs[cn.last]
56
+ end
57
+
58
+ def basename(ref_or_obj)
59
+ cn = category_and_name(ref_or_obj)
60
+ return nil if cn.nil?
61
+ cn.last
62
+ end
63
+
64
+ def parameters(operation_object, empty_unless_local = false)
65
+ return [] if empty_unless_local && !operation_object.key?('parameters')
66
+ cps = @doc.dig('components', 'parameters') || {}
67
+ uniqs = {}
68
+ path_item_object = parent(operation_object)
69
+ [path_item_object, operation_object].each do |p|
70
+ p.fetch('parameters', []).each do |param|
71
+ r = basename(param)
72
+ r = cps[r] if r.is_a?(String)
73
+ uniqs["#{r['name']}:#{r['in']}"] = param
74
+ end
75
+ end
76
+ uniqs.keys.sort!.map { |k| uniqs[k] }
77
+ end
78
+ end
79
+
80
+
81
+ class HelperTask
82
+ include TaskInterface
83
+
84
+ def generate(context_binding)
85
+ Gen.h = Helper.new(Gen.doc)
86
+ end
87
+
88
+ def output_name
89
+ nil
90
+ end
91
+
92
+ def discard
93
+ true
94
+ end
95
+ end
96
+
data/lib/loaders.rb ADDED
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright © 2024 Ismo Kärkkäinen
4
+ # Licensed under Universal Permissive License. See LICENSE.txt.
5
+
6
+ module Loaders
7
+
8
+ GEM_PREFIX = 'gem:'
9
+
10
+ def self.gem_loader(name)
11
+ return false unless name.downcase.start_with?(GEM_PREFIX)
12
+ begin
13
+ require(name.slice(GEM_PREFIX.size...name.size))
14
+ rescue LoadError => e
15
+ raise StandardError, "Failed to require #{name}\n#{e.to_s}"
16
+ rescue Exception => e
17
+ raise StandardError, "Problem with #{name}\n#{e.to_s}"
18
+ end
19
+ true
20
+ end
21
+
22
+ RUBY_EXT = '.rb'
23
+
24
+ def self.ruby_loader(name)
25
+ return false unless name.downcase.end_with?(RUBY_EXT)
26
+ origwd = Dir.pwd
27
+ d = File.dirname(name)
28
+ Dir.chdir(d) unless d == '.'
29
+ begin
30
+ require(File.join(Dir.pwd, File.basename(name)))
31
+ rescue LoadError => e
32
+ raise StandardError, "Failed to require #{name}\n#{e.to_s}"
33
+ rescue Exception => e
34
+ raise StandardError, "Problem with #{name}\n#{e.to_s}"
35
+ end
36
+ Dir.chdir(origwd) unless d == '.'
37
+ true
38
+ end
39
+
40
+ def self.loaders
41
+ [ method(:gem_loader), method(:ruby_loader) ]
42
+ end
43
+
44
+ def self.document
45
+ %(
46
+ - #{Loaders::GEM_PREFIX}gem_name : requires the gem.
47
+ - ruby_file#{Loaders::RUBY_EXT} : changes to Ruby file directory and requires the file.
48
+ )
49
+ end
50
+
51
+ end
data/lib/task.rb ADDED
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright © 2024 Ismo Kärkkäinen
4
+ # Licensed under Universal Permissive License. See LICENSE.txt.
5
+
6
+ require 'erb'
7
+ require_relative 'common'
8
+
9
+
10
+ module TaskInterface
11
+ def generate(context_binding)
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def output_name
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def discard
20
+ false
21
+ end
22
+
23
+ def executable
24
+ false
25
+ end
26
+ end
27
+
28
+ class Task
29
+ include TaskInterface
30
+
31
+ attr_reader :src, :template, :template_name
32
+ attr_accessor :name, :executable, :discard, :x
33
+
34
+ def initialize(src, template, template_name)
35
+ @src = src
36
+ @template = template
37
+ @template_name = template_name
38
+ if @template.nil?
39
+ raise ArgumentError, "template_name or template must be given" if @template_name.nil?
40
+ begin
41
+ @template = File.read(@template_name)
42
+ rescue Errno::ENOENT
43
+ raise StandardError, "Could not load #{@template_name}"
44
+ rescue StandardError => e
45
+ raise StandardError, "#{e}\nFailed to read #{@template_name}"
46
+ end
47
+ end
48
+ @name = nil
49
+ @executable = false
50
+ @discard = false
51
+ @x = nil
52
+ end
53
+
54
+ # If this is overridden to perform some processing but not to produce output,
55
+ # set @discard = true and return value will be ignored. No other methods are
56
+ # called in that case.
57
+ def internal_generate(context_binding)
58
+ ERB.new(@template).result(context_binding)
59
+ end
60
+
61
+ # You can override this instead of internal_generate if you do not need the
62
+ # exception handling.
63
+ def generate(context_binding)
64
+ n = @template_name.nil? ? '' : "#{@template_name} "
65
+ internal_generate(context_binding)
66
+ rescue SyntaxError => e
67
+ aargh("Template #{n}syntax error: #{e.full_message}", 5)
68
+ rescue Exception => e
69
+ aargh("Template #{n}error: #{e.full_message}", 6)
70
+ end
71
+
72
+ # This is only called when generate produced output that is not discarded.
73
+ def output_name
74
+ return @name unless @name.nil?
75
+ # Using template name may show where name assignment is missing.
76
+ # Name assignment may also be missing in the task creation stage.
77
+ return File.basename(@template_name) unless @template_name.nil?
78
+ nil
79
+ end
80
+ end
81
+
82
+ class WriteTask
83
+ include TaskInterface
84
+
85
+ attr_reader :name, :contents, :executable
86
+
87
+ def initialize(name, contents, executable = false)
88
+ raise ArgumentError, "name and contents must be given" if name.nil? || contents.nil?
89
+ @name = name
90
+ @contents = contents
91
+ @executable = executable
92
+ end
93
+
94
+ def generate(context_binding)
95
+ @contents
96
+ end
97
+
98
+ def output_name
99
+ @name
100
+ end
101
+ end
metadata CHANGED
@@ -1,27 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi-sourcetools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismo Kärkkäinen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-17 00:00:00.000000000 Z
11
+ date: 2024-07-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
 
15
15
  Tools for handling API specification in OpenAPI format. Replacement of
16
16
  duplicate definitions with references. Other checks. Does not validate
17
- the document against specification.
17
+ the document against OpenAPI format specification.
18
18
  email: ismokarkkainen@icloud.com
19
19
  executables:
20
20
  - openapi-addheaders
21
+ - openapi-addparameters
21
22
  - openapi-addresponses
22
23
  - openapi-addschemas
23
24
  - openapi-checkschemas
24
25
  - openapi-frequencies
26
+ - openapi-generate
25
27
  - openapi-merge
26
28
  - openapi-processpaths
27
29
  extensions: []
@@ -29,14 +31,21 @@ extra_rdoc_files: []
29
31
  files:
30
32
  - LICENSE.txt
31
33
  - bin/openapi-addheaders
34
+ - bin/openapi-addparameters
32
35
  - bin/openapi-addresponses
33
36
  - bin/openapi-addschemas
34
37
  - bin/openapi-checkschemas
35
38
  - bin/openapi-frequencies
39
+ - bin/openapi-generate
36
40
  - bin/openapi-merge
37
41
  - bin/openapi-processpaths
38
42
  - lib/apiobjects.rb
39
43
  - lib/common.rb
44
+ - lib/gen.rb
45
+ - lib/generate.rb
46
+ - lib/helper.rb
47
+ - lib/loaders.rb
48
+ - lib/task.rb
40
49
  homepage: https://xn--ismo-krkkinen-gfbd.fi/openapi-sourcetools/index.html
41
50
  licenses:
42
51
  - UPL-1.0