picatrix 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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([{"root"=>{:target=>"view_submissions", :link_relation=>"\"newest\"", :inline=>false, :method=>:get}}, {"view_submissions"=>{:target=>"view_submission", :link_relation=>"\":item_id\"", :inline=>true, :method=>:get}}, {"view_submissions"=>{:target=>"submission_filter_template", :link_relation=>"\"filter\"", :inline=>true, :method=>:get}}, {"submission_filter_template"=>{:target=>"view_submissions", :link_relation=>"\"filter\"", :inline=>false, :method=>:get}}, {"view_submissions"=>{:target=>"submission_add_template", :link_relation=>"\"add\"", :inline=>true, :method=>:get}}, {"submission_add_template"=>{:target=>"view_submission", :link_relation=>"\"submit\"", :inline=>false, :method=>:post}}, {"view_submission"=>{:target=>"view_submissions", :link_relation=>"\"newest\"", :inline=>false, :method=>:get}}, {"view_submission"=>{:target=>"submission_delete_template", :link_relation=>"\"remove\"", :inline=>true, :method=>:get}}, {"submission_delete_template"=>{:target=>"view_submissions", :link_relation=>"\"newest\"", :inline=>false, :method=>:delete}}, {"view_submission"=>{:target=>"submission_edit_template", :link_relation=>"\"edit\"", :inline=>true, :method=>:get}}, {"submission_edit_template"=>{:target=>"view_submission", :link_relation=>"\"self\"", :inline=>false, :method=>:patch}}])
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/newest")
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/filter" do
35
- # get collection
36
- items = ViewSubmission.all
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
- # return that collection
42
- 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"}}}, "category"=>"#{params[:category]}", "has_photo"=>"#{params[:has_photo]}"}.merge({"view_submissions" => hashed_items}))
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
- post "/view_submission/submit" do
48
- # create item
49
- item = ViewSubmission.create(params)
50
- # return new item
51
- json({"@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}, "@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}, "up"=>{"title"=>"View submissions", "href"=>"http://localhost:9292/view_submissions/newest"}, "s:edit"=>{"title"=>"update category or photo url", "encoding"=>"json", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"PATCH", "template"=>{"photo"=>"{new_url}", "category"=>"{new_category}"}}, "s:remove"=>{"title"=>"remove submission", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"DELETE"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}", :message=>0})
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
- get "/view_submissions/newest" do
57
- # get collection
58
- items = ViewSubmission.all
59
- # render collection into templates
60
- hashed_items = items.collect do |item|
61
- {"@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}"}
62
- end
63
- # return that collection
64
- json({"title"=>"View submissions", "description"=>"idk yet", "@meta"=>{"@title"=>"Submissions", "@description"=>"This resource represents submissions."}, "@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}, "@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}, "up"=>{"title"=>"View submissions", "href"=>"http://localhost:9292/view_submissions/newest"}, "s:edit"=>{"title"=>"update category or photo url", "encoding"=>"json", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"PATCH", "template"=>{"photo"=>"{new_url}", "category"=>"{new_category}"}}, "s:remove"=>{"title"=>"remove submission", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"DELETE"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}"}.merge({"view_submissions" => hashed_items}))
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/newest" do
70
- # get collection
71
- items = ViewSubmission.all
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
- patch "/view_submission/self" do
83
- # create item
84
- item = ViewSubmission.find(params)
85
- # return new item
86
- json({"@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}, "@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}, "up"=>{"title"=>"View submissions", "href"=>"http://localhost:9292/view_submissions/newest"}, "s:edit"=>{"title"=>"update category or photo url", "encoding"=>"json", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"PATCH", "template"=>{"photo"=>"{new_url}", "category"=>"{new_category}"}}, "s:remove"=>{"title"=>"remove submission", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"DELETE"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}", :message=>0})
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
- get "/view_submission/:item_id" do
93
- item_id = params[:item_id]
94
- item = ViewSubmission.find(item_id)
95
- json({"@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}, "@controls"=>{"self"=>{"title"=>"submission #{item.id}", "href"=>"http://localhost:9292/view_submission/#{item.id}"}, "up"=>{"title"=>"View submissions", "href"=>"http://localhost:9292/view_submissions/newest"}, "s:edit"=>{"title"=>"update category or photo url", "encoding"=>"json", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"PATCH", "template"=>{"photo"=>"{new_url}", "category"=>"{new_category}"}}, "s:remove"=>{"title"=>"remove submission", "href"=>"http://localhost:9292/view_submission/#{item.id}", "method"=>"DELETE"}}, "id"=>"#{item.id}", "category"=>"#{item.category}", "photo"=>"#{item.photo}"})
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,7 @@
1
+ {
2
+ "@namespaces": {
3
+ "s": {
4
+ "name": "http://localhost:9292/rels#"
5
+ }
6
+ }
7
+ }
@@ -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
@@ -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(array = [], options = {}, app_name = "app")
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
- hash = array.group_by {|e| e.keys.first}
23
- @nodes = hash[:node].flat_map {|e| e[:node]}.reduce({}, :merge)
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
- @default_response = { message: 0 }
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
- @generated = []
31
- @assets = assets
32
- # items must come before collectable_items
33
- @addressable_items = addressable_items
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
- if node_properties[:type] == "item"
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