UNPKG

15.9 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 }
98 AnalyticsClass.prototype.getModuleName = function () {
99 return 'Analytics';
100 };
101 /**
102 * configure Analytics
103 * @param {Object} config - Configuration of the Analytics
104 */
105 AnalyticsClass.prototype.configure = function (config) {
106 var _this = this;
107 if (!config)
108 return this._config;
109 logger.debug('configure Analytics', config);
110 var amplifyConfig = core_1.Parser.parseMobilehubConfig(config);
111 this._config = Object.assign({}, this._config, amplifyConfig.Analytics, config);
112 if (this._config['disabled']) {
113 this._disabled = true;
114 }
115 // turn on the autoSessionRecord if not specified
116 if (this._config['autoSessionRecord'] === undefined) {
117 this._config['autoSessionRecord'] = true;
118 }
119 this._pluggables.forEach(function (pluggable) {
120 // for backward compatibility
121 var providerConfig = pluggable.getProviderName() === 'AWSPinpoint' &&
122 !_this._config['AWSPinpoint']
123 ? _this._config
124 : _this._config[pluggable.getProviderName()];
125 pluggable.configure(__assign({ disabled: _this._config['disabled'], autoSessionRecord: _this._config['autoSessionRecord'] }, providerConfig));
126 });
127 if (this._pluggables.length === 0) {
128 this.addPluggable(new AWSPinpointProvider_1.AWSPinpointProvider());
129 }
130 dispatchAnalyticsEvent('configured', null, "The Analytics category has been configured successfully");
131 logger.debug('current configuration', this._config);
132 return this._config;
133 };
134 /**
135 * add plugin into Analytics category
136 * @param {Object} pluggable - an instance of the plugin
137 */
138 AnalyticsClass.prototype.addPluggable = function (pluggable) {
139 if (pluggable && pluggable.getCategory() === 'Analytics') {
140 this._pluggables.push(pluggable);
141 // for backward compatibility
142 var providerConfig = pluggable.getProviderName() === 'AWSPinpoint' &&
143 !this._config['AWSPinpoint']
144 ? this._config
145 : this._config[pluggable.getProviderName()];
146 var config = __assign({ disabled: this._config['disabled'] }, providerConfig);
147 pluggable.configure(config);
148 return config;
149 }
150 };
151 /**
152 * Get the plugin object
153 * @param providerName - the name of the plugin
154 */
155 AnalyticsClass.prototype.getPluggable = function (providerName) {
156 for (var i = 0; i < this._pluggables.length; i += 1) {
157 var pluggable = this._pluggables[i];
158 if (pluggable.getProviderName() === providerName) {
159 return pluggable;
160 }
161 }
162 logger.debug('No plugin found with providerName', providerName);
163 return null;
164 };
165 /**
166 * Remove the plugin object
167 * @param providerName - the name of the plugin
168 */
169 AnalyticsClass.prototype.removePluggable = function (providerName) {
170 var idx = 0;
171 while (idx < this._pluggables.length) {
172 if (this._pluggables[idx].getProviderName() === providerName) {
173 break;
174 }
175 idx += 1;
176 }
177 if (idx === this._pluggables.length) {
178 logger.debug('No plugin found with providerName', providerName);
179 return;
180 }
181 else {
182 this._pluggables.splice(idx, idx + 1);
183 return;
184 }
185 };
186 /**
187 * stop sending events
188 */
189 AnalyticsClass.prototype.disable = function () {
190 this._disabled = true;
191 };
192 /**
193 * start sending events
194 */
195 AnalyticsClass.prototype.enable = function () {
196 this._disabled = false;
197 };
198 /**
199 * Record Session start
200 * @return - A promise which resolves if buffer doesn't overflow
201 */
202 AnalyticsClass.prototype.startSession = function (provider) {
203 return __awaiter(this, void 0, void 0, function () {
204 var params;
205 return __generator(this, function (_a) {
206 params = { event: { name: '_session.start' }, provider: provider };
207 return [2 /*return*/, this._sendEvent(params)];
208 });
209 });
210 };
211 /**
212 * Record Session stop
213 * @return - A promise which resolves if buffer doesn't overflow
214 */
215 AnalyticsClass.prototype.stopSession = function (provider) {
216 return __awaiter(this, void 0, void 0, function () {
217 var params;
218 return __generator(this, function (_a) {
219 params = { event: { name: '_session.stop' }, provider: provider };
220 return [2 /*return*/, this._sendEvent(params)];
221 });
222 });
223 };
224 /**
225 * Record one analytic event and send it to Pinpoint
226 * @param {String} name - The name of the event
227 * @param {Object} [attributes] - Attributes of the event
228 * @param {Object} [metrics] - Event metrics
229 * @return - A promise which resolves if buffer doesn't overflow
230 */
231 AnalyticsClass.prototype.record = function (event, provider, metrics) {
232 return __awaiter(this, void 0, void 0, function () {
233 var params;
234 return __generator(this, function (_a) {
235 params = null;
236 // this is just for compatibility, going to be deprecated
237 if (typeof event === 'string') {
238 params = {
239 event: {
240 name: event,
241 attributes: provider,
242 metrics: metrics,
243 },
244 provider: 'AWSPinpoint',
245 };
246 }
247 else {
248 params = { event: event, provider: provider };
249 }
250 return [2 /*return*/, this._sendEvent(params)];
251 });
252 });
253 };
254 AnalyticsClass.prototype.updateEndpoint = function (attrs, provider) {
255 return __awaiter(this, void 0, void 0, function () {
256 var event;
257 return __generator(this, function (_a) {
258 event = __assign(__assign({}, attrs), { name: '_update_endpoint' });
259 return [2 /*return*/, this.record(event, provider)];
260 });
261 });
262 };
263 AnalyticsClass.prototype._sendEvent = function (params) {
264 var _this = this;
265 if (this._disabled) {
266 logger.debug('Analytics has been disabled');
267 return Promise.resolve();
268 }
269 var provider = params.provider ? params.provider : 'AWSPinpoint';
270 return new Promise(function (resolve, reject) {
271 _this._pluggables.forEach(function (pluggable) {
272 if (pluggable.getProviderName() === provider) {
273 pluggable.record(params, { resolve: resolve, reject: reject });
274 }
275 });
276 });
277 };
278 AnalyticsClass.prototype.autoTrack = function (trackerType, opts) {
279 if (!trackers[trackerType]) {
280 logger.debug('invalid tracker type');
281 return;
282 }
283 // to sync up two different configuration ways of auto session tracking
284 if (trackerType === 'session') {
285 this._config['autoSessionRecord'] = opts['enable'];
286 }
287 var tracker = this._trackers[trackerType];
288 if (!tracker) {
289 this._trackers[trackerType] = new trackers[trackerType](this.record, opts);
290 }
291 else {
292 tracker.configure(opts);
293 }
294 };
295 return AnalyticsClass;
296}());
297exports.AnalyticsClass = AnalyticsClass;
298var endpointUpdated = false;
299var authConfigured = false;
300var analyticsConfigured = false;
301var listener = function (capsule) {
302 var channel = capsule.channel, payload = capsule.payload;
303 logger.debug('on hub capsule ' + channel, payload);
304 switch (channel) {
305 case 'auth':
306 authEvent(payload);
307 break;
308 case 'storage':
309 storageEvent(payload);
310 break;
311 case 'analytics':
312 analyticsEvent(payload);
313 break;
314 default:
315 break;
316 }
317};
318var storageEvent = function (payload) {
319 var _a = payload.data, attrs = _a.attrs, metrics = _a.metrics;
320 if (!attrs)
321 return;
322 if (analyticsConfigured) {
323 _instance
324 .record({
325 name: 'Storage',
326 attributes: attrs,
327 metrics: metrics,
328 })
329 .catch(function (e) {
330 logger.debug('Failed to send the storage event automatically', e);
331 });
332 }
333};
334var authEvent = function (payload) {
335 var event = payload.event;
336 if (!event) {
337 return;
338 }
339 var recordAuthEvent = function (eventName) { return __awaiter(void 0, void 0, void 0, function () {
340 var err_1;
341 return __generator(this, function (_a) {
342 switch (_a.label) {
343 case 0:
344 if (!(authConfigured && analyticsConfigured)) return [3 /*break*/, 4];
345 _a.label = 1;
346 case 1:
347 _a.trys.push([1, 3, , 4]);
348 return [4 /*yield*/, _instance.record({ name: "_userauth." + eventName })];
349 case 2: return [2 /*return*/, _a.sent()];
350 case 3:
351 err_1 = _a.sent();
352 logger.debug("Failed to send the " + eventName + " event automatically", err_1);
353 return [3 /*break*/, 4];
354 case 4: return [2 /*return*/];
355 }
356 });
357 }); };
358 switch (event) {
359 case 'signIn':
360 return recordAuthEvent('sign_in');
361 case 'signUp':
362 return recordAuthEvent('sign_up');
363 case 'signOut':
364 return recordAuthEvent('sign_out');
365 case 'signIn_failure':
366 return recordAuthEvent('auth_fail');
367 case 'configured':
368 authConfigured = true;
369 if (authConfigured && analyticsConfigured) {
370 sendEvents();
371 }
372 break;
373 }
374};
375var analyticsEvent = function (payload) {
376 var event = payload.event;
377 if (!event)
378 return;
379 switch (event) {
380 case 'pinpointProvider_configured':
381 analyticsConfigured = true;
382 if (authConfigured && analyticsConfigured) {
383 sendEvents();
384 }
385 break;
386 }
387};
388var sendEvents = function () {
389 var config = _instance.configure();
390 if (!endpointUpdated && config['autoSessionRecord']) {
391 _instance.updateEndpoint({ immediate: true }).catch(function (e) {
392 logger.debug('Failed to update the endpoint', e);
393 });
394 endpointUpdated = true;
395 }
396 _instance.autoTrack('session', {
397 enable: config['autoSessionRecord'],
398 });
399};
400exports.Analytics = new AnalyticsClass();
401core_1.Amplify.register(exports.Analytics);
402//# sourceMappingURL=Analytics.js.map
\No newline at end of file