UNPKG

15.8 kBJavaScriptView Raw
1"use strict";
2/*
3 * Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
6 * the License. A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0/
9 *
10 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
12 * and limitations under the License.
13 */
14var __assign = (this && this.__assign) || function () {
15 __assign = Object.assign || function(t) {
16 for (var s, i = 1, n = arguments.length; i < n; i++) {
17 s = arguments[i];
18 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
19 t[p] = s[p];
20 }
21 return t;
22 };
23 return __assign.apply(this, arguments);
24};
25var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27 return new (P || (P = Promise))(function (resolve, reject) {
28 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31 step((generator = generator.apply(thisArg, _arguments || [])).next());
32 });
33};
34var __generator = (this && this.__generator) || function (thisArg, body) {
35 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
36 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37 function verb(n) { return function (v) { return step([n, v]); }; }
38 function step(op) {
39 if (f) throw new TypeError("Generator is already executing.");
40 while (_) try {
41 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
42 if (y = 0, t) op = [op[0] & 2, t.value];
43 switch (op[0]) {
44 case 0: case 1: t = op; break;
45 case 4: _.label++; return { value: op[1], done: false };
46 case 5: _.label++; y = op[1]; op = [0]; continue;
47 case 7: op = _.ops.pop(); _.trys.pop(); continue;
48 default:
49 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53 if (t[2]) _.ops.pop();
54 _.trys.pop(); continue;
55 }
56 op = body.call(thisArg, _);
57 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59 }
60};
61Object.defineProperty(exports, "__esModule", { value: true });
62var core_1 = require("@aws-amplify/core");
63var AWSPinpointProvider_1 = require("./Providers/AWSPinpointProvider");
64var trackers_1 = require("./trackers");
65var logger = new core_1.ConsoleLogger('AnalyticsClass');
66var AMPLIFY_SYMBOL = (typeof Symbol !== 'undefined' &&
67 typeof Symbol.for === 'function'
68 ? Symbol.for('amplify_default')
69 : '@@amplify_default');
70var dispatchAnalyticsEvent = function (event, data, message) {
71 core_1.Hub.dispatch('analytics', { event: event, data: data, message: message }, 'Analytics', AMPLIFY_SYMBOL);
72};
73var trackers = {
74 pageView: trackers_1.PageViewTracker,
75 event: trackers_1.EventTracker,
76 session: trackers_1.SessionTracker,
77};
78var _instance = null;
79/**
80 * Provide mobile analytics client functions
81 */
82var AnalyticsClass = /** @class */ (function () {
83 /**
84 * Initialize Analtyics
85 * @param config - Configuration of the Analytics
86 */
87 function AnalyticsClass() {
88 this._config = {};
89 this._pluggables = [];
90 this._disabled = false;
91 this._trackers = {};
92 _instance = this;
93 this.record = this.record.bind(this);
94 core_1.Hub.listen('auth', listener);
95 core_1.Hub.listen('storage', listener);
96 core_1.Hub.listen('analytics', listener);
97 core_1.Amplify.register(this);
98 }
99 AnalyticsClass.prototype.getModuleName = function () {
100 return 'Analytics';
101 };
102 /**
103 * configure Analytics
104 * @param {Object} config - Configuration of the Analytics
105 */
106 AnalyticsClass.prototype.configure = function (config) {
107 var _this = this;
108 if (!config)
109 return this._config;
110 logger.debug('configure Analytics', config);
111 var amplifyConfig = core_1.Parser.parseMobilehubConfig(config);
112 this._config = Object.assign({}, this._config, amplifyConfig.Analytics, config);
113 if (this._config['disabled']) {
114 this._disabled = true;
115 }
116 this._pluggables.forEach(function (pluggable) {
117 // for backward compatibility
118 var providerConfig = pluggable.getProviderName() === 'AWSPinpoint' &&
119 !_this._config['AWSPinpoint']
120 ? _this._config
121 : _this._config[pluggable.getProviderName()];
122 pluggable.configure(__assign({ disabled: _this._config['disabled'] }, providerConfig));
123 });
124 if (this._pluggables.length === 0) {
125 this.addPluggable(new AWSPinpointProvider_1.AWSPinpointProvider());
126 }
127 // turn on the autoSessionRecord if not specified
128 if (this._config['autoSessionRecord'] === undefined) {
129 this._config['autoSessionRecord'] = true;
130 }
131 dispatchAnalyticsEvent('configured', null, "The Analytics category has been configured successfully");
132 logger.debug('current configuration', this._config);
133 return this._config;
134 };
135 /**
136 * add plugin into Analytics category
137 * @param {Object} pluggable - an instance of the plugin
138 */
139 AnalyticsClass.prototype.addPluggable = function (pluggable) {
140 if (pluggable && pluggable.getCategory() === 'Analytics') {
141 this._pluggables.push(pluggable);
142 // for backward compatibility
143 var providerConfig = pluggable.getProviderName() === 'AWSPinpoint' &&
144 !this._config['AWSPinpoint']
145 ? this._config
146 : this._config[pluggable.getProviderName()];
147 var config = __assign({ disabled: this._config['disabled'] }, providerConfig);
148 pluggable.configure(config);
149 return config;
150 }
151 };
152 /**
153 * Get the plugin object
154 * @param providerName - the name of the plugin
155 */
156 AnalyticsClass.prototype.getPluggable = function (providerName) {
157 for (var i = 0; i < this._pluggables.length; i += 1) {
158 var pluggable = this._pluggables[i];
159 if (pluggable.getProviderName() === providerName) {
160 return pluggable;
161 }
162 }
163 logger.debug('No plugin found with providerName', providerName);
164 return null;
165 };
166 /**
167 * Remove the plugin object
168 * @param providerName - the name of the plugin
169 */
170 AnalyticsClass.prototype.removePluggable = function (providerName) {
171 var idx = 0;
172 while (idx < this._pluggables.length) {
173 if (this._pluggables[idx].getProviderName() === providerName) {
174 break;
175 }
176 idx += 1;
177 }
178 if (idx === this._pluggables.length) {
179 logger.debug('No plugin found with providerName', providerName);
180 return;
181 }
182 else {
183 this._pluggables.splice(idx, idx + 1);
184 return;
185 }
186 };
187 /**
188 * stop sending events
189 */
190 AnalyticsClass.prototype.disable = function () {
191 this._disabled = true;
192 };
193 /**
194 * start sending events
195 */
196 AnalyticsClass.prototype.enable = function () {
197 this._disabled = false;
198 };
199 /**
200 * Record Session start
201 * @return - A promise which resolves if buffer doesn't overflow
202 */
203 AnalyticsClass.prototype.startSession = function (provider) {
204 return __awaiter(this, void 0, void 0, function () {
205 var params;
206 return __generator(this, function (_a) {
207 params = { event: { name: '_session.start' }, provider: provider };
208 return [2 /*return*/, this._sendEvent(params)];
209 });
210 });
211 };
212 /**
213 * Record Session stop
214 * @return - A promise which resolves if buffer doesn't overflow
215 */
216 AnalyticsClass.prototype.stopSession = function (provider) {
217 return __awaiter(this, void 0, void 0, function () {
218 var params;
219 return __generator(this, function (_a) {
220 params = { event: { name: '_session.stop' }, provider: provider };
221 return [2 /*return*/, this._sendEvent(params)];
222 });
223 });
224 };
225 /**
226 * Record one analytic event and send it to Pinpoint
227 * @param {String} name - The name of the event
228 * @param {Object} [attributes] - Attributes of the event
229 * @param {Object} [metrics] - Event metrics
230 * @return - A promise which resolves if buffer doesn't overflow
231 */
232 AnalyticsClass.prototype.record = function (event, provider, metrics) {
233 return __awaiter(this, void 0, void 0, function () {
234 var params;
235 return __generator(this, function (_a) {
236 params = null;
237 // this is just for compatibility, going to be deprecated
238 if (typeof event === 'string') {
239 params = {
240 event: {
241 name: event,
242 attributes: provider,
243 metrics: metrics,
244 },
245 provider: 'AWSPinpoint',
246 };
247 }
248 else {
249 params = { event: event, provider: provider };
250 }
251 return [2 /*return*/, this._sendEvent(params)];
252 });
253 });
254 };
255 AnalyticsClass.prototype.updateEndpoint = function (attrs, provider) {
256 return __awaiter(this, void 0, void 0, function () {
257 var event;
258 return __generator(this, function (_a) {
259 event = __assign(__assign({}, attrs), { name: '_update_endpoint' });
260 return [2 /*return*/, this.record(event, provider)];
261 });
262 });
263 };
264 AnalyticsClass.prototype._sendEvent = function (params) {
265 var _this = this;
266 if (this._disabled) {
267 logger.debug('Analytics has been disabled');
268 return Promise.resolve();
269 }
270 var provider = params.provider ? params.provider : 'AWSPinpoint';
271 return new Promise(function (resolve, reject) {
272 _this._pluggables.forEach(function (pluggable) {
273 if (pluggable.getProviderName() === provider) {
274 pluggable.record(params, { resolve: resolve, reject: reject });
275 }
276 });
277 });
278 };
279 AnalyticsClass.prototype.autoTrack = function (trackerType, opts) {
280 if (!trackers[trackerType]) {
281 logger.debug('invalid tracker type');
282 return;
283 }
284 // to sync up two different configuration ways of auto session tracking
285 if (trackerType === 'session') {
286 this._config['autoSessionRecord'] = opts['enable'];
287 }
288 var tracker = this._trackers[trackerType];
289 if (!tracker) {
290 this._trackers[trackerType] = new trackers[trackerType](this.record, opts);
291 }
292 else {
293 tracker.configure(opts);
294 }
295 };
296 return AnalyticsClass;
297}());
298exports.AnalyticsClass = AnalyticsClass;
299var endpointUpdated = false;
300var authConfigured = false;
301var analyticsConfigured = false;
302var listener = function (capsule) {
303 var channel = capsule.channel, payload = capsule.payload;
304 logger.debug('on hub capsule ' + channel, payload);
305 switch (channel) {
306 case 'auth':
307 authEvent(payload);
308 break;
309 case 'storage':
310 storageEvent(payload);
311 break;
312 case 'analytics':
313 analyticsEvent(payload);
314 break;
315 default:
316 break;
317 }
318};
319var storageEvent = function (payload) {
320 var _a = payload.data, attrs = _a.attrs, metrics = _a.metrics;
321 if (!attrs)
322 return;
323 if (analyticsConfigured) {
324 _instance
325 .record({
326 name: 'Storage',
327 attributes: attrs,
328 metrics: metrics,
329 })
330 .catch(function (e) {
331 logger.debug('Failed to send the storage event automatically', e);
332 });
333 }
334};
335var authEvent = function (payload) {
336 var event = payload.event;
337 if (!event) {
338 return;
339 }
340 var recordAuthEvent = function (eventName) { return __awaiter(void 0, void 0, void 0, function () {
341 var err_1;
342 return __generator(this, function (_a) {
343 switch (_a.label) {
344 case 0:
345 if (!(authConfigured && analyticsConfigured)) return [3 /*break*/, 4];
346 _a.label = 1;
347 case 1:
348 _a.trys.push([1, 3, , 4]);
349 return [4 /*yield*/, _instance.record({ name: "_userauth." + eventName })];
350 case 2: return [2 /*return*/, _a.sent()];
351 case 3:
352 err_1 = _a.sent();
353 logger.debug("Failed to send the " + eventName + " event automatically", err_1);
354 return [3 /*break*/, 4];
355 case 4: return [2 /*return*/];
356 }
357 });
358 }); };
359 switch (event) {
360 case 'signIn':
361 return recordAuthEvent('sign_in');
362 case 'signUp':
363 return recordAuthEvent('sign_up');
364 case 'signOut':
365 return recordAuthEvent('sign_out');
366 case 'signIn_failure':
367 return recordAuthEvent('auth_fail');
368 case 'configured':
369 authConfigured = true;
370 if (authConfigured && analyticsConfigured) {
371 sendEvents();
372 }
373 break;
374 }
375};
376var analyticsEvent = function (payload) {
377 var event = payload.event;
378 if (!event)
379 return;
380 switch (event) {
381 case 'pinpointProvider_configured':
382 analyticsConfigured = true;
383 if (authConfigured && analyticsConfigured) {
384 sendEvents();
385 }
386 break;
387 }
388};
389var sendEvents = function () {
390 var config = _instance.configure();
391 if (!endpointUpdated && config['autoSessionRecord']) {
392 _instance.updateEndpoint({ immediate: true }).catch(function (e) {
393 logger.debug('Failed to update the endpoint', e);
394 });
395 endpointUpdated = true;
396 }
397 _instance.autoTrack('session', {
398 enable: config['autoSessionRecord'],
399 });
400};
401exports.Analytics = new AnalyticsClass();
402//# sourceMappingURL=Analytics.js.map
\No newline at end of file