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