idcf-json_hyper_schema 0.1.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 +7 -0
- data/.codeclimate.yml +21 -0
- data/.gitignore +10 -0
- data/.rubocop.yml +28 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +58 -0
- data/LICENSE.txt +21 -0
- data/README.md +174 -0
- data/Rakefile +8 -0
- data/bin/json_expand +12 -0
- data/idcf-json_hyper_schema.gemspec +31 -0
- data/lib/idcf/json_hyper_schema.rb +14 -0
- data/lib/idcf/json_hyper_schema/analyst.rb +155 -0
- data/lib/idcf/json_hyper_schema/expands/base.rb +185 -0
- data/lib/idcf/json_hyper_schema/expands/link_info_base.rb +201 -0
- data/lib/idcf/json_hyper_schema/expands/link_info_v4.rb +10 -0
- data/lib/idcf/json_hyper_schema/expands/v4.rb +10 -0
- data/lib/idcf/json_hyper_schema/version.rb +5 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ffd49fb93bcdb6b81071e58dd5ebebb6587941db
|
4
|
+
data.tar.gz: b118944ec52abfc512b2485cd09cc0dc6e555d92
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 65a81b483dd7ba5850af10409de7e642b41b0c46218fe30caffe171cb9fb7b645c0ea3d04e723250bcfa0b87ef2027be6d2b53407ccc1cec636dd3d70730e937
|
7
|
+
data.tar.gz: 509d639623c599763209b9690b5dd8436f8aa935841e286c05d050d3ba9f522142ad118d71f5056eed4465477c54a0fe70d9fd137142ee13cf11c0972981a824
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
engines:
|
3
|
+
duplication:
|
4
|
+
enabled: true
|
5
|
+
config:
|
6
|
+
languages:
|
7
|
+
- ruby
|
8
|
+
exclude_paths:
|
9
|
+
- 'test/**/*'
|
10
|
+
fixme:
|
11
|
+
enabled: true
|
12
|
+
rubocop:
|
13
|
+
enabled: true
|
14
|
+
ratings:
|
15
|
+
paths:
|
16
|
+
- "**.rb"
|
17
|
+
exclude_paths:
|
18
|
+
- vendor/bundle
|
19
|
+
- .idea
|
20
|
+
- bin
|
21
|
+
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.2
|
3
|
+
Metrics/BlockLength:
|
4
|
+
Exclude:
|
5
|
+
- '*.gemspec'
|
6
|
+
- 'spec/**/*'
|
7
|
+
Metrics/LineLength:
|
8
|
+
Exclude:
|
9
|
+
- 'spec/**/*'
|
10
|
+
Metrics/MethodLength:
|
11
|
+
Exclude:
|
12
|
+
- 'spec/**/*'
|
13
|
+
Metrics/ClassLength:
|
14
|
+
Exclude:
|
15
|
+
- 'spec/**/*'
|
16
|
+
Style/IdenticalConditionalBranches:
|
17
|
+
Exclude:
|
18
|
+
- 'spec/**/*'
|
19
|
+
Metrics/PerceivedComplexity:
|
20
|
+
Exclude:
|
21
|
+
- 'spec/**/*'
|
22
|
+
Metrics/AbcSize:
|
23
|
+
Exclude:
|
24
|
+
- 'spec/**/*'
|
25
|
+
Style/ClassLength:
|
26
|
+
Max: 150
|
27
|
+
Style/MethodLength:
|
28
|
+
Max: 15
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
idcf-json_hyper_schema (0.1.0)
|
5
|
+
activerecord (~> 4.2, >= 4.2.3)
|
6
|
+
activesupport (~> 4.2, >= 4.2.3)
|
7
|
+
json_schema (~> 0.17.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (4.2.10)
|
13
|
+
activesupport (= 4.2.10)
|
14
|
+
builder (~> 3.1)
|
15
|
+
activerecord (4.2.10)
|
16
|
+
activemodel (= 4.2.10)
|
17
|
+
activesupport (= 4.2.10)
|
18
|
+
arel (~> 6.0)
|
19
|
+
activesupport (4.2.10)
|
20
|
+
i18n (~> 0.7)
|
21
|
+
minitest (~> 5.1)
|
22
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
23
|
+
tzinfo (~> 1.1)
|
24
|
+
arel (6.0.4)
|
25
|
+
builder (3.2.3)
|
26
|
+
diff-lcs (1.3)
|
27
|
+
i18n (0.8.6)
|
28
|
+
json_schema (0.17.0)
|
29
|
+
minitest (5.10.3)
|
30
|
+
rake (10.5.0)
|
31
|
+
rspec (3.6.0)
|
32
|
+
rspec-core (~> 3.6.0)
|
33
|
+
rspec-expectations (~> 3.6.0)
|
34
|
+
rspec-mocks (~> 3.6.0)
|
35
|
+
rspec-core (3.6.0)
|
36
|
+
rspec-support (~> 3.6.0)
|
37
|
+
rspec-expectations (3.6.0)
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
+
rspec-support (~> 3.6.0)
|
40
|
+
rspec-mocks (3.6.0)
|
41
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
42
|
+
rspec-support (~> 3.6.0)
|
43
|
+
rspec-support (3.6.0)
|
44
|
+
thread_safe (0.3.6)
|
45
|
+
tzinfo (1.2.3)
|
46
|
+
thread_safe (~> 0.1)
|
47
|
+
|
48
|
+
PLATFORMS
|
49
|
+
ruby
|
50
|
+
|
51
|
+
DEPENDENCIES
|
52
|
+
bundler (~> 1.14)
|
53
|
+
idcf-json_hyper_schema!
|
54
|
+
rake (~> 10.0)
|
55
|
+
rspec
|
56
|
+
|
57
|
+
BUNDLED WITH
|
58
|
+
1.15.4
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 tkiminami
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# Idcf::JsonHyperSchema
|
2
|
+
|
3
|
+
Analysis of json-hyper-schema
|
4
|
+
|
5
|
+
## Supported Draft Version(s)
|
6
|
+
- draft-4
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Note: requires Ruby 2.2.7 or higher.
|
11
|
+
|
12
|
+
```
|
13
|
+
gem 'idcf-json_hyper_schema'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
```
|
19
|
+
$ bundle
|
20
|
+
```
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
```
|
25
|
+
$ gem install idcf-json_hyper_schema
|
26
|
+
```
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
### How to Expand
|
31
|
+
```
|
32
|
+
bin/json_expand [path] > [output path]
|
33
|
+
```
|
34
|
+
|
35
|
+
### load
|
36
|
+
```
|
37
|
+
require 'idcf/json_hyper_schema'
|
38
|
+
|
39
|
+
path = File.expand_path('./sample.json')
|
40
|
+
p Idcf::JsonHyperSchema::Analyst.new.load(path)
|
41
|
+
```
|
42
|
+
|
43
|
+
### expand
|
44
|
+
```
|
45
|
+
require 'idcf/json_hyper_schema'
|
46
|
+
|
47
|
+
path = File.expand_path('./sample.json')
|
48
|
+
j = JSON.parse(File.read(path))
|
49
|
+
expand_obj = Idcf::JsonHyperSchema::Analyst.new.expand(j)
|
50
|
+
p expand_obj.schema
|
51
|
+
```
|
52
|
+
|
53
|
+
### expand options
|
54
|
+
|
55
|
+
| name | type | default | description |
|
56
|
+
| ---- | ---- | ---- | ---- |
|
57
|
+
| global_access | boolean | true | '$ref' but when showing outside, is it acquired? |
|
58
|
+
|
59
|
+
|
60
|
+
### links
|
61
|
+
```
|
62
|
+
require 'idcf/json_hyper_schema'
|
63
|
+
|
64
|
+
path = File.expand_path('./sample.json')
|
65
|
+
analyst = Idcf::JsonHyperSchema::Analyst.new.load(path)
|
66
|
+
p analyst.links(j)
|
67
|
+
```
|
68
|
+
|
69
|
+
or
|
70
|
+
|
71
|
+
```
|
72
|
+
require 'idcf/json_hyper_schema'
|
73
|
+
|
74
|
+
path = File.expand_path('./sample.json')
|
75
|
+
j = JSON.parse(File.read(path))
|
76
|
+
p Idcf::JsonHyperSchema::Analyst.new.schema_links(j)
|
77
|
+
```
|
78
|
+
|
79
|
+
## How to Use the Link Object
|
80
|
+
|
81
|
+
| Q | example | note |
|
82
|
+
|:---|:---|:---|
|
83
|
+
| description | link.description | |
|
84
|
+
| title | link.title | |
|
85
|
+
| method | link.method | Returned in lower case |
|
86
|
+
| How do I know the right method to use? | link.method?('get') | Case insensitive |
|
87
|
+
| How can I get a replaceable URL? | link.href | |
|
88
|
+
| Can I get a list of replacement parameters for URLs? | link.url_param_names | /api/{name}/{sec}{?hoge} : ["name", "sec"] |
|
89
|
+
| Can I get a list of get parameters? | link.query_param_names | /api/{name}/{sec}{?hoge} : ["hoge"] |
|
90
|
+
| Can I get a parameter information? | link.properties | |
|
91
|
+
| What can I do when I want to know what are required information? | link.required | |
|
92
|
+
| How can I create a URL by handing over parameters? | link.make_uri(['aaa'], { 'hoge' => 'h_param' }) | api/{name}{?hoge} -> api/aaa?hoge=h_param |
|
93
|
+
| How can I create a POST parameter by handing over parameters? | link.make_params({ 'hoge' => 'h_param' }) | { 'hoge' => 'h_param' } |
|
94
|
+
|
95
|
+
## shema example
|
96
|
+
|
97
|
+
### post
|
98
|
+
```post example
|
99
|
+
{
|
100
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
101
|
+
"title": "sample",
|
102
|
+
"description": "",
|
103
|
+
"definitions": {},
|
104
|
+
"properties": {
|
105
|
+
"test": {
|
106
|
+
"links": [
|
107
|
+
{
|
108
|
+
"title": "sample",
|
109
|
+
"description": "",
|
110
|
+
"href": "/api/{name}",
|
111
|
+
"method": "post",
|
112
|
+
"rel": "self",
|
113
|
+
"schema": {
|
114
|
+
"properties": {
|
115
|
+
"hoge": {
|
116
|
+
"type": "string"
|
117
|
+
}
|
118
|
+
}
|
119
|
+
},
|
120
|
+
"targetSchema": {
|
121
|
+
"example": {},
|
122
|
+
"properties": {}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
]
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
```
|
130
|
+
|
131
|
+
### get
|
132
|
+
|
133
|
+
```get example
|
134
|
+
{
|
135
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
136
|
+
"title": "sample",
|
137
|
+
"description": "",
|
138
|
+
"definitions": {},
|
139
|
+
"properties": {
|
140
|
+
"test": {
|
141
|
+
"links": [
|
142
|
+
{
|
143
|
+
"title": "sample",
|
144
|
+
"description": "",
|
145
|
+
"href": "/api/{name}{?hoge,piyo}",
|
146
|
+
"method": "post",
|
147
|
+
"rel": "self",
|
148
|
+
"schema": {
|
149
|
+
"properties": {}
|
150
|
+
},
|
151
|
+
"targetSchema": {
|
152
|
+
"example": {},
|
153
|
+
"properties": {}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
]
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
```
|
161
|
+
|
162
|
+
## Development
|
163
|
+
|
164
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
165
|
+
|
166
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
167
|
+
|
168
|
+
## Contributing
|
169
|
+
|
170
|
+
1. Fork it ( https://github.com/idcf/idcf-json_hyper_schema/fork )
|
171
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
172
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
173
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
174
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/json_expand
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'idcf/json_hyper_schema'
|
5
|
+
require 'active_support'
|
6
|
+
require 'active_support/core_ext'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
raise 'not found path' if ARGV.empty?
|
10
|
+
path = File.expand_path(ARGV[0])
|
11
|
+
analyst = Idcf::JsonHyperSchema::Analyst.new.load(path)
|
12
|
+
puts JSON.pretty_generate(analyst.load_schema)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'idcf/json_hyper_schema/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'idcf-json_hyper_schema'
|
8
|
+
spec.version = Idcf::JsonHyperSchema::VERSION
|
9
|
+
spec.authors = ['IDC Frontier Inc.']
|
10
|
+
spec.email = []
|
11
|
+
|
12
|
+
spec.summary = 'IDCF Json-Hyper-Schema Expand tools'
|
13
|
+
spec.description = 'IDCF Json-Hyper-Schema Expand tools'
|
14
|
+
spec.homepage = 'https://www.idcfcloud.jp'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = 'exe'
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec'
|
27
|
+
|
28
|
+
spec.add_dependency 'activerecord', '~> 4.2', '>= 4.2.3'
|
29
|
+
spec.add_dependency 'activesupport', '~> 4.2', '>= 4.2.3'
|
30
|
+
spec.add_dependency 'json_schema', '~> 0.17.0'
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative './json_hyper_schema/version'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
require 'active_support/core_ext/class/attribute'
|
5
|
+
require 'active_support/dependencies/autoload'
|
6
|
+
require 'json_schema'
|
7
|
+
|
8
|
+
module Idcf
|
9
|
+
# json_hyper_schema
|
10
|
+
module JsonHyperSchema
|
11
|
+
extend ActiveSupport::Autoload
|
12
|
+
autoload :Analyst, 'idcf/json_hyper_schema/analyst'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
module Idcf
|
2
|
+
module JsonHyperSchema
|
3
|
+
# json-hyper-schema analyst
|
4
|
+
class Analyst
|
5
|
+
attr_reader :process_version, :schema, :load_schema
|
6
|
+
|
7
|
+
# json file laod
|
8
|
+
#
|
9
|
+
# @param path [String]
|
10
|
+
# @param options [Hash]
|
11
|
+
# @return [Hash]
|
12
|
+
# @raise
|
13
|
+
def load(path, options = {})
|
14
|
+
@schema ||= {}
|
15
|
+
unless @schema[path].nil?
|
16
|
+
@load_schema = @schema[path]
|
17
|
+
return self
|
18
|
+
end
|
19
|
+
j = JSON.parse(File.read(path))
|
20
|
+
@load_schema = expand(j, options).schema
|
21
|
+
@schema[path] = @load_schema
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# json file laod
|
26
|
+
#
|
27
|
+
# @param schema [Hash]
|
28
|
+
# @param options [Hash]
|
29
|
+
# @return [Expand::Base]
|
30
|
+
# @raise
|
31
|
+
def expand(schema, options = {})
|
32
|
+
return schema unless schema.class == Hash
|
33
|
+
@process_version = schema_version(schema)
|
34
|
+
result = expand_class.new(options)
|
35
|
+
result.do!(schema)
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
# links
|
40
|
+
#
|
41
|
+
# @return Expands::LinkInfoBase
|
42
|
+
def links
|
43
|
+
p_schema = JsonSchema.parse!(@load_schema)
|
44
|
+
@process_version = schema_version(p_schema)
|
45
|
+
p_schema.expand_references!
|
46
|
+
find_links(p_schema)
|
47
|
+
end
|
48
|
+
|
49
|
+
# schema links
|
50
|
+
#
|
51
|
+
# @param schema [Hash]
|
52
|
+
# @param options [Hash]
|
53
|
+
# @return Expands::LinkInfoBase
|
54
|
+
def schema_links(schema, options = {})
|
55
|
+
ex_schema = expand(schema, options)
|
56
|
+
p_schema = JsonSchema.parse!(ex_schema.schema)
|
57
|
+
t_v = @process_version
|
58
|
+
p_schema.expand_references!
|
59
|
+
result = find_links(p_schema)
|
60
|
+
@process_version = t_v
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# base module
|
67
|
+
# namespace
|
68
|
+
#
|
69
|
+
# @return [String]
|
70
|
+
def base_module
|
71
|
+
list = self.class.to_s.underscore.split('/')
|
72
|
+
list.pop
|
73
|
+
list.join('/')
|
74
|
+
end
|
75
|
+
|
76
|
+
# expand class
|
77
|
+
#
|
78
|
+
# @return [Class]
|
79
|
+
def expand_class
|
80
|
+
path = "#{base_module}/expands/#{@process_version}"
|
81
|
+
require path
|
82
|
+
path.classify.constantize
|
83
|
+
end
|
84
|
+
|
85
|
+
# find links
|
86
|
+
#
|
87
|
+
# @param schema [JsonSchema::Schema]
|
88
|
+
# @return [Array]
|
89
|
+
# @raise
|
90
|
+
def find_links(schema)
|
91
|
+
[].tap do |result|
|
92
|
+
l_class = link_class
|
93
|
+
schema.links.each do |link|
|
94
|
+
link_obj = l_class.new(link)
|
95
|
+
result << link_obj
|
96
|
+
end
|
97
|
+
|
98
|
+
schema.properties.each do |_, sub|
|
99
|
+
result.concat(find_links(sub))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# link class
|
105
|
+
#
|
106
|
+
# @return [Idcf::JsonHyperSchema::Expands::LinkInfoBase]
|
107
|
+
# @raise
|
108
|
+
def link_class
|
109
|
+
path = "#{base_module}/expands/link_info_#{@process_version}"
|
110
|
+
require path
|
111
|
+
path.classify.constantize
|
112
|
+
end
|
113
|
+
|
114
|
+
# schema version
|
115
|
+
#
|
116
|
+
# @param schema [Hash]
|
117
|
+
# @return [String]
|
118
|
+
# @raise
|
119
|
+
def schema_version(schema)
|
120
|
+
v_list = schema_version_list
|
121
|
+
result = v_list.last
|
122
|
+
check = schema.is_a?(JsonSchema::Schema) ? schema.data : schema
|
123
|
+
unless check['$schema'].nil? || check['$schema'].empty?
|
124
|
+
result = schema_version_str(check['$schema'])
|
125
|
+
end
|
126
|
+
|
127
|
+
raise 'The undefined version.' if v_list.index(result).nil?
|
128
|
+
result
|
129
|
+
end
|
130
|
+
|
131
|
+
# schema version list
|
132
|
+
# support schema version list
|
133
|
+
#
|
134
|
+
# @return array
|
135
|
+
def schema_version_list
|
136
|
+
result = []
|
137
|
+
Dir.glob("#{File.dirname(__FILE__)}/expands/v*.rb") do |f|
|
138
|
+
result << File.basename(f, '.rb')
|
139
|
+
end
|
140
|
+
result.sort
|
141
|
+
end
|
142
|
+
|
143
|
+
# schema version str
|
144
|
+
#
|
145
|
+
# @param schema [String] $schema
|
146
|
+
# @return [String]
|
147
|
+
def schema_version_str(schema)
|
148
|
+
schema =~ /draft[^\d]{1,2}(\d+)/
|
149
|
+
mt = Regexp.last_match(1)
|
150
|
+
return "v#{mt.to_i}" unless mt.nil?
|
151
|
+
''
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require_relative '../analyst'
|
3
|
+
module Idcf
|
4
|
+
module JsonHyperSchema
|
5
|
+
module Expands
|
6
|
+
# json schema expand
|
7
|
+
# json schema v4
|
8
|
+
class Base
|
9
|
+
FULL_HREF_REGEXP = Regexp.new('\A[a-zA-Z]*:?//').freeze
|
10
|
+
attr_reader :origin,
|
11
|
+
:definition_ids,
|
12
|
+
:schema,
|
13
|
+
:options
|
14
|
+
|
15
|
+
# initialize
|
16
|
+
#
|
17
|
+
# @param global_access [Boolean] Is an external reference performed?
|
18
|
+
def initialize(global_access: true)
|
19
|
+
@definition_ids = {}
|
20
|
+
@options =
|
21
|
+
{
|
22
|
+
global_access: global_access
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# do
|
27
|
+
#
|
28
|
+
# @param schema [Hash]
|
29
|
+
# @return [Hash]
|
30
|
+
# @raise
|
31
|
+
def do!(schema)
|
32
|
+
raise 'schema is not hash' unless schema.class == Hash
|
33
|
+
target = schema.deep_dup
|
34
|
+
@origin = schema.deep_dup
|
35
|
+
@definition_ids = delete_id(make_ids(target))
|
36
|
+
@schema = exp(target)
|
37
|
+
@schema
|
38
|
+
end
|
39
|
+
|
40
|
+
# ref find
|
41
|
+
#
|
42
|
+
# @param path [String]
|
43
|
+
# @return Mixed
|
44
|
+
def find(path)
|
45
|
+
if path =~ FULL_HREF_REGEXP
|
46
|
+
return path unless @options[:global_access]
|
47
|
+
global_find(path)
|
48
|
+
else
|
49
|
+
local_search(path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def make_ids(schema)
|
56
|
+
{}.tap do |result|
|
57
|
+
next if schema['definitions'].nil?
|
58
|
+
schema['definitions'].each do |_k, v|
|
59
|
+
result[v['id']] = v.deep_dup unless v['id'].nil?
|
60
|
+
result.merge!(search_child_ids(v))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def search_child_ids(child)
|
66
|
+
{}.tap do |result|
|
67
|
+
next unless child.class == Hash
|
68
|
+
child.each do |_k, v|
|
69
|
+
next unless v.class == Hash
|
70
|
+
result[v['id']] = v.deep_dup unless v['id'].nil?
|
71
|
+
result.merge!(search_child_ids(v))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete_id(data)
|
77
|
+
return data unless data.class == Hash
|
78
|
+
data.delete('id') if data['id'].class != Hash
|
79
|
+
|
80
|
+
data.each do |k, v|
|
81
|
+
data[k] = delete_id(v)
|
82
|
+
end
|
83
|
+
data
|
84
|
+
end
|
85
|
+
|
86
|
+
def exp(schema)
|
87
|
+
case schema
|
88
|
+
when Hash
|
89
|
+
schema = exp_hash(schema)
|
90
|
+
when Array
|
91
|
+
schema = exp_array(schema)
|
92
|
+
end
|
93
|
+
|
94
|
+
schema
|
95
|
+
end
|
96
|
+
|
97
|
+
def exp_hash(schema)
|
98
|
+
schema.keys.each do |k|
|
99
|
+
exp = expansion(k, schema[k])
|
100
|
+
if k == '$ref' && exp.class == Hash
|
101
|
+
schema.delete(k)
|
102
|
+
schema.merge!(exp)
|
103
|
+
else
|
104
|
+
schema[k] = exp
|
105
|
+
end
|
106
|
+
end
|
107
|
+
schema
|
108
|
+
end
|
109
|
+
|
110
|
+
def exp_array(schema)
|
111
|
+
schema.each_with_index do |v, k|
|
112
|
+
schema[k] = expansion(k, v)
|
113
|
+
end
|
114
|
+
schema
|
115
|
+
end
|
116
|
+
|
117
|
+
def expansion(key, piece)
|
118
|
+
case piece
|
119
|
+
when String
|
120
|
+
expansion_string(key, piece)
|
121
|
+
when Hash, Array
|
122
|
+
exp(piece)
|
123
|
+
else
|
124
|
+
piece
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def expansion_string(key, piece)
|
129
|
+
return piece unless key == '$ref'
|
130
|
+
d = find(piece)
|
131
|
+
return piece if d.nil?
|
132
|
+
return exp(d) if d.class == Hash || d.class == Array
|
133
|
+
|
134
|
+
key = piece
|
135
|
+
key = Regexp.last_match(1) if piece =~ /#(.*)/
|
136
|
+
{
|
137
|
+
key => d
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def global_find(path)
|
142
|
+
return nil unless path =~ /#.+/
|
143
|
+
res = open(path)
|
144
|
+
code, message = res.status
|
145
|
+
raise "error: #{message}" unless code == '200'
|
146
|
+
|
147
|
+
j = JSON.parse(res.read)
|
148
|
+
expand = Idcf::JsonHyperSchema::Analyst.new.expand(j)
|
149
|
+
expand.find(Regexp.last_match(0))
|
150
|
+
end
|
151
|
+
|
152
|
+
# local data search
|
153
|
+
# definitions_id or local_path
|
154
|
+
#
|
155
|
+
# @param path [String] ex) #definitions/name
|
156
|
+
# @return Mixed
|
157
|
+
def local_search(path)
|
158
|
+
ids = @definition_ids[path]
|
159
|
+
return ids unless ids.nil?
|
160
|
+
paths = local_search_path_list(path)
|
161
|
+
return nil if paths.empty?
|
162
|
+
data = search_data(@origin, paths)
|
163
|
+
data.nil? ? nil : delete_id(data.deep_dup)
|
164
|
+
end
|
165
|
+
|
166
|
+
def local_search_path_list(path)
|
167
|
+
path[1, path.size - 1].split('/').select do |v|
|
168
|
+
v.strip != ''
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def search_data(data, paths)
|
173
|
+
result = data.deep_dup
|
174
|
+
paths.each do |k|
|
175
|
+
next if k.blank?
|
176
|
+
key = result.class == Hash ? k : k.to_i
|
177
|
+
result = result[key]
|
178
|
+
break if result.nil?
|
179
|
+
end
|
180
|
+
result
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
module Idcf
|
2
|
+
module JsonHyperSchema
|
3
|
+
module Expands
|
4
|
+
# Link Info Base
|
5
|
+
# json schema v4
|
6
|
+
class LinkInfoBase
|
7
|
+
attr_reader :data
|
8
|
+
FULL_HREF_REGEXP = Regexp.new('\A[a-zA-Z]*:?//').freeze
|
9
|
+
PARAMS_REGEXP = Regexp.new(':(.+)|\{([^\}\?]+)\}').freeze
|
10
|
+
BIND_PARAMS_REGEXP = Regexp.new('\A#(/|[a-zA-Z_\-])*\Z').freeze
|
11
|
+
QUERY_PARAMS_REGEXP = Regexp.new('\{\?(.*)\}').freeze
|
12
|
+
|
13
|
+
def initialize(data)
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
# description
|
18
|
+
#
|
19
|
+
# @return String
|
20
|
+
def description
|
21
|
+
@data.description.nil? ? '' : @data.description
|
22
|
+
end
|
23
|
+
|
24
|
+
# title
|
25
|
+
#
|
26
|
+
# @return String
|
27
|
+
def title
|
28
|
+
@data.title.nil? ? '' : @data.title
|
29
|
+
end
|
30
|
+
|
31
|
+
# method
|
32
|
+
#
|
33
|
+
# @return String
|
34
|
+
def method
|
35
|
+
@data.method.nil? ? 'get' : @data.method.to_s.downcase
|
36
|
+
end
|
37
|
+
|
38
|
+
# is_method
|
39
|
+
#
|
40
|
+
# @return String
|
41
|
+
def method?(val)
|
42
|
+
method == val.to_s.downcase
|
43
|
+
end
|
44
|
+
|
45
|
+
# href string
|
46
|
+
#
|
47
|
+
# @return String
|
48
|
+
def href
|
49
|
+
href = @data.href
|
50
|
+
return '' if href.nil?
|
51
|
+
l = []
|
52
|
+
href.split('/').each do |v|
|
53
|
+
next if v.empty?
|
54
|
+
l << v.gsub(PARAMS_REGEXP, '%s').gsub(QUERY_PARAMS_REGEXP, '')
|
55
|
+
end
|
56
|
+
href_head = href =~ FULL_HREF_REGEXP ? '' : base_href
|
57
|
+
"#{href_head}/#{l.join('/')}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# url params
|
61
|
+
# ex) /hoge/{id}/{sec}{?name} : ["id", "sec"]
|
62
|
+
#
|
63
|
+
# @return Array
|
64
|
+
def url_param_names
|
65
|
+
[].tap do |result|
|
66
|
+
href = @data.href
|
67
|
+
next if href.nil?
|
68
|
+
href.split('/').each do |v|
|
69
|
+
str = url_param_str(v)
|
70
|
+
result << str unless str.empty?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# http query params
|
76
|
+
# ex) /hoge/{id}/{sec}{?name} : ["name"]
|
77
|
+
#
|
78
|
+
# @return Array
|
79
|
+
def query_param_names
|
80
|
+
result = [].tap do |list|
|
81
|
+
href = @data.href
|
82
|
+
next if href.nil?
|
83
|
+
params = href =~ QUERY_PARAMS_REGEXP
|
84
|
+
next if params.nil?
|
85
|
+
list.concat(Regexp.last_match(1).split(','))
|
86
|
+
end
|
87
|
+
result.concat(properties.keys) if method?('get')
|
88
|
+
result.uniq
|
89
|
+
end
|
90
|
+
|
91
|
+
# properties
|
92
|
+
#
|
93
|
+
# @return Hash
|
94
|
+
def properties
|
95
|
+
d = @data.schema
|
96
|
+
return {} if d.nil? || d.properties.nil?
|
97
|
+
d.properties.deep_dup
|
98
|
+
end
|
99
|
+
|
100
|
+
# required
|
101
|
+
#
|
102
|
+
# @return Array
|
103
|
+
def required
|
104
|
+
d = @data.schema
|
105
|
+
return [] if d.nil? || d.required.nil?
|
106
|
+
d.required.deep_dup
|
107
|
+
end
|
108
|
+
|
109
|
+
# make uri
|
110
|
+
#
|
111
|
+
# @param url_params [Array]
|
112
|
+
# @param params [Hash]
|
113
|
+
# @param host [String]
|
114
|
+
# @return String
|
115
|
+
def make_uri(url_params, params, host = nil)
|
116
|
+
uri = URI(make_url(url_params, host))
|
117
|
+
query_params = []
|
118
|
+
[uri.query, make_query_params(params).to_param].each do |param|
|
119
|
+
query_params << param if param.present?
|
120
|
+
end
|
121
|
+
uri.query = query_params.join('&')
|
122
|
+
uri.to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
# make params
|
126
|
+
# The price of the rest except for a query parameter
|
127
|
+
#
|
128
|
+
# @param args
|
129
|
+
# @return Hash
|
130
|
+
def make_params(args)
|
131
|
+
{}.tap do |result|
|
132
|
+
param = args.deep_dup
|
133
|
+
next unless param.class == Hash
|
134
|
+
param = param.stringify_keys
|
135
|
+
make_query_params(args).each do |qk, _qv|
|
136
|
+
param.delete(qk)
|
137
|
+
end
|
138
|
+
properties.each do |pk, _pv|
|
139
|
+
result[pk] = param[pk] if param.key?(pk)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def make_url(args, host = nil)
|
147
|
+
result = href
|
148
|
+
r_params = []
|
149
|
+
url_param_names.each_index do |index|
|
150
|
+
r_params << CGI.escape(args[index])
|
151
|
+
end
|
152
|
+
result = result % r_params unless r_params.empty?
|
153
|
+
result = URI.join(host, result).to_s unless host.nil?
|
154
|
+
result
|
155
|
+
end
|
156
|
+
|
157
|
+
def make_query_params(param)
|
158
|
+
{}.tap do |result|
|
159
|
+
next unless param.class == Hash
|
160
|
+
query_param_names.each do |k|
|
161
|
+
result[k] = param[k] if param.key?(k)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def url_param_str(piece)
|
167
|
+
return '' unless piece =~ PARAMS_REGEXP
|
168
|
+
(1..2).each do |num|
|
169
|
+
next if Regexp.last_match(num).nil?
|
170
|
+
p_name = url_param_name(Regexp.last_match(num))
|
171
|
+
return p_name unless p_name.nil?
|
172
|
+
end
|
173
|
+
''
|
174
|
+
end
|
175
|
+
|
176
|
+
def base_href
|
177
|
+
list = []
|
178
|
+
parent_base_urls(@data.parent).each do |base|
|
179
|
+
list << base.gsub(%r{\A/+}, '').gsub(%r{\Z/+}, '')
|
180
|
+
break if base =~ FULL_HREF_REGEXP
|
181
|
+
end
|
182
|
+
list.reverse.join('/')
|
183
|
+
end
|
184
|
+
|
185
|
+
def parent_base_urls(schema)
|
186
|
+
[].tap do |result|
|
187
|
+
next if schema.nil?
|
188
|
+
result << schema.data['base'] unless schema.data['base'].nil?
|
189
|
+
result.concat(parent_base_urls(schema.parent))
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def url_param_name(name)
|
194
|
+
return nil if name[0] == '?'
|
195
|
+
return name unless name =~ BIND_PARAMS_REGEXP
|
196
|
+
name.split('/').pop
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: idcf-json_hyper_schema
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- IDC Frontier Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-12-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.2'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 4.2.3
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '4.2'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 4.2.3
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: activesupport
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '4.2'
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 4.2.3
|
85
|
+
type: :runtime
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - "~>"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '4.2'
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 4.2.3
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: json_schema
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.17.0
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 0.17.0
|
109
|
+
description: IDCF Json-Hyper-Schema Expand tools
|
110
|
+
email: []
|
111
|
+
executables: []
|
112
|
+
extensions: []
|
113
|
+
extra_rdoc_files: []
|
114
|
+
files:
|
115
|
+
- ".codeclimate.yml"
|
116
|
+
- ".gitignore"
|
117
|
+
- ".rubocop.yml"
|
118
|
+
- Gemfile
|
119
|
+
- Gemfile.lock
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- bin/json_expand
|
124
|
+
- idcf-json_hyper_schema.gemspec
|
125
|
+
- lib/idcf/json_hyper_schema.rb
|
126
|
+
- lib/idcf/json_hyper_schema/analyst.rb
|
127
|
+
- lib/idcf/json_hyper_schema/expands/base.rb
|
128
|
+
- lib/idcf/json_hyper_schema/expands/link_info_base.rb
|
129
|
+
- lib/idcf/json_hyper_schema/expands/link_info_v4.rb
|
130
|
+
- lib/idcf/json_hyper_schema/expands/v4.rb
|
131
|
+
- lib/idcf/json_hyper_schema/version.rb
|
132
|
+
homepage: https://www.idcfcloud.jp
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 2.6.8
|
153
|
+
signing_key:
|
154
|
+
specification_version: 4
|
155
|
+
summary: IDCF Json-Hyper-Schema Expand tools
|
156
|
+
test_files: []
|