copper-sdk 0.7.0 → 0.8.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.
package/es/copper-sdk.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! *****************************************************************************
1
+ /******************************************************************************
2
2
  Copyright (c) Microsoft Corporation.
3
3
 
4
4
  Permission to use, copy, modify, and/or distribute this software for any
@@ -12,17 +12,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
12
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
13
  PERFORMANCE OF THIS SOFTWARE.
14
14
  ***************************************************************************** */
15
+ /* global Reflect, Promise, SuppressedError, Symbol */
15
16
 
16
- var __assign = function() {
17
- __assign = Object.assign || function __assign(t) {
18
- for (var s, i = 1, n = arguments.length; i < n; i++) {
19
- s = arguments[i];
20
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
21
- }
22
- return t;
23
- };
24
- return __assign.apply(this, arguments);
25
- };
26
17
 
27
18
  function __awaiter(thisArg, _arguments, P, generator) {
28
19
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -34,630 +25,520 @@ function __awaiter(thisArg, _arguments, P, generator) {
34
25
  });
35
26
  }
36
27
 
37
- function __generator(thisArg, body) {
38
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
39
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
40
- function verb(n) { return function (v) { return step([n, v]); }; }
41
- function step(op) {
42
- if (f) throw new TypeError("Generator is already executing.");
43
- while (_) try {
44
- 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;
45
- if (y = 0, t) op = [op[0] & 2, t.value];
46
- switch (op[0]) {
47
- case 0: case 1: t = op; break;
48
- case 4: _.label++; return { value: op[1], done: false };
49
- case 5: _.label++; y = op[1]; op = [0]; continue;
50
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
51
- default:
52
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
53
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
54
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
55
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
56
- if (t[2]) _.ops.pop();
57
- _.trys.pop(); continue;
58
- }
59
- op = body.call(thisArg, _);
60
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
61
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
62
- }
63
- }
28
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
29
+ var e = new Error(message);
30
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
31
+ };
64
32
 
65
- var version = "0.7.0";
33
+ var version = "0.8.0";
66
34
 
