@twintag/twintag-sdk 0.2.235-TTPL-1970-twintagsdk-397570c85978488f2e5cebf3cab22c0a2faa6217

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.
@@ -0,0 +1,2365 @@
1
+ /*! *****************************************************************************
2
+ Copyright (c) Microsoft Corporation.
3
+
4
+ Permission to use, copy, modify, and/or distribute this software for any
5
+ purpose with or without fee is hereby granted.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
+ PERFORMANCE OF THIS SOFTWARE.
14
+ ***************************************************************************** */
15
+
16
+ function __awaiter(thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ }
25
+
26
+ // DO NOT EDIT: This file is automatically generated by build/version.js
27
+ /**
28
+ * The twintag-sdk version.
29
+ */
30
+ const VERSION = '0.2.235-TTPL-1970-twintagsdk-397570c85978488f2e5cebf3cab22c0a2faa6217';
31
+
32
+ class TwintagErrorValue {
33
+ }
34
+ class TwintagError extends Error {
35
+ constructor(message, errors, name, stack) {
36
+ super(message);
37
+ this.name = name;
38
+ this.stack = stack;
39
+ this.errors = errors;
40
+ }
41
+ setMessage(message) {
42
+ this.message = message;
43
+ }
44
+ }
45
+
46
+ const explicitDisableOffline = {
47
+ offlineAction: 'explicit disable offline',
48
+ disabled: true
49
+ };
50
+
51
+ /**
52
+ * @internal
53
+ */
54
+ class Client {
55
+ constructor(token) {
56
+ this.token = token;
57
+ }
58
+ do(path, args, offlineOptions, skipParse, skipAuth // TODO: Deprecate in virtual web endpoint.
59
+ ) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ // first check if we are in a browser context
62
+ if (typeof window !== 'undefined') {
63
+ if (window.twintagOfflineSupport && !window.twintagOfflineSupport.onLine) {
64
+ if (offlineOptions && offlineOptions.disabled) {
65
+ return this.doOnline(path, args, offlineOptions, skipParse, skipAuth);
66
+ }
67
+ return this.doOffline(path, args, offlineOptions, skipParse, skipAuth);
68
+ }
69
+ }
70
+ return this.doOnline(path, args, offlineOptions, skipParse, skipAuth);
71
+ });
72
+ }
73
+ doOnline(path, args, offlineOptions, skipParse, skipAuth // TODO: Deprecate in virtual web endpoint.
74
+ ) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ //Inject authorization for our host
77
+ const headers = new Headers(args === null || args === void 0 ? void 0 : args.headers);
78
+ if (this.token && !skipAuth) {
79
+ if (!headers.get('Authorization')) {
80
+ headers.set('Authorization', 'Bearer ' + this.token);
81
+ }
82
+ }
83
+ //Add client analytics
84
+ headers.set('X-Client-Name', 'twintag.js');
85
+ headers.set('X-Client-Version', VERSION);
86
+ args.headers = headers;
87
+ const resp = yield fetch(new Request(path, args));
88
+ if (!resp.ok) {
89
+ // custom API error
90
+ const err = yield resp.json();
91
+ return [{}, this.CreateTwintagError(err)];
92
+ }
93
+ if (skipParse) {
94
+ if (!resp.body) {
95
+ return [{}, undefined];
96
+ }
97
+ return [resp.body, undefined];
98
+ }
99
+ try {
100
+ const res = yield resp.json();
101
+ return [res, undefined];
102
+ }
103
+ catch (error) {
104
+ const err = new TwintagErrorValue();
105
+ err.title = 'failed to parse response';
106
+ err.detail = 'something went wrong when parsing response';
107
+ return [{}, this.CreateTwintagError([err])];
108
+ }
109
+ });
110
+ }
111
+ doOffline(path, args, offlineOptions, skipParse, skipAuth // TODO: Deprecate in virtual web endpoint.
112
+ ) {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ const offlineSupportHandler = window.twintagOfflineSupport;
115
+ if (offlineSupportHandler) {
116
+ offlineSupportHandler.addOfflineRequest({
117
+ path,
118
+ args,
119
+ offlineOptions,
120
+ skipParse,
121
+ skipAuth
122
+ });
123
+ }
124
+ return [{}, undefined];
125
+ });
126
+ }
127
+ get(path, offlineOptions, args, skipAuth // TODO: Deprecate
128
+ ) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ if (!args) {
131
+ args = {};
132
+ }
133
+ args.method = 'GET';
134
+ return yield this.do(path, args, offlineOptions, false, skipAuth);
135
+ });
136
+ }
137
+ put(path, body, offlineOptions, args, skipAuth // TODO: Deprecate
138
+ ) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ if (!args) {
141
+ args = {};
142
+ }
143
+ args.method = 'PUT';
144
+ if (!args.body && body) {
145
+ args.body = JSON.stringify(body);
146
+ }
147
+ return yield this.do(path, args, offlineOptions, false, skipAuth);
148
+ });
149
+ }
150
+ post(path, body, args, skipAuth) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ if (!args) {
153
+ args = {};
154
+ }
155
+ args.method = 'POST';
156
+ if (!args.body && body) {
157
+ args.body = JSON.stringify(body);
158
+ }
159
+ return yield this.do(path, args, explicitDisableOffline, false, skipAuth);
160
+ });
161
+ }
162
+ delete(path, body, offlineOptions, args) {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ if (!args) {
165
+ args = {};
166
+ }
167
+ args.method = 'delete';
168
+ if (!args.body && body) {
169
+ args.body = JSON.stringify(body);
170
+ }
171
+ return yield this.do(path, args, offlineOptions, true);
172
+ });
173
+ }
174
+ CreateTwintagError(err) {
175
+ if (err && err.errors && err.errors.length > 0) {
176
+ return new TwintagError(err.errors[0].detail, err.errors[0], err.errors[0].title);
177
+ }
178
+ return new TwintagError('Failed to perform the request', err, 'Twintag Error');
179
+ }
180
+ }
181
+
182
+ class Environment {
183
+ constructor() {
184
+ this._host = 'https://twintag.io';
185
+ this._adminHost = '';
186
+ this._cachingHost = '';
187
+ this.useCaching = false;
188
+ this.autoDetect = true;
189
+ }
190
+ get host() {
191
+ this.autoDetectOrigin();
192
+ return this._host;
193
+ }
194
+ set host(host) {
195
+ this.autoDetect = false;
196
+ this._host = host;
197
+ }
198
+ get adminHost() {
199
+ this.autoDetectOrigin();
200
+ return this._adminHost;
201
+ }
202
+ set adminHost(adminHost) {
203
+ this.autoDetect = false;
204
+ this._adminHost = adminHost;
205
+ }
206
+ get cachingHost() {
207
+ this.autoDetectOrigin();
208
+ return this._cachingHost;
209
+ }
210
+ set cachingHost(cachingHost) {
211
+ this.autoDetect = false;
212
+ this._cachingHost = cachingHost;
213
+ }
214
+ autoDetectOrigin() {
215
+ var _a, _b;
216
+ if (!this.autoDetect)
217
+ return;
218
+ if (typeof window !== 'undefined'
219
+ && (window === null || window === void 0 ? void 0 : window.origin) !== undefined
220
+ && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.hostname) !== "localhost"
221
+ && ((_b = window === null || window === void 0 ? void 0 : window.location) === null || _b === void 0 ? void 0 : _b.hostname) !== "127.0.0.1") {
222
+ this._host = window.origin;
223
+ }
224
+ const base = new URL(this._host);
225
+ const adminSub = 'admin.';
226
+ const cachingSub = 'cache.';
227
+ this._adminHost = `${base.protocol}//${adminSub}${base.host}`;
228
+ this._cachingHost = `${base.protocol}//${cachingSub}${base.host}`;
229
+ this.autoDetect = false;
230
+ }
231
+ }
232
+ /**
233
+ * Default environment config.
234
+ *
235
+ * @Internal
236
+ */
237
+ const environment = new Environment();
238
+
239
+ /**
240
+ * Twintag SDK.
241
+ *
242
+ * @packageDocumentation
243
+ */
244
+ /**
245
+ * SetHost allows you to overwrite the Twintag domain.
246
+ *
247
+ * @hidden
248
+ */
249
+ function setHost(host) {
250
+ environment.host = host;
251
+ }
252
+ /**
253
+ * SetAdminHost allows you to overwrite the Twintag administrative domain.
254
+ *
255
+ * @hidden
256
+ */
257
+ function setAdminHost(host) {
258
+ environment.adminHost = host;
259
+ }
260
+ /**
261
+ * setCachingHost allows you to overwrite the Twintag caching domain.
262
+ *
263
+ * @hidden
264
+ */
265
+ function setCachingHost(host) {
266
+ environment.cachingHost = host;
267
+ }
268
+ /**
269
+ * retryRequest allows you to retry a cached/stored request
270
+ *
271
+ * @hidden
272
+ */
273
+ function retryRequest(request) {
274
+ return __awaiter(this, void 0, void 0, function* () {
275
+ request.skipParse = true; //no need to parse the response as this is a retry, so our app is in a different state
276
+ const client = new Client();
277
+ return yield client.doOnline(request.path, request.args, request.offlineOptions, request.skipParse, request.skipAuth);
278
+ });
279
+ }
280
+
281
+ class Parser {
282
+ static parseSpecialTypes(data) {
283
+ let singleInstance = false;
284
+ if (!(data instanceof Array)) {
285
+ singleInstance = true;
286
+ data = [data];
287
+ }
288
+ data.forEach((instance) => {
289
+ for (const prop in instance) {
290
+ if (prop.startsWith('$')) {
291
+ continue;
292
+ }
293
+ if (instance[`$${prop}Type`]) {
294
+ switch (instance[`$${prop}Type`]) {
295
+ case 'dateTime':
296
+ instance[prop] = new Date(instance[prop]);
297
+ break;
298
+ }
299
+ }
300
+ }
301
+ });
302
+ return singleInstance ? data[0] : data;
303
+ }
304
+ }
305
+
306
+ class FileUploader {
307
+ /**
308
+ * Construct listObject with objectApiName, scemaScope, viewId and client.
309
+ *
310
+ * @param objectAPIName
311
+ * @param client
312
+ * @param viewId
313
+ * @param schemaScope
314
+ *
315
+ * @internal
316
+ */
317
+ constructor(client, viewId, signedUrl, fileQid, instanceQid) {
318
+ this._client = client;
319
+ this.viewId = viewId;
320
+ this.instanceQid = instanceQid;
321
+ this.fileQid = fileQid;
322
+ this.signedUrl = signedUrl;
323
+ }
324
+ /**
325
+ * Upload uploads the file provided file to the resppective structured data column
326
+ *
327
+ * @param file, file to be uploaded
328
+ *
329
+ */
330
+ Upload(file) {
331
+ return __awaiter(this, void 0, void 0, function* () {
332
+ this.uploadFile(file);
333
+ });
334
+ }
335
+ /**
336
+ * Private method to upload file.
337
+ *
338
+ * @param file type properties
339
+ *
340
+ * @internal
341
+ */
342
+ uploadFile(file) {
343
+ return __awaiter(this, void 0, void 0, function* () {
344
+ yield this.uploadToS3(this.signedUrl, file);
345
+ yield this.endUpload(this.instanceQid, this.fileQid);
346
+ });
347
+ }
348
+ /**
349
+ * Private method to upload file to s3.
350
+ *
351
+ * @param uploadUrl presigned s3 upload url
352
+ * @param file file object to upload
353
+ *
354
+ * @internal
355
+ */
356
+ uploadToS3(uploadUrl, file) {
357
+ return __awaiter(this, void 0, void 0, function* () {
358
+ const body = yield file.arrayBuffer();
359
+ return this._client.do(uploadUrl, { method: 'put', body: body }, explicitDisableOffline, true, true);
360
+ });
361
+ }
362
+ /**
363
+ * Private method to end upload call.
364
+ *
365
+ * @param fileContext instance qid
366
+ * @param fileQid file qid
367
+ *
368
+ * @internal
369
+ */
370
+ endUpload(fileContext, fileQid) {
371
+ return __awaiter(this, void 0, void 0, function* () {
372
+ let url = this.fileUrl();
373
+ url += '/end';
374
+ const body = {
375
+ fileQid: fileQid,
376
+ fileContext: fileContext,
377
+ };
378
+ this._client.put(url, body);
379
+ });
380
+ }
381
+ fileUrl() {
382
+ if (this.viewId !== '') {
383
+ return environment.host + '/api/v1/views/' + this.viewId + '/data/files';
384
+ }
385
+ else {
386
+ return environment.adminHost + '/api/v1/data/files';
387
+ }
388
+ }
389
+ }
390
+
391
+ /**
392
+ * A list object class represents data from a list type of object.
393
+ * This object can be used to interact with the list of data of a list object.
394
+ * CRUD operations can be performed on this object
395
+ */
396
+ class ListObject {
397
+ /**
398
+ * Construct listObject with objectApiName, scemaScope, viewId and client.
399
+ *
400
+ * @param objectAPIName
401
+ * @param client
402
+ * @param viewId
403
+ * @param schemaScope
404
+ *
405
+ * @internal
406
+ */
407
+ constructor(objectAPIName, client, viewId, projectId, useCaching = false) {
408
+ this._useCaching = false;
409
+ this._client = client;
410
+ this.viewId = viewId;
411
+ this.objectApiName = objectAPIName;
412
+ this._projectId = projectId;
413
+ this._useCaching = useCaching;
414
+ }
415
+ /**
416
+ * Get a record from list object with the specified id.
417
+ * Optional parameter lang can be passed to get data in a specific language.
418
+ *
419
+ * Example:
420
+ * Without language
421
+ * ```js
422
+ * await object.get('')
423
+ * ```
424
+ *
425
+ * With language parameter
426
+ * ```js
427
+ * await object.get('', 'en')
428
+ * ```
429
+ *
430
+ * @param id Id value of the record
431
+ * @param lang: optional language value. Allowed inputs are "all" or any language defined in project languages. If no value is passed, then project's default language will be used for returning data
432
+ *
433
+ * @category ListObject
434
+ */
435
+ get(id, lang, offlineOptions) {
436
+ return __awaiter(this, void 0, void 0, function* () {
437
+ let url = '';
438
+ if (this._useCaching) {
439
+ if (this.viewId === '') {
440
+ url = `${environment.cachingHost}/data/${this.objectApiName}/${id}?withSDFileURL=false&schemaScope=${this._projectId}`;
441
+ }
442
+ else {
443
+ url = `${environment.cachingHost}/api/v1/views/${this.viewId}/data/${this.objectApiName}/${id}?withSDFileURL=false&`;
444
+ }
445
+ }
446
+ else {
447
+ url = this.dataUrl(id);
448
+ }
449
+ url += lang
450
+ ? `${url.indexOf('?') < 0 ? '?' : '&'}language=${lang === 'all' ? '*' : lang}`
451
+ : '';
452
+ const [res, err] = yield this._client.get(url, offlineOptions);
453
+ if (err) {
454
+ err.setMessage(`failed to get data: ${err.message}`);
455
+ throw err;
456
+ }
457
+ return Parser.parseSpecialTypes(res);
458
+ });
459
+ }
460
+ /**
461
+ * Add data to list object for the specified view.
462
+ *
463
+ * @param data An object representing the data
464
+ *
465
+ * @category ListObject
466
+ */
467
+ insert(data, offlineOptions) {
468
+ return __awaiter(this, void 0, void 0, function* () {
469
+ const url = this.dataUrl();
470
+ const fileTypes = this.parseForSpecialTypes(data);
471
+ const [res, err] = yield this._client.put(url, data, offlineOptions, {
472
+ headers: { 'Content-Type': 'application/json' },
473
+ });
474
+ if (err) {
475
+ err.setMessage(`failed to insert data: ${err.message}`);
476
+ throw err;
477
+ }
478
+ return yield this.parseResponse(res, fileTypes);
479
+ });
480
+ }
481
+ /**
482
+ * Private method to parse file types in request.
483
+ * Ideally validate if the value is of File type. Since at the time of development File polyfill was not injected * to epsilon, checking for instance of File is not possible. adding null check for value deletion support
484
+ * @param data
485
+ *
486
+ * @internal
487
+ */
488
+ parseForSpecialTypes(data) {
489
+ const fileType = [];
490
+ Object.entries(data).forEach(([key, value]) => {
491
+ if (value instanceof Date) {
492
+ const tzoffset = new Date().getTimezoneOffset() * 60000; // offset in milliseconds
493
+ const dateTimeInMilliSeconds = new Date(value).getTime();
494
+ data[key] = new Date(dateTimeInMilliSeconds - tzoffset).toISOString().split('T').join(' ').split('.')[0];
495
+ }
496
+ else if (value && typeof value === 'object') {
497
+ fileType.push({
498
+ apiName: key,
499
+ file: data[key],
500
+ });
501
+ data[key] = {
502
+ name: value.name,
503
+ size: value.size,
504
+ fileContent: value.fileContent
505
+ };
506
+ }
507
+ });
508
+ return fileType;
509
+ }
510
+ /**
511
+ * Private method to parse the insert/update response and assign FileUploader to file type columns
512
+ * @param resp
513
+ * @param fileTypes
514
+ *
515
+ * @internal
516
+ */
517
+ parseResponse(resp, fileTypes) {
518
+ return __awaiter(this, void 0, void 0, function* () {
519
+ fileTypes.forEach((obj) => __awaiter(this, void 0, void 0, function* () {
520
+ const fileResp = resp[obj.apiName];
521
+ resp[obj.apiName] = new FileUploader(this._client, this.viewId, fileResp.uploadUrl, fileResp.metafest.fileQid, resp.$qid);
522
+ if (obj.file instanceof Blob) {
523
+ yield resp[obj.apiName].Upload(obj.file);
524
+ resp[obj.apiName] = fileResp.metafest;
525
+ }
526
+ }));
527
+ return resp;
528
+ });
529
+ }
530
+ /**
531
+ * Add data to list object in insertInBulk.
532
+ *
533
+ * @param data array of object representing the data
534
+ *
535
+ * @category ListObject
536
+ */
537
+ insertInBulk(data, offlineOptions) {
538
+ return __awaiter(this, void 0, void 0, function* () {
539
+ let url = this.dataUrl();
540
+ url += '/import';
541
+ const [res, err] = yield this._client.put(url, data, offlineOptions, {
542
+ headers: { 'Content-Type': 'application/json' },
543
+ });
544
+ if (err) {
545
+ err.setMessage(`failed to insert bulk data: ${err.message}`);
546
+ throw err;
547
+ }
548
+ return res;
549
+ });
550
+ }
551
+ /**
552
+ * Update an existing record on the list type object
553
+ *
554
+ * @param data An object representing the data. The QID of the record is required in the data object
555
+ *
556
+ * @category ListObject
557
+ */
558
+ update(data, offlineOptions) {
559
+ return __awaiter(this, void 0, void 0, function* () {
560
+ const url = this.dataUrl();
561
+ const fileTypes = this.parseForSpecialTypes(data);
562
+ const [res, err] = yield this._client.put(url, data, offlineOptions, {
563
+ headers: { 'Content-Type': 'application/json' },
564
+ });
565
+ if (err) {
566
+ err.setMessage(`failed to update data: ${err.message}`);
567
+ throw err;
568
+ }
569
+ return this.parseResponse(res, fileTypes);
570
+ });
571
+ }
572
+ /**
573
+ * Delete a record in the list object.
574
+ *
575
+ * @param id ID value of the record
576
+ *
577
+ * @category ListObject
578
+ */
579
+ delete(id, dataScope = '', offlineOptions) {
580
+ return __awaiter(this, void 0, void 0, function* () {
581
+ const url = this.dataUrl();
582
+ const req = {
583
+ id: id,
584
+ $dataScope: dataScope
585
+ };
586
+ const [, err] = yield this._client.delete(url, req, offlineOptions, {
587
+ headers: { 'Content-Type': 'application/json' },
588
+ });
589
+ if (err) {
590
+ err.setMessage(`failed to delete data: ${err.message}`);
591
+ throw err;
592
+ }
593
+ });
594
+ }
595
+ /**
596
+ * Get a record from list object using a filter.
597
+ * Example:
598
+ * ```js
599
+ * let f: Filter = {
600
+ * "strCol": "test",
601
+ * "numCol":{
602
+ * lt: 10
603
+ * }
604
+ * }
605
+ * let res = await obj.match(f)
606
+ * ```
607
+ *
608
+ * Above input will filter "strCol" for "test" and "numCol" for values less than 10
609
+ *
610
+ * @param filter: {@link Filter}
611
+ * @param lang: optional language value. Allowed inputs are "all" or any language defined in project languages. If no value is passed, then project's default language will be used for returning data
612
+ * @category ListObject
613
+ */
614
+ match(f, lang) {
615
+ return __awaiter(this, void 0, void 0, function* () {
616
+ const filterQueryArg = this.getFilterQuery(f);
617
+ let url = '';
618
+ if (this._useCaching) {
619
+ if (this.viewId === '') {
620
+ url = `${environment.cachingHost}/data/${this.objectApiName}?withSDFileURL=false&schemaScope=${this._projectId}${filterQueryArg}`;
621
+ }
622
+ else {
623
+ url = `${environment.cachingHost}/api/v1/views/${this.viewId}/data/${this.objectApiName}?withSDFileURL=false&${filterQueryArg}`;
624
+ }
625
+ }
626
+ else {
627
+ url = this.dataUrl(null, filterQueryArg) + '&withSDFileURL=false';
628
+ }
629
+ url += lang
630
+ ? `${url.indexOf('?') < 0 ? '?' : '&'}language=${lang === 'all' ? '*' : lang}`
631
+ : '';
632
+ const [res, err] = yield this._client.get(url);
633
+ if (err) {
634
+ err.setMessage('failed to get data');
635
+ throw err;
636
+ }
637
+ return Parser.parseSpecialTypes(res);
638
+ });
639
+ }
640
+ getFile(instanceQID, fileQID, forceDownload = false) {
641
+ return __awaiter(this, void 0, void 0, function* () {
642
+ let url = this.dataUrl(instanceQID);
643
+ url += '/files/' + fileQID;
644
+ if (forceDownload) {
645
+ url += '?forcedownload=' + forceDownload;
646
+ }
647
+ const [res, err] = yield this._client.get(url);
648
+ if (err) {
649
+ err.setMessage(`failed to get data: ${err.message}`);
650
+ throw err;
651
+ }
652
+ return res;
653
+ });
654
+ }
655
+ /**
656
+ * Private method to get filter query for match method.
657
+ *
658
+ * @param Filter
659
+ *
660
+ * @internal
661
+ */
662
+ getFilterQuery(f) {
663
+ let filterPredicate = '';
664
+ if (f != null) {
665
+ for (const [objName, objectsData] of Object.entries(f)) {
666
+ if (typeof objectsData === 'object') {
667
+ const fe = objectsData;
668
+ filterPredicate += fe.gt
669
+ ? this.getFilterValue(objName, fe.gt, '>')
670
+ : '';
671
+ filterPredicate += fe.lt
672
+ ? this.getFilterValue(objName, fe.lt, '<')
673
+ : '';
674
+ filterPredicate += fe.gte
675
+ ? this.getFilterValue(objName, fe.gte, '>=')
676
+ : '';
677
+ filterPredicate += fe.lte
678
+ ? this.getFilterValue(objName, fe.lte, '<=')
679
+ : '';
680
+ }
681
+ else {
682
+ filterPredicate += `&filter=${objName}=${encodeURIComponent(this.handleTypes(objectsData))}`;
683
+ }
684
+ }
685
+ }
686
+ return filterPredicate;
687
+ }
688
+ /**
689
+ * Private method to get create filter string.
690
+ * @param objName
691
+ * @param input
692
+ * @param op
693
+ * @internal
694
+ */
695
+ getFilterValue(objName, input, op) {
696
+ const v = this.handleTypes(input);
697
+ if (v) {
698
+ console.log("_________ getfilter ??? ", `&filter=${objName}${op}${encodeURIComponent(v)}`);
699
+ return `&filter=${objName}${op}${encodeURIComponent(v)}`;
700
+ }
701
+ return '';
702
+ }
703
+ /**
704
+ * Private method to handle different types.
705
+ * @param input
706
+ * @internal
707
+ */
708
+ handleTypes(input) {
709
+ switch (typeof input) {
710
+ case 'string':
711
+ case 'number': {
712
+ return input;
713
+ }
714
+ default: {
715
+ if (input instanceof Date) {
716
+ return input.toISOString().replace('T', '%20').replace('Z', '');
717
+ }
718
+ return '';
719
+ }
720
+ }
721
+ }
722
+ /**
723
+ * Private method to form the url.
724
+ *
725
+ * @param instanceId
726
+ *
727
+ * @internal
728
+ */
729
+ dataUrl(instanceId, fp) {
730
+ let url = '';
731
+ if (this.viewId === '') {
732
+ url = environment.adminHost + '/api/v1/data/' + this.objectApiName;
733
+ }
734
+ else {
735
+ url =
736
+ environment.host +
737
+ '/api/v1/views/' +
738
+ this.viewId +
739
+ '/data/' +
740
+ this.objectApiName;
741
+ }
742
+ if (instanceId) {
743
+ url += '/' + instanceId;
744
+ }
745
+ if (fp) {
746
+ url += `?${fp}`;
747
+ }
748
+ return url;
749
+ }
750
+ }
751
+
752
+ /**
753
+ * A epsilon class to execute the epsilon
754
+ */
755
+ class Epsilon {
756
+ /**
757
+ * Construct epsilon with viewId, client, host and adminHost.
758
+ *
759
+ * @param viewId
760
+ * @param client
761
+ *
762
+ * @internal
763
+ */
764
+ constructor(viewId, client) {
765
+ this.viewId = viewId;
766
+ this._client = client;
767
+ }
768
+ setDefaults() {
769
+ var _a;
770
+ return __awaiter(this, void 0, void 0, function* () {
771
+ if (!this.view) {
772
+ this.view = new View(this.viewId);
773
+ }
774
+ if (!this.folders || ((_a = this.folders) === null || _a === void 0 ? void 0 : _a.length) === 0) {
775
+ this.folders = yield this.view.list();
776
+ }
777
+ });
778
+ }
779
+ /**
780
+ * Execute an epsilon.
781
+ *
782
+ * @param fileName name of epsilon file.
783
+ * @param requestOptions object
784
+ * @param offlineOptions object of type OfflineOptions (optional)
785
+ *
786
+ */
787
+ execute(fileName, requestOptions, offlineOptions) {
788
+ var _a;
789
+ return __awaiter(this, void 0, void 0, function* () {
790
+ const url = yield this.getEpsilonFileURL(fileName);
791
+ const headers = new Headers(requestOptions.headers);
792
+ const data = yield ((_a = this.view) === null || _a === void 0 ? void 0 : _a.data());
793
+ headers.append('Authorization', 'Bearer ' + data.authToken);
794
+ headers.append('Content-Type', 'application/json');
795
+ const request = {
796
+ method: 'POST',
797
+ headers: headers,
798
+ redirect: 'follow',
799
+ body: JSON.stringify(requestOptions),
800
+ };
801
+ let __offlineOptions = offlineOptions;
802
+ if (!__offlineOptions) {
803
+ __offlineOptions = {
804
+ offlineAction: requestOptions.action || 'No title',
805
+ disabled: true
806
+ };
807
+ }
808
+ const [res, err] = yield this._client.do(url, request, __offlineOptions);
809
+ if (err) {
810
+ err.setMessage(`failed to execute epsilon: ${err.message}`);
811
+ throw err;
812
+ }
813
+ return res;
814
+ });
815
+ }
816
+ getEpsilonFileURL(fileName) {
817
+ var _a, _b;
818
+ return __awaiter(this, void 0, void 0, function* () {
819
+ if (!this.folders || ((_a = this.folders) === null || _a === void 0 ? void 0 : _a.length) === 0)
820
+ yield this.setDefaults();
821
+ const virtualFile = (_b = this.folders) === null || _b === void 0 ? void 0 : _b.filter((result) => {
822
+ return result.Name === fileName;
823
+ });
824
+ if (virtualFile && virtualFile[0])
825
+ return (environment.host +
826
+ '/api/v1/views/' +
827
+ virtualFile[0].TemplateBagId +
828
+ '/files/' +
829
+ virtualFile[0].FileQid);
830
+ return '';
831
+ });
832
+ }
833
+ }
834
+
835
+ class TwintagBase {
836
+ constructor(qid) {
837
+ this._useCaching = false;
838
+ this._qid = qid;
839
+ }
840
+ /**
841
+ * set caching host
842
+ * @param val
843
+ * @hidden
844
+ */
845
+ useCaching(val) {
846
+ this._useCaching = val;
847
+ }
848
+ viewURL() {
849
+ return environment.host + '/api/v1/views/' + this._qid;
850
+ }
851
+ twintagURL() {
852
+ return environment.host + '/api/v1/twintags/' + this._data.bagQid;
853
+ }
854
+ setconfig(init) {
855
+ this._client = init.client;
856
+ this._data = init.data;
857
+ this._project = init.project;
858
+ }
859
+ client() {
860
+ return __awaiter(this, void 0, void 0, function* () {
861
+ if (!this._client) {
862
+ this._client = new Client();
863
+ }
864
+ if (!this._client.token) {
865
+ const data = yield this.data();
866
+ this.setToken(data.authToken);
867
+ }
868
+ return this._client;
869
+ });
870
+ }
871
+ /**
872
+ * Set the token used for authorization. This can be used to authorize
873
+ * requests by the project API key rather than the view QID. However,
874
+ * It is recommended use the {@link Project} object instead.
875
+ */
876
+ setToken(token) {
877
+ if (!this._client) {
878
+ this._client = new Client();
879
+ }
880
+ this._client.token = token;
881
+ }
882
+ /**
883
+ * Data gets the view definition. This includes the view rights.
884
+ */
885
+ data() {
886
+ return __awaiter(this, void 0, void 0, function* () {
887
+ const data = this._data;
888
+ if (data) {
889
+ return data;
890
+ }
891
+ let client = this._client;
892
+ if (!client) {
893
+ client = new Client();
894
+ this._client = client;
895
+ }
896
+ const [newData, err] = yield client.get(environment.host + '/api/v1/views/' + this._qid);
897
+ if (err) {
898
+ err.setMessage(`failed to get twintag data`);
899
+ throw err;
900
+ }
901
+ this._data = newData;
902
+ return this._data;
903
+ });
904
+ }
905
+ }
906
+
907
+ /**
908
+ * CreateBag creates a free bag without an association to an Enterprise project.
909
+ */
910
+ function createBag(qid) {
911
+ return __awaiter(this, void 0, void 0, function* () {
912
+ return createBagInternal(new Client(), undefined, qid);
913
+ });
914
+ }
915
+ /**
916
+ * CreateBagInternal is the internal createBag function.
917
+ *
918
+ * @internal */
919
+ function createBagInternal(client, project, qid) {
920
+ return __awaiter(this, void 0, void 0, function* () {
921
+ let viewReq;
922
+ if (qid && qid !== '') {
923
+ viewReq = {
924
+ id: qid,
925
+ type: 'user',
926
+ data: {
927
+ rights: ['read', 'list'],
928
+ isCanocical: 1,
929
+ },
930
+ };
931
+ }
932
+ else {
933
+ viewReq = {
934
+ type: 'owner',
935
+ data: undefined,
936
+ };
937
+ }
938
+ const path = environment.host + '/api/v1/views';
939
+ const [data, err] = yield client.put(path, viewReq);
940
+ if (err) {
941
+ err.setMessage(`failed to create a twintag`);
942
+ throw err;
943
+ }
944
+ const view = new View(data.id);
945
+ // Pass state
946
+ view._setConfig({ project: project, client: client, data: data });
947
+ return view;
948
+ });
949
+ }
950
+ /**
951
+ * The view class allows you to interact with a view into a bag.
952
+ * A view is represented by a `qid`. This is the string you see in its url:
953
+ * `https://twintag.io/<qid>`.
954
+ * A bag can have multiple views, each view can have different rights associated.
955
+ * For example: owner, download-only, upload-only, ...
956
+ *
957
+ * To construct a view object, you pass its QID, E.g.:
958
+ * ```
959
+ * let view = new Twintag.View(viewId)
960
+ * ```
961
+ */
962
+ class View {
963
+ /**
964
+ * Construct a view by its QID.
965
+ *
966
+ * @param init Internal parameter.
967
+ */
968
+ constructor(qid) {
969
+ this._base = new TwintagBase(qid);
970
+ }
971
+ get qid() {
972
+ return this._base._qid;
973
+ }
974
+ set qid(val) {
975
+ this._base._qid = val;
976
+ }
977
+ get _client() {
978
+ return this._base._client;
979
+ }
980
+ set _client(val) {
981
+ this._base._client = val;
982
+ }
983
+ get _data() {
984
+ return this._base._data;
985
+ }
986
+ set _data(val) {
987
+ this._base._data = val;
988
+ }
989
+ get project() {
990
+ return this._base._project;
991
+ }
992
+ set project(val) {
993
+ this._base._project = val;
994
+ }
995
+ useCaching(val) {
996
+ this._base._useCaching = val;
997
+ }
998
+ /**
999
+ * _setConfig allows us to pass internal state.
1000
+ *
1001
+ * @internal */
1002
+ _setConfig(init) {
1003
+ this._base.setconfig(init);
1004
+ }
1005
+ /**
1006
+ * Set the token used for authorization. This can be used to authorize
1007
+ * requests by the project API key rather than the view QID. However,
1008
+ * It is recommended use the {@link Project} object instead.
1009
+ */
1010
+ setToken(token) {
1011
+ this._base.setToken(token);
1012
+ }
1013
+ fileURL(obj, qid, op, useCachingHost = false) {
1014
+ let url = (useCachingHost && this._base._useCaching ? environment.cachingHost : environment.host) + '/api/v1/views/' + this._base._qid + '/' + obj;
1015
+ if (qid) {
1016
+ url += '/' + qid;
1017
+ }
1018
+ if (op) {
1019
+ url += '/' + op;
1020
+ }
1021
+ return url;
1022
+ }
1023
+ fileURLUpload(obj, qid, op) {
1024
+ return __awaiter(this, void 0, void 0, function* () {
1025
+ const data = yield this._base.data();
1026
+ let url = this.fileURL(obj, qid, op);
1027
+ if (data.uploadsession) {
1028
+ url += '?uploadsession=' + data.uploadsession;
1029
+ }
1030
+ return url;
1031
+ });
1032
+ }
1033
+ /**
1034
+ * Data gets the view definition. This includes the view rights.
1035
+ */
1036
+ data() {
1037
+ return __awaiter(this, void 0, void 0, function* () {
1038
+ return yield this._base.data();
1039
+ });
1040
+ }
1041
+ /**
1042
+ * Upload allows you to upload a file into a bag.
1043
+ *
1044
+ * Required rights: upload.
1045
+ *
1046
+ * @param name Optionally overwrite the file name.
1047
+ * @param parent: parent of the file. FileQid of the folder
1048
+ *
1049
+ * @category File management
1050
+ */
1051
+ upload(f, name, parent) {
1052
+ return __awaiter(this, void 0, void 0, function* () {
1053
+ // Start
1054
+ const uploadStartReq = {
1055
+ mode: 420,
1056
+ name: name ? name : f.name,
1057
+ size: f.size,
1058
+ parent: parent ? parent : null
1059
+ };
1060
+ let url = yield this.fileURLUpload('files');
1061
+ const client = yield this._base.client();
1062
+ const [startResp, startErr] = yield client.put(url, uploadStartReq);
1063
+ if (startErr) {
1064
+ startErr.setMessage(`failed to start upload file to twintag`);
1065
+ throw startErr;
1066
+ }
1067
+ // Upload
1068
+ const [, uploadErr] = yield client.do(startResp.uploadUrl, { method: 'PUT', body: f }, explicitDisableOffline, true, true);
1069
+ if (uploadErr) {
1070
+ uploadErr.setMessage(`failed to upload file to twintag`);
1071
+ throw uploadErr;
1072
+ }
1073
+ // End
1074
+ url = yield this.fileURLUpload('files', startResp.metafest.fileQid, 'end');
1075
+ const [, endErr] = yield client.do(url, { method: 'PUT', body: '{}' }, explicitDisableOffline, true);
1076
+ if (endErr) {
1077
+ endErr.setMessage(`failed to complete the file upload to twintag`);
1078
+ throw endErr;
1079
+ }
1080
+ const fileInfo = {
1081
+ FileQid: startResp.metafest.fileQid,
1082
+ Name: startResp.metafest.fileName,
1083
+ Parent: undefined,
1084
+ Size: startResp.metafest.size,
1085
+ MTime: startResp.metafest.modTime,
1086
+ FileMode: startResp.metafest.fileMode.toString(),
1087
+ };
1088
+ return fileInfo;
1089
+ });
1090
+ }
1091
+ /**
1092
+ * Upload a {@VirtualFile | virtual file} into a bag.
1093
+ *
1094
+ * Required rights: owner.
1095
+ *
1096
+ * @category File management
1097
+ */
1098
+ uploadVirtual(f, name) {
1099
+ return __awaiter(this, void 0, void 0, function* () {
1100
+ const uploadReq = {
1101
+ mode: f.mode,
1102
+ name: name,
1103
+ size: 0,
1104
+ fileContent: f.GetDefinition(),
1105
+ };
1106
+ const url = yield this.fileURLUpload('virtual');
1107
+ const client = yield this._base.client();
1108
+ const [, err] = yield client.put(url, uploadReq, explicitDisableOffline, {}, true);
1109
+ if (err) {
1110
+ err.setMessage(`failed to upload virtual file to twintag`);
1111
+ throw err;
1112
+ }
1113
+ // TODO: Parse FileInfo in response
1114
+ });
1115
+ }
1116
+ /**
1117
+ * Download a file from a bag.
1118
+ *
1119
+ * Required rights: download.
1120
+ *
1121
+ * @category File management
1122
+ */
1123
+ download(name) {
1124
+ return __awaiter(this, void 0, void 0, function* () {
1125
+ // TODO: support name & fileInfo
1126
+ const url = this.fileURL('web', name);
1127
+ const client = yield this._base.client();
1128
+ const [res, err] = yield client.do(url, { method: 'get', headers: { 'Content-Type': 'application/octet-stream' } }, explicitDisableOffline, true, true);
1129
+ if (err) {
1130
+ err.setMessage(`failed to download file from twintag`);
1131
+ throw err;
1132
+ }
1133
+ return res;
1134
+ });
1135
+ }
1136
+ /**
1137
+ * Convenience method to download a JSON file from a bag and parse it.
1138
+ *
1139
+ * Required rights: download.
1140
+ *
1141
+ * @category File management
1142
+ */
1143
+ downloadJSON(name) {
1144
+ return __awaiter(this, void 0, void 0, function* () {
1145
+ // TODO: support name & fileInfo
1146
+ const url = this.fileURL('web', name);
1147
+ const client = yield this._base.client();
1148
+ const [res, err] = yield client.get(url, explicitDisableOffline, { headers: { 'Content-Type': 'application/json' } }, true);
1149
+ if (err) {
1150
+ err.setMessage(`failed to downlaod JSON file from twintag`);
1151
+ throw err;
1152
+ }
1153
+ return res;
1154
+ });
1155
+ }
1156
+ /**
1157
+ * Rename a file from a bag.
1158
+ *
1159
+ * Required rights: upload & download.
1160
+ *
1161
+ * @category File management
1162
+ */
1163
+ rename(source, name) {
1164
+ return __awaiter(this, void 0, void 0, function* () {
1165
+ return yield this.doMove(source, name, undefined, undefined, false);
1166
+ });
1167
+ }
1168
+ /**
1169
+ * Move a file.
1170
+ *
1171
+ * Required rights: upload & download, plus owner rights when specifying a bag.
1172
+ *
1173
+ * @category File management
1174
+ */
1175
+ move(source, name, parent, view) {
1176
+ return __awaiter(this, void 0, void 0, function* () {
1177
+ return yield this.doMove(source, name, parent, view, false);
1178
+ });
1179
+ }
1180
+ /**
1181
+ * Copy a file.
1182
+ *
1183
+ * Required rights: upload & download, plus owner rights when specifying a bag.
1184
+ *
1185
+ * @category File management
1186
+ */
1187
+ copy(source, name, parent, view) {
1188
+ return __awaiter(this, void 0, void 0, function* () {
1189
+ return yield this.doMove(source, name, parent, view, true);
1190
+ });
1191
+ }
1192
+ doMove(source, name, parent, view, copy) {
1193
+ return __awaiter(this, void 0, void 0, function* () {
1194
+ // TODO: implementation
1195
+ if (parent === undefined)
1196
+ parent = '';
1197
+ if (view === undefined)
1198
+ view = '';
1199
+ if (name === undefined)
1200
+ name = '';
1201
+ if (copy === undefined)
1202
+ copy = false;
1203
+ const url = this.fileURL('files/' + source.FileQid + '/move');
1204
+ const fileMoveRequest = {
1205
+ fileQid: source.FileQid,
1206
+ targetBag: view,
1207
+ targetFolder: parent,
1208
+ targetName: name,
1209
+ isCopy: copy,
1210
+ };
1211
+ const client = yield this._base.client();
1212
+ const [resp, err] = yield client.put(url, fileMoveRequest);
1213
+ if (err) {
1214
+ err.setMessage(`failed to move file in twintag`);
1215
+ throw err;
1216
+ }
1217
+ return resp;
1218
+ });
1219
+ }
1220
+ /**
1221
+ * Delete a file from a bag.
1222
+ *
1223
+ * Required rights: delete.
1224
+ *
1225
+ * @category File management
1226
+ */
1227
+ delete(file) {
1228
+ return __awaiter(this, void 0, void 0, function* () {
1229
+ // TODO: support filename; filename[], FileInfo & fileInfo[]
1230
+ const url = this.fileURL('files');
1231
+ const client = yield this._base.client();
1232
+ const [, err] = yield client.delete(url, [file.FileQid.toString()]);
1233
+ if (err) {
1234
+ err.setMessage(`failed to delete file from twintag`);
1235
+ throw err;
1236
+ }
1237
+ });
1238
+ }
1239
+ /**
1240
+ * Delete an entire bag.
1241
+ *
1242
+ * Required rights: owner.
1243
+ */
1244
+ deleteBag() {
1245
+ return __awaiter(this, void 0, void 0, function* () {
1246
+ const url = this._base.viewURL();
1247
+ const client = yield this._base.client();
1248
+ const [, err] = yield client.delete(url);
1249
+ if (err) {
1250
+ err.setMessage(`failed to delete twintag`);
1251
+ throw err;
1252
+ }
1253
+ });
1254
+ }
1255
+ /**
1256
+ * Get a view with limited rights.
1257
+ *
1258
+ * Required rights: owner.
1259
+ */
1260
+ getUserView(rights) {
1261
+ return __awaiter(this, void 0, void 0, function* () {
1262
+ const url = environment.host + '/api/v1/views';
1263
+ if (!this._base._data) {
1264
+ yield this._base.data();
1265
+ }
1266
+ const viewReq = {
1267
+ id: undefined,
1268
+ type: 'user',
1269
+ data: {
1270
+ ownerId: this._base._qid,
1271
+ rights: rights,
1272
+ isCanocical: 1,
1273
+ },
1274
+ bagStorageQid: this._base._data.bagQid
1275
+ };
1276
+ const client = yield this._base.client();
1277
+ const [data, err] = yield client.put(url, viewReq);
1278
+ if (err) {
1279
+ err.setMessage(`failed to get view information`);
1280
+ throw err;
1281
+ }
1282
+ const userView = new View(data.id);
1283
+ // Pass state
1284
+ userView._setConfig({ project: this._base._project, data: data });
1285
+ return userView;
1286
+ });
1287
+ }
1288
+ /**
1289
+ * List the files in the bag or a sub-folder.
1290
+ *
1291
+ * Required rights: list.
1292
+ *
1293
+ * @category File management
1294
+ */
1295
+ list(folder) {
1296
+ return __awaiter(this, void 0, void 0, function* () {
1297
+ // TODO: support path
1298
+ const url = this.fileURL('folders', folder);
1299
+ const client = yield this._base.client();
1300
+ const [res, err] = yield client.get(url);
1301
+ if (err) {
1302
+ err.setMessage(`failed to get list of files from twintag`);
1303
+ throw err;
1304
+ }
1305
+ return res;
1306
+ });
1307
+ }
1308
+ /**
1309
+ * This method creates a folder for a twintag.
1310
+ * @param folderName
1311
+ * @param folderParent
1312
+ * @returns
1313
+ */
1314
+ addFolder(folderName, folderParent) {
1315
+ return __awaiter(this, void 0, void 0, function* () {
1316
+ if (folderName.trim().length === 0) {
1317
+ throw new Error("Invalid folder name.");
1318
+ }
1319
+ const url = this.fileURL('folders');
1320
+ const body = {
1321
+ name: folderName,
1322
+ parent: folderParent ? folderParent : null
1323
+ };
1324
+ const client = yield this._base.client();
1325
+ const [res, err] = yield client.put(url, body);
1326
+ if (err) {
1327
+ err.setMessage(`failed to create folder: ${err.message}`);
1328
+ throw err;
1329
+ }
1330
+ return res;
1331
+ });
1332
+ }
1333
+ /**
1334
+ * Seal the bag.
1335
+ *
1336
+ * Required rights: list.
1337
+ *
1338
+ * @hidden
1339
+ */
1340
+ seal() {
1341
+ return __awaiter(this, void 0, void 0, function* () {
1342
+ const url = this.fileURL('seal');
1343
+ const client = yield this._base.client();
1344
+ const [, err] = yield client.put(url, {});
1345
+ if (err) {
1346
+ err.setMessage(`failed to seal`);
1347
+ throw err;
1348
+ }
1349
+ });
1350
+ }
1351
+ /**
1352
+ * Get the bag metadata of this specific bag. The metadata is returned as an object.
1353
+ *
1354
+ * Required rights: download.
1355
+ *
1356
+ * @param lang: optional language value. Allowed inputs are "all" or any language defined in project languages. If no value is passed, then project's default language will be used for returning data
1357
+ * @category Metadata
1358
+ */
1359
+ getMetadata(lang) {
1360
+ return __awaiter(this, void 0, void 0, function* () {
1361
+ let url = this.fileURL('data/metadata', undefined, undefined, true);
1362
+ url += lang ? `?language=${(lang === 'all' ? '*' : lang)}` : '';
1363
+ const client = yield this._base.client();
1364
+ const [res, err] = yield client.get(url);
1365
+ if (err) {
1366
+ err.setMessage(`failed to get metadata of twintag`);
1367
+ throw err;
1368
+ }
1369
+ return Parser.parseSpecialTypes(res);
1370
+ });
1371
+ }
1372
+ /**
1373
+ * Set the bag metadata of this specific bag. Returns a full view of the resulting metadata.
1374
+ *
1375
+ * Required rights: owner.
1376
+ *
1377
+ * @param data An object representing the metadata.
1378
+ *
1379
+ * @category Metadata
1380
+ */
1381
+ setMetadata(data) {
1382
+ return __awaiter(this, void 0, void 0, function* () {
1383
+ const url = this.fileURL('data/metadata');
1384
+ const client = yield this._base.client();
1385
+ const [res, err] = yield client.put(url, data, explicitDisableOffline, { headers: { 'Content-Type': 'application/json' } });
1386
+ if (err) {
1387
+ err.setMessage(`failed to set metadata to twintag`);
1388
+ throw err;
1389
+ }
1390
+ return res;
1391
+ });
1392
+ }
1393
+ /**
1394
+ * Get the bag data of a specific bag and object. The data is returned as an object.
1395
+ *
1396
+ * Required rights: download.
1397
+ *
1398
+ * @param objectAPIName The apiName of the object for which the data is being requested
1399
+ *
1400
+ * @param attribute Optional parameter to specify the attribute for which the data is required
1401
+ *
1402
+ * @category Structured Data
1403
+ */
1404
+ getData(objectAPIName, attribute) {
1405
+ return __awaiter(this, void 0, void 0, function* () {
1406
+ let url = this.fileURL('data/' + objectAPIName, undefined, undefined, true);
1407
+ if (attribute && attribute !== '') {
1408
+ url = url + '?property=' + attribute;
1409
+ }
1410
+ const client = yield this._base.client();
1411
+ const [res, err] = yield client.get(url);
1412
+ if (err) {
1413
+ err.setMessage(`failed to get data to twintag object: ${objectAPIName}`);
1414
+ throw err;
1415
+ }
1416
+ return Parser.parseSpecialTypes(res);
1417
+ });
1418
+ }
1419
+ /**
1420
+ * Set the bag data of this specific bag and object. Returns a full view of the resulting data.
1421
+ *
1422
+ * Required rights: owner.
1423
+ *
1424
+ * @param data An object representing the data.
1425
+ * @param objectApiName APIName of the object for which the data is being set.
1426
+ *
1427
+ * @category Structured Data
1428
+ */
1429
+ setData(objectApiName, data) {
1430
+ return __awaiter(this, void 0, void 0, function* () {
1431
+ const url = this.fileURL('data/' + objectApiName);
1432
+ const client = yield this._base.client();
1433
+ const [res, err] = yield client.put(url, data, explicitDisableOffline, { headers: { 'Content-Type': 'application/json' } });
1434
+ if (err) {
1435
+ err.setMessage(`failed to set data to twintag object: ${objectApiName}`);
1436
+ throw err;
1437
+ }
1438
+ return res;
1439
+ });
1440
+ }
1441
+ /**
1442
+ * Get an object for the view
1443
+ *
1444
+ * Required rights: owner.
1445
+ *
1446
+ * @param objectApiName APIName of the object
1447
+ *
1448
+ * @category Structured Data
1449
+ */
1450
+ object(objectApiName) {
1451
+ return __awaiter(this, void 0, void 0, function* () {
1452
+ const client = yield this._base.client();
1453
+ const data = yield this._base.data();
1454
+ if (!data.data.project || !data.data.project.projectId || data.data.project.projectId === '') {
1455
+ throw new Error(`view not tagged to any project`);
1456
+ }
1457
+ return new ListObject(objectApiName, client, data.id, '', this._base._useCaching);
1458
+ });
1459
+ }
1460
+ /**
1461
+ * Sends notification to the registered users of the view.
1462
+ *
1463
+ * Required rights: owner.
1464
+ *
1465
+ * @param message message to be sent as a notification.
1466
+ * @param channel optional, if not specified then default channel is 'email'
1467
+ *
1468
+ * Example:
1469
+ * ```js
1470
+ * await viewObj.notify(`This is a custom email body.`)
1471
+ * ```
1472
+ *
1473
+ * You can further customize email body by passing {@link NotificationRequest}:
1474
+ * ```js
1475
+ * await viewObj.notify({
1476
+ * message: "custom user message"
1477
+ * subject: "custom email subject"
1478
+ * bagAlias: "Custom alias for bag"
1479
+ * showBagReport: true
1480
+ * language: "en-GB"
1481
+ * })
1482
+ * ```
1483
+ * You can provide any ISO 15897 locale for language attribute.
1484
+ * Currently supported values: en_GB, nl_BE, fr_BE
1485
+ * @category Notification
1486
+ */
1487
+ notify(request, channel) {
1488
+ return __awaiter(this, void 0, void 0, function* () {
1489
+ const client = yield this._base.client();
1490
+ let body;
1491
+ if (typeof request === 'string') {
1492
+ body = {
1493
+ message: request,
1494
+ };
1495
+ }
1496
+ else {
1497
+ body = request;
1498
+ }
1499
+ channel = channel ? channel : 'email';
1500
+ const url = this._base.viewURL() + '/notification?type=' + channel;
1501
+ const [res, err] = yield client.post(url, body, { headers: { 'Content-Type': 'application/json' } });
1502
+ if (err) {
1503
+ err.setMessage('failed to notify to all subcribers of twintag');
1504
+ throw err;
1505
+ }
1506
+ return res;
1507
+ });
1508
+ }
1509
+ /**
1510
+ * Sends email to the registered users of the view.
1511
+ *
1512
+ * @param request message to be sent.
1513
+ *
1514
+ * Example:
1515
+ * ```js
1516
+ * await viewObj.sendFeedback({content: 'This is test content'})
1517
+ * ```
1518
+ *
1519
+ * You can further customize email body by passing {@link FeedbackRequest}:
1520
+ * ```js
1521
+ * await viewObj.sendFeedback({
1522
+ * content: 'This is test content',
1523
+ * subject: "custom email subject",
1524
+ * email: 'email';
1525
+ * })
1526
+ * ```
1527
+ * @category Notification
1528
+ */
1529
+ sendFeedback(request) {
1530
+ return __awaiter(this, void 0, void 0, function* () {
1531
+ const client = yield this._base.client();
1532
+ let body;
1533
+ if (typeof request === 'string') {
1534
+ body = {
1535
+ content: request,
1536
+ };
1537
+ }
1538
+ else {
1539
+ body = request;
1540
+ }
1541
+ const url = this._base.viewURL() + '/feedback';
1542
+ const [res, err] = yield client.put(url, body, explicitDisableOffline, { headers: { 'Content-Type': 'application/json' } });
1543
+ if (err) {
1544
+ err.setMessage(`failed to submit feedback`);
1545
+ throw err;
1546
+ }
1547
+ return res;
1548
+ });
1549
+ }
1550
+ /**
1551
+ * Sends email
1552
+ *
1553
+ * Required rights: Any.
1554
+ *
1555
+ * @param request EmailRequest object
1556
+ *
1557
+ * Example:
1558
+ *
1559
+ * You can call this method by passing {@link EmailRequest}:
1560
+ * ```js
1561
+ * await viewObj.sendToSubscribers({
1562
+ * recepients: ["to@mail.com"]
1563
+ * body: "email body"
1564
+ * subject: "email subject"
1565
+ * cc: ["cc@mail.com"]
1566
+ * bcc: ["bcc@mail.com"]
1567
+ * })
1568
+ * ```
1569
+ * @category Notifications
1570
+ */
1571
+ sendToSubscribers(request) {
1572
+ return __awaiter(this, void 0, void 0, function* () {
1573
+ const client = yield this._base.client();
1574
+ yield this._base.data();
1575
+ const url = this._base.viewURL() + `/notification?type=customEmail`;
1576
+ const [res, err] = yield client.post(url, request, { headers: { 'Content-Type': 'application/json' } });
1577
+ if (err) {
1578
+ err.setMessage('failed to notify to all subcribers of twintag through custom email');
1579
+ throw err;
1580
+ }
1581
+ return res;
1582
+ });
1583
+ }
1584
+ /**
1585
+ * Execute an epsilon.
1586
+ *
1587
+ * Required rights: any.
1588
+ *
1589
+ * @param filename name of epsilon file.
1590
+ * @param requestOptions object
1591
+ * @param action (optional) title/name of request for offline support
1592
+ *
1593
+ * @category Structured Data
1594
+ */
1595
+ executeEpsilon(filename, requestOptions, offlineOptions) {
1596
+ return __awaiter(this, void 0, void 0, function* () {
1597
+ if (!this._epsilon) {
1598
+ const client = yield this._base.client();
1599
+ const data = yield this.data();
1600
+ if (!data.data.project || !data.data.project.projectId || data.data.project.projectId === '') {
1601
+ throw new Error(`view not tagged to any project`);
1602
+ }
1603
+ this._epsilon = new Epsilon(data.id, client);
1604
+ }
1605
+ return yield this._epsilon.execute(filename, requestOptions, offlineOptions);
1606
+ });
1607
+ }
1608
+ }
1609
+
1610
+ /**
1611
+ * StructuredObject class represents an object of a project.
1612
+ * Operations like creating attributes, getting attributes can be informed.
1613
+ */
1614
+ class StructuredObject {
1615
+ /**
1616
+ * Create an object of StructuredObject
1617
+ *
1618
+ * @param apiKey You'll find the API Key on the Twintag project page.
1619
+ */
1620
+ constructor(apiKey, useCaching = false) {
1621
+ this.name = '';
1622
+ this.apiName = '';
1623
+ this.isList = false;
1624
+ this.isGlobal = false;
1625
+ this._useCaching = false;
1626
+ this.client = new Client(apiKey);
1627
+ this._useCaching = useCaching;
1628
+ }
1629
+ /**
1630
+ * Get the attributes of the object of the project. Returns the list of attributes.
1631
+ */
1632
+ getAttributes() {
1633
+ return __awaiter(this, void 0, void 0, function* () {
1634
+ const url = this.getURL(`/property?object=${this.apiName}&`, this.$schemaScope);
1635
+ const [res, err] = yield this.client.get(url);
1636
+ if (err) {
1637
+ err.setMessage(`failed to get attributes: ${err.message}`);
1638
+ throw err;
1639
+ }
1640
+ return res;
1641
+ });
1642
+ }
1643
+ /**
1644
+ * Get a specific attribute by name
1645
+ *
1646
+ * @param attributeName Name of the attribute
1647
+ */
1648
+ getAttribute(attributeName) {
1649
+ return __awaiter(this, void 0, void 0, function* () {
1650
+ const url = this.getURL(`/property?object=${this.apiName}&property=${attributeName}&`, this.$schemaScope);
1651
+ const [res, err] = yield this.client.get(url);
1652
+ if (err) {
1653
+ err.setMessage(`failed to get attribute for ${attributeName}: ${err.message}`);
1654
+ throw err;
1655
+ }
1656
+ return res;
1657
+ });
1658
+ }
1659
+ /**
1660
+ * Create a new attribute for the object of a project
1661
+ *
1662
+ * @param attributeName Name of the attribute
1663
+ * @param type Type of the attribute. Use the {@link AttributeType | AttributeType} enum or "string" for string type, "number" for number type and "datetime" for a datetime type, "richtext" for rich text type, "file" for file type, "boolean" for boolean type
1664
+ * @param positionBefore The apiName of the property before which the newly created property is placed
1665
+ */
1666
+ newAttribute(attributeName, type, positionBefore) {
1667
+ return __awaiter(this, void 0, void 0, function* () {
1668
+ const url = environment.adminHost + '/api/v1/property';
1669
+ const reqProperty = {
1670
+ $object: this.apiName,
1671
+ name: attributeName,
1672
+ type: this.getTypeByName(type),
1673
+ nextProperty: positionBefore,
1674
+ };
1675
+ const [res, err] = yield this.client.put(url, reqProperty);
1676
+ if (err) {
1677
+ err.setMessage(`failed to create new attribute: ${err.message}`);
1678
+ throw err;
1679
+ }
1680
+ return res;
1681
+ });
1682
+ }
1683
+ /**
1684
+ * Delete a attribute for the object of a project
1685
+ *
1686
+ * @param attributeName Name of the attribute
1687
+ */
1688
+ deleteAttribute(attributeName) {
1689
+ return __awaiter(this, void 0, void 0, function* () {
1690
+ const url = environment.adminHost + '/api/v1/property';
1691
+ const reqProperty = {
1692
+ $object: this.apiName,
1693
+ name: attributeName,
1694
+ };
1695
+ const [, err] = yield this.client.delete(url, reqProperty);
1696
+ if (err) {
1697
+ err.setMessage(`failed to delete attribute: ${attributeName}: ${err.message}`);
1698
+ throw err;
1699
+ }
1700
+ });
1701
+ }
1702
+ /**
1703
+ * Update an attribute for an object of a project
1704
+ *
1705
+ * @param property The desired state of the attribute. $qid is required in the object
1706
+ *
1707
+ */
1708
+ updateAttribute(property) {
1709
+ return __awaiter(this, void 0, void 0, function* () {
1710
+ const url = environment.adminHost + '/api/v1/property';
1711
+ if (!property.$qid) {
1712
+ throw new Error(`$qid is not provided in the request object`);
1713
+ }
1714
+ const reqProperty = {
1715
+ $object: this.apiName,
1716
+ $qid: property.$qid,
1717
+ name: property.name,
1718
+ nextProperty: property.nextProperty,
1719
+ apiName: property.apiName,
1720
+ };
1721
+ const [res, err] = yield this.client.put(url, reqProperty);
1722
+ if (err) {
1723
+ err.setMessage(`failed to update attribute: ${property.name}: ${err.message}`);
1724
+ throw err;
1725
+ }
1726
+ return res;
1727
+ });
1728
+ }
1729
+ /**
1730
+ * Rename the object
1731
+ * @param newName
1732
+ */
1733
+ rename(newName) {
1734
+ return __awaiter(this, void 0, void 0, function* () {
1735
+ const url = environment.adminHost + '/api/v1/object';
1736
+ const reqobject = {
1737
+ $qid: this.$qid,
1738
+ name: newName,
1739
+ };
1740
+ const [resp, err] = yield this.client.put(url, reqobject);
1741
+ if (err) {
1742
+ err.setMessage(`failed to rename structured object: ${err.message}`);
1743
+ throw err;
1744
+ }
1745
+ return resp;
1746
+ });
1747
+ }
1748
+ /**
1749
+ * Update the key property of the object.
1750
+ * If a attribute by the given name already exists, the attribute will be marked as key attribute.
1751
+ * If the attribute by the given name doesnot exists, a new attribute will be created and marked as key attribute.
1752
+ * If instances for the object already exist, key property for the object cannot be updated.
1753
+ * @param attributeName
1754
+ */
1755
+ updateKeyAttribute(attributeName) {
1756
+ return __awaiter(this, void 0, void 0, function* () {
1757
+ const url = environment.adminHost + '/api/v1/object';
1758
+ const reqobject = {
1759
+ $qid: this.$qid,
1760
+ keyProperty: attributeName,
1761
+ };
1762
+ const [resp, err] = yield this.client.put(url, reqobject);
1763
+ if (err) {
1764
+ err.setMessage(`failed to update key property of object: ${err.message}`);
1765
+ throw err;
1766
+ }
1767
+ return resp;
1768
+ });
1769
+ }
1770
+ /**
1771
+ * Update the access of the object.
1772
+ */
1773
+ updateAccess(access) {
1774
+ return __awaiter(this, void 0, void 0, function* () {
1775
+ const url = environment.adminHost + '/api/v1/object';
1776
+ const reqobject = {
1777
+ $qid: this.$qid,
1778
+ access: access,
1779
+ };
1780
+ const [resp, err] = yield this.client.put(url, reqobject);
1781
+ if (err) {
1782
+ err.setMessage(`failed to update access of object: ${err.message}`);
1783
+ throw err;
1784
+ }
1785
+ return resp;
1786
+ });
1787
+ }
1788
+ /**
1789
+ * Add translation column for an existing structured data object column
1790
+ * @param langAttributes: indexed type. pass key value pair for language and corresponding column name (see example below)
1791
+ * @param parent: api name of column for which translation column is being created
1792
+ * Example
1793
+ * ```js
1794
+ * //first create column for which translation has to be added
1795
+ * const col = await object.newAttribute('col name')
1796
+ *
1797
+ * let langAttr = {
1798
+ * 'fr':'french column name',
1799
+ * 'nl':'dutch column name'
1800
+ * }
1801
+ *
1802
+ * const res = await object.addTranslationAttribute(langAttr, col.apiName)
1803
+ * ```
1804
+ * This will create 2 language columns, each for french and dutch language.
1805
+ * @returns Promise<Attribute[]>
1806
+ */
1807
+ addTranslationAttribute(langAttributes, parent) {
1808
+ return __awaiter(this, void 0, void 0, function* () {
1809
+ const resAttributes = [];
1810
+ if (langAttributes == null) {
1811
+ return null;
1812
+ }
1813
+ for (const [language, columnName] of Object.entries(langAttributes)) {
1814
+ const reqBody = {
1815
+ $object: this.apiName,
1816
+ $schemaScope: this.$schemaScope,
1817
+ name: columnName,
1818
+ parent: parent,
1819
+ language: language,
1820
+ type: this.getTypeByName('string'),
1821
+ };
1822
+ const url = environment.adminHost + '/api/v1/property';
1823
+ const [resp, err] = yield this.client.put(url, reqBody);
1824
+ if (err) {
1825
+ err.setMessage(`failed to add translation attribute ${columnName}: ${err.message}`);
1826
+ }
1827
+ if (resp) {
1828
+ resAttributes.push(resp);
1829
+ }
1830
+ }
1831
+ return resAttributes;
1832
+ });
1833
+ }
1834
+ getTypeByName(type) {
1835
+ switch (type === null || type === void 0 ? void 0 : type.toLowerCase()) {
1836
+ case 'number':
1837
+ return 2;
1838
+ case 'datetime':
1839
+ return 3;
1840
+ case 'richtext':
1841
+ return 4;
1842
+ case 'file':
1843
+ return 5;
1844
+ case 'boolean':
1845
+ return 6;
1846
+ default:
1847
+ return 1;
1848
+ }
1849
+ }
1850
+ /**
1851
+ * Get URL
1852
+ * @internal
1853
+ */
1854
+ getURL(url, schemaScope) {
1855
+ if (this._useCaching) {
1856
+ return environment.cachingHost + url + `schemaScope=${schemaScope}`;
1857
+ }
1858
+ return environment.adminHost + '/api/v1' + url;
1859
+ }
1860
+ }
1861
+ /**
1862
+ * Types of attributes
1863
+ */
1864
+ var AttributeType;
1865
+ (function (AttributeType) {
1866
+ AttributeType["String"] = "string";
1867
+ AttributeType["Number"] = "number";
1868
+ AttributeType["Datetime"] = "datetime";
1869
+ AttributeType["Richtext"] = "richtext";
1870
+ AttributeType["File"] = "file";
1871
+ AttributeType["Boolean"] = "boolean";
1872
+ })(AttributeType || (AttributeType = {}));
1873
+
1874
+ /**
1875
+ * The twintag class allows you to interact with a view into a twintag.
1876
+ * A view is represented by a `qid`. This is the string you see in its url:
1877
+ * `https://twintag.io/<qid>`.
1878
+ * A twintag can have multiple views, each view can have different rights associated.
1879
+ * For example: owner, download-only, upload-only, ...
1880
+ *
1881
+ * To construct a twintag object, you pass its QID, E.g.:
1882
+ * ```
1883
+ * let twintag = new Zaza.Twintag(viewId)
1884
+ * ```
1885
+ */
1886
+ class Twintag {
1887
+ /**
1888
+ * Construct a view by its QID.
1889
+ *
1890
+ * @param init Internal parameter.
1891
+ */
1892
+ constructor(qid) {
1893
+ this._base = new TwintagBase(qid);
1894
+ }
1895
+ /**
1896
+ * _setConfig allows us to pass internal state.
1897
+ *
1898
+ * @internal */
1899
+ _setConfig(init) {
1900
+ this._base.setconfig(init);
1901
+ }
1902
+ /**
1903
+ * Delete a project twintag along with its metadata (if any)
1904
+ * This view instance should be generated with project.
1905
+ *
1906
+ * Example:
1907
+ * ```js
1908
+ * const vi = project.getView('viewid')
1909
+ * await vi.deleteProjectTwintag()
1910
+ * ```
1911
+ */
1912
+ deleteProjectTwintag() {
1913
+ return __awaiter(this, void 0, void 0, function* () {
1914
+ if (!this._base._data) {
1915
+ yield this._base.data();
1916
+ }
1917
+ const url = this._base.twintagURL();
1918
+ const [, err] = yield this._base._client.delete(url);
1919
+ if (err) {
1920
+ err.setMessage(`failed to delete project twintag`);
1921
+ throw err;
1922
+ }
1923
+ });
1924
+ }
1925
+ }
1926
+
1927
+ /**
1928
+ * The project class allows you to interact with a Twintag project.
1929
+ *
1930
+ * To construct a project object you pass the API key you find
1931
+ * on the Twintag project page. E.g.:
1932
+ * ```
1933
+ * let project = new Twintag.Project('<Project API key>')
1934
+ * ```
1935
+ */
1936
+ class Project {
1937
+ /**
1938
+ * Create a project
1939
+ *
1940
+ * @param apiKey You'll find the API Key on the Twintag project page.
1941
+ */
1942
+ constructor(apiKey) {
1943
+ this.projectId = '';
1944
+ this._useCaching = false;
1945
+ this.apiKey = apiKey;
1946
+ this.client = new Client(apiKey);
1947
+ }
1948
+ /**
1949
+ * set caching host
1950
+ * @param val
1951
+ * @hidden
1952
+ */
1953
+ useCaching(val) {
1954
+ this._useCaching = val;
1955
+ this.getProjectId();
1956
+ }
1957
+ /**
1958
+ * Create a bag, automatically linked to the project.
1959
+ */
1960
+ createBag() {
1961
+ return __awaiter(this, void 0, void 0, function* () {
1962
+ return yield createBagInternal(this.client, this);
1963
+ });
1964
+ }
1965
+ /**
1966
+ * Create a {@link View | view } object with project-level privileges.
1967
+ * Your project API key is automatically used for all changes.
1968
+ */
1969
+ getView(qid) {
1970
+ const view = new View(qid);
1971
+ // Pass state
1972
+ view._setConfig({ project: this, client: this.client });
1973
+ return view;
1974
+ }
1975
+ /**
1976
+ * Create a {@link Twintag | twintag } object with project-level privileges.
1977
+ * Your project API key is automatically used for all changes.
1978
+ */
1979
+ getTwintag(qid) {
1980
+ const twintag = new Twintag(qid);
1981
+ twintag._setConfig({ project: this, client: this.client });
1982
+ return twintag;
1983
+ }
1984
+ /**
1985
+ * List the metadata of a all twintags within your project.
1986
+ * @param lang: optional language value. Allowed inputs are "all" or any language defined in project languages. If no value is passed, then project's default language will be used for returning data
1987
+ * @typeParam T The objects in the resulting array will be cast to this type.
1988
+ */
1989
+ getMetadata(lang) {
1990
+ return __awaiter(this, void 0, void 0, function* () {
1991
+ const langParam = lang ? `language=${(lang === 'all' ? '*' : lang)}` : '';
1992
+ const url = this.getURL('/data/metadata?withSDFileURL=false', false, langParam);
1993
+ const [res, err] = yield this.client.get(url);
1994
+ if (err) {
1995
+ err.setMessage('failed to get metadata');
1996
+ throw err;
1997
+ }
1998
+ return res;
1999
+ });
2000
+ }
2001
+ /**
2002
+ * Create an object for the project. Returns a StructuredObject object on which various operations can be performed.
2003
+ *
2004
+ * @param objectName Name with which the object is to be created
2005
+ * @param objectAPIName APIName with which the object is to be created
2006
+ * @param isList Optional paramaeter to specify if the object is of list type. By default false is set as the value for this param.
2007
+ * @param isGlobal Optional parameter to specify if the object is of global type. By default false is set as the value for this param.
2008
+ * @param keyProperty Optional parameter to specify the key property for the object is. By default no key property will be created.
2009
+ */
2010
+ newObject(objectName, objectAPIName = "", isList, isGlobal, keyProperty, access) {
2011
+ return __awaiter(this, void 0, void 0, function* () {
2012
+ const url = environment.adminHost + '/api/v1/object';
2013
+ const reqobject = {
2014
+ name: objectName,
2015
+ apiName: objectAPIName,
2016
+ isList: isList ? isList : false,
2017
+ isGlobal: isGlobal ? isGlobal : false,
2018
+ keyProperty: keyProperty ? keyProperty : '',
2019
+ access: access,
2020
+ };
2021
+ const [obj, err] = yield this.client.put(url, reqobject);
2022
+ if (err) {
2023
+ err.setMessage('failed to create object');
2024
+ throw err;
2025
+ }
2026
+ const object = new StructuredObject(this.apiKey, this._useCaching);
2027
+ object.$qid = obj.$qid;
2028
+ object.$schemaScope = obj.$schemaScope;
2029
+ object.isGlobal = obj.isGlobal;
2030
+ object.isList = obj.isList;
2031
+ object.keyProperty = obj.keyProperty;
2032
+ object.name = obj.name;
2033
+ object.apiName = obj.apiName;
2034
+ object.access = obj.access;
2035
+ return object;
2036
+ });
2037
+ }
2038
+ /**
2039
+ * Get an object by name. Returns a StructuredObject object on which various operations can be performed.
2040
+ *
2041
+ * @param objectAPIName APIName of the object
2042
+ */
2043
+ getObject(objectAPIName) {
2044
+ return __awaiter(this, void 0, void 0, function* () {
2045
+ const url = this.getURL(`/object?object=${objectAPIName}`, true);
2046
+ const [obj, err] = yield this.client.get(url);
2047
+ if (err) {
2048
+ err.setMessage('failed to get object');
2049
+ throw err;
2050
+ }
2051
+ const object = new StructuredObject(this.apiKey, this._useCaching);
2052
+ object.$qid = obj.$qid;
2053
+ object.$schemaScope = obj.$schemaScope;
2054
+ object.isGlobal = obj.isGlobal;
2055
+ object.isList = obj.isList;
2056
+ object.keyProperty = obj.keyProperty;
2057
+ object.name = obj.name;
2058
+ object.apiName = obj.apiName;
2059
+ return object;
2060
+ });
2061
+ }
2062
+ /**
2063
+ * Delete an object by its name
2064
+ *
2065
+ * @param objectAPIName Name of the object
2066
+ */
2067
+ deleteObject(objectAPIName) {
2068
+ return __awaiter(this, void 0, void 0, function* () {
2069
+ const url = environment.adminHost + '/api/v1/object?object=' + objectAPIName;
2070
+ const reqobject = {
2071
+ apiName: objectAPIName,
2072
+ };
2073
+ const [, err] = yield this.client.delete(url, reqobject);
2074
+ if (err) {
2075
+ err.setMessage('failed to delete object');
2076
+ throw err;
2077
+ }
2078
+ return;
2079
+ });
2080
+ }
2081
+ /**
2082
+ * Delete project twintag.
2083
+ * @param viewId view id of the twintag to be deleted.
2084
+ *
2085
+ * Example:
2086
+ * ```js
2087
+ * await project.deleteTwintag('viewid')
2088
+ * ```
2089
+ */
2090
+ deleteTwintag(viewID) {
2091
+ return __awaiter(this, void 0, void 0, function* () {
2092
+ return yield this.getTwintag(viewID).deleteProjectTwintag();
2093
+ });
2094
+ }
2095
+ /**
2096
+ * Get an object for the view
2097
+ *
2098
+ * Required rights: owner.
2099
+ *
2100
+ * @param objectAPIName Name of the object
2101
+ *
2102
+ * @category Structured Data
2103
+ */
2104
+ object(objectAPIName) {
2105
+ return new ListObject(objectAPIName, this.client, '', this.projectId, this._useCaching);
2106
+ }
2107
+ /**
2108
+ * @internal
2109
+ * Get project id for when caching is enabled
2110
+ */
2111
+ getProjectId() {
2112
+ this.projectId = '';
2113
+ let claim;
2114
+ //adding checks for various platforms that uses sdk
2115
+ if (typeof atob !== 'undefined') {
2116
+ //from epsilon pluglet
2117
+ claim = JSON.parse(atob(this.apiKey.split('.')[1]));
2118
+ }
2119
+ else if (typeof window !== 'undefined') {
2120
+ //from document (e.g. index.js)
2121
+ claim = JSON.parse(window.atob(this.apiKey.split('.')[1]));
2122
+ // @ts-ignore
2123
+ }
2124
+ else if (typeof Buffer !== 'undefined') {
2125
+ //from any nodejs application
2126
+ // @ts-ignore
2127
+ claim = JSON.parse(Buffer.from(this.apiKey.split('.')[1], 'base64').toString());
2128
+ }
2129
+ if (claim == null)
2130
+ return null;
2131
+ this.projectId = claim.ProjectId;
2132
+ return this.projectId;
2133
+ }
2134
+ /**
2135
+ * @internal
2136
+ * @param url
2137
+ */
2138
+ getURL(url, argumentPreset, langParam = '') {
2139
+ const append = argumentPreset ? `&schemaScope=${this.projectId}` : `?schemaScope=${this.projectId}`;
2140
+ if (this._useCaching) {
2141
+ langParam = langParam ? `&${langParam}` : '';
2142
+ return `${environment.cachingHost}/${url}${append}${langParam}`;
2143
+ }
2144
+ else {
2145
+ langParam = langParam ? `?${langParam}` : '';
2146
+ return `${environment.adminHost}/api/v1/${url}${langParam}`;
2147
+ }
2148
+ }
2149
+ /**
2150
+ * Get bags in a project
2151
+ */
2152
+ getBags() {
2153
+ return __awaiter(this, void 0, void 0, function* () {
2154
+ const url = environment.adminHost + '/api/v1/twintags';
2155
+ const [res, err] = yield this.client.get(url);
2156
+ if (err) {
2157
+ err.setMessage('failed to get bag details for the project');
2158
+ throw err;
2159
+ }
2160
+ return res;
2161
+ });
2162
+ }
2163
+ /**
2164
+ * Sends email
2165
+ *
2166
+ * @param request EmailRequest object
2167
+ *
2168
+ * Example:
2169
+ *
2170
+ * You can call this method by passing {@link EmailRequest}:
2171
+ * ```js
2172
+ * await projectObj.sendToSubscribers({
2173
+ * recepients: ["to@mail.com"]
2174
+ * body: "email body"
2175
+ * subject: "email subject"
2176
+ * cc: ["cc@mail.com"]
2177
+ * bcc: ["bcc@mail.com"]
2178
+ * })
2179
+ * ```
2180
+ * @category Notifications
2181
+ */
2182
+ sendToSubscribers(request) {
2183
+ return __awaiter(this, void 0, void 0, function* () {
2184
+ const client = yield this.client;
2185
+ const url = environment.adminHost + '/api/v1/subscribers/send';
2186
+ const [res, err] = yield client.post(url, request, { headers: { 'Content-Type': 'application/json' } });
2187
+ if (err) {
2188
+ err.setMessage('failed to notify to all the subsribers');
2189
+ throw err;
2190
+ }
2191
+ return res;
2192
+ });
2193
+ }
2194
+ /**
2195
+ * Adds languages for a project.
2196
+ * Example:
2197
+ * ```js
2198
+ * await project.setAllowedLanguages(['en','nl'])
2199
+ * ```
2200
+ *
2201
+ * You can set default language for project in same function as well
2202
+ * Example:
2203
+ * ```js
2204
+ * await project.setAllowedLanguages(['en','nl'], 'nl')
2205
+ * ```
2206
+ *
2207
+ * @param request: array of languages
2208
+ * @param defaultLanguage: optional
2209
+ * @category Languages
2210
+ */
2211
+ setAllowedLanguages(request, defaultLanguage) {
2212
+ return __awaiter(this, void 0, void 0, function* () {
2213
+ const req = { allowedLanguages: request };
2214
+ const url = environment.adminHost + `/api/v1/project/allowedLanguages`;
2215
+ const [res, err] = yield this.client.put(url, req);
2216
+ if (err) {
2217
+ err.setMessage(`failed to add languages: ${err.message}`);
2218
+ throw err;
2219
+ }
2220
+ if (defaultLanguage) {
2221
+ yield this.setDefaultLanguage(defaultLanguage);
2222
+ }
2223
+ return res;
2224
+ });
2225
+ }
2226
+ /**
2227
+ * Get all allowed languages for a project.
2228
+ * Example:
2229
+ * ```js
2230
+ * let res = await project.getAllowedLanguages()
2231
+ * ```
2232
+ * @returns Promise<string[]>
2233
+ */
2234
+ getAllowedLanguages() {
2235
+ return __awaiter(this, void 0, void 0, function* () {
2236
+ const url = environment.adminHost + `/api/v1/project/allowedLanguages`;
2237
+ const [res, err] = yield this.client.get(url);
2238
+ if (err) {
2239
+ err.setMessage(`failed to get allowed languages: ${err.message}`);
2240
+ throw err;
2241
+ }
2242
+ return res;
2243
+ });
2244
+ }
2245
+ /**
2246
+ * Sets default language for the project.
2247
+ * Example:
2248
+ * ```js
2249
+ * await project.setDefaultLanguage('nl')
2250
+ * ```
2251
+ *
2252
+ * @param request: default language.
2253
+ * @category Languages
2254
+ */
2255
+ setDefaultLanguage(request) {
2256
+ return __awaiter(this, void 0, void 0, function* () {
2257
+ const req = { defaultLanguage: request };
2258
+ const url = environment.adminHost + `/api/v1/project/defaultLanguage`;
2259
+ const [res, err] = yield this.client.put(url, req);
2260
+ if (err) {
2261
+ err.setMessage(`failed to set default language: ${err.message}`);
2262
+ throw err;
2263
+ }
2264
+ return res;
2265
+ });
2266
+ }
2267
+ /**
2268
+ * gets default language for the project.
2269
+ * Example:
2270
+ * ```js
2271
+ * await project.getDefaultLanguage()
2272
+ * ```
2273
+ *
2274
+ * @category Languages
2275
+ */
2276
+ getDefaultLanguage() {
2277
+ return __awaiter(this, void 0, void 0, function* () {
2278
+ const url = environment.adminHost + `/api/v1/project/defaultLanguage`;
2279
+ const [res, err] = yield this.client.get(url);
2280
+ if (err) {
2281
+ err.setMessage(`failed to get default language: ${err.message}`);
2282
+ throw err;
2283
+ }
2284
+ return res;
2285
+ });
2286
+ }
2287
+ }
2288
+ /**
2289
+ * BagType: Enum for type of bag.
2290
+ */
2291
+ var BagType;
2292
+ (function (BagType) {
2293
+ BagType["Download"] = "download";
2294
+ BagType["Upload"] = "upload";
2295
+ BagType["UploadDownload"] = "upload-download";
2296
+ BagType["Owner"] = "owner";
2297
+ })(BagType || (BagType = {}));
2298
+
2299
+ /**
2300
+ * A virtual file is a file that doesn't have static content like a normal file.
2301
+ * Instead, the content of the file is materialized upon request.
2302
+ *
2303
+ * To create a virtual file you first construct one of the VirtualFile sub-classes.
2304
+ * Next, you upload them using {@link View.uploadVirtual}. E.g.:
2305
+ * ```js
2306
+ * let virtual = new Twintag.Link("https://example.com")
2307
+ * await view.uploadVirtual(virtual, "My link")
2308
+ * ```
2309
+ */
2310
+ class VirtualFile {
2311
+ /**
2312
+ * Construct a virtual file.
2313
+ *
2314
+ * @internal
2315
+ * */
2316
+ constructor(mode) {
2317
+ this.mode = mode;
2318
+ }
2319
+ }
2320
+ /**
2321
+ * A link is a virtual file that represents a web link.
2322
+ *
2323
+ * First construct the link, next upload it to a bag using {@link View.uploadVirtual}. E.g.:
2324
+ * ```js
2325
+ * let virtual = new Twintag.Link("https://example.com")
2326
+ * await view.uploadVirtual(virtual, "My link")
2327
+ * ```
2328
+ */
2329
+ class Link extends VirtualFile {
2330
+ /**
2331
+ *
2332
+ * Construct a web link by URL.
2333
+ *
2334
+ * @param target The default target is "_blank ". Other targets may be restricted.
2335
+ */
2336
+ constructor(url, target) {
2337
+ super(50);
2338
+ this.url = url;
2339
+ this.target = "_blank";
2340
+ if (target) {
2341
+ this.target = target;
2342
+ }
2343
+ }
2344
+ /**
2345
+ * Get the virtual file definition.
2346
+ *
2347
+ * @internal
2348
+ */
2349
+ GetDefinition() {
2350
+ const def = {
2351
+ specversion: "1.0",
2352
+ definition: {
2353
+ type: "web-link",
2354
+ data: {
2355
+ url: this.url,
2356
+ target: this.target
2357
+ }
2358
+ }
2359
+ };
2360
+ return def;
2361
+ }
2362
+ }
2363
+
2364
+ export { AttributeType, BagType, FileUploader, Link, Project, VERSION, View, createBag, retryRequest, setAdminHost, setCachingHost, setHost };
2365
+ //# sourceMappingURL=twintag.esm.js.map