nano-pure-pkg 0.0.1

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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/ahoy_matey-5.5.0/CHANGELOG.md +403 -0
  3. data/ahoy_matey-5.5.0/CONTRIBUTING.md +42 -0
  4. data/ahoy_matey-5.5.0/LICENSE.txt +22 -0
  5. data/ahoy_matey-5.5.0/README.md +802 -0
  6. data/ahoy_matey-5.5.0/app/controllers/ahoy/base_controller.rb +44 -0
  7. data/ahoy_matey-5.5.0/app/controllers/ahoy/events_controller.rb +51 -0
  8. data/ahoy_matey-5.5.0/app/controllers/ahoy/visits_controller.rb +15 -0
  9. data/ahoy_matey-5.5.0/config/routes.rb +10 -0
  10. data/ahoy_matey-5.5.0/lib/ahoy/base_store.rb +104 -0
  11. data/ahoy_matey-5.5.0/lib/ahoy/controller.rb +56 -0
  12. data/ahoy_matey-5.5.0/lib/ahoy/database_store.rb +96 -0
  13. data/ahoy_matey-5.5.0/lib/ahoy/engine.rb +37 -0
  14. data/ahoy_matey-5.5.0/lib/ahoy/geocode_v2_job.rb +31 -0
  15. data/ahoy_matey-5.5.0/lib/ahoy/helper.rb +40 -0
  16. data/ahoy_matey-5.5.0/lib/ahoy/model.rb +15 -0
  17. data/ahoy_matey-5.5.0/lib/ahoy/query_methods.rb +88 -0
  18. data/ahoy_matey-5.5.0/lib/ahoy/tracker.rb +287 -0
  19. data/ahoy_matey-5.5.0/lib/ahoy/utils.rb +7 -0
  20. data/ahoy_matey-5.5.0/lib/ahoy/version.rb +3 -0
  21. data/ahoy_matey-5.5.0/lib/ahoy/visit_properties.rb +122 -0
  22. data/ahoy_matey-5.5.0/lib/ahoy/warden.rb +5 -0
  23. data/ahoy_matey-5.5.0/lib/ahoy.rb +167 -0
  24. data/ahoy_matey-5.5.0/lib/ahoy_matey.rb +1 -0
  25. data/ahoy_matey-5.5.0/lib/generators/ahoy/activerecord_generator.rb +59 -0
  26. data/ahoy_matey-5.5.0/lib/generators/ahoy/base_generator.rb +13 -0
  27. data/ahoy_matey-5.5.0/lib/generators/ahoy/install_generator.rb +44 -0
  28. data/ahoy_matey-5.5.0/lib/generators/ahoy/mongoid_generator.rb +16 -0
  29. data/ahoy_matey-5.5.0/lib/generators/ahoy/templates/active_record_event_model.rb.tt +10 -0
  30. data/ahoy_matey-5.5.0/lib/generators/ahoy/templates/active_record_migration.rb.tt +62 -0
  31. data/ahoy_matey-5.5.0/lib/generators/ahoy/templates/active_record_visit_model.rb.tt +6 -0
  32. data/ahoy_matey-5.5.0/lib/generators/ahoy/templates/base_store_initializer.rb.tt +25 -0
  33. data/ahoy_matey-5.5.0/lib/generators/ahoy/templates/database_store_initializer.rb.tt +10 -0
  34. data/ahoy_matey-5.5.0/lib/generators/ahoy/templates/mongoid_event_model.rb.tt +14 -0
  35. data/ahoy_matey-5.5.0/lib/generators/ahoy/templates/mongoid_visit_model.rb.tt +50 -0
  36. data/ahoy_matey-5.5.0/vendor/assets/javascripts/ahoy.js +544 -0
  37. data/nano-pure-pkg.gemspec +12 -0
  38. metadata +77 -0
