rack-swagger 0.0.1 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.gitignore +1 -1
- data/README.md +85 -1
- data/Rakefile +30 -0
- data/lib/rack/swagger.rb +35 -1
- data/lib/rack/swagger/asset_server.rb +22 -0
- data/lib/rack/swagger/index_page_server.rb +32 -0
- data/lib/rack/swagger/json_server.rb +30 -0
- data/lib/rack/swagger/rentpath/logo_small.png +0 -0
- data/lib/rack/swagger/rentpath/rentpath.diff +47 -0
- data/lib/rack/swagger/routes_to_models.rb +111 -0
- data/lib/rack/swagger/server_helpers.rb +55 -0
- data/lib/rack/swagger/sinatra_helpers.rb +78 -0
- data/lib/rack/swagger/version.rb +1 -1
- data/rack-swagger.gemspec +8 -2
- data/spec/lib/rack/swagger/asset_server_spec.rb +18 -0
- data/spec/lib/rack/swagger/index_page_server_spec.rb +21 -0
- data/spec/lib/rack/swagger/routes_to_models_spec.rb +81 -0
- data/spec/lib/rack/swagger/server_helpers_spec.rb +44 -0
- data/spec/lib/rack/swagger/sinatra_helpers_spec.rb +85 -0
- data/spec/spec_helper.rb +25 -0
- data/swagger-ui/dist/css/reset.css +125 -0
- data/swagger-ui/dist/css/screen.css +1224 -0
- data/swagger-ui/dist/css/screen.css.orig +1224 -0
- data/swagger-ui/dist/images/explorer_icons.png +0 -0
- data/swagger-ui/dist/images/logo_small.png +0 -0
- data/swagger-ui/dist/images/pet_store_api.png +0 -0
- data/swagger-ui/dist/images/throbber.gif +0 -0
- data/swagger-ui/dist/images/wordnik_api.png +0 -0
- data/swagger-ui/dist/index.html +105 -0
- data/swagger-ui/dist/index.html.orig +105 -0
- data/swagger-ui/dist/lib/backbone-min.js +38 -0
- data/swagger-ui/dist/lib/handlebars-1.0.0.js +2278 -0
- data/swagger-ui/dist/lib/highlight.7.3.pack.js +1 -0
- data/swagger-ui/dist/lib/jquery-1.8.0.min.js +2 -0
- data/swagger-ui/dist/lib/jquery.ba-bbq.min.js +18 -0
- data/swagger-ui/dist/lib/jquery.slideto.min.js +1 -0
- data/swagger-ui/dist/lib/jquery.wiggle.min.js +8 -0
- data/swagger-ui/dist/lib/shred.bundle.js +2765 -0
- data/swagger-ui/dist/lib/shred/content.js +193 -0
- data/swagger-ui/dist/lib/swagger-client.js +1477 -0
- data/swagger-ui/dist/lib/swagger-oauth.js +211 -0
- data/swagger-ui/dist/lib/swagger.js +1678 -0
- data/swagger-ui/dist/lib/underscore-min.js +32 -0
- data/swagger-ui/dist/o2c.html +15 -0
- data/swagger-ui/dist/swagger-ui.js +2477 -0
- data/swagger-ui/dist/swagger-ui.min.js +1 -0
- data/swagger-ui/master.tar.gz +0 -0
- data/swagger-ui/swagger-ui-v2.0.22.tar +0 -0
- data/swagger_ui_version.yml +4 -0
- data/templates/swagger_ui_version.yml +4 -0
- metadata +132 -12
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MjQ5NjkwY2ZjMGE0NTgyMWY0Yzg1M2U2YWZlY2RiM2YzOTkwYTJiYQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTJjMDg5ZThmODYxNmM5OTFkYTM3MTE0YjlmNDcwOTA5NzU3Zjc5ZA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MjAwZDA5MzIzODAyNmUyNmJmYWM1ZWI5ZDI2NTA2N2UwN2FhMzExZWE0Y2Fk
|
10
|
+
NmY1MTg4N2U0M2NhMzYyMWQ4MTkyMzZlM2EwMmQ3MzhhOWIxOGVmNTZjZTM0
|
11
|
+
NDkwNDk0MDkyNjZmNzIxZWE1OTYzZDExZmU3Y2ZiYWM4NWZiZGQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NGQ4M2ZiNGNjMTkwMWYxNzkyYTRhMzk1N2ZjNzFhODM1ODY5YWM2MmNhNjZh
|
14
|
+
NzkyYzAzOTZhOGYzNGY4YzI3ZDVlMGFjMzk1ZTg3ZDc3NGJmYmFiOGJiMjc1
|
15
|
+
ZGQ1MzVkN2E1MmU0ZjViMTJmZThlYWNjMjc3ZjQ1NDE5MzM2ZjA=
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -20,7 +20,90 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
Set up a docs folder in your project. Place the root API doc there and call it
|
24
|
+
"swagger.json". Place your resource API docs there as well. For example, if you
|
25
|
+
have one resource called "pet", your docs folder will have two files:
|
26
|
+
|
27
|
+
* swagger.json (the root API doc)
|
28
|
+
* pet.json (the pet resource)
|
29
|
+
|
30
|
+
In your config.ru, run Rack::Swagger.app(), passing in the path to your docs
|
31
|
+
folder.
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
run Rack::Swagger.app(File.expand_path("../docs/", __FILE__))
|
35
|
+
```
|
36
|
+
|
37
|
+
This will serve the swagger-ui front-end at **/docs/**, and your
|
38
|
+
doc files at **/docs/api-docs/**.
|
39
|
+
|
40
|
+
Your resource definitions should look ike this:
|
41
|
+
|
42
|
+
```json
|
43
|
+
{
|
44
|
+
"path": "/pet",
|
45
|
+
"description": "Operations about pets"
|
46
|
+
},
|
47
|
+
```
|
48
|
+
|
49
|
+
## Getting basePath right
|
50
|
+
|
51
|
+
##### Using overwrite_base_path
|
52
|
+
|
53
|
+
If you are seeing a lot of 404s or CORS-related errors in your docs, you may
|
54
|
+
need to tweak the basePath.
|
55
|
+
|
56
|
+
You always need to have the basePath point to the same hostname as your API. If
|
57
|
+
you have multiple deploys of your application under different hostnames, and
|
58
|
+
they share the same set of JSON files, you can use the overwrite_base_path
|
59
|
+
option in Rack::Swagger.app() to vary this dynamically.
|
60
|
+
|
61
|
+
For example, say you have an environment variable called MY_API_HOST, which
|
62
|
+
contains the hostname of your app for a given deployment:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
Rack::Swagger.app(
|
66
|
+
File.expand_path("../docs/", __FILE__),
|
67
|
+
overwrite_base_path: ENV["MY_API_HOST"]
|
68
|
+
)
|
69
|
+
```
|
70
|
+
|
71
|
+
##### Setting basePath manually
|
72
|
+
|
73
|
+
If you're not using overwrite_base_path, rack-swagger will just use your
|
74
|
+
basePath value from your JSON files. But just know that basePath will have
|
75
|
+
different values depending on the file:
|
76
|
+
|
77
|
+
* For the resource files, it should point to the API root path.
|
78
|
+
* For the root file, it should point to the API root path, plus "/docs/api-docs".
|
79
|
+
|
80
|
+
## Upgrading swagger-ui
|
81
|
+
|
82
|
+
A distribution of swagger-ui is included with rack-swagger. For developers who
|
83
|
+
want to upgrade this distribution, there is a Rake task which pulls down the
|
84
|
+
latest version and applies some changes to it. To use, run:
|
85
|
+
|
86
|
+
```
|
87
|
+
rake swagger_ui
|
88
|
+
```
|
89
|
+
|
90
|
+
If someone downloads the distribution without using the Rake task and you're
|
91
|
+
trying to restore back to the original, remove the directory and version
|
92
|
+
file before running the rake task:
|
93
|
+
|
94
|
+
```
|
95
|
+
rm -rf swagger-ui/
|
96
|
+
rm swagger_ui_version.yml
|
97
|
+
rake swagger_ui
|
98
|
+
```
|
99
|
+
|
100
|
+
Then check in the updated code.
|
101
|
+
|
102
|
+
## Notes
|
103
|
+
|
104
|
+
For an example of properly formatted Swagger 1.2 JSON files working together
|
105
|
+
with [swagger-ui](https://github.com/wordnik/swagger-ui), see:
|
106
|
+
[http://petstore.swagger.wordnik.com/](Pet Store Demo).
|
24
107
|
|
25
108
|
## Contributing
|
26
109
|
|
@@ -29,3 +112,4 @@ TODO: Write usage instructions here
|
|
29
112
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
113
|
4. Push to the branch (`git push origin my-new-feature`)
|
31
114
|
5. Create a new Pull Request
|
115
|
+
|
data/Rakefile
CHANGED
@@ -1,2 +1,32 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require 'yaml'
|
3
|
+
require 'httpclient'
|
4
|
+
require 'json'
|
2
5
|
|
6
|
+
task default: [:swagger_ui]
|
7
|
+
|
8
|
+
desc "Update swagger-ui distribution files if they have changed."
|
9
|
+
task swagger_ui: ["swagger-ui", :update_swagger_ui]
|
10
|
+
|
11
|
+
directory "swagger-ui"
|
12
|
+
|
13
|
+
task :update_swagger_ui do
|
14
|
+
client = HTTPClient.new
|
15
|
+
res = client.get('https://codeload.github.com/wordnik/swagger-ui/legacy.tar.gz/master', follow_redirect: true)
|
16
|
+
raise "Github API returned #{res.inspect}" if res.status != 200
|
17
|
+
|
18
|
+
# pull down swagger-ui mainline
|
19
|
+
cd "swagger-ui"
|
20
|
+
tar = res.content
|
21
|
+
File.open("master.tar.gz", "w+") { |f| f << tar }
|
22
|
+
sh("tar xvf master.tar.gz --include '*swagger-ui*/dist*' --strip-components 1")
|
23
|
+
cd ".."
|
24
|
+
|
25
|
+
# apply branding
|
26
|
+
puts `cat lib/rack/swagger/rentpath/rentpath.diff | patch -p1`
|
27
|
+
cp "lib/rack/swagger/rentpath/logo_small.png", "swagger-ui/dist/images/logo_small.png"
|
28
|
+
|
29
|
+
# replace petstore with real docs
|
30
|
+
index_page = File.read("swagger-ui/dist/index.html")
|
31
|
+
File.open("swagger-ui/dist/index.html", "w+") { |f| f << index_page.gsub("http://petstore.swagger.wordnik.com/api/api-docs", "api-docs") }
|
32
|
+
end
|
data/lib/rack/swagger.rb
CHANGED
@@ -1,7 +1,41 @@
|
|
1
|
+
require "rack/swagger/server_helpers"
|
2
|
+
require "rack/swagger/asset_server"
|
3
|
+
require "rack/swagger/index_page_server"
|
4
|
+
require "rack/swagger/json_server"
|
5
|
+
|
6
|
+
require "rack/swagger/sinatra_helpers"
|
1
7
|
require "rack/swagger/version"
|
2
8
|
|
3
9
|
module Rack
|
4
10
|
module Swagger
|
5
|
-
#
|
11
|
+
# Rack app for serving the swagger-ui front-end and your JSON-formatted
|
12
|
+
# Swagger doc files.
|
13
|
+
#
|
14
|
+
# Description:
|
15
|
+
# The app will serve the swagger-ui front-end at /docs/, and redirect
|
16
|
+
# requests for /docs to /docs/. It will serve the root Swagger doc
|
17
|
+
# file at /docs/api-docs, and resource files in a subpath of /docs/api-docs,
|
18
|
+
# such as /docs/api-docs/pet for the "pet" resource. This mimics the way
|
19
|
+
# the Pet Store demo is set up.
|
20
|
+
#
|
21
|
+
# See: http://petstore.swagger.wordnik.com/
|
22
|
+
#
|
23
|
+
# Parameters:
|
24
|
+
# docs_dir: a String containing the path to the directory with your root
|
25
|
+
# Swagger JSON doc file (called swagger.json) and all resource-specific
|
26
|
+
# doc files (for example, pet.json for the "pet" resource).
|
27
|
+
#
|
28
|
+
# Usage:
|
29
|
+
# In your config.ru, add:
|
30
|
+
#
|
31
|
+
# run Rack::Swagger.app(File.expand_path("../docs/", __FILE__))
|
32
|
+
#
|
33
|
+
def self.app(docs_dir, opts={})
|
34
|
+
Rack::Cascade.new([
|
35
|
+
JsonServer.new(docs_dir, opts),
|
36
|
+
IndexPageServer.new,
|
37
|
+
AssetServer.new
|
38
|
+
])
|
39
|
+
end
|
6
40
|
end
|
7
41
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Rack
|
2
|
+
module Swagger
|
3
|
+
class AssetServer
|
4
|
+
include ServerHelpers
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
dist_path = swagger_dist_path
|
8
|
+
|
9
|
+
@app = Rack::Builder.new do
|
10
|
+
map "/docs" do
|
11
|
+
run Rack::Directory.new(dist_path)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rack
|
2
|
+
module Swagger
|
3
|
+
class IndexPageServer
|
4
|
+
include ServerHelpers
|
5
|
+
|
6
|
+
def call(env)
|
7
|
+
case env['PATH_INFO']
|
8
|
+
when "/docs/"
|
9
|
+
query = Rack::Utils.parse_nested_query(env["QUERY_STRING"])
|
10
|
+
|
11
|
+
if query["url"] == "api-docs"
|
12
|
+
display_file_or_404(:html, swagger_index_html_path)
|
13
|
+
|
14
|
+
else
|
15
|
+
res = Rack::Response.new
|
16
|
+
res.redirect("?url=" + "api-docs")
|
17
|
+
res.finish
|
18
|
+
end
|
19
|
+
|
20
|
+
when "/docs"
|
21
|
+
res = Rack::Response.new
|
22
|
+
res.redirect("docs/?url=" + "api-docs")
|
23
|
+
res.finish
|
24
|
+
|
25
|
+
else
|
26
|
+
[404, {}, ["Not found"]]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Rack
|
2
|
+
module Swagger
|
3
|
+
class JsonServer
|
4
|
+
include ServerHelpers
|
5
|
+
|
6
|
+
RESOURCE_DOC_JSON_MATCHER = /^\/docs\/api-docs\/(.+)\/?/
|
7
|
+
ROOT_DOC_JSON_MATCHER = /^\/docs\/api-docs\/?/
|
8
|
+
|
9
|
+
def initialize(docs_dir, opts)
|
10
|
+
@docs_dir = docs_dir
|
11
|
+
@opts = opts
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
case env['PATH_INFO']
|
16
|
+
when RESOURCE_DOC_JSON_MATCHER
|
17
|
+
resource_doc = $1
|
18
|
+
display_file_or_404(:json, "#{@docs_dir}/#{resource_doc}.json", :resource)
|
19
|
+
|
20
|
+
when ROOT_DOC_JSON_MATCHER
|
21
|
+
display_file_or_404(:json, "#{@docs_dir}/swagger.json", :root)
|
22
|
+
|
23
|
+
else
|
24
|
+
[404, {}, ["Not found"]]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
diff --git a/swagger-ui/dist/css/screen.css b/swagger-ui/dist/css/screen.css
|
2
|
+
index f214883..f5c779e 100644
|
3
|
+
--- a/swagger-ui/dist/css/screen.css
|
4
|
+
+++ b/swagger-ui/dist/css/screen.css
|
5
|
+
@@ -1158,7 +1158,7 @@
|
6
|
+
cursor: pointer;
|
7
|
+
}
|
8
|
+
.swagger-section #header {
|
9
|
+
- background-color: #89bf04;
|
10
|
+
+ background-color: #e7f0f7;
|
11
|
+
padding: 14px;
|
12
|
+
}
|
13
|
+
.swagger-section #header a#logo {
|
14
|
+
@@ -1193,7 +1193,7 @@
|
15
|
+
padding: 6px 8px;
|
16
|
+
font-size: 0.9em;
|
17
|
+
color: white;
|
18
|
+
- background-color: #547f00;
|
19
|
+
+ background-color: #6090b0;
|
20
|
+
-moz-border-radius: 4px;
|
21
|
+
-webkit-border-radius: 4px;
|
22
|
+
-o-border-radius: 4px;
|
23
|
+
diff --git a/swagger-ui/dist/images/logo_small.png b/swagger-ui/dist/images/logo_small.png
|
24
|
+
index 5496a65..8891290 100644
|
25
|
+
Binary files a/swagger-ui/dist/images/logo_small.png and b/swagger-ui/dist/images/logo_small.png differ
|
26
|
+
diff --git a/swagger-ui/dist/index.html b/swagger-ui/dist/index.html
|
27
|
+
index caf4ef0..1ccb8cc 100644
|
28
|
+
--- a/swagger-ui/dist/index.html
|
29
|
+
+++ b/swagger-ui/dist/index.html
|
30
|
+
@@ -1,7 +1,7 @@
|
31
|
+
<!DOCTYPE html>
|
32
|
+
<html>
|
33
|
+
<head>
|
34
|
+
- <title>Swagger UI</title>
|
35
|
+
+ <title>RentPath Mobile API Documentation</title>
|
36
|
+
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
|
37
|
+
<link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
|
38
|
+
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
|
39
|
+
@@ -67,7 +67,7 @@
|
40
|
+
<body class="swagger-section">
|
41
|
+
<div id='header'>
|
42
|
+
<div class="swagger-ui-wrap">
|
43
|
+
- <a id="logo" href="http://swagger.wordnik.com">swagger</a>
|
44
|
+
+ <img src="images/logo_small.png"></img>
|
45
|
+
<form id='api_selector'>
|
46
|
+
<div class='input icon-btn'>
|
47
|
+
<img id="show-pet-store-icon" src="images/pet_store_api.png" title="Show Swagger Petstore Example Apis">
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'active_support/inflector/inflections'
|
2
|
+
require 'active_support/inflections'
|
3
|
+
require 'active_support/inflector/methods'
|
4
|
+
require 'json'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
# A set of scripts for generating the "models" portion of the resource JSON
|
8
|
+
# files.
|
9
|
+
#
|
10
|
+
# Usage:
|
11
|
+
# include Rack::Swagger::RoutesToModels
|
12
|
+
# models = generate_models(get_json("http://{URL}"))
|
13
|
+
module Rack
|
14
|
+
module Swagger
|
15
|
+
module RoutesToModels
|
16
|
+
def get_json(url)
|
17
|
+
raw = `curl "#{url}"`
|
18
|
+
json = JSON.parse raw
|
19
|
+
rescue
|
20
|
+
puts "#{__FILE__}:#{__LINE__}: URL not parsable."
|
21
|
+
{}
|
22
|
+
end
|
23
|
+
|
24
|
+
def traverse(gp='root', parent='root', obj, &blk)
|
25
|
+
case obj
|
26
|
+
when Hash
|
27
|
+
type = to_model_name(parent)
|
28
|
+
blk.call(gp, parent, type)
|
29
|
+
obj.each {|k,v| traverse(parent, k, v, &blk) }
|
30
|
+
when Array
|
31
|
+
type = to_model_name(parent, singularize: true)
|
32
|
+
blk.call(gp, parent, "[#{type}]")
|
33
|
+
obj.each {|v| traverse(parent, "#{type}", v, &blk) }
|
34
|
+
else
|
35
|
+
blk.call(gp, parent, "#{obj.class}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_model_name(str, singularize: false)
|
40
|
+
str2 = ActiveSupport::Inflector.camelize(str)
|
41
|
+
str2 = ActiveSupport::Inflector.singularize(str2) if singularize
|
42
|
+
"Model_#{str2}"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def new_model(name)
|
47
|
+
{id: name, properties: {}}
|
48
|
+
end
|
49
|
+
|
50
|
+
def new_property(ruby_type)
|
51
|
+
case ruby_type
|
52
|
+
when "String"
|
53
|
+
{type: "string"}
|
54
|
+
when "Boolean"
|
55
|
+
{type: "boolean", format: "boolean"}
|
56
|
+
when "Float"
|
57
|
+
{type: "number", format: "float"}
|
58
|
+
when "Fixnum"
|
59
|
+
{type: "integer", format: "int64"}
|
60
|
+
when /\[(.+)\]/
|
61
|
+
{type: "array", items: new_property($1) }
|
62
|
+
else
|
63
|
+
{ "$ref" => ruby_type.gsub(/^Model_/, "") }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_models(json, root_name, debug=false)
|
68
|
+
models = {}
|
69
|
+
|
70
|
+
traverse('root', json) do |parent, obj_name, obj_type|
|
71
|
+
if ['FalseClass', 'TrueClass'].include? obj_type
|
72
|
+
obj_type = "Boolean"
|
73
|
+
end
|
74
|
+
|
75
|
+
if debug
|
76
|
+
puts sprintf("parent: %30s obj_name: %20s obj_type: %20s", parent, obj_name, obj_type.to_s[0...20])
|
77
|
+
end
|
78
|
+
|
79
|
+
if obj_type == "NilClass"
|
80
|
+
# skip
|
81
|
+
|
82
|
+
elsif parent.match(/^Model_/)
|
83
|
+
parent_wo_model = parent.gsub(/^Model_/, "")
|
84
|
+
|
85
|
+
unless models[parent_wo_model]
|
86
|
+
models[parent_wo_model] = new_model(parent_wo_model)
|
87
|
+
end
|
88
|
+
|
89
|
+
models[parent_wo_model][:properties][obj_name] = new_property(obj_type)
|
90
|
+
elsif !parent.match(/^Model_/) && !obj_name.match(/^Model_/)
|
91
|
+
c_parent = to_model_name(parent).gsub(/^Model_/, "")
|
92
|
+
|
93
|
+
unless models[c_parent]
|
94
|
+
models[c_parent] = new_model(c_parent)
|
95
|
+
end
|
96
|
+
|
97
|
+
models[c_parent][:properties][obj_name] = new_property(obj_type)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
root = models["Root"]
|
102
|
+
models.delete("Root")
|
103
|
+
root[:properties].delete("root")
|
104
|
+
root[:id] = root_name
|
105
|
+
|
106
|
+
models[root_name] = root
|
107
|
+
models
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|