moonrope 1.4.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +9 -0
- data/Gemfile.lock +47 -0
- data/MIT-LICENCE +20 -0
- data/README.md +24 -0
- data/bin/moonrope +28 -0
- data/docs/authentication.md +114 -0
- data/docs/controllers.md +106 -0
- data/docs/exceptions.md +27 -0
- data/docs/introduction.md +29 -0
- data/docs/structures.md +214 -0
- data/example/authentication.rb +50 -0
- data/example/controllers/meta_controller.rb +14 -0
- data/example/controllers/users_controller.rb +92 -0
- data/example/structures/pet_structure.rb +12 -0
- data/example/structures/user_structure.rb +35 -0
- data/html/assets/lock.svg +3 -0
- data/html/assets/reset.css +101 -0
- data/html/assets/style.css +348 -0
- data/html/assets/tool.svg +4 -0
- data/html/assets/try.js +151 -0
- data/html/authenticators/default.html +191 -0
- data/html/controllers/meta/version.html +144 -0
- data/html/controllers/meta.html +73 -0
- data/html/controllers/users/create.html +341 -0
- data/html/controllers/users/list.html +348 -0
- data/html/controllers/users/show.html +261 -0
- data/html/controllers/users/update.html +387 -0
- data/html/controllers/users.html +93 -0
- data/html/index.html +166 -0
- data/html/moonrope.txt +0 -0
- data/html/structures/pet.html +176 -0
- data/html/structures/user.html +338 -0
- data/lib/moonrope/action.rb +165 -37
- data/lib/moonrope/authenticator.rb +39 -0
- data/lib/moonrope/base.rb +24 -6
- data/lib/moonrope/controller.rb +4 -2
- data/lib/moonrope/doc_context.rb +94 -0
- data/lib/moonrope/doc_server.rb +123 -0
- data/lib/moonrope/dsl/action_dsl.rb +159 -9
- data/lib/moonrope/dsl/authenticator_dsl.rb +31 -0
- data/lib/moonrope/dsl/base_dsl.rb +21 -18
- data/lib/moonrope/dsl/controller_dsl.rb +60 -9
- data/lib/moonrope/dsl/filterable_dsl.rb +27 -0
- data/lib/moonrope/dsl/structure_dsl.rb +27 -2
- data/lib/moonrope/errors.rb +3 -0
- data/lib/moonrope/eval_environment.rb +82 -3
- data/lib/moonrope/eval_helpers/filter_helper.rb +82 -0
- data/lib/moonrope/eval_helpers.rb +28 -5
- data/lib/moonrope/guard.rb +35 -0
- data/lib/moonrope/html_generator.rb +65 -0
- data/lib/moonrope/param_set.rb +11 -1
- data/lib/moonrope/rack_middleware.rb +1 -1
- data/lib/moonrope/railtie.rb +31 -14
- data/lib/moonrope/request.rb +25 -14
- data/lib/moonrope/structure.rb +74 -11
- data/lib/moonrope/structure_attribute.rb +15 -0
- data/lib/moonrope/version.rb +1 -1
- data/lib/moonrope.rb +5 -4
- data/moonrope.gemspec +21 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/specs/action_spec.rb +455 -0
- data/spec/specs/base_spec.rb +29 -0
- data/spec/specs/controller_spec.rb +31 -0
- data/spec/specs/param_set_spec.rb +31 -0
- data/templates/basic/_action_form.erb +77 -0
- data/templates/basic/_errors_table.erb +32 -0
- data/templates/basic/_structure_attributes_list.erb +55 -0
- data/templates/basic/action.erb +168 -0
- data/templates/basic/assets/lock.svg +3 -0
- data/templates/basic/assets/reset.css +101 -0
- data/templates/basic/assets/style.css +348 -0
- data/templates/basic/assets/tool.svg +4 -0
- data/templates/basic/assets/try.js +151 -0
- data/templates/basic/authenticator.erb +51 -0
- data/templates/basic/controller.erb +20 -0
- data/templates/basic/index.erb +114 -0
- data/templates/basic/layout.erb +46 -0
- data/templates/basic/structure.erb +23 -0
- data/test/test_helper.rb +81 -0
- data/test/tests/action_access_test.rb +63 -0
- data/test/tests/actions_test.rb +524 -0
- data/test/tests/authenticators_test.rb +87 -0
- data/test/tests/base_test.rb +35 -0
- data/test/tests/controllers_test.rb +49 -0
- data/test/tests/eval_environment_test.rb +136 -0
- data/test/tests/evel_helpers_test.rb +60 -0
- data/test/tests/examples_test.rb +11 -0
- data/test/tests/helpers_test.rb +97 -0
- data/test/tests/param_set_test.rb +44 -0
- data/test/tests/rack_middleware_test.rb +109 -0
- data/test/tests/request_test.rb +232 -0
- data/test/tests/structures_param_extensions_test.rb +159 -0
- data/test/tests/structures_test.rb +335 -0
- metadata +82 -48
@@ -0,0 +1,50 @@
|
|
1
|
+
authenticator :default do
|
2
|
+
|
3
|
+
description <<-DESCRIPTION
|
4
|
+
To authenticate to the API, you need to pass an appropriate API token with your
|
5
|
+
request. To find out how to obtain an API token, please refer to the Authentication
|
6
|
+
API documentaton which outlines the available methods available for this.
|
7
|
+
DESCRIPTION
|
8
|
+
|
9
|
+
header "X-Auth-Application", "The API application which is generated by us and provided to you.", :example => "abc123abc123abc123"
|
10
|
+
header "X-Auth-Token", "The API token for the user you wish to authenticate as.", :example => "abc123abc123abc123"
|
11
|
+
|
12
|
+
error "InvalidApplicationToken", "The application token provided in X-Auth-Application is not valid.", :attributes => {:token => "The token used to find the application"}
|
13
|
+
error "InvalidAuthToken", "The auth token provided in X-Auth-Token is not valid.", :attributes => {:token => "The token that was used"}
|
14
|
+
error "ExpiredAuthToken", "The auth token provided in X-Auth-Token has expired.", :attributes => {:expired_at => "The time the token expired"}
|
15
|
+
|
16
|
+
lookup do
|
17
|
+
if app_token = header['X-Auth-Application']
|
18
|
+
api_application = APIApplication.find_by_token(app_token)
|
19
|
+
if api_application.nil?
|
20
|
+
error "InvalidApplicationToken", :token => app_token
|
21
|
+
end
|
22
|
+
|
23
|
+
if auth_token = header['X-Auth-Token']
|
24
|
+
api_token = api_application.api_tokens.find_by_token(auth_token)
|
25
|
+
if api_token.nil? || api_token.inactive?
|
26
|
+
error "InvalidAuthToken", :token => auth_token
|
27
|
+
end
|
28
|
+
|
29
|
+
if api_token.expired?
|
30
|
+
error "ExpiredAuthToken", :expired_at => api_token.expired_at
|
31
|
+
end
|
32
|
+
|
33
|
+
api_token
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
rule :default, "NotAuthenticated", "Must be authenticated with a valid user API token." do
|
39
|
+
identity.is_a?(APIToken) && identity.user
|
40
|
+
end
|
41
|
+
|
42
|
+
rule :must_be_admin, "MustBeAdmin", "Must be authenticated as a valid admin user." do
|
43
|
+
identity.is_a?(APIToken) && identity.user && identity.user.admin?
|
44
|
+
end
|
45
|
+
|
46
|
+
rule :anonymous, "MustBeAnonymous", "Must not be authenticated (no auth headers provided)." do
|
47
|
+
identity == :anonymous
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
controller :meta do
|
2
|
+
|
3
|
+
friendly_name "Meta API"
|
4
|
+
description <<-DESC
|
5
|
+
The meta API provides you with access to information about the API itself.
|
6
|
+
DESC
|
7
|
+
|
8
|
+
action :version do
|
9
|
+
description "Return the current software version"
|
10
|
+
returns :string, :eg => "v1.2.3"
|
11
|
+
action { LlamaCom::VERSION }
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
controller :users do
|
2
|
+
|
3
|
+
friendly_name "Users API"
|
4
|
+
description <<-DESC
|
5
|
+
The Users API provides full access to manage the users
|
6
|
+
which exist on your account.
|
7
|
+
DESC
|
8
|
+
|
9
|
+
action :list do
|
10
|
+
title "List all users"
|
11
|
+
description "This action will return a list of all users which the authenticated user has access to."
|
12
|
+
param :page, "The page number", :default => 1, :type => Integer
|
13
|
+
param :per_page, "The number of items to return per page", :default => 30, :type => Integer
|
14
|
+
sortable :username, :id, :created_at, :updated_at
|
15
|
+
paginated
|
16
|
+
filterable do
|
17
|
+
attribute :username, :type => String
|
18
|
+
attribute :age, :type => Integer
|
19
|
+
attribute :admin, :type => :boolean
|
20
|
+
end
|
21
|
+
returns :array, :structure => :user
|
22
|
+
action do
|
23
|
+
paginate(User.all) do |user|
|
24
|
+
structure user, :return => true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
action :show do
|
30
|
+
title "Get unit information"
|
31
|
+
param :username, "The user's username", :type => String, :required => true
|
32
|
+
returns :hash, :structure => :user, :structure_opts => {:paramable => true}
|
33
|
+
error "UserNotFound", "No user was found matching the given username", :attributes => {:username => "The username which was looked up"}
|
34
|
+
action do
|
35
|
+
if user = User.find_by_username(params.username)
|
36
|
+
structure user, :return => true
|
37
|
+
else
|
38
|
+
error 'UserNotFound', :username => params.username
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
shared_action :properties do
|
44
|
+
param :username, "The user's username", :type => String
|
45
|
+
param :first_name, "The user's first name", :type => String
|
46
|
+
param :last_name, "The user's last name", :type => String
|
47
|
+
param :email_address, "The user's e-mail address", :type => String
|
48
|
+
param :password, "The user's password", :type => String
|
49
|
+
param :admin, "Should this user be an admin?", :type => :boolean do |object, value|
|
50
|
+
if identity.admin?
|
51
|
+
object.admin = value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
action :create do
|
57
|
+
title "Create a new user"
|
58
|
+
description <<-DESCRIPTION
|
59
|
+
This action will create a new user with the properties which have been provided.
|
60
|
+
DESCRIPTION
|
61
|
+
use :properties
|
62
|
+
returns :hash, :structure => :user, :structure_opts => {:full => true}
|
63
|
+
error "ValidationError", "The details provided were not sufficient to save the user", :attributes => {:errors => "An array of errors for each field"}
|
64
|
+
action do
|
65
|
+
user = User.new
|
66
|
+
if user.save
|
67
|
+
structure user, :return => true
|
68
|
+
else
|
69
|
+
error 'ValidationError', :errors => user.errors
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
action :update do
|
75
|
+
title "Update an existing user"
|
76
|
+
description "This action will update an existing user with the properties provided."
|
77
|
+
param :id, "The ID of the user to update", :type => Integer, :required => true
|
78
|
+
use :properties
|
79
|
+
returns :hash, :structure => :user, :structure_opts => {:full => true}
|
80
|
+
error 'UserNotFound', "The user specified could not be found", :attributes => {:id => "The ID that was looked up"}
|
81
|
+
error "ValidationError", "The details provided were not sufficient to save the user", :attributes => {:errors => "An array of errors for each field"}
|
82
|
+
action do
|
83
|
+
user = User.find_by_id(params.id) || error('UserNotFound', :id => params.id)
|
84
|
+
if user.save
|
85
|
+
structure user, :return => true
|
86
|
+
else
|
87
|
+
error 'ValidationError', :errors => user.errors
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
structure :pet do
|
2
|
+
|
3
|
+
# Uncomment the below line to stop this structure being documented.
|
4
|
+
# no_doc!
|
5
|
+
|
6
|
+
basic :id, "The ID of the pet", :type => Integer, :eg => 148
|
7
|
+
basic :name, "The name of the pet", :type => String, :eg => "Fido"
|
8
|
+
basic :color, "What color is the pet?", :type => String, :eg => "Green"
|
9
|
+
|
10
|
+
expansion :user, "The user who owns this pet", :type => Hash, :structure => :user
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
structure :user do
|
2
|
+
|
3
|
+
basic :id, "The user's internal system ID", :type => Integer, :eg => 123
|
4
|
+
basic :username, "The user's unique username", :type => String, :eg => "adamcooke"
|
5
|
+
group :name do
|
6
|
+
basic :first, "The user's first name", :type => String, :eg => "Adam", :source_attribute => :first_name
|
7
|
+
basic :last, "The user's last name", :type => String, :eg => "Cooke", :source_attribute => :last_name
|
8
|
+
end
|
9
|
+
|
10
|
+
full :admin, "Is this user an administrator?", :type => :boolean
|
11
|
+
full :age, "The user's age", :type => Integer, :doc => false
|
12
|
+
full :created_at, "The timestamp the user was created", :type => :timestamp
|
13
|
+
full :updated_at, "The timestamp the user was updated", :type => :timestamp
|
14
|
+
|
15
|
+
expansion :pets, "All pets that belong to this user", :structure => :pet, :type => Array
|
16
|
+
|
17
|
+
expansion :balance, "The user's balance", :type => Float, :eg => 12.50 do
|
18
|
+
o.user.balance
|
19
|
+
end
|
20
|
+
|
21
|
+
expansion :hidden, "This is a hidden expansion", :doc => false do
|
22
|
+
o.user.hidden
|
23
|
+
end
|
24
|
+
|
25
|
+
condition Proc.new { identity.admin? }, "Can only be accessed by API users with admin access" do
|
26
|
+
# This value will only be provided to users who are accesing the API with
|
27
|
+
# the permission to view
|
28
|
+
full :support_pin, "The PIN this user needs to use to access support", :type => String, :eg => "4953"
|
29
|
+
end
|
30
|
+
|
31
|
+
condition :default => :anonymous do
|
32
|
+
full :mask, "The unique mask that represents this user", :type => String, :eg => 'abc123abc123'
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
html, body, body div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, figure, footer, header, hgroup, menu, nav, section, time, mark, audio, video {
|
2
|
+
margin: 0;
|
3
|
+
padding: 0;
|
4
|
+
border: 0;
|
5
|
+
outline: 0;
|
6
|
+
font-size: 100%;
|
7
|
+
letter-spacing:0;
|
8
|
+
vertical-align: baseline;
|
9
|
+
background: transparent;
|
10
|
+
font-weight:inherit;
|
11
|
+
}
|
12
|
+
|
13
|
+
* {
|
14
|
+
-webkit-box-sizing: border-box;
|
15
|
+
-moz-box-sizing: border-box;
|
16
|
+
box-sizing: border-box;
|
17
|
+
}
|
18
|
+
u { text-decoration: none;}
|
19
|
+
b { font-weight:normal;}
|
20
|
+
article, aside, figure, footer, header, hgroup, nav, section {display: block;}
|
21
|
+
|
22
|
+
object,embed {max-width: 100%;}
|
23
|
+
ul {list-style: none;}
|
24
|
+
blockquote, q {quotes: none;}
|
25
|
+
b,strong { font-weight:bold;}
|
26
|
+
blockquote:before, blockquote:after, q:before, q:after {content: ''; content: none;}
|
27
|
+
|
28
|
+
a {margin: 0; padding: 0; font-size: 100%; vertical-align: baseline; background: transparent;}
|
29
|
+
|
30
|
+
del {text-decoration: line-through;}
|
31
|
+
|
32
|
+
abbr[title], dfn[title] {border-bottom: 1px dotted #000; cursor: help;}
|
33
|
+
|
34
|
+
/* tables still need cellspacing="0" in the markup */
|
35
|
+
table {border-collapse: collapse; border-spacing: 0;}
|
36
|
+
mark { color:inherit;}
|
37
|
+
|
38
|
+
hr {display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0;}
|
39
|
+
|
40
|
+
input, select {vertical-align: middle;}
|
41
|
+
|
42
|
+
pre {
|
43
|
+
white-space: pre; /* CSS2 */
|
44
|
+
white-space: pre-wrap; /* CSS 2.1 */
|
45
|
+
white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
|
46
|
+
word-wrap: break-word; /* IE */
|
47
|
+
}
|
48
|
+
|
49
|
+
input[type="radio"] {vertical-align: text-bottom;}
|
50
|
+
input[type="checkbox"] {vertical-align: bottom; *vertical-align: baseline;}
|
51
|
+
.ie6 input {vertical-align: text-bottom;}
|
52
|
+
|
53
|
+
select, input, textarea {font: 99% sans-serif;}
|
54
|
+
|
55
|
+
table {font-size: inherit; font: 100%;}
|
56
|
+
|
57
|
+
/* Accessible focus treatment
|
58
|
+
people.opera.com/patrickl/experiments/keyboard/test */
|
59
|
+
a:hover, a:active {outline: none;}
|
60
|
+
|
61
|
+
small {font-size: 85%;}
|
62
|
+
|
63
|
+
strong, th {font-weight: bold;}
|
64
|
+
|
65
|
+
td, td img {vertical-align: top;}
|
66
|
+
|
67
|
+
/* Make sure sup and sub don't screw with your line-heights
|
68
|
+
gist.github.com/413930 */
|
69
|
+
sub, sup {font-size: 75%; line-height: 0; position: relative;}
|
70
|
+
sup {top: -0.5em;}
|
71
|
+
sub {bottom: -0.25em;}
|
72
|
+
|
73
|
+
/* standardize any monospaced elements */
|
74
|
+
pre, code, kbd, samp {font-family: monospace, sans-serif;}
|
75
|
+
|
76
|
+
/* hand cursor on clickable elements */
|
77
|
+
.clickable,
|
78
|
+
label,
|
79
|
+
input[type=button],
|
80
|
+
input[type=submit],
|
81
|
+
button {cursor: pointer;}
|
82
|
+
|
83
|
+
/* Webkit browsers add a 2px margin outside the chrome of form elements */
|
84
|
+
button, input, select, textarea {margin: 0;}
|
85
|
+
|
86
|
+
/* make buttons play nice in IE */
|
87
|
+
button {width: auto; overflow: visible;}
|
88
|
+
|
89
|
+
/* scale images in IE7 more attractively */
|
90
|
+
.ie7 img {-ms-interpolation-mode: bicubic;}
|
91
|
+
|
92
|
+
/* prevent BG image flicker upon hover */
|
93
|
+
.ie6 html {filter: expression(document.execCommand("BackgroundImageCache", false, true));}
|
94
|
+
|
95
|
+
/* let's clear some floats */
|
96
|
+
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
|
97
|
+
.clearfix:after { clear: both; }
|
98
|
+
.clearfix { zoom: 1; }
|
99
|
+
|
100
|
+
select, input, textarea, a { outline: none;}
|
101
|
+
a { color:inherit;}
|
@@ -0,0 +1,348 @@
|
|
1
|
+
html {
|
2
|
+
font-family: Lato, Arial, sans-serif;
|
3
|
+
font-size:16px;
|
4
|
+
}
|
5
|
+
|
6
|
+
a {
|
7
|
+
text-decoration: none;
|
8
|
+
}
|
9
|
+
|
10
|
+
.sidebarBackground {
|
11
|
+
background:#2f3e4d;
|
12
|
+
width:200px;
|
13
|
+
position:fixed;
|
14
|
+
top:0;
|
15
|
+
bottom:0;
|
16
|
+
z-index:1;
|
17
|
+
}
|
18
|
+
|
19
|
+
.sidebar {
|
20
|
+
width:200px;
|
21
|
+
float:left;
|
22
|
+
z-index:10;
|
23
|
+
position:absolute;
|
24
|
+
}
|
25
|
+
.sidebar a {
|
26
|
+
display:block;
|
27
|
+
padding:7px 15px;
|
28
|
+
border-bottom:1px solid #394959;
|
29
|
+
color:#889db1;
|
30
|
+
font-size:85%;
|
31
|
+
}
|
32
|
+
|
33
|
+
.sidebar a:hover {
|
34
|
+
background-color:#26323f;
|
35
|
+
}
|
36
|
+
|
37
|
+
.sidebar a.active {
|
38
|
+
background-color:#1d2630;
|
39
|
+
color:#fff;
|
40
|
+
}
|
41
|
+
|
42
|
+
.footer {
|
43
|
+
margin-left:200px;
|
44
|
+
border-top:3px solid #efefef;
|
45
|
+
padding:20px 40px 100px 40px;
|
46
|
+
font-size:90%;
|
47
|
+
color:#999;
|
48
|
+
}
|
49
|
+
|
50
|
+
.content {
|
51
|
+
margin-left:200px;
|
52
|
+
padding:40px;
|
53
|
+
padding-right:15%;
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
.content h1 {
|
58
|
+
font-size:32px;
|
59
|
+
font-weight:900;
|
60
|
+
margin-bottom:15px;
|
61
|
+
}
|
62
|
+
|
63
|
+
.content h2 {
|
64
|
+
font-size:24px;
|
65
|
+
font-weight:700;
|
66
|
+
color:#f65552;
|
67
|
+
margin-bottom:10px;
|
68
|
+
margin-top:30px;
|
69
|
+
}
|
70
|
+
|
71
|
+
.content h3 {
|
72
|
+
font-size:18px;
|
73
|
+
font-weight:700;
|
74
|
+
color:#888;
|
75
|
+
margin-bottom:10px;
|
76
|
+
margin-top:30px;
|
77
|
+
}
|
78
|
+
|
79
|
+
.content p.text {
|
80
|
+
line-height:1.5;
|
81
|
+
margin-bottom:15px;
|
82
|
+
}
|
83
|
+
|
84
|
+
|
85
|
+
.content .standardList {
|
86
|
+
margin-bottom:15px;
|
87
|
+
line-height:1.5;
|
88
|
+
}
|
89
|
+
|
90
|
+
.content .standardList li {
|
91
|
+
list-style:square;
|
92
|
+
margin-bottom:15px;
|
93
|
+
margin-left:35px;
|
94
|
+
}
|
95
|
+
|
96
|
+
.content code {
|
97
|
+
font-family:'Droid Sans Mono', fixed;
|
98
|
+
color:#f65552;
|
99
|
+
padding:1px 2px;
|
100
|
+
font-size:90%;
|
101
|
+
}
|
102
|
+
|
103
|
+
.content pre.code {
|
104
|
+
font-family:'Droid Sans Mono', fixed;
|
105
|
+
white-space: pre;
|
106
|
+
background:#efefef;
|
107
|
+
padding:10px 10px 10px;
|
108
|
+
font-size:90%;
|
109
|
+
margin-bottom:15px;
|
110
|
+
border-radius:7px 7px 7px 7px;
|
111
|
+
}
|
112
|
+
|
113
|
+
.content pre.code span.jsonKey {
|
114
|
+
color:#7f55ad;
|
115
|
+
font-weight:bold;
|
116
|
+
}
|
117
|
+
|
118
|
+
.content pre.code span.jsonString {
|
119
|
+
color:#9eb503;
|
120
|
+
}
|
121
|
+
|
122
|
+
.content pre.code span.jsonComment {
|
123
|
+
color:#bbb;
|
124
|
+
font-style:italic;
|
125
|
+
}
|
126
|
+
|
127
|
+
.content a.link {
|
128
|
+
color:#2d80c8;
|
129
|
+
font-weight:700;
|
130
|
+
border-bottom:1px solid #2d80c8;
|
131
|
+
}
|
132
|
+
|
133
|
+
.content p.apiURL span {
|
134
|
+
color:#aaa;
|
135
|
+
}
|
136
|
+
|
137
|
+
.table {
|
138
|
+
width:100%;
|
139
|
+
}
|
140
|
+
|
141
|
+
.table th, .table td {
|
142
|
+
border-bottom:1px solid #ccc;
|
143
|
+
text-align: left;
|
144
|
+
padding:7px 0;
|
145
|
+
}
|
146
|
+
|
147
|
+
.table th {
|
148
|
+
border-bottom:2px solid #666;
|
149
|
+
font-size:90%;
|
150
|
+
}
|
151
|
+
|
152
|
+
.paramTable__req {
|
153
|
+
background:#ea4c89;
|
154
|
+
color:#fff;
|
155
|
+
font-weight:bold;
|
156
|
+
font-size:10px;
|
157
|
+
text-transform: uppercase;
|
158
|
+
padding:1px 3px;
|
159
|
+
border-radius: 2px;
|
160
|
+
vertical-align: 1px;
|
161
|
+
margin-left:5px;
|
162
|
+
}
|
163
|
+
|
164
|
+
.paramTable__field {
|
165
|
+
width:100%;
|
166
|
+
border:0;
|
167
|
+
padding:0;
|
168
|
+
font:inherit;
|
169
|
+
color:#7f55ad;
|
170
|
+
}
|
171
|
+
|
172
|
+
.paramTable__description {
|
173
|
+
font-size:90%;
|
174
|
+
color:#999;
|
175
|
+
margin-top:3px;
|
176
|
+
}
|
177
|
+
|
178
|
+
.paramTable__name {
|
179
|
+
font-family:'Droid Sans Mono', fixed;
|
180
|
+
font-size:90%;
|
181
|
+
}
|
182
|
+
|
183
|
+
.paramTable__restrictedList {
|
184
|
+
font-size:80%;
|
185
|
+
margin-top:7px;
|
186
|
+
background:url(lock.svg) no-repeat 0 1px;
|
187
|
+
background-size:14px;
|
188
|
+
color:#ed4300;
|
189
|
+
padding-left:20px;
|
190
|
+
}
|
191
|
+
|
192
|
+
.paramTable__nil {
|
193
|
+
color:#ccc;
|
194
|
+
font-size:90%;
|
195
|
+
}
|
196
|
+
|
197
|
+
.apiURLFull {
|
198
|
+
font-size:110%;
|
199
|
+
font-weight:bold;
|
200
|
+
}
|
201
|
+
|
202
|
+
.apiURLFull span {
|
203
|
+
color:#aaaaaa;
|
204
|
+
font-weight:normal;
|
205
|
+
}
|
206
|
+
|
207
|
+
.errorAttributeList {
|
208
|
+
font-size:80%;
|
209
|
+
}
|
210
|
+
|
211
|
+
.errorAttributeList li {
|
212
|
+
margin-bottom:8px;
|
213
|
+
list-style:square;
|
214
|
+
margin-left:16px;
|
215
|
+
}
|
216
|
+
.errorAttributeList li:last-child {
|
217
|
+
margin-bottom:0;
|
218
|
+
}
|
219
|
+
|
220
|
+
.errorAttributeList__name {
|
221
|
+
font-family:'Droid Sans Mono', fixed;
|
222
|
+
}
|
223
|
+
|
224
|
+
.errorAttributeList__desc {
|
225
|
+
color:#999;
|
226
|
+
}
|
227
|
+
|
228
|
+
/* Try Action Form */
|
229
|
+
|
230
|
+
.tryForm {
|
231
|
+
display:none;
|
232
|
+
border:2px solid #ccc;
|
233
|
+
background:#f7f7f7;
|
234
|
+
border-radius:7px;
|
235
|
+
overflow: hidden;
|
236
|
+
}
|
237
|
+
|
238
|
+
.tryForm__header {
|
239
|
+
background:#ddd;
|
240
|
+
padding:15px 25px;
|
241
|
+
font-weight:700;
|
242
|
+
color:#999;
|
243
|
+
|
244
|
+
}
|
245
|
+
|
246
|
+
.tryForm__header input {
|
247
|
+
background:none;
|
248
|
+
border:0;
|
249
|
+
padding:0;
|
250
|
+
vertical-align:0px;
|
251
|
+
font:inherit;
|
252
|
+
font-weight:700;
|
253
|
+
color:#000;
|
254
|
+
width:auto;
|
255
|
+
}
|
256
|
+
|
257
|
+
.tryForm__output {
|
258
|
+
display:none;
|
259
|
+
background:#111;
|
260
|
+
color:#fff;
|
261
|
+
padding:15px;
|
262
|
+
font-family:'Droid Sans Mono', fixed;
|
263
|
+
white-space: pre;
|
264
|
+
word-wrap:normal;
|
265
|
+
font-size:90%;
|
266
|
+
overflow-x:auto;
|
267
|
+
}
|
268
|
+
|
269
|
+
.tryForm__output--success {
|
270
|
+
border-top:7px solid #68be28;
|
271
|
+
}
|
272
|
+
|
273
|
+
.tryForm__output--error {
|
274
|
+
border-top:7px solid #d4172e;
|
275
|
+
}
|
276
|
+
|
277
|
+
.tryForm__heading {
|
278
|
+
border-bottom:1px solid #ddd;
|
279
|
+
border-top:4px solid #aaa;
|
280
|
+
margin-bottom:15px;
|
281
|
+
padding:8px 25px;
|
282
|
+
background:#efefef;
|
283
|
+
font-weight:700;
|
284
|
+
font-size:80%;
|
285
|
+
text-transform: uppercase;
|
286
|
+
color:#888;
|
287
|
+
}
|
288
|
+
|
289
|
+
.tryForm__table {
|
290
|
+
font-size:90%;
|
291
|
+
width:calc(100% - 50px);
|
292
|
+
margin:0 25px;
|
293
|
+
margin-bottom:15px;
|
294
|
+
}
|
295
|
+
|
296
|
+
.tryForm__table td {
|
297
|
+
padding:5px 0;
|
298
|
+
background:#f8f8f8;
|
299
|
+
}
|
300
|
+
|
301
|
+
.tryForm__tableField {
|
302
|
+
border:0;
|
303
|
+
background:none;
|
304
|
+
border-bottom:1px solid #ccc;
|
305
|
+
padding:0;
|
306
|
+
padding-bottom:4px;
|
307
|
+
width:100%;
|
308
|
+
font:inherit;
|
309
|
+
color:#7f55ad;
|
310
|
+
font-weight:700;
|
311
|
+
}
|
312
|
+
|
313
|
+
.tryForm__tableField:focus {
|
314
|
+
border-color:#7f55ad;
|
315
|
+
}
|
316
|
+
|
317
|
+
.tryForm__button {
|
318
|
+
margin:15px 25px;
|
319
|
+
text-align: right;
|
320
|
+
}
|
321
|
+
|
322
|
+
.tryFormActivate {
|
323
|
+
margin:20px 0;
|
324
|
+
}
|
325
|
+
.tryFormActivate__button {
|
326
|
+
background:url(tool.svg) #fffce0 no-repeat 12px 7px;
|
327
|
+
background-size:12px;
|
328
|
+
border:1px solid #dad7bb;
|
329
|
+
color:#6c6a55;
|
330
|
+
border-radius:4px;
|
331
|
+
padding:6px 12px 6px 30px;
|
332
|
+
font-size:12px;
|
333
|
+
font-weight:700;
|
334
|
+
}
|
335
|
+
|
336
|
+
.tryForm__checkbox {
|
337
|
+
margin-bottom:4px;
|
338
|
+
}
|
339
|
+
|
340
|
+
.tryForm__checkbox:last-child {
|
341
|
+
margin-bottom:0;
|
342
|
+
}
|
343
|
+
|
344
|
+
.tryForm__checkbox input {
|
345
|
+
float:left;
|
346
|
+
margin-right:4px;
|
347
|
+
margin-top:4px;
|
348
|
+
}
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
2
|
+
<path fill="#6c6a55" d="M5.5 0c-1.38 0-2.5 1.12-2.5 2.5 0 .32.08.62.19.91l-2.91 2.88c-.39.39-.39 1.05 0 1.44.2.2.46.28.72.28.26 0 .52-.09.72-.28l2.88-2.91c.28.11.58.19.91.19 1.38 0 2.5-1.12 2.5-2.5 0-.16 0-.32-.03-.47l-.97.97h-2v-2l.97-.97c-.15-.03-.31-.03-.47-.03zm-4.5 6.5c.28 0 .5.22.5.5s-.22.5-.5.5-.5-.22-.5-.5.22-.5.5-.5z"
|
3
|
+
/>
|
4
|
+
</svg>
|