@@ -0,0 +1,287 @@
1
+ require "active_support/core_ext/digest/uuid"
2
+
3
+ module Ahoy
4
+ class Tracker
5
+ UUID_NAMESPACE = "a82ae811-5011-45ab-a728-569df7499c5f"
6
+
7
+ attr_reader :request, :controller
8
+
9
+ def initialize(**options)
10
+ @store = Ahoy::Store.new(options.merge(ahoy: self))
11
+ @controller = options[:controller]
12
+ @request = options[:request] || @controller.try(:request)
13
+ @visit_token = options[:visit_token]
14
+ @user = options[:user]
15
+ @options = options
16
+ end
17
+
18
+ # can't use keyword arguments here
19
+ def track(name, properties = {}, options = {})
20
+ if exclude?
21
+ debug "Event excluded"
22
+ else
23
+ data = {
24
+ visit_token: visit_token,
25
+ user_id: user.try(:id),
26
+ name: name.to_s,
27
+ properties: properties,
28
+ time: trusted_time(options[:time]),
29
+ event_id: options[:id] || generate_id
30
+ }.select { |_, v| v }
31
+
32
+ @store.track_event(data)
33
+ end
34
+ true
35
+ rescue => e
36
+ report_exception(e)
37
+ end
38
+
39
+ def track_visit(defer: false, started_at: nil)
40
+ if exclude?
41
+ debug "Visit excluded"
42
+ else
43
+ if defer
44
+ set_cookie("ahoy_track", true, nil, false)
45
+ else
46
+ delete_cookie("ahoy_track", false)
47
+
48
+ data = {
49
+ visit_token: visit_token,
50
+ visitor_token: visitor_token,
51
+ user_id: user.try(:id),
52
+ started_at: trusted_time(started_at)
53
+ }.merge(visit_properties).select { |_, v| v }
54
+
55
+ @store.track_visit(data)
56
+
57
+ Ahoy::GeocodeV2Job.perform_later(visit_token, data[:ip]) if Ahoy.geocode && data[:ip]
58
+ end
59
+ end
60
+ true
61
+ rescue => e
62
+ report_exception(e)
63
+ end
64
+
65
+ def geocode(data)
66
+ data = {
67
+ visit_token: visit_token
68
+ }.merge(data).select { |_, v| v }
69
+
70
+ @store.geocode(data)
71
+ true
72
+ rescue => e
73
+ report_exception(e)
74
+ end
75
+
76
+ def authenticate(user)
77
+ if exclude?
78
+ debug "Authentication excluded"
79
+ else
80
+ @store.user = user
81
+
82
+ data = {
83
+ visit_token: visit_token,
84
+ user_id: user.try(:id)
85
+ }
86
+ @store.authenticate(data)
87
+ end
88
+ true
89
+ rescue => e
90
+ report_exception(e)
91
+ end
92
+
93
+ def visit
94
+ @visit ||= @store.visit
95
+ end
96
+
97
+ def visit_or_create
98
+ @visit ||= @store.visit_or_create
99
+ end
100
+
101
+ def new_visit?
102
+ Ahoy.cookies? ? !existing_visit_token : visit.nil?
103
+ end
104
+
105
+ def new_visitor?
106
+ !existing_visitor_token
107
+ end
108
+
109
+ def set_visit_cookie
110
+ set_cookie("ahoy_visit", visit_token, Ahoy.visit_duration)
111
+ end
112
+
113
+ def set_visitor_cookie
114
+ if new_visitor?
115
+ set_cookie("ahoy_visitor", visitor_token, Ahoy.visitor_duration)
116
+ end
117
+ end
118
+
119
+ def user
120
+ @user ||= @store.user
121
+ end
122
+
123
+ def visit_properties
124
+ @visit_properties ||= request ? Ahoy::VisitProperties.new(request, api: api?).generate : {}
125
+ end
126
+
127
+ def visit_token
128
+ @visit_token ||= ensure_token(visit_token_helper)
129
+ end
130
+ alias_method :visit_id, :visit_token
131
+
132
+ def visitor_token
133
+ @visitor_token ||= ensure_token(visitor_token_helper)
134
+ end
135
+ alias_method :visitor_id, :visitor_token
136
+
137
+ def reset
138
+ reset_visit
139
+ delete_cookie("ahoy_visitor")
140
+ end
141
+
142
+ def reset_visit
143
+ delete_cookie("ahoy_visit")
144
+ delete_cookie("ahoy_events")
145
+ delete_cookie("ahoy_track", false)
146
+ end
147
+
148
+ def exclude?
149
+ unless defined?(@exclude)
150
+ @exclude = @store.exclude?
151
+ end
152
+ @exclude
153
+ end
154
+
155
+ protected
156
+
157
+ def api?
158
+ @options[:api]
159
+ end
160
+
161
+ # private, but used by API
162
+ def missing_params?
163
+ if Ahoy.cookies? && api? && Ahoy.protect_from_forgery
164
+ !(existing_visit_token && existing_visitor_token)
165
+ else
166
+ false
167
+ end
168
+ end
169
+
170
+ def set_cookie(name, value, duration = nil, use_domain = true)
171
+ # safety net
172
+ return unless Ahoy.cookies? && request
173
+
174
+ cookie = Ahoy.cookie_options.merge(value: value)
175
+ cookie[:expires] = duration.from_now if duration
176
+ # prefer cookie_options[:domain] over cookie_domain
177
+ cookie[:domain] ||= Ahoy.cookie_domain if Ahoy.cookie_domain
178
+ cookie.delete(:domain) unless use_domain
179
+ request.cookie_jar[name] = cookie
180
+ end
181
+
182
+ def delete_cookie(name, use_domain = true)
183
+ if request && request.cookie_jar[name]
184
+ options = Ahoy.cookie_options.slice(:path)
185
+ if use_domain
186
+ domain = Ahoy.cookie_options[:domain] || Ahoy.cookie_domain
187
+ options[:domain] = domain if domain
188
+ end
189
+ request.cookie_jar.delete(name, **options)
190
+ end
191
+ end
192
+
193
+ def trusted_time(time = nil)
194
+ if !time || (api? && !(1.minute.ago..Time.now).cover?(time))
195
+ Time.current
196
+ else
197
+ time
198
+ end
199
+ end
200
+
201
+ def report_exception(e)
202
+ if defined?(ActionDispatch::RemoteIp::IpSpoofAttackError) && e.is_a?(ActionDispatch::RemoteIp::IpSpoofAttackError)
203
+ debug "Tracking excluded due to IP spoofing"
204
+ else
205
+ raise e if !defined?(Rails) || Rails.env.development? || Rails.env.test?
206
+ Safely.report_exception(e)
207
+ end
208
+ end
209
+
210
+ def generate_id
211
+ @store.generate_id
212
+ end
213
+
214
+ def visit_token_helper
215
+ @visit_token_helper ||= begin
216
+ token = existing_visit_token
217
+ token ||= visit&.visit_token unless Ahoy.cookies?
218
+ token ||= generate_id unless Ahoy.api_only
219
+ token
220
+ end
221
+ end
222
+
223
+ def visitor_token_helper
224
+ @visitor_token_helper ||= begin
225
+ token = existing_visitor_token
226
+ token ||= visitor_anonymity_set unless Ahoy.cookies?
227
+ token ||= generate_id unless Ahoy.api_only
228
+ token
229
+ end
230
+ end
231
+
232
+ def existing_visit_token
233
+ @existing_visit_token ||= begin
234
+ token = visit_header
235
+ token ||= visit_cookie if Ahoy.cookies? && !(api? && Ahoy.protect_from_forgery)
236
+ token ||= visit_param if api?
237
+ token
238
+ end
239
+ end
240
+
241
+ def existing_visitor_token
242
+ @existing_visitor_token ||= begin
243
+ token = visitor_header
244
+ token ||= visitor_cookie if Ahoy.cookies? && !(api? && Ahoy.protect_from_forgery)
245
+ token ||= visitor_param if api?
246
+ token
247
+ end
248
+ end
249
+
250
+ def visitor_anonymity_set
251
+ @visitor_anonymity_set ||= request && Digest::UUID.uuid_v5(UUID_NAMESPACE, ["visitor", Ahoy.mask_ip(request.remote_ip), request.user_agent].join("/"))
252
+ end
253
+
254
+ def visit_cookie
255
+ @visit_cookie ||= request && request.cookies["ahoy_visit"]
256
+ end
257
+
258
+ def visitor_cookie
259
+ @visitor_cookie ||= request && request.cookies["ahoy_visitor"]
260
+ end
261
+
262
+ def visit_header
263
+ @visit_header ||= request && request.headers["Ahoy-Visit"]
264
+ end
265
+
266
+ def visitor_header
267
+ @visitor_header ||= request && request.headers["Ahoy-Visitor"]
268
+ end
269
+
270
+ def visit_param
271
+ @visit_param ||= request && request.params["visit_token"]
272
+ end
273
+
274
+ def visitor_param
275
+ @visitor_param ||= request && request.params["visitor_token"]
276
+ end
277
+
278
+ def ensure_token(token)
279
+ token = Ahoy::Utils.ensure_utf8(token)
280
+ token.to_s.gsub(/[^a-z0-9\-]/i, "").first(64) if token
281
+ end
282
+
283
+ def debug(message)
284
+ Ahoy.log message
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,7 @@
1
+ module Ahoy
2
+ module Utils
3
+ def self.ensure_utf8(str)
4
+ str.encode("UTF-8", "binary", invalid: :replace, undef: :replace, replace: "") if str
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Ahoy
2
+ VERSION = "5.5.0"
3
+ end
@@ -0,0 +1,122 @@
1
+ require "cgi"
2
+ require "device_detector"
3
+ require "uri"
4
+
5
+ module Ahoy
6
+ class VisitProperties
7
+ attr_reader :request, :params, :referrer, :landing_page
8
+
9
+ def initialize(request, api:)
10
+ @request = request
11
+ @params = request.params
12
+ @referrer = api ? params["referrer"] : request.referer
13
+ @landing_page = api ? params["landing_page"] : request.original_url
14
+ end
15
+
16
+ def generate
17
+ @generate ||= request_properties.merge(tech_properties).merge(traffic_properties).merge(utm_properties)
18
+ end
19
+
20
+ private
21
+
22
+ def utm_properties
23
+ landing_params = {}
24
+ begin
25
+ landing_uri = URI.parse(landing_page)
26
+ # could also use Rack::Utils.parse_nested_query
27
+ landing_params = CGI.parse(landing_uri.query) if landing_uri
28
+ rescue
29
+ # do nothing
30
+ end
31
+
32
+ props = {}
33
+ %w(utm_source utm_medium utm_term utm_content utm_campaign).each do |name|
34
+ props[name.to_sym] = params[name] || landing_params[name].try(:first)
35
+ end
36
+ props
37
+ end
38
+
39
+ def traffic_properties
40
+ uri = URI.parse(referrer) rescue nil
41
+ {
42
+ referring_domain: uri.try(:host).try(:first, 255)
43
+ }
44
+ end
45
+
46
+ def tech_properties
47
+ if Ahoy.user_agent_parser == :device_detector
48
+ client = DeviceDetector.new(request.user_agent)
49
+ device_type =
50
+ case client.device_type
51
+ when "smartphone"
52
+ "Mobile"
53
+ when "tv"
54
+ "TV"
55
+ else
56
+ client.device_type.try(:titleize)
57
+ end
58
+
59
+ {
60
+ browser: client.name,
61
+ os: client.os_name,
62
+ device_type: device_type
63
+ }
64
+ else
65
+ raise "Add browser to your Gemfile to use legacy user agent parsing" unless defined?(Browser)
66
+ raise "Add user_agent_parser to your Gemfile to use legacy user agent parsing" unless defined?(UserAgentParser)
67
+
68
+ # cache for performance
69
+ @@user_agent_parser ||= UserAgentParser::Parser.new
70
+
71
+ user_agent = request.user_agent
72
+ agent = @@user_agent_parser.parse(user_agent)
73
+ browser = Browser.new(user_agent)
74
+ device_type =
75
+ if browser.bot?
76
+ "Bot"
77
+ elsif browser.device.tv?
78
+ "TV"
79
+ elsif browser.device.console?
80
+ "Console"
81
+ elsif browser.device.tablet?
82
+ "Tablet"
83
+ elsif browser.device.mobile?
84
+ "Mobile"
85
+ else
86
+ "Desktop"
87
+ end
88
+
89
+ {
90
+ browser: agent.name,
91
+ os: agent.os.name,
92
+ device_type: device_type
93
+ }
94
+ end
95
+ end
96
+
97
+ # masking based on Google Analytics anonymization
98
+ # https://support.google.com/analytics/answer/2763052
99
+ def ip
100
+ ip = request.remote_ip
101
+ if ip && Ahoy.mask_ips
102
+ Ahoy.mask_ip(ip)
103
+ else
104
+ ip
105
+ end
106
+ end
107
+
108
+ def request_properties
109
+ {
110
+ ip: ip,
111
+ user_agent: Ahoy::Utils.ensure_utf8(request.user_agent),
112
+ referrer: referrer,
113
+ landing_page: landing_page,
114
+ platform: params["platform"],
115
+ app_version: params["app_version"],
116
+ os_version: params["os_version"],
117
+ screen_height: params["screen_height"],
118
+ screen_width: params["screen_width"]
119
+ }
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,5 @@
1
+ Warden::Manager.after_set_user except: :fetch do |user, auth, _|
2
+ request = ActionDispatch::Request.new(auth.env)
3
+ ahoy = Ahoy::Tracker.new(request: request)
4
+ ahoy.authenticate(user)
5
+ end
@@ -0,0 +1,167 @@
1
+ # stdlib
2
+ require "ipaddr"
3
+
4
+ # dependencies
5
+ require "active_support"
6
+ require "active_support/core_ext"
7
+ require "safely/core"
8
+
9
+ # modules
10
+ require_relative "ahoy/utils"
11
+ require_relative "ahoy/base_store"
12
+ require_relative "ahoy/controller"
13
+ require_relative "ahoy/database_store"
14
+ require_relative "ahoy/helper"
15
+ require_relative "ahoy/model"
16
+ require_relative "ahoy/query_methods"
17
+ require_relative "ahoy/tracker"
18
+ require_relative "ahoy/version"
19
+ require_relative "ahoy/visit_properties"
20
+
21
+ require_relative "ahoy/engine" if defined?(Rails)
22
+
23
+ module Ahoy
24
+ # activejob optional
25
+ autoload :GeocodeV2Job, "ahoy/geocode_v2_job"
26
+
27
+ mattr_accessor :visit_duration
28
+ self.visit_duration = 4.hours
29
+
30
+ mattr_accessor :visitor_duration
31
+ self.visitor_duration = 2.years
32
+
33
+ def self.cookies=(value)
34
+ if value == false
35
+ if defined?(Mongoid::Document) && defined?(Ahoy::Visit) && Ahoy::Visit < Mongoid::Document
36
+ raise <<~EOS
37
+ This feature requires a new index in Ahoy 5. Set:
38
+
39
+ class Ahoy::Visit
40
+ index({visitor_token: 1, started_at: 1})
41
+ end
42
+
43
+ Create the index before upgrading, and set:
44
+
45
+ Ahoy.cookies = :none
46
+ EOS
47
+ else
48
+ raise <<~EOS
49
+ This feature requires a new index in Ahoy 5. Create a migration with:
50
+
51
+ add_index :ahoy_visits, [:visitor_token, :started_at]
52
+
53
+ Run it before upgrading, and set:
54
+
55
+ Ahoy.cookies = :none
56
+ EOS
57
+ end
58
+ end
59
+ @@cookies = value
60
+ end
61
+
62
+ mattr_reader :cookies
63
+ self.cookies = true
64
+
65
+ # TODO deprecate in favor of cookie_options
66
+ mattr_accessor :cookie_domain
67
+
68
+ mattr_accessor :cookie_options
69
+ self.cookie_options = {}
70
+
71
+ mattr_accessor :server_side_visits
72
+ self.server_side_visits = true
73
+
74
+ mattr_accessor :quiet
75
+ self.quiet = true
76
+
77
+ mattr_accessor :geocode
78
+ self.geocode = false
79
+
80
+ mattr_accessor :max_content_length
81
+ self.max_content_length = 8192
82
+
83
+ mattr_accessor :max_events_per_request
84
+ self.max_events_per_request = 10
85
+
86
+ mattr_accessor :job_queue
87
+ self.job_queue = :ahoy
88
+
89
+ mattr_accessor :api
90
+ self.api = false
91
+
92
+ mattr_accessor :api_only
93
+ self.api_only = false
94
+
95
+ mattr_accessor :protect_from_forgery
96
+ self.protect_from_forgery = true
97
+
98
+ mattr_accessor :preserve_callbacks
99
+ self.preserve_callbacks = [:load_authlogic, :activate_authlogic]
100
+
101
+ mattr_accessor :user_method
102
+ self.user_method = lambda do |controller|
103
+ (controller.respond_to?(:current_user, true) && controller.send(:current_user)) || (controller.respond_to?(:current_resource_owner, true) && controller.send(:current_resource_owner)) || nil
104
+ end
105
+
106
+ mattr_accessor :exclude_method
107
+
108
+ mattr_accessor :track_bots
109
+ self.track_bots = false
110
+
111
+ mattr_accessor :bot_detection_version
112
+ self.bot_detection_version = 2
113
+
114
+ mattr_accessor :token_generator
115
+ self.token_generator = -> { SecureRandom.uuid }
116
+
117
+ mattr_accessor :mask_ips
118
+ self.mask_ips = false
119
+
120
+ mattr_accessor :user_agent_parser
121
+ self.user_agent_parser = :device_detector
122
+
123
+ mattr_accessor :logger
124
+
125
+ def self.log(message)
126
+ logger.info { "[ahoy] #{message}" } if logger
127
+ end
128
+
129
+ def self.cookies?
130
+ cookies && cookies != :none
131
+ end
132
+
133
+ def self.mask_ip(ip)
134
+ addr = IPAddr.new(ip)
135
+ if addr.ipv4?
136
+ # set last octet to 0
137
+ addr.mask(24).to_s
138
+ else
139
+ # set last 80 bits to zeros
140
+ addr.mask(48).to_s
141
+ end
142
+ end
143
+
144
+ def self.instance
145
+ Thread.current[:ahoy]
146
+ end
147
+
148
+ def self.instance=(value)
149
+ Thread.current[:ahoy] = value
150
+ end
151
+ end
152
+
153
+ ActiveSupport.on_load(:action_controller) do
154
+ include Ahoy::Controller
155
+ end
156
+
157
+ ActiveSupport.on_load(:active_record) do
158
+ extend Ahoy::Model
159
+ end
160
+
161
+ ActiveSupport.on_load(:action_view) do
162
+ include Ahoy::Helper
163
+ end
164
+
165
+ ActiveSupport.on_load(:mongoid) do
166
+ Mongoid::Document::ClassMethods.include(Ahoy::Model)
167
+ end
@@ -0,0 +1 @@
1
+ require_relative "ahoy"
@@ -0,0 +1,59 @@
1
+ require "rails/generators"
2
+ require "rails/generators/active_record"
3
+
4
+ module Ahoy
5
+ module Generators
6
+ class ActiverecordGenerator < Rails::Generators::Base
7
+ include ActiveRecord::Generators::Migration
8
+ source_root File.join(__dir__, "templates")
9
+
10
+ class_option :database, type: :string, aliases: "-d"
11
+
12
+ def copy_templates
13
+ template "database_store_initializer.rb", "config/initializers/ahoy.rb"
14
+ template "active_record_visit_model.rb", "app/models/ahoy/visit.rb"
15
+ template "active_record_event_model.rb", "app/models/ahoy/event.rb"
16
+ migration_template "active_record_migration.rb", "db/migrate/create_ahoy_visits_and_events.rb", migration_version: migration_version
17
+ puts "\nAlmost set! Last, run:\n\n rails db:migrate"
18
+ end
19
+
20
+ def properties_type
21
+ case adapter
22
+ when /postg/i # postgres, postgis
23
+ "jsonb"
24
+ when /mysql|trilogy/i
25
+ "json"
26
+ else
27
+ "text"
28
+ end
29
+ end
30
+
31
+ # requires database connection to check for MariaDB
32
+ def serialize_properties?
33
+ properties_type == "text" || (properties_type == "json" && ActiveRecord::Base.connection.try(:mariadb?))
34
+ end
35
+
36
+ # use connection_db_config instead of connection.adapter
37
+ # so database connection isn't needed
38
+ def adapter
39
+ ActiveRecord::Base.connection_db_config.adapter.to_s
40
+ end
41
+
42
+ def migration_version
43
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
44
+ end
45
+
46
+ def primary_key_type
47
+ ", id: :#{key_type}" if key_type
48
+ end
49
+
50
+ def foreign_key_type
51
+ ", type: :#{key_type}" if key_type
52
+ end
53
+
54
+ def key_type
55
+ Rails.configuration.generators.options.dig(:active_record, :primary_key_type)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,13 @@
1
+ require "rails/generators"
2
+
3
+ module Ahoy
4
+ module Generators
5
+ class BaseGenerator < Rails::Generators::Base
6
+ source_root File.join(__dir__, "templates")
7
+
8
+ def copy_templates
9
+ template "base_store_initializer.rb", "config/initializers/ahoy.rb"
10
+ end
11
+ end
12
+ end
13
+ end