safrano 0.6.5 → 0.6.7
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/lib/odata/collection_media.rb +1 -1
- data/lib/odata/complex_type.rb +2 -2
- data/lib/odata/error.rb +17 -0
- data/lib/odata/function_import.rb +67 -8
- data/lib/odata/model_ext.rb +2 -1
- data/lib/odata/request/json.rb +7 -1
- data/lib/safrano/core.rb +4 -4
- data/lib/safrano/multipart.rb +6 -6
- data/lib/safrano/service.rb +9 -2
- data/lib/safrano/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a93263d81a1f266029f7aac03d6b7226477f10d27d33255462e08133955ab759
|
4
|
+
data.tar.gz: 894a0bfab2eeeee57543bee7dd0c1ec93b5bc73e0afc6fe5f979c7b7e7067039
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0900d4f692a9139226d4fb84703f8a0c47a071b97b0a46c8455016f6a7d0d09caf2b12f32e616c9880a10a0b50e09917ca22afc4af7fc0f4cddac690193b25c
|
7
|
+
data.tar.gz: 30a623f667830e0dc4342bcf240843d313173ef12c0e877dc1814e779fc7f53459e7ec7e958aedd22b4387c9390907844a0c2c84a639db8d98dc62805203a671
|
@@ -21,7 +21,7 @@ module Safrano
|
|
21
21
|
class Static < Handler
|
22
22
|
def initialize(root: nil, mediaklass:)
|
23
23
|
@root = File.absolute_path(root || Dir.pwd)
|
24
|
-
@file_server = ::Rack::
|
24
|
+
@file_server = ::Rack::Files.new(@root)
|
25
25
|
@media_class = mediaklass
|
26
26
|
@media_dir_name = mediaklass.to_s
|
27
27
|
register
|
data/lib/odata/complex_type.rb
CHANGED
@@ -81,9 +81,9 @@ module Safrano
|
|
81
81
|
end
|
82
82
|
|
83
83
|
# needed for ComplexType result
|
84
|
-
def to_odata_json(
|
84
|
+
def to_odata_json(req)
|
85
85
|
t = self.class.klassmod.output_template
|
86
|
-
innerh =
|
86
|
+
innerh = req.service.get_entity_odata_h(entity: @value, template: t)
|
87
87
|
innerj = innerh.to_json
|
88
88
|
|
89
89
|
"#{DJ_OPEN}#{innerj}#{DJ_CLOSE}"
|
data/lib/odata/error.rb
CHANGED
@@ -48,6 +48,13 @@ module Safrano
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
# used in function import error handling. cf. func import / do_execute_func
|
52
|
+
def self.with_error(result)
|
53
|
+
if result.respond_to?(:error) && (err = result.error)
|
54
|
+
yield err
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
51
58
|
# base module for HTTP errors, when used as a Error Class
|
52
59
|
module ErrorClass
|
53
60
|
include ::Safrano::Contract::Invalid
|
@@ -94,10 +101,20 @@ module Safrano
|
|
94
101
|
# generic http 500 server err
|
95
102
|
class ServerError
|
96
103
|
extend ErrorClass
|
104
|
+
include ErrorInstance
|
97
105
|
HTTP_CODE = 500
|
98
106
|
@msg = 'Server error'
|
99
107
|
end
|
100
108
|
|
109
|
+
class ServiceOperationError
|
110
|
+
extend ErrorClass
|
111
|
+
include ErrorInstance
|
112
|
+
HTTP_CODE = 500
|
113
|
+
def initialize(msg:, sopname: nil)
|
114
|
+
@msg = "Error in service operation #{sopname}: #{msg}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
101
118
|
# for outputing Sequel exceptions that we could not prevent
|
102
119
|
class SequelExceptionError < ServerError
|
103
120
|
include ErrorInstance
|
@@ -10,6 +10,21 @@ module Safrano
|
|
10
10
|
end
|
11
11
|
|
12
12
|
module FunctionImport
|
13
|
+
# error classes
|
14
|
+
class DefinitionMissing < StandardError
|
15
|
+
def initialize(fnam)
|
16
|
+
msg = "Function import #{fnam}: definition is missing. Provide definition either as a return code block or with .definition(lambda)"
|
17
|
+
super(msg)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
class ProcRedefinition < StandardError
|
21
|
+
def initialize(fnam)
|
22
|
+
msg = "Function import #{fnam}: Block/lambda Redefinition . Provide definition either as a return code block or with .definition(lambda) but not both"
|
23
|
+
super(msg)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Function import object
|
13
28
|
class Function
|
14
29
|
@allowed_transitions = [Safrano::TransitionEnd]
|
15
30
|
attr_reader :name
|
@@ -53,8 +68,6 @@ module Safrano
|
|
53
68
|
alias auto_query_params auto_query_parameters
|
54
69
|
|
55
70
|
def return(klassmod, &proc)
|
56
|
-
raise('Please provide a code block') unless block_given?
|
57
|
-
|
58
71
|
@returning = if klassmod.respond_to? :return_as_instance_descriptor
|
59
72
|
klassmod.return_as_instance_descriptor
|
60
73
|
else
|
@@ -62,13 +75,35 @@ module Safrano
|
|
62
75
|
# --> assume it is a Primitive
|
63
76
|
ResultDefinition.asPrimitiveType(klassmod)
|
64
77
|
end
|
65
|
-
|
78
|
+
# block is optional since 0.6.7
|
79
|
+
# the function definition can now also be made with .definition(lambda)
|
80
|
+
# consistency check that there is a single definition either as a
|
81
|
+
# return-block or a definition lambda is made on publish finalise
|
82
|
+
|
83
|
+
if block_given?
|
84
|
+
# proc already defined...
|
85
|
+
raise Redefinition.new(@name) if @proc
|
86
|
+
|
87
|
+
@proc = proc
|
88
|
+
end
|
89
|
+
|
66
90
|
self
|
67
91
|
end
|
68
92
|
|
69
|
-
def
|
70
|
-
raise('Please provide a
|
93
|
+
def definition(lambda)
|
94
|
+
raise('Please provide a lambda') unless lambda
|
95
|
+
# proc already defined...
|
96
|
+
raise ProcRedefinition.new(@name) if @proc
|
97
|
+
|
98
|
+
@proc = lambda
|
99
|
+
end
|
100
|
+
|
101
|
+
# this is called from service.finalize_publishing
|
102
|
+
def check_definition
|
103
|
+
raise DefinitionMissing.new(@name) unless @proc
|
104
|
+
end
|
71
105
|
|
106
|
+
def return_collection(klassmod, lambda: nil, &proc)
|
72
107
|
@returning = if klassmod.respond_to? :return_as_collection_descriptor
|
73
108
|
klassmod.return_as_collection_descriptor
|
74
109
|
else
|
@@ -77,7 +112,14 @@ module Safrano
|
|
77
112
|
# ResultAsPrimitiveTypeColl.new(klassmod)
|
78
113
|
ResultDefinition.asPrimitiveTypeColl(klassmod)
|
79
114
|
end
|
80
|
-
|
115
|
+
# block is optional since 0.6.7
|
116
|
+
if block_given?
|
117
|
+
# proc already defined...
|
118
|
+
raise ProcRedefinition.new(@name) if @proc
|
119
|
+
|
120
|
+
@proc = proc
|
121
|
+
end
|
122
|
+
|
81
123
|
self
|
82
124
|
end
|
83
125
|
# def initialize_params
|
@@ -151,14 +193,31 @@ module Safrano
|
|
151
193
|
def with_transition_validated(req)
|
152
194
|
# initialize_params
|
153
195
|
@params = req.params
|
154
|
-
|
155
|
-
|
196
|
+
unless (@error = check_url_func_params)
|
197
|
+
begin
|
198
|
+
return yield
|
199
|
+
rescue LocalJumpError => e
|
200
|
+
@error = Safrano::ServiceOperationReturnError.new
|
201
|
+
end
|
202
|
+
end
|
156
203
|
[nil, :error, @error] if @error
|
157
204
|
end
|
158
205
|
|
159
206
|
def do_execute_func(req)
|
160
207
|
with_transition_validated(req) do
|
161
208
|
result = @proc.call(**@funcparams)
|
209
|
+
|
210
|
+
# (application-)error handling
|
211
|
+
# the result is an Error object or class
|
212
|
+
|
213
|
+
# Note: Sequel::Error exceptions are already
|
214
|
+
# handled on rack app level (cf. the call methode )
|
215
|
+
Safrano::with_error(result) do |error|
|
216
|
+
@error = error
|
217
|
+
return [nil, :error, @error] # this is return from do_execute_func !
|
218
|
+
end
|
219
|
+
|
220
|
+
# non error case
|
162
221
|
[@returning.do_execute_func_result(result, req, @auto_query_params), :run]
|
163
222
|
end
|
164
223
|
end
|
data/lib/odata/model_ext.rb
CHANGED
@@ -753,7 +753,8 @@ module Safrano
|
|
753
753
|
# json is default content type so we dont need to specify it here again
|
754
754
|
# TODO quirks array mode !
|
755
755
|
# [201, EMPTY_HASH, new_entity.to_odata_post_json(service: req.service)]
|
756
|
-
[201, {
|
756
|
+
[201, { Safrano::LOCATION => new_entity.uri },
|
757
|
+
new_entity.to_odata_create_json(request: req)]
|
757
758
|
else # TODO: other formats
|
758
759
|
415
|
759
760
|
end
|
data/lib/odata/request/json.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'time'
|
3
|
-
|
3
|
+
require 'base64'
|
4
4
|
# client parsing functionality to ease testing
|
5
5
|
|
6
6
|
module Safrano
|
7
|
+
module RFC2047
|
8
|
+
def self.encode(str)
|
9
|
+
"=?utf-8?b?#{Base64.strict_encode64(str)}?="
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
module OData
|
8
14
|
# this is used to parse inbound json payload on POST / PUT & co
|
9
15
|
# it does not do symbolize but proper (hopefully) type casting when needed
|
data/lib/safrano/core.rb
CHANGED
@@ -13,10 +13,10 @@ module Safrano
|
|
13
13
|
|
14
14
|
# some prominent constants... probably already defined elsewhere eg in Rack
|
15
15
|
# but lets KISS
|
16
|
-
CONTENT_TYPE = '
|
17
|
-
CONTENT_LENGTH = '
|
18
|
-
LOCATION = '
|
19
|
-
|
16
|
+
CONTENT_TYPE = 'content-type'
|
17
|
+
CONTENT_LENGTH = 'content-length'
|
18
|
+
LOCATION = 'location'
|
19
|
+
|
20
20
|
TEXTPLAIN_UTF8 = 'text/plain;charset=utf-8'
|
21
21
|
APPJSON = 'application/json'
|
22
22
|
APPXML = 'application/xml'
|
data/lib/safrano/multipart.rb
CHANGED
@@ -142,12 +142,12 @@ module MIME
|
|
142
142
|
@lines = inpstr.readlines(@sep)
|
143
143
|
else
|
144
144
|
# rack input wrapper only has gets but not readlines
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
145
|
+
# BUT the rack SPEC says it only supports gets without argument!
|
146
|
+
# --> finally we end up using read and split into lines...
|
147
|
+
# normally should be ok for $batch POST payloads
|
148
|
+
|
149
|
+
# inpstr.read should be a String
|
150
|
+
@lines = inpstr.read.lines(@sep)
|
151
151
|
|
152
152
|
end
|
153
153
|
# tmp hack for test-tools that convert CRLF in payload to LF :-(
|
data/lib/safrano/service.rb
CHANGED
@@ -375,7 +375,7 @@ module Safrano
|
|
375
375
|
def finalize_publishing
|
376
376
|
# build the cmap
|
377
377
|
@cmap = {}
|
378
|
-
@collections
|
378
|
+
@collections&.each do |klass|
|
379
379
|
@cmap[klass.entity_set_name] = klass
|
380
380
|
# set namespace needed to have qualified type name
|
381
381
|
copy_namespace_to(klass)
|
@@ -393,7 +393,7 @@ module Safrano
|
|
393
393
|
set_uribase
|
394
394
|
|
395
395
|
# finalize the uri's and include NoMappingBeforeOutput or MappingBeforeOutput as needed
|
396
|
-
@collections
|
396
|
+
@collections&.each do |klass|
|
397
397
|
klass.finalize_publishing(self)
|
398
398
|
|
399
399
|
klass.build_uri(@uribase)
|
@@ -448,9 +448,14 @@ module Safrano
|
|
448
448
|
Safrano::Filter::DateTimeLit.include Safrano::Filter::DateTimeDefault
|
449
449
|
Safrano::Filter::DateTimeOffsetLit.include Safrano::Filter::DateTimeDefault
|
450
450
|
end
|
451
|
+
|
452
|
+
# check function import definition
|
453
|
+
function_imports.each_value { |func| func.check_definition }
|
451
454
|
end
|
452
455
|
|
453
456
|
def execute_deferred_iblocks
|
457
|
+
return unless @collections
|
458
|
+
|
454
459
|
@collections.each do |k|
|
455
460
|
k.instance_eval(&k.deferred_iblock) if k.deferred_iblock
|
456
461
|
end
|
@@ -460,6 +465,8 @@ module Safrano
|
|
460
465
|
## evaluated after '@collections' is filled !
|
461
466
|
# A regexp matching all allowed base entities (eg product|categories )
|
462
467
|
def base_url_regexp
|
468
|
+
return unless @collections
|
469
|
+
|
463
470
|
@collections.map(&:entity_set_name).join('|')
|
464
471
|
end
|
465
472
|
|
data/lib/safrano/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safrano
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- oz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rfc2047
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
117
|
+
version: '2.0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
124
|
+
version: '2.0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rake
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|