traim 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -9
- data/lib/traim.rb +121 -129
- data/test/resource.rb +20 -20
- data/traim.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ece137da93d77a125ef001c07c3d259e5ccb0128
|
4
|
+
data.tar.gz: dd4af9b6a0c3078182eaeb210c20faf17d427592
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a93dbdabe1d31e39e4b687de31e09d193e7b88f3e16f9a3283b5c7e8d55ec14bf19f96d0869cd18681d233eacdc7debb710a3bd2f2a38e396ac82e9e04452f34
|
7
|
+
data.tar.gz: 19dad77694405744df974cb015b5346f24bbf2a79b76af75b02655c2c038946a89c4ed3e44b6ddeb49dd4fb0bf1b4338b6f6445e3a22847fffbfe63667ccc63d
|
data/README.md
CHANGED
@@ -69,8 +69,8 @@ Traim.application do
|
|
69
69
|
attribute :id
|
70
70
|
attribute :name
|
71
71
|
|
72
|
-
action :show do
|
73
|
-
user = model.find_by_email params["
|
72
|
+
action :show do
|
73
|
+
user = model.find_by_email params["email"]
|
74
74
|
user.name = "[admin] #{user.name}"
|
75
75
|
user
|
76
76
|
end
|
@@ -140,7 +140,7 @@ Traim.application do
|
|
140
140
|
member :blurred do
|
141
141
|
|
142
142
|
# GET /users/1/blurred
|
143
|
-
show do
|
143
|
+
show do
|
144
144
|
record.name[1..2] = 'xx'
|
145
145
|
record
|
146
146
|
end
|
@@ -162,13 +162,13 @@ Traim.application do
|
|
162
162
|
collection :admin do
|
163
163
|
|
164
164
|
# GET /users/admin
|
165
|
-
show do
|
165
|
+
show do
|
166
166
|
model.all
|
167
167
|
end
|
168
168
|
|
169
169
|
# POST /users/admin
|
170
|
-
create do
|
171
|
-
model.create(params
|
170
|
+
create do
|
171
|
+
model.create(params)
|
172
172
|
end
|
173
173
|
end
|
174
174
|
end
|
@@ -223,10 +223,9 @@ Traim.application do
|
|
223
223
|
attribute :id
|
224
224
|
attribute :name
|
225
225
|
|
226
|
-
action :show do
|
226
|
+
action :show do
|
227
227
|
auth(params["id"])
|
228
|
-
|
229
|
-
user
|
228
|
+
record
|
230
229
|
end
|
231
230
|
end
|
232
231
|
end
|
data/lib/traim.rb
CHANGED
@@ -78,6 +78,11 @@ class Traim
|
|
78
78
|
app = @applications[name] ||= Application.new(name)
|
79
79
|
end
|
80
80
|
|
81
|
+
def show(&block); @resource.action(:show, &block) end
|
82
|
+
def create(&block); @resource.action(:create, &block) end
|
83
|
+
def update(&block); @resource.action(:update, &block) end
|
84
|
+
def destory(&block); @resource.action(:destory, &block) end
|
85
|
+
|
81
86
|
def helpers(&block)
|
82
87
|
@helpers_block = block
|
83
88
|
end
|
@@ -91,124 +96,44 @@ class Traim
|
|
91
96
|
if app = @applications[segment]
|
92
97
|
app.route(request, seg)
|
93
98
|
else
|
94
|
-
|
95
|
-
|
96
|
-
router.run(seg, inbox)
|
97
|
-
router.render(request)
|
99
|
+
model = run(seg, inbox, request)
|
100
|
+
render(request, model)
|
98
101
|
end
|
99
102
|
end
|
100
103
|
|
101
|
-
def
|
102
|
-
|
103
|
-
instance_eval(&block)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
class Error < StandardError
|
108
|
-
|
109
|
-
def initialize(options = {})
|
110
|
-
@message = options[:message] || error_message
|
111
|
-
@body = options[:body] || error_message
|
112
|
-
super(@message)
|
113
|
-
end
|
114
|
-
|
115
|
-
def status; 500 end
|
116
|
-
def error_message; 'Internal Server Error' end
|
117
|
-
def header; DEFAULT_HEADER end
|
118
|
-
def body; {message: @body} end
|
119
|
-
end
|
120
|
-
class NotImplementedError < Error
|
121
|
-
def error_message; "Not Implemented Error" end
|
122
|
-
def status; 501 end
|
123
|
-
end
|
124
|
-
class BadRequestError < Error
|
125
|
-
def error_message; "Bad Request Error" end
|
126
|
-
def status; 400 end
|
127
|
-
end
|
128
|
-
class NotFoundError < Error
|
129
|
-
def error_message; "Not Found Error" end
|
130
|
-
def status; 404 end
|
131
|
-
end
|
132
|
-
|
133
|
-
class Router
|
134
|
-
|
135
|
-
def status; @status || ok end
|
136
|
-
def logger; Traim.logger end
|
137
|
-
|
138
|
-
# status code sytax suger
|
139
|
-
def ok; @status = 200 end
|
140
|
-
def created; @status = 201 end
|
141
|
-
def no_cotent; @status = 204 end
|
142
|
-
|
143
|
-
def headers(key, value)
|
144
|
-
@headers[key] = value
|
145
|
-
end
|
146
|
-
|
147
|
-
def initialize(resources)
|
148
|
-
@status = nil
|
149
|
-
@resources = resources
|
150
|
-
@headers = {}
|
151
|
-
end
|
152
|
-
|
153
|
-
def self.resources; @resources ||= {} end
|
154
|
-
|
155
|
-
def resources(name)
|
156
|
-
@resources[name]
|
157
|
-
end
|
158
|
-
|
159
|
-
def show(&block); @resource.action(:show, &block) end
|
160
|
-
def create(&block); @resource.action(:create, &block) end
|
161
|
-
def update(&block); @resource.action(:update, &block) end
|
162
|
-
def destory(&block); @resource.action(:destory, &block) end
|
163
|
-
|
164
|
-
def run(seg, inbox)
|
104
|
+
def run(seg, inbox, request)
|
105
|
+
model = nil
|
165
106
|
begin
|
166
107
|
segment = inbox[:segment].to_sym
|
167
108
|
|
168
|
-
if
|
169
|
-
raise BadRequestError unless @resource = resources
|
109
|
+
if model.nil?
|
110
|
+
raise BadRequestError unless @resource = @resources[segment]
|
111
|
+
model = Model.new(@resource.model, request)
|
170
112
|
next
|
171
113
|
end
|
172
114
|
|
173
|
-
if
|
115
|
+
if model.id.nil?
|
174
116
|
if collection = @resource.collections[segment]
|
175
|
-
|
176
|
-
|
117
|
+
instance_eval(&collection)
|
118
|
+
break
|
177
119
|
else
|
178
|
-
|
179
|
-
@record = @resource.model_delegator.show(@id)
|
120
|
+
model.id = segment.to_s.to_i
|
180
121
|
next
|
181
122
|
end
|
182
123
|
end
|
183
124
|
|
184
|
-
if
|
185
|
-
|
186
|
-
|
187
|
-
return instance_eval(&member)
|
188
|
-
end
|
125
|
+
if member = @resource.members[segment]
|
126
|
+
instance_eval(&member)
|
127
|
+
break
|
189
128
|
end
|
190
129
|
|
191
130
|
raise BadRequestError
|
192
131
|
end while seg.capture(:segment, inbox)
|
132
|
+
|
133
|
+
model.instance_eval(&@helpers_block) unless @helpers_block.nil?
|
134
|
+
model
|
193
135
|
end
|
194
136
|
|
195
|
-
def to_json
|
196
|
-
if @result.kind_of?(ActiveRecord::Relation)
|
197
|
-
hash = @result.map do |object|
|
198
|
-
@resource.to_hash(object, @resources)
|
199
|
-
end
|
200
|
-
JSON.dump(hash)
|
201
|
-
else
|
202
|
-
new_hash = {}
|
203
|
-
if @result.errors.size == 0
|
204
|
-
new_hash = @resource.to_hash(@result, @resources)
|
205
|
-
else
|
206
|
-
new_hash = @result.errors.messages
|
207
|
-
end
|
208
|
-
JSON.dump(new_hash)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
137
|
def action(name)
|
213
138
|
raise NotImplementedError unless action = @resource.actions[name]
|
214
139
|
|
@@ -219,43 +144,89 @@ class Traim
|
|
219
144
|
def default_actions
|
220
145
|
@default_actions ||= begin
|
221
146
|
actions = {}
|
222
|
-
|
223
|
-
|
224
|
-
delegator.create(params["payload"])
|
147
|
+
actions["POST"] = lambda do
|
148
|
+
create(params)
|
225
149
|
end
|
226
|
-
actions["GET"] = lambda do
|
227
|
-
|
150
|
+
actions["GET"] = lambda do
|
151
|
+
show(id)
|
228
152
|
end
|
229
|
-
actions["PUT"] = lambda do
|
230
|
-
result =
|
153
|
+
actions["PUT"] = lambda do
|
154
|
+
result = update(id, params)
|
231
155
|
result
|
232
156
|
end
|
233
|
-
actions["DELETE"] = lambda do
|
234
|
-
|
157
|
+
actions["DELETE"] = lambda do
|
158
|
+
delete(id)
|
235
159
|
end
|
236
160
|
actions
|
237
161
|
end
|
238
162
|
end
|
239
163
|
|
240
|
-
def model
|
241
|
-
|
164
|
+
def to_json(resources, model)
|
165
|
+
if @result.kind_of?(ActiveRecord::Relation)
|
166
|
+
hash = @result.map do |object|
|
167
|
+
@resource.to_hash(object, resources, model)
|
168
|
+
end
|
169
|
+
JSON.dump(hash)
|
170
|
+
else
|
171
|
+
new_hash = {}
|
172
|
+
if @result.errors.size == 0
|
173
|
+
new_hash = @resource.to_hash(@result, resources, model)
|
174
|
+
else
|
175
|
+
new_hash = @result.errors.messages
|
176
|
+
end
|
177
|
+
JSON.dump(new_hash)
|
178
|
+
end
|
179
|
+
end
|
242
180
|
|
243
|
-
def render(request)
|
181
|
+
def render(request, model)
|
244
182
|
method_block = action(request.request_method)
|
245
|
-
|
183
|
+
|
246
184
|
if (method_block[:options][:permit])
|
247
|
-
if not_permmited_payload =
|
185
|
+
if not_permmited_payload = request.params.detect { |key, value| !method_block[:options][:permit].include?(key) }
|
248
186
|
raise BadRequestError.new(message: "Not permitted payload: #{not_permmited_payload}")
|
249
187
|
end
|
250
188
|
end
|
251
|
-
params = {"payload" => payload}
|
252
|
-
params["id"] = @id unless @id.nil?
|
253
|
-
@result = @resource.execute(params, &method_block[:block])
|
254
189
|
|
255
|
-
|
190
|
+
model.params = request.params
|
191
|
+
@result = model.instance_eval(&method_block[:block])
|
192
|
+
[model.status, model.headers, [to_json(@resources, model)]]
|
193
|
+
end
|
194
|
+
|
195
|
+
def compile(&block)
|
196
|
+
logger.debug("Compile application: #{@name}")
|
197
|
+
instance_eval(&block)
|
256
198
|
end
|
257
199
|
end
|
258
200
|
|
201
|
+
class Error < StandardError
|
202
|
+
def initialize(options = {})
|
203
|
+
@message = options[:message] || error_message
|
204
|
+
@body = options[:body] || error_message
|
205
|
+
super(@message)
|
206
|
+
end
|
207
|
+
|
208
|
+
def status; 500 end
|
209
|
+
def error_message; 'Internal Server Error' end
|
210
|
+
def header; DEFAULT_HEADER end
|
211
|
+
def body; {message: @body} end
|
212
|
+
end
|
213
|
+
class NotImplementedError < Error
|
214
|
+
def error_message; "Not Implemented Error" end
|
215
|
+
def status; 501 end
|
216
|
+
end
|
217
|
+
class BadRequestError < Error
|
218
|
+
def error_message; "Bad Request Error" end
|
219
|
+
def status; 400 end
|
220
|
+
end
|
221
|
+
class ForbiddenError < Error
|
222
|
+
def error_message; "Forbidden Error" end
|
223
|
+
def status; 403 end
|
224
|
+
end
|
225
|
+
class NotFoundError < Error
|
226
|
+
def error_message; "Not Found Error" end
|
227
|
+
def status; 404 end
|
228
|
+
end
|
229
|
+
|
259
230
|
class Resource
|
260
231
|
ACTION_METHODS = {create: 'POST', show: 'GET', update: 'PUT', destory: 'DELETE'}
|
261
232
|
|
@@ -264,19 +235,11 @@ class Traim
|
|
264
235
|
instance_eval(&block)
|
265
236
|
end
|
266
237
|
|
267
|
-
def execute(params, &block)
|
268
|
-
yield params
|
269
|
-
end
|
270
|
-
|
271
238
|
def model(object = nil, options = {})
|
272
239
|
@model = object unless object.nil?
|
273
240
|
@model
|
274
241
|
end
|
275
242
|
|
276
|
-
def model_delegator
|
277
|
-
@model_delegator ||= Model.new(model)
|
278
|
-
end
|
279
|
-
|
280
243
|
def actions; @actions ||= {} end
|
281
244
|
def action(name, options = {}, &block)
|
282
245
|
actions[ACTION_METHODS[name]] = {block: block, options: options}
|
@@ -314,7 +277,7 @@ class Traim
|
|
314
277
|
fields << {name: name, type: 'connection'}
|
315
278
|
end
|
316
279
|
|
317
|
-
def to_hash(object, resources, nested_associations = [])
|
280
|
+
def to_hash(object, resources, model, nested_associations = [])
|
318
281
|
return if object.nil?
|
319
282
|
|
320
283
|
fields.inject({}) do | hash, attr|
|
@@ -323,20 +286,20 @@ class Traim
|
|
323
286
|
if attr[:block].nil?
|
324
287
|
object.attributes[name.to_s]
|
325
288
|
else
|
326
|
-
|
289
|
+
model.instance_exec(object, &attr[:block])
|
327
290
|
end
|
328
291
|
elsif attr[:type] == 'association'
|
329
292
|
raise Error if nested_associations.include?(name)
|
330
293
|
nested_associations << name
|
331
294
|
object.send(name).map do |association|
|
332
|
-
resources[name].to_hash(association, resources, nested_associations.dup)
|
295
|
+
resources[name].to_hash(association, resources, model, nested_associations.dup)
|
333
296
|
end
|
334
297
|
else
|
335
298
|
resource_name = name.to_s.pluralize.to_sym
|
336
299
|
raise Error.new(message: "Inifinite Association") if nested_associations.include?(resource_name)
|
337
300
|
raise Error if object.class.reflections[name.to_s].blank?
|
338
301
|
nested_associations << resource_name
|
339
|
-
resources[resource_name].to_hash(object.send(name), resources, nested_associations.dup)
|
302
|
+
resources[resource_name].to_hash(object.send(name), resources, model, nested_associations.dup)
|
340
303
|
end
|
341
304
|
hash
|
342
305
|
end
|
@@ -345,10 +308,39 @@ class Traim
|
|
345
308
|
|
346
309
|
class Model
|
347
310
|
|
348
|
-
def initialize(model)
|
349
|
-
@model
|
311
|
+
def initialize(model, request = nil)
|
312
|
+
@model = model
|
313
|
+
@request = request
|
314
|
+
@headers = {}
|
315
|
+
ok
|
316
|
+
end
|
317
|
+
|
318
|
+
attr_accessor :id
|
319
|
+
attr_accessor :model
|
320
|
+
attr_accessor :record
|
321
|
+
attr_accessor :params
|
322
|
+
attr_accessor :request
|
323
|
+
attr_accessor :status
|
324
|
+
|
325
|
+
def logger; Traim.logger end
|
326
|
+
|
327
|
+
# status code sytax suger
|
328
|
+
def ok; @status = 200 end
|
329
|
+
def created; @status = 201 end
|
330
|
+
def no_cotent; @status = 204 end
|
331
|
+
|
332
|
+
def instance_record(id)
|
333
|
+
@id = id
|
334
|
+
@record = show(@id)
|
350
335
|
end
|
351
336
|
|
337
|
+
def headers(key = nil, value = nil)
|
338
|
+
return @headers if key.nil?
|
339
|
+
@headers[key] = value
|
340
|
+
end
|
341
|
+
|
342
|
+
def record; @record ||= show(id) end
|
343
|
+
|
352
344
|
def create(params)
|
353
345
|
resource = @model.new(params)
|
354
346
|
resource.save
|
data/test/resource.rb
CHANGED
@@ -3,7 +3,7 @@ require_relative "../lib/traim"
|
|
3
3
|
|
4
4
|
Traim.config do |app|
|
5
5
|
app.logger = Logger.new(STDOUT)
|
6
|
-
app.logger.level = Logger::
|
6
|
+
app.logger.level = Logger::INFO
|
7
7
|
end
|
8
8
|
|
9
9
|
class User < ActiveRecord::Base
|
@@ -73,10 +73,9 @@ test "customize functionality" do |user|
|
|
73
73
|
attribute :id
|
74
74
|
attribute :name
|
75
75
|
|
76
|
-
action :show do
|
77
|
-
|
78
|
-
|
79
|
-
user
|
76
|
+
action :show do
|
77
|
+
record.name = "[admin] #{record.name}"
|
78
|
+
record
|
80
79
|
end
|
81
80
|
end
|
82
81
|
end
|
@@ -95,19 +94,20 @@ test "member create, read, update and destory functionality" do |user|
|
|
95
94
|
attribute :name
|
96
95
|
|
97
96
|
member :blurred do
|
98
|
-
show do
|
97
|
+
show do
|
99
98
|
logger.info("show blurred")
|
99
|
+
logger.info("class #{self.class.name}")
|
100
100
|
record.name[1..2] = "xx"
|
101
101
|
record
|
102
102
|
end
|
103
103
|
|
104
|
-
update do
|
105
|
-
record.assign_attributes(params
|
104
|
+
update do
|
105
|
+
record.assign_attributes(params)
|
106
106
|
record.save
|
107
107
|
record
|
108
108
|
end
|
109
109
|
|
110
|
-
destory do
|
110
|
+
destory do
|
111
111
|
record.delete
|
112
112
|
end
|
113
113
|
end
|
@@ -138,12 +138,12 @@ test "collection create, read, update and destory functionality" do |user|
|
|
138
138
|
attribute :name
|
139
139
|
|
140
140
|
collection :admin do
|
141
|
-
show do
|
141
|
+
show do
|
142
142
|
model.all
|
143
143
|
end
|
144
144
|
|
145
|
-
create do
|
146
|
-
model.create(params
|
145
|
+
create do
|
146
|
+
model.create(params)
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
@@ -193,13 +193,13 @@ test "has many functionality" do |user|
|
|
193
193
|
action :show
|
194
194
|
|
195
195
|
collection :admin do
|
196
|
-
show do
|
196
|
+
show do
|
197
197
|
model.all
|
198
198
|
end
|
199
199
|
|
200
|
-
create do
|
200
|
+
create do
|
201
201
|
# what to response?
|
202
|
-
model.create(params
|
202
|
+
model.create(params)
|
203
203
|
end
|
204
204
|
end
|
205
205
|
end
|
@@ -322,19 +322,19 @@ test "helpers functionality" do |user|
|
|
322
322
|
attribute :name
|
323
323
|
|
324
324
|
member :blurred do
|
325
|
-
show do
|
325
|
+
show do
|
326
326
|
auth('test')
|
327
327
|
record.name[1..2] = "xx"
|
328
328
|
record
|
329
329
|
end
|
330
330
|
|
331
|
-
update do
|
332
|
-
record.assign_attributes(params
|
331
|
+
update do
|
332
|
+
record.assign_attributes(params)
|
333
333
|
record.save
|
334
334
|
record
|
335
335
|
end
|
336
336
|
|
337
|
-
destory do
|
337
|
+
destory do
|
338
338
|
record.delete
|
339
339
|
end
|
340
340
|
end
|
@@ -362,7 +362,7 @@ test "headers functionality" do |user|
|
|
362
362
|
attribute :name
|
363
363
|
|
364
364
|
member :headers do
|
365
|
-
show do
|
365
|
+
show do
|
366
366
|
headers("test", "yeah")
|
367
367
|
record
|
368
368
|
end
|
data/traim.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: traim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Travis Liu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|