picatrix 0.2.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +12 -2
- data/README.md +46 -30
- data/Rakefile +1 -0
- data/bin/console +7 -1
- data/definitions/app.proto +47 -0
- data/definitions/mason.proto +63 -0
- data/lib/picatrix/buffy.rb +56 -0
- data/lib/picatrix/cruddy.rb +45 -0
- data/lib/picatrix/digraph_parser.rb +7 -0
- data/lib/picatrix/fixtures/view_submission.rb +19 -0
- data/lib/picatrix/generated/app.pb.rb +79 -0
- data/lib/picatrix/generated/app.rb +171 -60
- data/lib/picatrix/generated/mason/namespaces.json +7 -0
- data/lib/picatrix/generated/mason.pb.rb +90 -0
- data/lib/picatrix/generated/view_submissions.rb +49 -0
- data/lib/picatrix/jenny.rb +30 -155
- data/lib/picatrix/link_relation_index.rb +36 -0
- data/lib/picatrix/pacman.rb +8 -5
- data/lib/picatrix/routes.rb +40 -0
- data/lib/picatrix/templates/app.rb +138 -22
- data/lib/picatrix/templates/control.rb +15 -0
- data/lib/picatrix/templates/type.rb +35 -21
- data/lib/picatrix/transform_to_hash.rb +0 -10
- data/lib/picatrix/version.rb +1 -1
- data/lib/picatrix.rb +22 -1
- data/picatrix.gemspec +2 -0
- metadata +42 -9
- data/lib/picatrix/generated/view_submission.rb +0 -27
- data/lib/picatrix/schemas/view_submission_item.json +0 -12
- data/lib/picatrix/templates/mason/submission_filter_template.json +0 -4
- data/lib/picatrix/templates/mason/view_submission.json +0 -35
- data/lib/picatrix/templates/mason/view_submission_min.json +0 -11
- data/lib/picatrix/templates/mason/view_submissions.json +0 -36
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sinatra'
|
2
2
|
require 'sinatra/json'
|
3
|
+
require 'protobuf'
|
3
4
|
require 'require_all'
|
4
5
|
|
5
6
|
require_all("./lib/picatrix/generated/*.rb")
|
@@ -8,91 +9,201 @@ class App < Sinatra::Base
|
|
8
9
|
set :public_folder => "public", :static => true
|
9
10
|
|
10
11
|
get '/rels' do
|
11
|
-
json(
|
12
|
+
json({:@controls=>{:up=>"http://localhost:9292/", :self=>"http://localhost:9292/rels"}, :link_relations=>{:newest=>["root -(GET)-> view_submissions", "view_submission -(GET)-> view_submissions", "view_submissions -(DELETE)-> view_submissions"], :":item_id"=>["view_submissions -(GET)-> view_submission"], :filter=>["view_submissions -(GET)-> view_submissions"], :submit=>["view_submissions -(POST)-> view_submission"], :edit=>["view_submission -(PATCH)-> view_submission"]}})
|
12
13
|
end
|
13
14
|
|
14
15
|
get '/' do
|
15
|
-
status, headers, body = call env.merge("PATH_INFO" => "/view_submissions
|
16
|
+
status, headers, body = call env.merge("PATH_INFO" => "/view_submissions")
|
16
17
|
[status, headers, body]
|
17
18
|
end
|
18
19
|
|
20
|
+
def json(hash = {})
|
21
|
+
# anything set here will be sent in all responses
|
22
|
+
super({"@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}}.merge!(hash))
|
23
|
+
end
|
19
24
|
|
20
|
-
|
21
|
-
get "/view_submissions/newest" do
|
22
|
-
# get collection
|
23
|
-
items = ViewSubmission.all
|
24
|
-
# render collection into templates
|
25
|
-
hashed_items = items.collect do |item|
|
26
|
-
{"@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}"}
|
27
|
-
end
|
28
|
-
# return that collection
|
29
|
-
json({"title"=>"View submissions", "description"=>"idk yet", "@meta"=>{"@title"=>"Submissions", "@description"=>"This resource represents submissions."}, "@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}, "@controls"=>{"self"=>{"href"=>"http://localhost:9292/view_submissions/newest"}, "s:filter"=>{"href"=>"http://localhost:9292/view_submissions/filter?category={category}&has_photo={has_photo}", "isHrefTemplate"=>true, "title"=>"filter submissions by category", "description"=>"in addition to category, you can ensure the submission has a photo"}, "s:add"=>{"title"=>"add new submission", "encoding"=>"json", "href"=>"http://localhost:9292/submission_add_template/submit", "method"=>"POST", "template"=>{"title"=>"default title", "category"=>"cats", "photo_url"=>"http://cats.com"}}}}.merge({"view_submissions" => hashed_items}))
|
30
|
-
end
|
31
|
-
|
32
25
|
|
33
|
-
|
34
|
-
get "/view_submissions
|
35
|
-
|
36
|
-
|
37
|
-
# render collection into templates
|
38
|
-
hashed_items = items.collect do |item|
|
39
|
-
{"@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}"}
|
26
|
+
|
27
|
+
get "/view_submissions" do
|
28
|
+
items = ViewSubmissionsResource.all.collection.collect do |r|
|
29
|
+
r.to_hash
|
40
30
|
end
|
41
|
-
|
42
|
-
|
31
|
+
|
32
|
+
|
33
|
+
controls = send(:filter, ViewSubmissions).call("view_submissions", params)
|
34
|
+
|
35
|
+
|
36
|
+
json(
|
37
|
+
{:@controls => controls}.
|
38
|
+
merge!({"view_submissions" => items})
|
39
|
+
)
|
43
40
|
end
|
44
41
|
|
45
42
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
|
44
|
+
get "/view_submission/:item_id" do
|
45
|
+
item = ViewSubmissionsResource.find(params[:item_id])
|
46
|
+
|
47
|
+
|
48
|
+
controls = send(:mason_self, ViewSubmission).call("view_submission", params)
|
49
|
+
|
50
|
+
|
51
|
+
json(
|
52
|
+
{:@controls => controls}.
|
53
|
+
merge!(item.to_hash.except(:controls))
|
54
|
+
)
|
52
55
|
end
|
53
56
|
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
58
|
+
|
59
|
+
post "/view_submission/:item_id" do
|
60
|
+
item = ViewSubmissionsResource.create(params[:item_id])
|
61
|
+
|
62
|
+
|
63
|
+
controls = {}
|
64
|
+
|
65
|
+
|
66
|
+
json(
|
67
|
+
{:@controls => controls}.
|
68
|
+
merge!(item.to_hash.except(:controls))
|
69
|
+
)
|
65
70
|
end
|
66
71
|
|
67
72
|
|
68
|
-
|
69
|
-
delete "/view_submissions
|
70
|
-
|
71
|
-
|
72
|
-
# render collection into templates
|
73
|
-
hashed_items = items.collect do |item|
|
74
|
-
{"@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}"}
|
73
|
+
|
74
|
+
delete "/view_submissions" do
|
75
|
+
items = ViewSubmissionsResource.all.collection.collect do |r|
|
76
|
+
r.to_hash
|
75
77
|
end
|
76
|
-
# return that collection
|
77
|
-
json({"title"=>"View submissions", "description"=>"idk yet", "@meta"=>{"@title"=>"Submissions", "@description"=>"This resource represents submissions."}, "@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}, "@controls"=>{"self"=>{"href"=>"http://localhost:9292/view_submissions/newest"}, "s:filter"=>{"href"=>"http://localhost:9292/view_submissions/filter?category={category}&has_photo={has_photo}", "isHrefTemplate"=>true, "title"=>"filter submissions by category", "description"=>"in addition to category, you can ensure the submission has a photo"}, "s:add"=>{"title"=>"add new submission", "encoding"=>"json", "href"=>"http://localhost:9292/submission_add_template/submit", "method"=>"POST", "template"=>{"title"=>"default title", "category"=>"cats", "photo_url"=>"http://cats.com"}}}, :message=>0}.merge({"view_submissions" => hashed_items}))
|
78
|
-
end
|
79
|
-
|
80
78
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
79
|
+
|
80
|
+
controls = {}
|
81
|
+
|
82
|
+
|
83
|
+
json(
|
84
|
+
{:@controls => controls}.
|
85
|
+
merge!({"view_submissions" => items})
|
86
|
+
)
|
87
87
|
end
|
88
88
|
|
89
89
|
|
90
90
|
|
91
|
+
patch "/view_submission/:item_id" do
|
92
|
+
item = ViewSubmissionsResource.find(params[:item_id])
|
91
93
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
94
|
+
|
95
|
+
controls = send(:edit, ViewSubmission).call("view_submission", params)
|
96
|
+
|
97
|
+
|
98
|
+
json(
|
99
|
+
{:@controls => controls}.
|
100
|
+
merge!(item.to_hash.except(:controls))
|
101
|
+
)
|
96
102
|
end
|
103
|
+
|
97
104
|
|
105
|
+
|
106
|
+
def mason_up(type)
|
107
|
+
if type == collection
|
108
|
+
proc do |path, params|
|
109
|
+
{
|
110
|
+
up: Mason::Up.new(
|
111
|
+
{
|
112
|
+
href: "http://localhost:9292/#{view_submissions}"
|
113
|
+
}
|
114
|
+
).to_hash
|
115
|
+
}
|
116
|
+
end
|
117
|
+
else
|
118
|
+
proc do |path, params|
|
119
|
+
{
|
120
|
+
up: Mason::Up.new(
|
121
|
+
{
|
122
|
+
href: "http://localhost:9292/#{path}"
|
123
|
+
}
|
124
|
+
).to_hash
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
def mason_self(item)
|
130
|
+
proc do |path, params|
|
131
|
+
if params[:item_id]
|
132
|
+
{
|
133
|
+
self: Mason::Self.new(
|
134
|
+
{
|
135
|
+
href: "http://localhost:9292/#{path}/#{params[:item_id]}"
|
136
|
+
}
|
137
|
+
).to_hash
|
138
|
+
}
|
139
|
+
else
|
140
|
+
{
|
141
|
+
self: Mason::Self.new(
|
142
|
+
{
|
143
|
+
href: "http://localhost:9292/#{path}"
|
144
|
+
}
|
145
|
+
).to_hash
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
def edit(item)
|
151
|
+
proc do |path, params|
|
152
|
+
{
|
153
|
+
edit: ("Edit" + item.to_s.singularize.camelize).constantize.new(
|
154
|
+
{
|
155
|
+
form: Mason::Edit.new(
|
156
|
+
href: "http://localhost:9292/#{path}/#{params[:item_id]}"
|
157
|
+
)
|
158
|
+
}
|
159
|
+
).to_hash
|
160
|
+
}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
def remove(item)
|
164
|
+
proc do |path, params|
|
165
|
+
{
|
166
|
+
remove: Mason::Remove.new(
|
167
|
+
{
|
168
|
+
href: "http://localhost:9292/#{path}/#{params[:item_id]}"
|
169
|
+
}
|
170
|
+
).to_hash
|
171
|
+
}
|
172
|
+
end
|
173
|
+
end
|
174
|
+
def create(item)
|
175
|
+
proc do |path, params|
|
176
|
+
{
|
177
|
+
create: ("Create" + item.to_s.singularize.camelize).constantize.new(
|
178
|
+
{
|
179
|
+
form: Mason::Create.new(
|
180
|
+
href: ""
|
181
|
+
)
|
182
|
+
}
|
183
|
+
)
|
184
|
+
}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
def filter(collection)
|
188
|
+
# TODO this prob cant really work here
|
189
|
+
proc do |path, params|
|
190
|
+
if params[:item_id]
|
191
|
+
{
|
192
|
+
"s:filter": Mason::Filter.new(
|
193
|
+
{
|
194
|
+
href: "http://localhost:9292/#{path}/#{params[:item_id]}"
|
195
|
+
}
|
196
|
+
).to_hash
|
197
|
+
}
|
198
|
+
else
|
199
|
+
{
|
200
|
+
"s:filter": Mason::Filter.new(
|
201
|
+
{
|
202
|
+
href: "http://localhost:9292/#{path}"
|
203
|
+
}
|
204
|
+
).to_hash
|
205
|
+
}
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
98
209
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
##
|
4
|
+
# This file is auto-generated. DO NOT EDIT!
|
5
|
+
#
|
6
|
+
require 'protobuf/message'
|
7
|
+
|
8
|
+
module Mason
|
9
|
+
|
10
|
+
##
|
11
|
+
# Enum Classes
|
12
|
+
#
|
13
|
+
class HTTPVerb < ::Protobuf::Enum
|
14
|
+
define :GET, 1
|
15
|
+
define :PUT, 2
|
16
|
+
define :PATCH, 3
|
17
|
+
define :DELETE, 4
|
18
|
+
define :POST, 5
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
##
|
23
|
+
# Message Classes
|
24
|
+
#
|
25
|
+
class Self < ::Protobuf::Message; end
|
26
|
+
class Up < ::Protobuf::Message; end
|
27
|
+
class Filter < ::Protobuf::Message
|
28
|
+
class HrefTemplate < ::Protobuf::Enum
|
29
|
+
define :TRUE, 0
|
30
|
+
define :FALSE, 1
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class Create < ::Protobuf::Message; end
|
36
|
+
class Edit < ::Protobuf::Message; end
|
37
|
+
class Remove < ::Protobuf::Message; end
|
38
|
+
class Controls < ::Protobuf::Message; end
|
39
|
+
|
40
|
+
|
41
|
+
##
|
42
|
+
# Message Fields
|
43
|
+
#
|
44
|
+
class Self
|
45
|
+
optional :string, :href, 1
|
46
|
+
optional :string, :title, 2
|
47
|
+
end
|
48
|
+
|
49
|
+
class Up
|
50
|
+
optional :string, :href, 1
|
51
|
+
optional :string, :title, 2
|
52
|
+
end
|
53
|
+
|
54
|
+
class Filter
|
55
|
+
optional :string, :href, 1
|
56
|
+
optional ::Mason::HTTPVerb, :method, 2, :default => ::Mason::HTTPVerb::GET
|
57
|
+
optional ::Mason::Filter::HrefTemplate, :isHrefTemplate, 3, :default => ::Mason::Filter::HrefTemplate::TRUE
|
58
|
+
end
|
59
|
+
|
60
|
+
class Create
|
61
|
+
optional :string, :href, 1
|
62
|
+
optional ::Mason::HTTPVerb, :method, 2, :default => ::Mason::HTTPVerb::POST
|
63
|
+
optional :string, :title, 3
|
64
|
+
optional :string, :encoding, 4
|
65
|
+
end
|
66
|
+
|
67
|
+
class Edit
|
68
|
+
optional :string, :href, 1
|
69
|
+
optional ::Mason::HTTPVerb, :method, 2, :default => ::Mason::HTTPVerb::PATCH
|
70
|
+
optional :string, :title, 3
|
71
|
+
optional :string, :encoding, 4
|
72
|
+
end
|
73
|
+
|
74
|
+
class Remove
|
75
|
+
optional :string, :href, 1
|
76
|
+
optional ::Mason::HTTPVerb, :method, 2, :default => ::Mason::HTTPVerb::DELETE
|
77
|
+
optional :string, :title, 3
|
78
|
+
end
|
79
|
+
|
80
|
+
class Controls
|
81
|
+
optional ::Mason::Self, :self, 2
|
82
|
+
optional ::Mason::Up, :up, 3
|
83
|
+
optional ::Mason::Edit, :edit, 4
|
84
|
+
optional ::Mason::Remove, :remove, 5
|
85
|
+
optional ::Mason::Create, :create, 6
|
86
|
+
optional ::Mason::Filter, :filter, 7
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# you can remove this if you don't use faker
|
2
|
+
# for your fixture data
|
3
|
+
require 'faker'
|
4
|
+
|
5
|
+
# the resource is the thing actually persisted
|
6
|
+
# technically, this is just an interface to it
|
7
|
+
# so long as your persistance layer is able to implement
|
8
|
+
# the methods in this fixture, the app will generate
|
9
|
+
class ViewSubmissionsResource
|
10
|
+
# method used to return single item from a collection
|
11
|
+
# creates an instance on the fly
|
12
|
+
# both the find and collection methods use this
|
13
|
+
def self.create(item_id)
|
14
|
+
ViewSubmission.new(
|
15
|
+
{
|
16
|
+
# any "bare" Proto type will be given an associated Faker
|
17
|
+
|
18
|
+
:id => id = Faker::Number.number(6),
|
19
|
+
|
20
|
+
:category => Faker::Lorem.word,
|
21
|
+
|
22
|
+
:photo => Faker::Lorem.word,
|
23
|
+
|
24
|
+
:controls => ViewSubmission::Controls.new(minimal_controls_for(item_id)),
|
25
|
+
|
26
|
+
:attachments => [ViewSubmission::Attachment.new(params = {})],
|
27
|
+
|
28
|
+
}
|
29
|
+
)
|
30
|
+
end
|
31
|
+
def self.find(params)
|
32
|
+
self.create(params)
|
33
|
+
end
|
34
|
+
def self.all
|
35
|
+
collection = []
|
36
|
+
rand(10).times {
|
37
|
+
collection << self.find(rand(1000))
|
38
|
+
}
|
39
|
+
ViewSubmissions.new(collection: collection)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.minimal_controls_for(item_id)
|
43
|
+
host = "http://localhost:9292"
|
44
|
+
{
|
45
|
+
self: Mason::Self.new(href: "#{host}/view_submission/#{item_id}"),
|
46
|
+
up: Mason::Up.new(href: "#{host}/view_submissions")
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
data/lib/picatrix/jenny.rb
CHANGED
@@ -7,184 +7,59 @@ module Picatrix
|
|
7
7
|
include Thor::Actions
|
8
8
|
|
9
9
|
attr_accessor :app_name, :routes, :root_path, :rels,
|
10
|
-
:destination_stack, :options
|
11
|
-
:default_response, :assets, :generated,
|
12
|
-
:addressable_items, :collectable_items
|
10
|
+
:destination_stack, :options
|
13
11
|
|
14
12
|
argument :name
|
15
13
|
source_root File.dirname(__FILE__)
|
16
14
|
|
17
|
-
def initialize(
|
15
|
+
def initialize(pacman, options = {}, app_name = "app")
|
18
16
|
# thor related
|
19
17
|
@options = options
|
20
18
|
@destination_stack = [self.class.source_root]
|
21
19
|
|
22
|
-
|
23
|
-
@
|
24
|
-
@edges = hash[:edge].flat_map {|e| e[:edge]}
|
20
|
+
@nodes = pacman.nodes
|
21
|
+
@edges = pacman.edges
|
25
22
|
|
26
23
|
@app_name = app_name
|
27
|
-
@rels = @edges
|
28
|
-
|
24
|
+
@rels = LinkRelationIndex.new(@edges).masoned
|
25
|
+
# TODO
|
26
|
+
@meta = {}
|
27
|
+
|
28
|
+
if File.exist?(
|
29
|
+
mason_path = "lib/picatrix/generated/mason/namespaces.json"
|
30
|
+
) #TODO this should be coming in from graph instead
|
31
|
+
@namespaces = JSON.parse(
|
32
|
+
File.read(
|
33
|
+
mason_path
|
34
|
+
)
|
35
|
+
)
|
36
|
+
@prefix = "#{@namespaces["@namespaces"].keys.first}:"
|
37
|
+
else
|
38
|
+
puts "no generated/mason/namespaces.json file"
|
39
|
+
@namespaces = {}
|
40
|
+
@prefix = ""
|
41
|
+
end
|
29
42
|
|
30
|
-
@
|
31
|
-
@
|
32
|
-
#
|
33
|
-
@
|
34
|
-
@collectable_items = collectable_items
|
35
|
-
@routes = routes
|
43
|
+
@control_templates = Cruddy.new(@edges).controls
|
44
|
+
@routes = Routes.new(@edges, @control_templates)
|
45
|
+
# make this available to the app scope
|
46
|
+
@root_path = @routes.root_path
|
36
47
|
end
|
37
48
|
|
38
49
|
def just_do_it
|
39
|
-
@generated.each do |node_name|
|
40
|
-
# bring in defined objects
|
41
|
-
require "./lib/picatrix/generated/#{node_name}.rb"
|
42
|
-
end
|
43
|
-
generate_app_file
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
def generate_app_file
|
48
50
|
template(
|
49
51
|
'templates/app.rb',
|
50
52
|
File.join("generated/#{app_name}.rb")
|
51
53
|
)
|
52
54
|
end
|
53
|
-
def assets
|
54
|
-
@assets ||= @edges.collect do | edge|
|
55
|
-
source = edge.keys.first
|
56
|
-
properties = edge[source]
|
57
|
-
# if you dont have an inline asset, ignore
|
58
|
-
next unless properties[:inline]
|
59
|
-
|
60
|
-
mason_path = "lib/picatrix/templates/mason/#{properties[:target]}.json"
|
61
|
-
|
62
|
-
if File.exist?(mason_path)
|
63
|
-
body = JSON.parse(
|
64
|
-
File.read(
|
65
|
-
mason_path
|
66
|
-
)
|
67
|
-
)
|
68
|
-
else
|
69
|
-
body = default_response
|
70
|
-
end
|
71
|
-
{
|
72
|
-
"#{properties[:target]}" => body
|
73
|
-
}
|
74
|
-
end.compact.reduce({}, :merge)
|
75
|
-
end
|
76
|
-
def routes
|
77
|
-
@routes ||= @edges.collect do |edge|
|
78
|
-
source = edge.keys.first
|
79
|
-
target = edge.values.first[:target]
|
80
|
-
properties = edge[source]
|
81
|
-
|
82
|
-
# we dont need a route if it is inline represented
|
83
|
-
next if properties[:inline]
|
84
|
-
|
85
|
-
link_relation = properties[:link_relation]
|
86
|
-
path = "#{target}/#{link_relation.delete('"')}"
|
87
|
-
|
88
|
-
if source == "root"
|
89
|
-
@root_path = path
|
90
|
-
end
|
91
|
-
|
92
|
-
mason_path = "lib/picatrix/templates/mason/#{edge[source][:target]}.json"
|
93
|
-
|
94
|
-
if File.exist?(mason_path)
|
95
|
-
body = JSON.parse(
|
96
|
-
File.read(
|
97
|
-
mason_path
|
98
|
-
)
|
99
|
-
)
|
100
|
-
else
|
101
|
-
body = default_response
|
102
|
-
end
|
103
|
-
|
104
|
-
if (asset = assets[source]) && body.is_a?(Hash)
|
105
|
-
body.merge!(asset)
|
106
|
-
end
|
107
|
-
|
108
|
-
{
|
109
|
-
path: path,
|
110
|
-
method: properties[:method],
|
111
|
-
# danger danger danger will robinson we are unescaping here!
|
112
|
-
body: body.to_s.delete("\\"),
|
113
|
-
collection: (collectable_items[target.singularize] || [])
|
114
|
-
}
|
115
|
-
end.compact!
|
116
|
-
end
|
117
|
-
def addressable_items
|
118
|
-
@addressable_items ||= @nodes.collect do |node|
|
119
|
-
node_name = node.first
|
120
|
-
node_properties = node.last
|
121
55
|
|
122
|
-
|
123
|
-
item_path = "#{node_name}/:item_id"
|
124
|
-
mason_path = "lib/picatrix/templates/mason/#{node_name}.json"
|
125
|
-
schema_path = "lib/picatrix/schemas/#{node_name}_item.json"
|
126
|
-
|
127
|
-
if File.exist?(mason_path)
|
128
|
-
body = JSON.parse(
|
129
|
-
File.read(
|
130
|
-
mason_path
|
131
|
-
)
|
132
|
-
)
|
133
|
-
else
|
134
|
-
body = default_response
|
135
|
-
end
|
136
|
-
|
137
|
-
if File.exist?(schema_path)
|
138
|
-
schema = JSON.parse(
|
139
|
-
File.read(
|
140
|
-
schema_path
|
141
|
-
)
|
142
|
-
)
|
143
|
-
|
144
|
-
# thor doesnt take locals in
|
145
|
-
@node_name = node_name
|
146
|
-
template(
|
147
|
-
'templates/type.rb',
|
148
|
-
File.join("generated/#{node_name}.rb")
|
149
|
-
)
|
150
|
-
@generated = generated << @node_name
|
151
|
-
else
|
152
|
-
schema = {}
|
153
|
-
end
|
154
|
-
{
|
155
|
-
path: item_path,
|
156
|
-
type: node_name,
|
157
|
-
schema: schema,
|
158
|
-
# danger danger danger will robinson we are unescaping here!
|
159
|
-
body: body.to_s.delete("\\")
|
160
|
-
}
|
161
|
-
end
|
162
|
-
end.compact!
|
163
|
-
end
|
164
|
-
def collectable_items
|
165
|
-
@collectable_items ||= @addressable_items.inject({}) do |memo, item|
|
166
|
-
memo[item[:type]] = {
|
167
|
-
name: "#{item[:type].pluralize}",
|
168
|
-
resource_name: "#{item[:type].camelcase}",
|
169
|
-
template: JSON.parse(
|
170
|
-
File.read("lib/picatrix/templates/mason/#{item[:type]}_min.json")
|
171
|
-
)
|
172
|
-
}
|
173
|
-
memo
|
174
|
-
end
|
175
|
-
end
|
176
|
-
def return_mapping_of(method)
|
177
|
-
{
|
178
|
-
post: :single_return,
|
179
|
-
get: :collection_return,
|
180
|
-
patch: :single_return,
|
181
|
-
delete: :collection_return
|
182
|
-
}[method]
|
183
|
-
end
|
56
|
+
private
|
184
57
|
def send_method_for(method)
|
185
58
|
{
|
186
59
|
post: :create,
|
187
|
-
patch: :find
|
60
|
+
patch: :find,
|
61
|
+
get: :find,
|
62
|
+
delete: :find
|
188
63
|
}[method]
|
189
64
|
end
|
190
65
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Picatrix
|
2
|
+
class LinkRelationIndex
|
3
|
+
attr_accessor :as_hash
|
4
|
+
def initialize(edges)
|
5
|
+
@as_hash = {
|
6
|
+
link_relations: edges.flat_map do |e|
|
7
|
+
source = e.first.at(0)
|
8
|
+
link_relation = e.first.at(1)[:link_relation].delete('"')
|
9
|
+
|
10
|
+
{
|
11
|
+
link_relation.to_sym => "#{source} -(#{e.first.at(1)[:method].upcase})-> #{e.first.at(1)[:target]}"
|
12
|
+
}
|
13
|
+
end.inject(Hash.new([])) do |h, a|
|
14
|
+
h[a.keys.first] += [a.values].flatten; h
|
15
|
+
end
|
16
|
+
}
|
17
|
+
|
18
|
+
@controls = {
|
19
|
+
"@controls": {
|
20
|
+
up: up_href,
|
21
|
+
self: self_href
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
def masoned
|
26
|
+
@controls.merge!(@as_hash)
|
27
|
+
end
|
28
|
+
private
|
29
|
+
def up_href
|
30
|
+
"http://localhost:9292/"
|
31
|
+
end
|
32
|
+
def self_href
|
33
|
+
"http://localhost:9292/rels"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|