hotwire_native_version_gate 0.1.0 → 0.3.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/VERSION +1 -1
- data/lib/hotwire_native_version_gate/concern.rb +18 -9
- data/lib/hotwire_native_version_gate/version_gate.rb +42 -13
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76b2d43b870dbf0099ed5a0c6e465a1853cc2ae96b2ab16f06570aa6397d71af
|
|
4
|
+
data.tar.gz: '08393f721a6e48fc5193c5a34c6b4c76936a1aa923c1b04c209c0666a66e7ad7'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ea6c7456e14d5cdc4336c9ea872741087b203b01dd00b45ae36961182b589c83c260195d05b131445ba873c89b2423d31b79ff327ba2ce56ec535802734688e0
|
|
7
|
+
data.tar.gz: a4345f8b1044668538d643242c8fc8fb67aa43291365794cf60c041ef7f1371570de93f25c4d23fb812011d477414cfefe7d119ccde86183396fb11ef5990ac7
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.3.0
|
|
@@ -9,25 +9,34 @@ module HotwireNativeVersionGate
|
|
|
9
9
|
VersionGate.native_feature(feature, ios: ios, android: android)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
13
|
-
VersionGate.
|
|
12
|
+
def native_version_regexes
|
|
13
|
+
VersionGate.native_version_regexes
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def native_version_regexes=(regexes)
|
|
17
|
+
VersionGate.native_version_regexes = regexes
|
|
14
18
|
end
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
included do
|
|
18
22
|
if respond_to?(:helper_method)
|
|
19
|
-
helper_method :native_feature_enabled?
|
|
23
|
+
helper_method :native_feature_enabled?, :hotwire_native_ios?, :hotwire_native_android?
|
|
20
24
|
end
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
def native_feature_enabled?(feature)
|
|
24
|
-
user_agent =
|
|
25
|
-
request.user_agent
|
|
26
|
-
else
|
|
27
|
-
nil
|
|
28
|
-
end
|
|
29
|
-
|
|
28
|
+
user_agent = respond_to?(:request) && request.respond_to?(:user_agent) ? request.user_agent : nil
|
|
30
29
|
VersionGate.feature_enabled?(feature, user_agent, context: self)
|
|
31
30
|
end
|
|
31
|
+
|
|
32
|
+
def hotwire_native_ios?
|
|
33
|
+
user_agent = respond_to?(:request) && request.respond_to?(:user_agent) ? request.user_agent : nil
|
|
34
|
+
VersionGate.ios?(user_agent)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def hotwire_native_android?
|
|
38
|
+
user_agent = respond_to?(:request) && request.respond_to?(:user_agent) ? request.user_agent : nil
|
|
39
|
+
VersionGate.android?(user_agent)
|
|
40
|
+
end
|
|
32
41
|
end
|
|
33
42
|
end
|
|
@@ -5,18 +5,18 @@ module HotwireNativeVersionGate
|
|
|
5
5
|
# Default regex example: Hotwire Native App iOS/1.0.0;
|
|
6
6
|
# Expected capture groups: platform = (iOS|Android), version = semantic version
|
|
7
7
|
DEFAULT_NATIVE_VERSION_REGEX = /\bHotwire Native App (?<platform>iOS|Android)\/(?<version>\d+(?:\.\d+)*)\b/
|
|
8
|
+
# Default fallback for apps that don't have the version in the User Agent ex: Hotwire Native iOS;
|
|
9
|
+
FALLBACK_NATIVE_VERSION_REGEX = /\b(Turbo|Hotwire) Native (?<platform>iOS|Android)\b/
|
|
8
10
|
|
|
9
11
|
@native_features = {}
|
|
10
|
-
@
|
|
12
|
+
@native_version_regexes = [ DEFAULT_NATIVE_VERSION_REGEX, FALLBACK_NATIVE_VERSION_REGEX ]
|
|
11
13
|
|
|
12
14
|
class << self
|
|
13
|
-
attr_reader :native_features, :
|
|
15
|
+
attr_reader :native_features, :native_version_regexes
|
|
14
16
|
|
|
15
|
-
def
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
@native_version_regex = regex
|
|
17
|
+
def native_version_regexes=(regexes)
|
|
18
|
+
regexes_array = validate_regexes(regexes)
|
|
19
|
+
@native_version_regexes = regexes_array
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def native_feature(feature, ios: false, android: false)
|
|
@@ -36,14 +36,43 @@ module HotwireNativeVersionGate
|
|
|
36
36
|
handle_feature(feature_config, user_agent, context: context)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
def ios?(user_agent)
|
|
40
|
+
platform = match_platform(user_agent)
|
|
41
|
+
platform&.downcase == 'ios'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def android?(user_agent)
|
|
45
|
+
platform = match_platform(user_agent)
|
|
46
|
+
platform&.downcase == 'android'
|
|
47
|
+
end
|
|
48
|
+
|
|
39
49
|
private
|
|
40
50
|
|
|
41
|
-
def
|
|
42
|
-
|
|
43
|
-
|
|
51
|
+
def validate_regexes(regexes)
|
|
52
|
+
# Support both single regex and array of regexes
|
|
53
|
+
regexes_array = Array(regexes)
|
|
54
|
+
|
|
55
|
+
regexes_array.each do |regex|
|
|
56
|
+
unless regex.is_a?(Regexp)
|
|
57
|
+
raise ArgumentError, "native_version_regexes must be an array of Regexp objects, got: #{regex.class}"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
regexes_array
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def match_key(user_agent, key)
|
|
65
|
+
@native_version_regexes.each do |regex|
|
|
66
|
+
match = user_agent.to_s.match(regex)
|
|
67
|
+
return match[key] if match&.names&.include?(key.to_s) && match[key]
|
|
68
|
+
end
|
|
44
69
|
nil
|
|
45
70
|
end
|
|
46
71
|
|
|
72
|
+
def match_platform(user_agent)
|
|
73
|
+
match_key(user_agent, :platform)
|
|
74
|
+
end
|
|
75
|
+
|
|
47
76
|
def handle_feature(feature_config, user_agent, context: nil)
|
|
48
77
|
# if false or nil, return false
|
|
49
78
|
return false unless feature_config
|
|
@@ -51,9 +80,9 @@ module HotwireNativeVersionGate
|
|
|
51
80
|
return true if feature_config == true
|
|
52
81
|
# if a string, compare the version
|
|
53
82
|
if feature_config.is_a?(String)
|
|
54
|
-
|
|
55
|
-
return false unless
|
|
56
|
-
return Gem::Version.new(feature_config) <= Gem::Version.new(
|
|
83
|
+
version = match_key(user_agent, :version)
|
|
84
|
+
return false unless version
|
|
85
|
+
return Gem::Version.new(feature_config) <= Gem::Version.new(version)
|
|
57
86
|
end
|
|
58
87
|
# if a symbol, call the method on the context (if provided) or self
|
|
59
88
|
if feature_config.is_a?(Symbol)
|