fmrest-core 0.17.1 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +4 -0
- data/lib/fmrest/v1/connection.rb +8 -7
- data/lib/fmrest/v1/raise_errors.rb +13 -3
- data/lib/fmrest/v1/token_session.rb +4 -1
- data/lib/fmrest/v1/type_coercer.rb +1 -1
- data/lib/fmrest/v1/utils.rb +14 -0
- data/lib/fmrest/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdfc316e5474cc3abbf196051aa48846f6b04452e0864a320445079a09a3f449
|
4
|
+
data.tar.gz: d23a6c290f33ab9c43f149de58af85825859aae9f0bc781200395bc883f66009
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48ddb1505f075011675b5bfbeb437d42e70dff62912a6c44b0ac454c205332e8e61da6a628c0ae0cda095214d54dded125f8f98fa0af711d2e8e34b1d24332e1
|
7
|
+
data.tar.gz: 16623334ee707adb60e479d6db8bff23f22aa23cac397e32b839d4dceaa7aed4a2e94558684d08b1eaaa1fb008093b9628014a73b8b7dbe93f3d2cd1bc3498fc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
### 0.18.0
|
4
|
+
|
5
|
+
* Better support for portals with mismatching field qualifiers
|
6
|
+
* Better ergonomics for script execution, improved documentation
|
7
|
+
* Defining an attribute on a model that would collide with an existing method
|
8
|
+
now raises an error
|
9
|
+
* Cleared Faraday deprecation messages on authentication methods
|
10
|
+
* Handle FileMaker Cloud case where HTTP 401 Unauthorized with content-type
|
11
|
+
text/html is returned after token expiry
|
12
|
+
* Add retry option to Rescuable mixin
|
13
|
+
* Added fmrest-ruby/VERSION to User-Agent headers
|
14
|
+
|
3
15
|
### 0.17.1
|
4
16
|
|
5
17
|
* Fixed crash when `fmid_token` is set but `username` isn't
|
data/README.md
CHANGED
@@ -543,6 +543,10 @@ class LoggyBee < FmRest::Layout
|
|
543
543
|
end
|
544
544
|
```
|
545
545
|
|
546
|
+
## Gotchas
|
547
|
+
|
548
|
+
Read about unexpected scenarios in the [gotchas doc](docs/Gotchas.md).
|
549
|
+
|
546
550
|
## API implementation completeness table
|
547
551
|
|
548
552
|
FM Data API reference: https://fmhelp.filemaker.com/docs/18/en/dataapi/
|
data/lib/fmrest/v1/connection.rb
CHANGED
@@ -8,7 +8,8 @@ module FmRest
|
|
8
8
|
BASE_PATH = "/fmi/data/v1"
|
9
9
|
DATABASES_PATH = "#{BASE_PATH}/databases"
|
10
10
|
|
11
|
-
|
11
|
+
DEFAULT_HEADERS = { "User-Agent" => "fmrest-ruby/#{::FmRest::VERSION} Faraday/#{::Faraday::VERSION}" }.freeze
|
12
|
+
AUTH_CONNECTION_HEADERS = DEFAULT_HEADERS.merge("Content-Type" => "application/json").freeze
|
12
13
|
CLARIS_ID_HTTP_AUTH_TYPE = "FMID"
|
13
14
|
|
14
15
|
# Builds a complete DAPI Faraday connection with middleware already
|
@@ -21,7 +22,7 @@ module FmRest
|
|
21
22
|
def build_connection(settings = FmRest.default_connection_settings, &block)
|
22
23
|
settings = ConnectionSettings.wrap(settings)
|
23
24
|
|
24
|
-
base_connection(settings) do |conn|
|
25
|
+
base_connection(settings, headers: DEFAULT_HEADERS) do |conn|
|
25
26
|
conn.use RaiseErrors
|
26
27
|
conn.use TokenSession, settings
|
27
28
|
|
@@ -38,7 +39,7 @@ module FmRest
|
|
38
39
|
yield conn, settings
|
39
40
|
else
|
40
41
|
conn.use TypeCoercer, settings
|
41
|
-
conn.response :json
|
42
|
+
conn.response :json, content_type: /\bjson$/
|
42
43
|
end
|
43
44
|
|
44
45
|
if settings.log
|
@@ -56,20 +57,20 @@ module FmRest
|
|
56
57
|
def auth_connection(settings = FmRest.default_connection_settings)
|
57
58
|
settings = ConnectionSettings.wrap(settings)
|
58
59
|
|
59
|
-
base_connection(settings,
|
60
|
+
base_connection(settings, headers: AUTH_CONNECTION_HEADERS) do |conn|
|
60
61
|
conn.use RaiseErrors
|
61
62
|
|
62
63
|
if settings.fmid_token?
|
63
|
-
conn.authorization CLARIS_ID_HTTP_AUTH_TYPE, settings.fmid_token
|
64
|
+
conn.request :authorization, CLARIS_ID_HTTP_AUTH_TYPE, settings.fmid_token
|
64
65
|
else
|
65
|
-
conn.basic_auth settings.username!, settings.password!
|
66
|
+
conn.request :basic_auth, settings.username!, settings.password!
|
66
67
|
end
|
67
68
|
|
68
69
|
if settings.log
|
69
70
|
conn.response :logger, FmRest.logger, bodies: true, headers: true, log_level: settings.log_level
|
70
71
|
end
|
71
72
|
|
72
|
-
conn.response :json
|
73
|
+
conn.response :json, content_type: /\bjson$/
|
73
74
|
conn.adapter Faraday.default_adapter
|
74
75
|
end
|
75
76
|
end
|
@@ -5,10 +5,9 @@ module FmRest
|
|
5
5
|
# FM Data API response middleware for raising exceptions on API response
|
6
6
|
# errors
|
7
7
|
#
|
8
|
-
# https://fmhelp.filemaker.com/help/17/fmp/en/index.html#page/FMP_Help/error-codes.html
|
9
|
-
#
|
10
8
|
class RaiseErrors < Faraday::Response::Middleware
|
11
|
-
#
|
9
|
+
# Error codes reference:
|
10
|
+
# https://help.claris.com/en/pro-help/content/error-codes.html
|
12
11
|
ERROR_RANGES = {
|
13
12
|
-1 => APIError::UnknownError,
|
14
13
|
100 => APIError::ResourceMissingError,
|
@@ -28,6 +27,17 @@ module FmRest
|
|
28
27
|
}.freeze
|
29
28
|
|
30
29
|
def on_complete(env)
|
30
|
+
# Sometimes, especially when using FileMaker Cloud, a failed
|
31
|
+
# authorization request will return a 401 (Unauthorized) with text/html
|
32
|
+
# content-type instead of the regular JSON, so we need to catch it
|
33
|
+
# manually here, emulating a regular account error
|
34
|
+
if !(/\bjson$/ === env.response_headers["content-type"]) && env.status == 401
|
35
|
+
raise FmRest::APIError::AccountError.new(212, "Authentication failed (HTTP 401: Unauthorized)")
|
36
|
+
end
|
37
|
+
|
38
|
+
# From this point on we want JSON
|
39
|
+
return unless env.body.is_a?(Hash)
|
40
|
+
|
31
41
|
# Sniff for either straight JSON parsing or Spyke's format
|
32
42
|
if env.body[:metadata] && env.body[:metadata][:messages]
|
33
43
|
check_errors(env.body[:metadata][:messages])
|
@@ -132,7 +132,10 @@ module FmRest
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def auth_connection
|
135
|
-
|
135
|
+
# NOTE: this is purposely not memoized so that settings can be
|
136
|
+
# refreshed (since proc-based settings will not be automatically
|
137
|
+
# re-eval'd, for example for fmid_token-based auth)
|
138
|
+
V1.auth_connection(@settings)
|
136
139
|
end
|
137
140
|
end
|
138
141
|
end
|
data/lib/fmrest/v1/utils.rb
CHANGED
@@ -8,6 +8,8 @@ module FmRest
|
|
8
8
|
# See https://help.claris.com/en/pro-help/content/finding-text.html
|
9
9
|
FM_FIND_OPERATORS_RE = /([@\*#\?!=<>"])/
|
10
10
|
|
11
|
+
FULLY_QUALIFIED_FIELD_NAME_MATCHER = /\A[^:]+::[^:]+\Z/.freeze
|
12
|
+
|
11
13
|
# Converts custom script options to a hash with the Data API's expected
|
12
14
|
# JSON script format.
|
13
15
|
#
|
@@ -104,6 +106,18 @@ module FmRest
|
|
104
106
|
s.gsub(FM_FIND_OPERATORS_RE, "\\\\\\1")
|
105
107
|
end
|
106
108
|
|
109
|
+
# Returns whether the given FileMaker field name is a fully-qualified
|
110
|
+
# name. In other words, whether it contains the string "::".
|
111
|
+
#
|
112
|
+
# Note that this is a simple naive check which doesn't account for
|
113
|
+
# invalid field names.
|
114
|
+
#
|
115
|
+
# @param field_name [String] The field name to test
|
116
|
+
# @return [Boolean] Whether the field is a FQN
|
117
|
+
def is_fully_qualified?(field_name)
|
118
|
+
FULLY_QUALIFIED_FIELD_NAME_MATCHER === field_name.to_s
|
119
|
+
end
|
120
|
+
|
107
121
|
private
|
108
122
|
|
109
123
|
def convert_script_arguments(script_arguments, suffix = nil)
|
data/lib/fmrest/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fmrest-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Carbajal
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|