idcf-json_hyper_schema 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|