Module: Prmd
- Defined in:
- lib/prmd.rb,
lib/prmd/schema.rb,
lib/prmd/version.rb,
lib/prmd/template.rb,
lib/prmd/commands/init.rb,
lib/prmd/url_generator.rb,
lib/prmd/commands/render.rb,
lib/prmd/commands/verify.rb,
lib/prmd/commands/combine.rb
Defined Under Namespace
Classes: Schema, Template, UrlGenerator
Constant Summary collapse
- VERSION =
"0.6.2"
- SCHEMAS =
These schemas are listed manually and in order because they reference each other.
[ "schema.json", "hyper-schema.json", "interagent-hyper-schema.json" ]
Class Method Summary collapse
- .combine(path, options = {}) ⇒ Object
- .init(resource, options = {}) ⇒ Object
- .render(schema, options = {}) ⇒ Object
- .verify(schema_data) ⇒ Object
Class Method Details
.combine(path, options = {}) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/prmd/commands/combine.rb', line 2 def self.combine(path, ={}) files = if File.directory?(path) Dir.glob(File.join(path, '**', '*.json')) + Dir.glob(File.join(path, '**', '*.yaml')) - [[:meta]] else [path] end # sort for stable loading on any platform schemata = [] files.sort.each do |file| begin schemata << [file, YAML.load(File.read(file))] rescue $stderr.puts "unable to parse #{file}" end end unless schemata.length == files.length exit(1) # one or more files failed to parse end data = { '$schema' => 'http://json-schema.org/draft-04/hyper-schema', 'definitions' => {}, 'properties' => {}, 'type' => ['object'] } # tracks which entities where defined in which file schemata_map = {} if [:meta] && File.exists?([:meta]) data.merge!(YAML.load(File.read([:meta]))) end schemata.each do |schema_file, schema_data| id = schema_data['id'].split('/').last if file = schemata_map[schema_data['id']] $stderr.puts "`#{schema_data['id']}` (from #{schema_file}) was already defined in `#{file}` and will overwrite the first definition" end schemata_map[schema_data['id']] = schema_file # schemas are now in a single scope by combine schema_data.delete('id') data['definitions'] data['definitions'][id] = schema_data reference_localizer = lambda do |datum| case datum when Array datum.map {|element| reference_localizer.call(element)} when Hash if datum.has_key?('$ref') datum['$ref'] = '#/definitions' + datum['$ref'].gsub('#', '').gsub('/schemata', '') end if datum.has_key?('href') && datum['href'].is_a?(String) datum['href'] = datum['href'].gsub('%23', '').gsub(%r{%2Fschemata(%2F[^%]*%2F)}, '%23%2Fdefinitions\1') end datum.each { |k,v| datum[k] = reference_localizer.call(v) } else datum end end reference_localizer.call(data['definitions'][id]) data['properties'][id] = { '$ref' => "#/definitions/#{id}" } end Prmd::Schema.new(data) end |
.init(resource, options = {}) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/prmd/commands/init.rb', line 2 def self.init(resource, ={}) data = { '$schema' => 'http://json-schema.org/draft-04/hyper-schema', 'title' => 'FIXME', 'definitions' => {}, 'description' => 'FIXME', 'links' => [], 'properties' => {}, 'type' => ['object'] } schema = Prmd::Schema.new(data) if resource if resource.include?('/') parent, resource = resource.split('/') end schema['id'] = "schemata/#{resource}" schema['title'] = "FIXME - #{resource[0...1].upcase}#{resource[1..-1]}" schema['definitions'] = { "created_at" => { "description" => "when #{resource} was created", "example" => "2012-01-01T12:00:00Z", "format" => "date-time", "type" => ["string"] }, "id" => { "description" => "unique identifier of #{resource}", "example" => "01234567-89ab-cdef-0123-456789abcdef", "format" => "uuid", "type" => ["string"] }, "identity" => { "$ref" => "/schemata/#{resource}#/definitions/id" }, "updated_at" => { "description" => "when #{resource} was updated", "example" => "2012-01-01T12:00:00Z", "format" => "date-time", "type" => ["string"] } } schema['links'] = [ { "description" => "Create a new #{resource}.", "href" => "/#{resource}s", "method" => "POST", "rel" => "create", "schema" => { "properties" => {}, "type" => ["object"] }, "title" => "Create" }, { "description" => "Delete an existing #{resource}.", "href" => "/#{resource}s/{(%2Fschemata%2F#{resource}%23%2Fdefinitions%2Fidentity)}", "method" => "DELETE", "rel" => "destroy", "title" => "Delete" }, { "description" => "Info for existing #{resource}.", "href" => "/#{resource}s/{(%2Fschemata%2F#{resource}%23%2Fdefinitions%2Fidentity)}", "method" => "GET", "rel" => "self", "title" => "Info" }, { "description" => "List existing #{resource}s.", "href" => "/#{resource}s", "method" => "GET", "rel" => "instances", "title" => "List" }, { "description" => "Update an existing #{resource}.", "href" => "/#{resource}s/{(%2Fschemata%2F#{resource}%23%2Fdefinitions%2Fidentity)}", "method" => "PATCH", "rel" => "update", "schema" => { "properties" => {}, "type" => ["object"] }, "title" => "Update" } ] if parent schema['links'] << { "description" => "List existing #{resource}s for existing #{parent}.", "href" => "/#{parent}s/{(%2Fschemata%2F#{parent}%23%2Fdefinitions%2Fidentity)}/#{resource}s", "method" => "GET", "rel" => "instances", "title" => "List" } end schema['properties'] = { "created_at" => { "$ref" => "/schemata/#{resource}#/definitions/created_at" }, "id" => { "$ref" => "/schemata/#{resource}#/definitions/id" }, "updated_at" => { "$ref" => "/schemata/#{resource}#/definitions/updated_at" } } end if [:yaml] schema.to_yaml else schema.to_json end end |
.render(schema, options = {}) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/prmd/commands/render.rb', line 2 def self.render(schema, ={}) doc = '' [:content_type] ||= 'application/json' [:style] ||= 'default' if [:prepend] doc << [:prepend].map {|path| File.read(path)}.join("\n") << "\n" end template_dir = File::([:template]) if not File.directory?(template_dir) # to keep backward compatibility template_dir = File.dirname([:template]) end doc << Prmd::Template::render('schema.erb', template_dir, { options: , schema: schema }) doc end |
.verify(schema_data) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/prmd/commands/verify.rb', line 13 def self.verify(schema_data) store = init_document_store if !(schema_uri = schema_data["$schema"]) return ["Missing $schema."] end # for good measure, make sure that the schema parses and that its # references can be expanded schema, errors = JsonSchema.parse!(schema_data) return JsonSchema::SchemaError.aggregate(errors) if !schema valid, errors = schema.(store: store) return JsonSchema::SchemaError.aggregate(errors) if !valid if !( = store.lookup_schema(schema_uri)) return ["Unknown $schema: #{schema_uri}."] end valid, errors = .validate(schema_data) return JsonSchema::SchemaError.aggregate(errors) if !valid [] end |