67
- var ENTITY_PATH_MAP = {
68
- lead: 'leads',
69
- person: 'people',
70
- company: 'companies',
71
- opportunity: 'opportunities',
72
- task: 'tasks',
73
- project: 'projects',
35
+ const ENTITY_PATH_MAP = {
36
+ lead: 'leads',
37
+ person: 'people',
38
+ company: 'companies',
39
+ opportunity: 'opportunities',
40
+ task: 'tasks',
41
+ project: 'projects',
74
42
  };
75
43
 
76
- var UITarget;
77
- (function (UITarget) {
78
- UITarget["ActivityLog"] = "ActivityLog";
79
- UITarget["ListView"] = "ListView";
80
- UITarget["Related"] = "Related";
44
+ var UITarget;
45
+ (function (UITarget) {
46
+ UITarget["ActivityLog"] = "ActivityLog";
47
+ UITarget["ListView"] = "ListView";
48
+ UITarget["Related"] = "Related";
81
49
  })(UITarget || (UITarget = {}));
82
50
 
83
- function logActivityDataGenerator(context, _a) {
84
- var activityType = _a.activityType, details = _a.details, activityDate = _a.activityDate;
85
- var url = '/v1/activities';
86
- var data = {
87
- parent: {
88
- type: context.type,
89
- id: context.id,
90
- },
91
- type: {
92
- category: 'user',
93
- id: activityType,
94
- },
95
- details: details,
96
- };
97
- if (activityDate) {
98
- data.activity_date = activityDate;
99
- }
100
- return {
101
- url: url,
102
- method: 'POST',
103
- data: data,
104
- target: {
105
- name: UITarget.ActivityLog,
106
- },
107
- };
108
- }
109
- function createEntityDataGenerator(context, _a) {
110
- var entityType = _a.entityType, data = _a.data;
111
- var url = "/v1/" + ENTITY_PATH_MAP[entityType];
112
- var target = entityType === context.type
113
- ? {
114
- name: UITarget.ListView,
115
- data: {
116
- entityType: entityType,
117
- entityData: data,
118
- },
119
- }
120
- : null;
121
- return {
122
- url: url,
123
- method: 'POST',
124
- data: data,
125
- target: target,
126
- };
127
- }
128
- function relateEntityDataGenerator(context, _a) {
129
- var entityType = _a.entityType, entityId = _a.entityId, data = _a.data;
130
- var url = "/v1/" + ENTITY_PATH_MAP[entityType] + "/" + entityId + "/related";
131
- var isCurrentEntity = entityType === context.type && entityId === context.id;
132
- var target = isCurrentEntity
133
- ? {
134
- name: UITarget.Related,
135
- data: data,
136
- }
137
- : null;
138
- return {
139
- url: url,
140
- method: 'POST',
141
- data: {
142
- resource: data,
143
- },
144
- target: target,
145
- };
51
+ function logActivityDataGenerator(context, { activityType, details, activityDate, }) {
52
+ const url = '/v1/activities';
53
+ const data = {
54
+ parent: {
55
+ type: context.type,
56
+ id: context.id,
57
+ },
58
+ type: {
59
+ category: 'user',
60
+ id: activityType,
61
+ },
62
+ details,
63
+ };
64
+ if (activityDate) {
65
+ data.activity_date = activityDate;
66
+ }
67
+ return {
68
+ url,
69
+ method: 'POST',
70
+ data,
71
+ target: {
72
+ name: UITarget.ActivityLog,
73
+ },
74
+ };
75
+ }
76
+ function createEntityDataGenerator(context, { entityType, data, }) {
77
+ const url = `/v1/${ENTITY_PATH_MAP[entityType]}`;
78
+ const target = entityType === context.type
79
+ ? {
80
+ name: UITarget.ListView,
81
+ data: {
82
+ entityType,
83
+ entityData: data,
84
+ },
85
+ }
86
+ : null;
87
+ return {
88
+ url,
89
+ method: 'POST',
90
+ data,
91
+ target,
92
+ };
93
+ }
94
+ function relateEntityDataGenerator(context, { entityType, entityId, data, }) {
95
+ const url = `/v1/${ENTITY_PATH_MAP[entityType]}/${entityId}/related`;
96
+ const isCurrentEntity = entityType === context.type && entityId === context.id;
97
+ const target = isCurrentEntity
98
+ ? {
99
+ name: UITarget.Related,
100
+ data,
101
+ }
102
+ : null;
103
+ return {
104
+ url,
105
+ method: 'POST',
106
+ data: {
107
+ resource: data,
108
+ },
109
+ target,
110
+ };
146
111
  }
147
112
 
148
- var Deferred = /** @class */ (function () {
149
- function Deferred() {
150
- var _this = this;
151
- this.resolve = function (value) {
152
- _this._resolve(value);
153
- };
154
- this.reject = function (reason) {
155
- _this._reject(reason);
156
- };
157
- this._promise = new Promise(function (resolve, reject) {
158
- _this._resolve = resolve;
159
- _this._reject = reject;
160
- });
161
- }
162
- Object.defineProperty(Deferred.prototype, "promise", {
163
- get: function () {
164
- return this._promise;
165
- },
166
- enumerable: false,
167
- configurable: true
168
- });
169
- return Deferred;
170
- }());
113
+ class Deferred {
114
+ static resetNextId() {
115
+ Deferred._nextId = 0;
116
+ }
117
+ static getNextId() {
118
+ return Deferred._nextId++;
119
+ }
120
+ constructor() {
121
+ this.resolve = (value) => {
122
+ this._resolve(value);
123
+ };
124
+ this.reject = (reason) => {
125
+ this._reject(reason);
126
+ };
127
+ this._promise = new Promise((resolve, reject) => {
128
+ this._resolve = resolve;
129
+ this._reject = reject;
130
+ });
131
+ this._id = Deferred.getNextId();
132
+ }
133
+ get promise() {
134
+ return this._promise;
135
+ }
136
+ get id() {
137
+ return this._id;
138
+ }
139
+ }
140
+ Deferred._nextId = 0;
171
141
 
172
- /**
173
- * getParameterByName
174
- */
175
- function getParameterByName(name, url) {
176
- if (url === void 0) { url = ''; }
177
- if (!url) {
178
- url = window.location.href;
179
- }
180
- name = name.replace(/[[]]/g, '\\$&');
181
- var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
182
- var results = regex.exec(url);
183
- if (!results || !results[2]) {
184
- return '';
185
- }
186
- return decodeURIComponent(results[2].replace(/\+/g, ' '));
187
- }
188
- function log() {
189
- var msg = [];
190
- for (var _i = 0; _i < arguments.length; _i++) {
191
- msg[_i] = arguments[_i];
192
- }
193
- console.log.apply(console, msg); // tslint:disable-line
194
- }
195
- function checkEnvironment() {
196
- // when the running environment is node.js, throwing error
197
- if (typeof window === 'undefined') {
198
- log('Copper can only run in browser environment');
199
- return false;
200
- }
201
- if (window.top === window) {
202
- log('Copper should be inside an iframe, otherwise it might not work as expected.');
203
- }
204
- return true;
205
- }
206
- /**
207
- * This method has side effect,
208
- * it will alter the obj passed in
209
- */
210
- function createArrayWhenEmpty(obj, name) {
211
- if (!obj[name]) {
212
- obj[name] = [];
213
- }
214
- }
215
- function delayExecution(func, delay) {
216
- if (delay === void 0) { delay = 1000; }
217
- setTimeout(function () {
218
- func();
219
- }, delay);
142
+ /**
143
+ * getParameterByName
144
+ */
145
+ function getParameterByName(name, url = '') {
146
+ if (!url) {
147
+ url = window.location.href;
148
+ }
149
+ name = name.replace(/[[]]/g, '\\$&');
150
+ const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
151
+ const results = regex.exec(url);
152
+ if (!results || !results[2]) {
153
+ return '';
154
+ }
155
+ return decodeURIComponent(results[2].replace(/\+/g, ' '));
156
+ }
157
+ function log(...msg) {
158
+ console.log(...msg); // tslint:disable-line
159
+ }
160
+ function checkEnvironment() {
161
+ // when the running environment is node.js, throwing error
162
+ if (typeof window === 'undefined') {
163
+ log('Copper can only run in browser environment');
164
+ return false;
165
+ }
166
+ if (window.top === window) {
167
+ log('Copper should be inside an iframe, otherwise it might not work as expected.');
168
+ }
169
+ return true;
170
+ }
171
+ /**
172
+ * This method has side effect,
173
+ * it will alter the obj passed in
174
+ */
175
+ function createArrayWhenEmpty(obj, name) {
176
+ if (!obj[name]) {
177
+ obj[name] = [];
178
+ }
179
+ }
180
+ function delayExecution(func, delay = 1000) {
181
+ setTimeout(() => {
182
+ func();
183
+ }, delay);
220
184
  }
221
185
 
222
- var EntityModel = /** @class */ (function () {
223
- function EntityModel(type, entityData, editableFields, onSave) {
224
- if (editableFields === void 0) { editableFields = []; }
225
- var propertyDefinitions = this._getEntityDataDefinition(entityData, editableFields);
226
- // override the type getter
227
- // we don't want type to be enumerable
228
- // since we want to be aligned with developer api
229
- propertyDefinitions.type = {
230
- enumerable: false,
231
- writable: false,
232
- value: type,
233
- };
234
- // override _onSave function
235
- propertyDefinitions._onSave = {
236
- enumerable: false,
237
- value: onSave,
238
- };
239
- Object.defineProperties(this, propertyDefinitions);
240
- }
241
- EntityModel.prototype.save = function () {
242
- return __awaiter(this, void 0, void 0, function () {
243
- return __generator(this, function (_a) {
244
- switch (_a.label) {
245
- case 0:
246
- if (!this._onSave) return [3 /*break*/, 2];
247
- return [4 /*yield*/, this._onSave(this)];
248
- case 1: return [2 /*return*/, _a.sent()];
249
- case 2: return [2 /*return*/, null];
250
- }
251
- });
252
- });
253
- };
254
- EntityModel.prototype.toJSON = function () {
255
- return JSON.stringify(this.toObject());
256
- };
257
- EntityModel.prototype.toObject = function () {
258
- var _this = this;
259
- var obj = {};
260
- Object.keys(this).forEach(function (key) {
261
- obj[key] = _this[key];
262
- });
263
- return obj;
264
- };
265
- EntityModel.prototype._getEntityDataDefinition = function (entityData, editableFields) {
266
- if (editableFields === void 0) { editableFields = []; }
267
- var propertyDefinitions = {};
268
- Object.keys(entityData).forEach(function (key) {
269
- if (editableFields.indexOf(key) === -1) {
270
- propertyDefinitions[key] = {
271
- get: function () {
272
- return entityData[key];
273
- },
274
- set: function () {
275
- log("property " + key + " is read only");
276
- },
277
- enumerable: true,
278
- };
279
- }
280
- else {
281
- propertyDefinitions[key] = {
282
- value: entityData[key],
283
- writable: true,
284
- enumerable: true,
285
- };
286
- }
287
- });
288
- return propertyDefinitions;
289
- };
290
- return EntityModel;
291
- }());
186
+ class EntityModel {
187
+ constructor(type, entityData, editableFields = [], onSave) {
188
+ const propertyDefinitions = this._getEntityDataDefinition(entityData, editableFields);
189
+ // override the type getter
190
+ // we don't want type to be enumerable
191
+ // since we want to be aligned with developer api
192
+ propertyDefinitions.type = {
193
+ enumerable: false,
194
+ writable: false,
195
+ value: type,
196
+ };
197
+ // override _onSave function
198
+ propertyDefinitions._onSave = {
199
+ enumerable: false,
200
+ value: onSave,
201
+ };
202
+ Object.defineProperties(this, propertyDefinitions);
203
+ }
204
+ save() {
205
+ return __awaiter(this, void 0, void 0, function* () {
206
+ if (this._onSave) {
207
+ return yield this._onSave(this);
208
+ }
209
+ return null;
210
+ });
211
+ }
212
+ toJSON() {
213
+ return JSON.stringify(this.toObject());
214
+ }
215
+ toObject() {
216
+ const obj = {};
217
+ Object.keys(this).forEach((key) => {
218
+ obj[key] = this[key];
219
+ });
220
+ return obj;
221
+ }
222
+ _getEntityDataDefinition(entityData, editableFields = []) {
223
+ const propertyDefinitions = {};
224
+ Object.keys(entityData).forEach((key) => {
225
+ if (editableFields.indexOf(key) === -1) {
226
+ propertyDefinitions[key] = {
227
+ get() {
228
+ return entityData[key];
229
+ },
230
+ set() {
231
+ log(`property ${key} is read only`);
232
+ },
233
+ enumerable: true,
234
+ };
235
+ }
236
+ else {
237
+ propertyDefinitions[key] = {
238
+ value: entityData[key],
239
+ writable: true,
240
+ enumerable: true,
241
+ };
242
+ }
243
+ });
244
+ return propertyDefinitions;
245
+ }
246
+ }
292
247
 
293
- var Copper = /** @class */ (function () {
294
- /**
295
- * Creates an instance of Copper.
296
- * @param {*} [_win=window] has to be any type to support testing
297
- * @memberof Copper
298
- */
299
- function Copper(parentOrigin, instanceId, options, _win) {
300
- if (_win === void 0) { _win = window; }
301
- this.parentOrigin = parentOrigin;
302
- this.instanceId = instanceId;
303
- this.options = options;
304
- this._win = _win;
305
- /**
306
- * store deferred queues by name
307
- */
308
- this.deferredQueues = {};
309
- /**
310
- * store event callbacks by event name
311
- */
312
- this.events = {};
313
- if (!this.parentOrigin || !this.instanceId) {
314
- throw new TypeError('parentOrigin or instanceId is empty');
315
- }
316
- this._listenMessage();
317
- // listen to contextUpdated event
318
- this._subscribeContextUpdated();
319
- // notify parent frame init
320
- this._postMessage('init');
321
- }
322
- Copper.init = function () {
323
- var parentOrigin = getParameterByName('origin');
324
- var instanceId = getParameterByName('instanceId');
325
- var options = {
326
- isGlobal: getParameterByName('isGlobal') === '1',
327
- };
328
- if (!checkEnvironment()) {
329
- throw new Error('Environment checking does not pass.');
330
- }
331
- return new Copper(parentOrigin, instanceId, options);
332
- };
333
- Object.defineProperty(Copper, "version", {
334
- get: function () {
335
- return version;
336
- },
337
- enumerable: false,
338
- configurable: true
339
- });
340
- Object.defineProperty(Copper.prototype, "win", {
341
- get: function () {
342
- return this._win;
343
- },
344
- enumerable: false,
345
- configurable: true
346
- });
347
- Copper.prototype.getContext = function () {
348
- return __awaiter(this, void 0, void 0, function () {
349
- var messageData;
350
- return __generator(this, function (_a) {
351
- switch (_a.label) {
352
- case 0: return [4 /*yield*/, this._deferredPost('getContext')];
353
- case 1:
354
- messageData = _a.sent();
355
- return [2 /*return*/, this._createContextModel(messageData)];
356
- }
357
- });
358
- });
359
- };
360
- Copper.prototype.getUserInfo = function () {
361
- return __awaiter(this, void 0, void 0, function () {
362
- return __generator(this, function (_a) {
363
- return [2 /*return*/, this._deferredPost('getUserInfo')];
364
- });
365
- });
366
- };
367
- Copper.prototype.getRouteInfo = function () {
368
- return __awaiter(this, void 0, void 0, function () {
369
- return __generator(this, function (_a) {
370
- return [2 /*return*/, this._deferredPost('getRouteInfo')];
371
- });
372
- });
373
- };
374
- Copper.prototype.saveContext = function (context) {
375
- return __awaiter(this, void 0, void 0, function () {
376
- var messageData;
377
- return __generator(this, function (_a) {
378
- switch (_a.label) {
379
- case 0: return [4 /*yield*/, this._deferredPost('saveContext', {
380
- data: {
381
- entityType: context.type,
382
- entityData: context.toObject(),
383
- },
384
- })];
385
- case 1:
386
- messageData = _a.sent();
387
- return [2 /*return*/, this._createContextModel(messageData)];
388
- }
389
- });
390
- });
391
- };
392
- Copper.prototype.setAppUI = function (data) {
393
- this._postMessage('setUI', { data: data });
394
- };
395
- Copper.prototype.showModal = function (params) {
396
- if (params === void 0) { params = {}; }
397
- this._postMessage('showModal', { params: params });
398
- };
399
- Copper.prototype.closeModal = function () {
400
- this._postMessage('closeModal');
401
- };
402
- /**
403
- * Allows developer to send message to another instance of its app
404
- * e.g. Sending data from modal to sidebar, so sidebar can display some data immediately
405
- *
406
- * @param target another instance/location of the app. '*' means broadcast to all other locations.
407
- */
408
- Copper.prototype.publishMessage = function (messageType, target, msg) {
409
- if (msg === void 0) { msg = {}; }
410
- this._postMessage('publishMessage', {
411
- target: target,
412
- data: {
413
- type: messageType,
414
- msg: msg,
415
- },
416
- });
417
- };
418
- Copper.prototype.logActivity = function (activityType, details, activityDate, refreshDelay) {
419
- if (refreshDelay === void 0) { refreshDelay = 0; }
420
- return __awaiter(this, void 0, void 0, function () {
421
- var context, data;
422
- return __generator(this, function (_a) {
423
- switch (_a.label) {
424
- case 0: return [4 /*yield*/, this._getCachedContext()];
425
- case 1:
426
- context = _a.sent();
427
- data = logActivityDataGenerator(context, {
428
- activityType: activityType,
429
- details: details,
430
- activityDate: activityDate,
431
- });
432
- return [2 /*return*/, this._action(data, refreshDelay)];
433
- }
434
- });
435
- });
436
- };
437
- Copper.prototype.createEntity = function (entityType, entityData, refreshDelay) {
438
- if (refreshDelay === void 0) { refreshDelay = 0; }
439
- return __awaiter(this, void 0, void 0, function () {
440
- var context, e_1, apiOptions, url, method, data, target, result;
441
- var _this = this;
442
- return __generator(this, function (_a) {
443
- switch (_a.label) {
444
- case 0:
445
- _a.trys.push([0, 2, , 3]);
446
- return [4 /*yield*/, this._getCachedContext()];
447
- case 1:
448
- context = _a.sent();
449
- return [3 /*break*/, 3];
450
- case 2:
451
- e_1 = _a.sent();
452
- // we allow create entity be called without actual context
453
- context = {};
454
- return [3 /*break*/, 3];
455
- case 3:
456
- apiOptions = createEntityDataGenerator(context, {
457
- entityType: entityType,
458
- data: entityData,
459
- });
460
- url = apiOptions.url, method = apiOptions.method, data = apiOptions.data, target = apiOptions.target;
461
- return [4 /*yield*/, this.api(url, { method: method, body: JSON.stringify(data) })];
462
- case 4:
463
- result = _a.sent();
464
- if (target && target.data) {
465
- target.data.entityData = result;
466
- delayExecution(function () {
467
- _this.refreshUI(target);
468
- }, refreshDelay);
469
- }
470
- return [2 /*return*/, result];
471
- }
472
- });
473
- });
474
- };
475
- Copper.prototype.relateEntity = function (entityType, entityId, relateData, refreshDelay) {
476
- if (refreshDelay === void 0) { refreshDelay = 0; }
477
- return __awaiter(this, void 0, void 0, function () {
478
- var context, data;
479
- return __generator(this, function (_a) {
480
- switch (_a.label) {
481
- case 0: return [4 /*yield*/, this._getCachedContext()];
482
- case 1:
483
- context = _a.sent();
484
- data = relateEntityDataGenerator(context, {
485
- entityType: entityType,
486
- entityId: parseInt(entityId, 10),
487
- data: relateData,
488
- });
489
- return [2 /*return*/, this._action(data, refreshDelay)];
490
- }
491
- });
492
- });
493
- };
494
- Copper.prototype.refreshUI = function (target) {
495
- this._postMessage('refreshUI', { target: target });
496
- };
497
- Copper.prototype.on = function (eventName, cb) {
498
- createArrayWhenEmpty(this.events, eventName);
499
- this.events[eventName].push(cb);
500
- };
501
- Copper.prototype.trigger = function (eventName, data) {
502
- var _this = this;
503
- if (this.events[eventName]) {
504
- this.events[eventName].forEach(function (cb) {
505
- cb.call(_this, data);
506
- });
507
- }
508
- };
509
- Copper.prototype.api = function (url, options) {
510
- if (!url) {
511
- return Promise.reject({
512
- id: 'sdk-api',
513
- version: Copper.version,
514
- detail: 'url cannot be empty',
515
- });
516
- }
517
- if (options && options.body) {
518
- try {
519
- JSON.parse(options.body);
520
- }
521
- catch (e) {
522
- return Promise.reject({
523
- id: 'sdk-api',
524
- version: Copper.version,
525
- detail: 'body must be a valid JSON string',
526
- });
527
- }
528
- }
529
- return this._deferredPost('api', {
530
- url: url,
531
- options: options,
532
- });
533
- };
534
- Copper.prototype.navigateToEntityDetail = function (entityType, entityId) {
535
- return this._deferredPost('navigateToEntityDetail', { entityType: entityType, entityId: entityId });
536
- };
537
- Copper.prototype.getSelectedRecords = function (_a) {
538
- var _b = _a === void 0 ? {} : _a, _c = _b.pageSize, pageSize = _c === void 0 ? 100 : _c, _d = _b.pageNumber, pageNumber = _d === void 0 ? 0 : _d;
539
- return this._deferredPost('getSelectedRecords', { pageSize: pageSize, pageNumber: pageNumber });
540
- };
541
- Copper.prototype.getConfig = function () {
542
- return this._deferredPost('getConfig');
543
- };
544
- Copper.prototype._getCachedContext = function () {
545
- return __awaiter(this, void 0, void 0, function () {
546
- var context;
547
- return __generator(this, function (_a) {
548
- switch (_a.label) {
549
- case 0:
550
- if (this._context) {
551
- return [2 /*return*/, this._context];
552
- }
553
- return [4 /*yield*/, this.getContext()];
554
- case 1:
555
- context = (_a.sent()).context;
556
- return [2 /*return*/, context];
557
- }
558
- });
559
- });
560
- };
561
- Copper.prototype._postMessage = function (type, message) {
562
- if (message === void 0) { message = {}; }
563
- this.win.top.postMessage(__assign(__assign({}, message), {
564
- // as a credential to the parent frame, so parent frame can recoganize the origin
565
- instanceId: this.instanceId,
566
- // tell parent frame current sdk version
567
- version: version,
568
- // type of message
569
- type: type }), this.parentOrigin);
570
- };
571
- Copper.prototype._listenMessage = function () {
572
- var _this = this;
573
- this.win.addEventListener('message', function (event) {
574
- if (!_this._isOriginValid(event)) {
575
- return;
576
- }
577
- // if type is a deferred type, we resolve it
578
- // otherwise we do something else
579
- _this._resolveDeferred(event.data.type, event.data);
580
- // if event type exists, we pass the event to SDK
581
- // so sdk user can subscribe those events
582
- if (event.data.type) {
583
- _this.trigger(event.data.type, event.data.msg || event.data.data);
584
- }
585
- }, false);
586
- };
587
- Copper.prototype._isOriginValid = function (event) {
588
- // only check origin for now
589
- return event.origin === this.parentOrigin;
590
- };
591
- Copper.prototype._enqueueDeferred = function (queueName, deferred) {
592
- createArrayWhenEmpty(this.deferredQueues, queueName);
593
- this.deferredQueues[queueName].push(deferred);
594
- };
595
- Copper.prototype._resolveDeferred = function (queueName, data) {
596
- if (!this.deferredQueues[queueName]) {
597
- return;
598
- }
599
- var deferred = this.deferredQueues[queueName].shift();
600
- if (deferred) {
601
- if (data.error) {
602
- return deferred.reject(data.error);
603
- }
604
- deferred.resolve(data.data);
605
- }
606
- };
607
- Copper.prototype._createContextModel = function (_a) {
608
- var entityType = _a.entityType, entityData = _a.entityData, editableFields = _a.editableFields;
609
- var context = new EntityModel(entityType, entityData, editableFields, this.saveContext.bind(this));
610
- this._context = context;
611
- return {
612
- type: entityType,
613
- context: context,
614
- };
615
- };
616
- Copper.prototype._action = function (_a, delay) {
617
- var url = _a.url, method = _a.method, data = _a.data, target = _a.target;
618
- return __awaiter(this, void 0, void 0, function () {
619
- var result;
620
- var _this = this;
621
- return __generator(this, function (_b) {
622
- switch (_b.label) {
623
- case 0: return [4 /*yield*/, this.api(url, { method: method, body: JSON.stringify(data) })];
624
- case 1:
625
- result = _b.sent();
626
- if (target) {
627
- delayExecution(function () {
628
- _this.refreshUI(target);
629
- }, delay);
630
- }
631
- return [2 /*return*/, result];
632
- }
633
- });
634
- });
635
- };
636
- Copper.prototype._createDeferredMethod = function (queueName, executor) {
637
- var deferred = new Deferred();
638
- this._enqueueDeferred(queueName, deferred);
639
- executor();
640
- return deferred.promise;
641
- };
642
- Copper.prototype._deferredPost = function (name, data) {
643
- var _this = this;
644
- return this._createDeferredMethod(name, function () {
645
- if (data) {
646
- _this._postMessage(name, data);
647
- }
648
- else {
649
- _this._postMessage(name);
650
- }
651
- });
652
- };
653
- Copper.prototype._subscribeContextUpdated = function () {
654
- var _this = this;
655
- this.on('contextUpdated', function () {
656
- // remove _context caching
657
- _this._context = null;
658
- });
659
- };
660
- return Copper;
661
- }());
248
+ class Copper {
249
+ static init() {
250
+ const parentOrigin = getParameterByName('origin');
251
+ const instanceId = getParameterByName('instanceId');
252
+ const options = {
253
+ isGlobal: getParameterByName('isGlobal') === '1',
254
+ };
255
+ if (!checkEnvironment()) {
256
+ throw new Error('Environment checking does not pass.');
257
+ }
258
+ return new Copper(parentOrigin, instanceId, options);
259
+ }
260
+ static get version() {
261
+ return version;
262
+ }
263
+ /**
264
+ * Creates an instance of Copper.
265
+ * @param {*} [_win=window] has to be any type to support testing
266
+ * @memberof Copper
267
+ */
268
+ constructor(parentOrigin, instanceId, options, _win = window) {
269
+ this.parentOrigin = parentOrigin;
270
+ this.instanceId = instanceId;
271
+ this.options = options;
272
+ this._win = _win;
273
+ /**
274
+ * store deferred queues by name
275
+ */
276
+ this.deferredQueues = {};
277
+ /**
278
+ * store event callbacks by event name
279
+ */
280
+ this.events = {};
281
+ if (!this.parentOrigin || !this.instanceId) {
282
+ throw new TypeError('parentOrigin or instanceId is empty');
283
+ }
284
+ this._listenMessage();
285
+ // listen to contextUpdated event
286
+ this._subscribeContextUpdated();
287
+ // notify parent frame init
288
+ this._postMessage('init');
289
+ }
290
+ get win() {
291
+ return this._win;
292
+ }
293
+ getContext() {
294
+ return __awaiter(this, void 0, void 0, function* () {
295
+ const messageData = yield this._deferredPost('getContext');
296
+ return this._createContextModel(messageData);
297
+ });
298
+ }
299
+ getUserInfo() {
300
+ return __awaiter(this, void 0, void 0, function* () {
301
+ return this._deferredPost('getUserInfo');
302
+ });
303
+ }
304
+ getRouteInfo() {
305
+ return __awaiter(this, void 0, void 0, function* () {
306
+ return this._deferredPost('getRouteInfo');
307
+ });
308
+ }
309
+ saveContext(context) {
310
+ return __awaiter(this, void 0, void 0, function* () {
311
+ const messageData = yield this._deferredPost('saveContext', {
312
+ data: {
313
+ entityType: context.type,
314
+ entityData: context.toObject(),
315
+ },
316
+ });
317
+ return this._createContextModel(messageData);
318
+ });
319
+ }
320
+ setAppUI(data) {
321
+ this._postMessage('setUI', { data });
322
+ }
323
+ showModal(params = {}) {
324
+ this._postMessage('showModal', { params });
325
+ }
326
+ closeModal() {
327
+ this._postMessage('closeModal');
328
+ }
329
+ /**
330
+ * Allows developer to send message to another instance of its app
331
+ * e.g. Sending data from modal to sidebar, so sidebar can display some data immediately
332
+ *
333
+ * @param target another instance/location of the app. '*' means broadcast to all other locations.
334
+ */
335
+ publishMessage(messageType, target, msg = {}) {
336
+ this._postMessage('publishMessage', {
337
+ target,
338
+ data: {
339
+ type: messageType,
340
+ msg,
341
+ },
342
+ });
343
+ }
344
+ logActivity(activityType_1, details_1, activityDate_1) {
345
+ return __awaiter(this, arguments, void 0, function* (activityType, details, activityDate, refreshDelay = 0) {
346
+ const context = yield this._getCachedContext();
347
+ const data = logActivityDataGenerator(context, {
348
+ activityType,
349
+ details,
350
+ activityDate,
351
+ });
352
+ return this._action(data, refreshDelay);
353
+ });
354
+ }
355
+ createEntity(entityType_1, entityData_1) {
356
+ return __awaiter(this, arguments, void 0, function* (entityType, entityData, refreshDelay = 0) {
357
+ let context;
358
+ try {
359
+ context = yield this._getCachedContext();
360
+ }
361
+ catch (e) {
362
+ // we allow create entity be called without actual context
363
+ context = {};
364
+ }
365
+ const apiOptions = createEntityDataGenerator(context, {
366
+ entityType,
367
+ data: entityData,
368
+ });
369
+ const { url, method, data, target } = apiOptions;
370
+ const result = yield this.api(url, { method, body: JSON.stringify(data) });
371
+ if (target && target.data) {
372
+ target.data.entityData = result;
373
+ delayExecution(() => {
374
+ this.refreshUI(target);
375
+ }, refreshDelay);
376
+ }
377
+ return result;
378
+ });
379
+ }
380
+ relateEntity(entityType_1, entityId_1, relateData_1) {
381
+ return __awaiter(this, arguments, void 0, function* (entityType, entityId, relateData, refreshDelay = 0) {
382
+ const context = yield this._getCachedContext();
383
+ const data = relateEntityDataGenerator(context, {
384
+ entityType,
385
+ entityId: parseInt(entityId, 10),
386
+ data: relateData,
387
+ });
388
+ return this._action(data, refreshDelay);
389
+ });
390
+ }
391
+ refreshUI(target) {
392
+ this._postMessage('refreshUI', { target });
393
+ }
394
+ on(eventName, cb) {
395
+ createArrayWhenEmpty(this.events, eventName);
396
+ this.events[eventName].push(cb);
397
+ }
398
+ trigger(eventName, data) {
399
+ if (this.events[eventName]) {
400
+ this.events[eventName].forEach((cb) => {
401
+ cb.call(this, data);
402
+ });
403
+ }
404
+ }
405
+ api(url, options) {
406
+ if (!url) {
407
+ return Promise.reject({
408
+ id: 'sdk-api',
409
+ version: Copper.version,
410
+ detail: 'url cannot be empty',
411
+ });
412
+ }
413
+ if (options && options.body) {
414
+ try {
415
+ JSON.parse(options.body);
416
+ }
417
+ catch (e) {
418
+ return Promise.reject({
419
+ id: 'sdk-api',
420
+ version: Copper.version,
421
+ detail: 'body must be a valid JSON string',
422
+ });
423
+ }
424
+ }
425
+ return this._deferredPost('api', {
426
+ url,
427
+ options,
428
+ });
429
+ }
430
+ navigateToEntityDetail(entityType, entityId) {
431
+ return this._deferredPost('navigateToEntityDetail', { entityType, entityId });
432
+ }
433
+ getSelectedRecords({ pageSize = 100, pageNumber = 0 } = {}) {
434
+ return this._deferredPost('getSelectedRecords', { pageSize, pageNumber });
435
+ }
436
+ getConfig() {
437
+ return this._deferredPost('getConfig');
438
+ }
439
+ _getCachedContext() {
440
+ return __awaiter(this, void 0, void 0, function* () {
441
+ if (this._context) {
442
+ return this._context;
443
+ }
444
+ const { context } = yield this.getContext();
445
+ return context;
446
+ });
447
+ }
448
+ _postMessage(type, message = {}, id = -1) {
449
+ var _a;
450
+ (_a = this.win.top) === null || _a === void 0 ? void 0 : _a.postMessage(Object.assign(Object.assign({}, message), {
451
+ // as a credential to the parent frame, so parent frame can recoganize the origin
452
+ instanceId: this.instanceId,
453
+ // tell parent frame current sdk version
454
+ version,
455
+ // type of message
456
+ type,
457
+ // optional id for message
458
+ id }), this.parentOrigin);
459
+ }
460
+ _listenMessage() {
461
+ this.win.addEventListener('message', (event) => {
462
+ if (!this._isOriginValid(event)) {
463
+ return;
464
+ }
465
+ // if type is a deferred type, we resolve it
466
+ // otherwise we do something else
467
+ this._resolveDeferred(event.data.type, event.data.id, event.data);
468
+ // if event type exists, we pass the event to SDK
469
+ // so sdk user can subscribe those events
470
+ if (event.data.type) {
471
+ this.trigger(event.data.type, event.data.msg || event.data.data);
472
+ }
473
+ }, false);
474
+ }
475
+ _isOriginValid(event) {
476
+ // only check origin for now
477
+ return event.origin === this.parentOrigin;
478
+ }
479
+ _enqueueDeferred(queueName, deferred) {
480
+ createArrayWhenEmpty(this.deferredQueues, queueName);
481
+ this.deferredQueues[queueName].push(deferred);
482
+ }
483
+ _resolveDeferred(queueName, messageId, data) {
484
+ const queue = this.deferredQueues[queueName];
485
+ if (!queue) {
486
+ return;
487
+ }
488
+ const foundIdx = queue.findIndex((d) => {
489
+ return d.id === messageId;
490
+ });
491
+ const deferred = queue[foundIdx];
492
+ if (deferred) {
493
+ queue.splice(foundIdx, 1);
494
+ if (data.error) {
495
+ return deferred.reject(data.error);
496
+ }
497
+ deferred.resolve(data.data);
498
+ }
499
+ }
500
+ _createContextModel({ entityType, entityData, editableFields, }) {
501
+ const context = new EntityModel(entityType, entityData, editableFields, this.saveContext.bind(this));
502
+ this._context = context;
503
+ return {
504
+ type: entityType,
505
+ context,
506
+ };
507
+ }
508
+ _action(_a, delay_1) {
509
+ return __awaiter(this, arguments, void 0, function* ({ url, method, data, target }, delay) {
510
+ const result = yield this.api(url, { method, body: JSON.stringify(data) });
511
+ if (target) {
512
+ delayExecution(() => {
513
+ this.refreshUI(target);
514
+ }, delay);
515
+ }
516
+ return result;
517
+ });
518
+ }
519
+ _createDeferredMethod(queueName, executor) {
520
+ const deferred = new Deferred();
521
+ this._enqueueDeferred(queueName, deferred);
522
+ executor(deferred);
523
+ return deferred.promise;
524
+ }
525
+ _deferredPost(name, data) {
526
+ return this._createDeferredMethod(name, (deferred) => {
527
+ if (data) {
528
+ this._postMessage(name, data, deferred.id);
529
+ }
530
+ else {
531
+ this._postMessage(name, {}, deferred.id);
532
+ }
533
+ });
534
+ }
535
+ _subscribeContextUpdated() {
536
+ this.on('contextUpdated', () => {
537
+ // remove _context caching
538
+ this._context = null;
539
+ });
540
+ }
541
+ }
662
542
 
663
- export default Copper;
543
+ export { Copper as default };
544
+ //# sourceMappingURL=copper-sdk.js.map