UNPKG

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