traim 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|