@yomotech/view-toolkit 0.0.12 → 0.0.14
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.
|
@@ -129,191 +129,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
129
129
|
type: Input
|
|
130
130
|
}] } });
|
|
131
131
|
|
|
132
|
-
class Couchdb {
|
|
133
|
-
utilityService;
|
|
134
|
-
couchDbBaseUrl = 'https://couchdb.yomotech.de';
|
|
135
|
-
constructor(utilityService) {
|
|
136
|
-
this.utilityService = utilityService;
|
|
137
|
-
}
|
|
138
|
-
async getTenantDatabases(tenantKey) {
|
|
139
|
-
if (!tenantKey || !tenantKey.trim()) {
|
|
140
|
-
throw new Error('Missing tenantKey');
|
|
141
|
-
}
|
|
142
|
-
const response = await fetch(`https://couchdb.yomotech.de/tenant-dbs`, {
|
|
143
|
-
method: 'GET',
|
|
144
|
-
headers: {
|
|
145
|
-
Accept: 'application/json',
|
|
146
|
-
'X-Tenant-Key': tenantKey.trim(),
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
const data = await this.parseJsonOrText(response);
|
|
150
|
-
if (!response.ok) {
|
|
151
|
-
throw new Error(`GET /tenant-dbs -> ${response.status} ${this.stringifyErrorDetails(data)}`);
|
|
152
|
-
}
|
|
153
|
-
return data;
|
|
154
|
-
}
|
|
155
|
-
async parseJsonOrText(response) {
|
|
156
|
-
const rawText = await response.text();
|
|
157
|
-
if (!rawText)
|
|
158
|
-
return null;
|
|
159
|
-
try {
|
|
160
|
-
return JSON.parse(rawText);
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
return rawText;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
stringifyErrorDetails(data) {
|
|
167
|
-
if (typeof data === 'string')
|
|
168
|
-
return data;
|
|
169
|
-
try {
|
|
170
|
-
return JSON.stringify(data);
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
return 'Unknown error';
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
async getFileContentFromCouchDb(couchDbName, filePath) {
|
|
177
|
-
try {
|
|
178
|
-
const dbName = couchDbName;
|
|
179
|
-
const docId = filePath?.trim();
|
|
180
|
-
if (!docId) {
|
|
181
|
-
console.error('Missing file path');
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
185
|
-
method: 'GET',
|
|
186
|
-
headers: await this.getReadHeaders(),
|
|
187
|
-
});
|
|
188
|
-
const doc = await this.parseJsonOrText(response);
|
|
189
|
-
if (!response.ok) {
|
|
190
|
-
console.error(`Failed to fetch file "${docId}" from "${dbName}": ${response.status}`, doc);
|
|
191
|
-
return null;
|
|
192
|
-
}
|
|
193
|
-
if (!doc?.data) {
|
|
194
|
-
console.error(`Document "${docId}" does not contain file data`);
|
|
195
|
-
return null;
|
|
196
|
-
}
|
|
197
|
-
// do not decode images as utf8 text
|
|
198
|
-
if (this.isImageFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
199
|
-
return {
|
|
200
|
-
type: 'base64file',
|
|
201
|
-
mimeType: doc.contentType || this.getImageMimeType(docId),
|
|
202
|
-
base64: doc.data,
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
const decodedContent = this.fromBase64(doc.data);
|
|
206
|
-
if (this.isJsonFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
207
|
-
try {
|
|
208
|
-
return JSON.parse(decodedContent);
|
|
209
|
-
}
|
|
210
|
-
catch (jsonError) {
|
|
211
|
-
console.error(`Failed to parse JSON for file "${docId}"`, jsonError);
|
|
212
|
-
return decodedContent;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return decodedContent;
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
console.error(`Unexpected error while fetching file "${filePath}" from "${couchDbName}"`, error);
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
isImageFile(fileNameOrPath, contentType) {
|
|
223
|
-
const lower = (fileNameOrPath || '').toLowerCase();
|
|
224
|
-
return (lower.endsWith('.png') ||
|
|
225
|
-
lower.endsWith('.jpg') ||
|
|
226
|
-
lower.endsWith('.jpeg') ||
|
|
227
|
-
lower.endsWith('.ico') ||
|
|
228
|
-
lower.endsWith('.svg') ||
|
|
229
|
-
(contentType || '').startsWith('image/'));
|
|
230
|
-
}
|
|
231
|
-
getImageMimeType(fileNameOrPath) {
|
|
232
|
-
const lower = (fileNameOrPath || '').toLowerCase();
|
|
233
|
-
if (lower.endsWith('.png'))
|
|
234
|
-
return 'image/png';
|
|
235
|
-
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
236
|
-
return 'image/jpeg';
|
|
237
|
-
if (lower.endsWith('.ico'))
|
|
238
|
-
return 'image/x-icon';
|
|
239
|
-
if (lower.endsWith('.svg'))
|
|
240
|
-
return 'image/svg+xml';
|
|
241
|
-
return 'image/png';
|
|
242
|
-
}
|
|
243
|
-
fromBase64(base64) {
|
|
244
|
-
try {
|
|
245
|
-
return decodeURIComponent(escape(atob(base64)));
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
return atob(base64);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
isJsonFile(fileNameOrPath, contentType) {
|
|
252
|
-
const lower = (fileNameOrPath || '').toLowerCase();
|
|
253
|
-
return lower.endsWith('.json') || contentType === 'application/json';
|
|
254
|
-
}
|
|
255
|
-
getDocumentUrl(dbName, docId) {
|
|
256
|
-
return `${this.getDbUrl(dbName)}/${encodeURIComponent(docId)}`;
|
|
257
|
-
}
|
|
258
|
-
getDbUrl(dbName) {
|
|
259
|
-
return `${this.couchDbBaseUrl}/${dbName}`;
|
|
260
|
-
}
|
|
261
|
-
async getReadHeaders() {
|
|
262
|
-
return {
|
|
263
|
-
Accept: 'application/json',
|
|
264
|
-
...(await this.buildTenantHeaders()),
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
async buildTenantHeaders() {
|
|
268
|
-
const tenantKey = await this.utilityService.getStorage('tenantKey');
|
|
269
|
-
const tenantName = await this.utilityService.getStorage('tenantName');
|
|
270
|
-
if (tenantKey) {
|
|
271
|
-
if (typeof tenantKey !== 'string' || !tenantKey.trim()) {
|
|
272
|
-
throw new Error('Missing tenantKey');
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
'X-Tenant-Key': tenantKey.trim(),
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
if (typeof tenantName !== 'string' || !tenantName.trim()) {
|
|
280
|
-
throw new Error('Missing tenantName');
|
|
281
|
-
}
|
|
282
|
-
return {
|
|
283
|
-
'X-Tenant': tenantName.trim(),
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
async getImageSrcFromCouchDb(couchDbName, filePath) {
|
|
288
|
-
const dbName = couchDbName;
|
|
289
|
-
const docId = filePath?.trim();
|
|
290
|
-
if (!docId) {
|
|
291
|
-
throw new Error('Missing file path');
|
|
292
|
-
}
|
|
293
|
-
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
294
|
-
method: 'GET',
|
|
295
|
-
headers: await this.getReadHeaders(),
|
|
296
|
-
});
|
|
297
|
-
const doc = await this.parseJsonOrText(response);
|
|
298
|
-
if (!response.ok) {
|
|
299
|
-
throw new Error(`Failed to fetch image "${docId}" from "${dbName}": ${response.status} ${this.stringifyErrorDetails(doc)}`);
|
|
300
|
-
}
|
|
301
|
-
if (!doc?.data) {
|
|
302
|
-
throw new Error(`Document "${docId}" does not contain image data`);
|
|
303
|
-
}
|
|
304
|
-
const mimeType = doc.contentType || 'image/png';
|
|
305
|
-
return `data:${mimeType};base64,${doc.data}`;
|
|
306
|
-
}
|
|
307
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Couchdb, deps: [{ token: UtilityService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
308
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Couchdb, providedIn: 'root' });
|
|
309
|
-
}
|
|
310
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Couchdb, decorators: [{
|
|
311
|
-
type: Injectable,
|
|
312
|
-
args: [{
|
|
313
|
-
providedIn: 'root',
|
|
314
|
-
}]
|
|
315
|
-
}], ctorParameters: () => [{ type: UtilityService }] });
|
|
316
|
-
|
|
317
132
|
class RequestService {
|
|
318
133
|
http;
|
|
319
134
|
pageSize = 0;
|
|
@@ -440,12 +255,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
440
255
|
|
|
441
256
|
class UtilityService {
|
|
442
257
|
platform;
|
|
443
|
-
couchdbService;
|
|
444
258
|
requestService;
|
|
445
259
|
stripe = null;
|
|
446
|
-
constructor(platform,
|
|
260
|
+
constructor(platform, requestService) {
|
|
447
261
|
this.platform = platform;
|
|
448
|
-
this.couchdbService = couchdbService;
|
|
449
262
|
this.requestService = requestService;
|
|
450
263
|
}
|
|
451
264
|
getScope(scope) {
|
|
@@ -724,66 +537,85 @@ class UtilityService {
|
|
|
724
537
|
}
|
|
725
538
|
}
|
|
726
539
|
}
|
|
727
|
-
async processData(
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
540
|
+
// async processData(
|
|
541
|
+
// data: any,
|
|
542
|
+
// options: {
|
|
543
|
+
// dataKey?: string;
|
|
544
|
+
// setImageUrl?: boolean;
|
|
545
|
+
// showTable?: boolean;
|
|
546
|
+
// projectSelected: string;
|
|
547
|
+
// },
|
|
548
|
+
// tenantName: any
|
|
549
|
+
// ): Promise<any[]> {
|
|
550
|
+
// if (options.dataKey) {
|
|
551
|
+
// data = data[options.dataKey];
|
|
552
|
+
// } else {
|
|
553
|
+
// if (!data?._embedded?.products && !Array.isArray(data)) {
|
|
554
|
+
// data = [data];
|
|
555
|
+
// } else {
|
|
556
|
+
// data = data?._embedded?.products;
|
|
557
|
+
// }
|
|
558
|
+
// }
|
|
559
|
+
// const transformed = await Promise.all(
|
|
560
|
+
// data.map(async (record: any) => {
|
|
561
|
+
// let imageUrl = record.imageUrl;
|
|
562
|
+
// const imagePath = `Media/` +
|
|
563
|
+
// record?.imageUrl?.split('/').pop();
|
|
564
|
+
// if (
|
|
565
|
+
// tenantName &&
|
|
566
|
+
// record?.imageUrl &&
|
|
567
|
+
// options.setImageUrl
|
|
568
|
+
// ) {
|
|
569
|
+
// try {
|
|
570
|
+
// imageUrl = "";
|
|
571
|
+
// imageUrl = await this.couchdbService.getFileContentFromCouchDb(
|
|
572
|
+
// `${tenantName}_${options.projectSelected}`,
|
|
573
|
+
// imagePath
|
|
574
|
+
// );
|
|
575
|
+
// } catch (err) {
|
|
576
|
+
// console.warn(`Failed to fetch image from CouchDB for ${imagePath}`, err);
|
|
577
|
+
// imageUrl = '';
|
|
578
|
+
// }
|
|
579
|
+
// }
|
|
580
|
+
// return {
|
|
581
|
+
// ...record,
|
|
582
|
+
// ...(imageUrl ? { imageUrl } : {}),
|
|
583
|
+
// ...(imagePath ? { imagePath } : {}),
|
|
584
|
+
// };
|
|
585
|
+
// })
|
|
586
|
+
// );
|
|
587
|
+
// return transformed;
|
|
588
|
+
// }
|
|
589
|
+
// async setTableDataImages(records: any, tenantName: any, projectSelected: any): Promise<any[]> {
|
|
590
|
+
// const transformed = await Promise.all(
|
|
591
|
+
// records.map(async (record: any) => {
|
|
592
|
+
// let imageUrl = record.imageUrl;
|
|
593
|
+
// const imagePath = record?.imagePath ? record?.imagePath : `Media/` +
|
|
594
|
+
// record?.imageUrl?.split('/').pop();
|
|
595
|
+
// if (
|
|
596
|
+
// tenantName &&
|
|
597
|
+
// record?.imageUrl &&
|
|
598
|
+
// record.hasOwnProperty('imageUrl')
|
|
599
|
+
// ) {
|
|
600
|
+
// try {
|
|
601
|
+
// imageUrl = "";
|
|
602
|
+
// imageUrl = await this.couchdbService.getFileContentFromCouchDb(
|
|
603
|
+
// `${tenantName}_${projectSelected}`,
|
|
604
|
+
// imagePath
|
|
605
|
+
// );
|
|
606
|
+
// } catch (err) {
|
|
607
|
+
// console.warn(`Failed to fetch image from CouchDB for ${imagePath}`, err);
|
|
608
|
+
// imageUrl = '';
|
|
609
|
+
// }
|
|
610
|
+
// }
|
|
611
|
+
// return {
|
|
612
|
+
// ...record,
|
|
613
|
+
// ...(imageUrl ? { imageUrl } : {}),
|
|
614
|
+
// };
|
|
615
|
+
// })
|
|
616
|
+
// );
|
|
617
|
+
// return transformed;
|
|
618
|
+
// }
|
|
787
619
|
// set date in localstorage
|
|
788
620
|
normalizeDatesForStorage(obj) {
|
|
789
621
|
const normalized = {};
|
|
@@ -945,7 +777,7 @@ class UtilityService {
|
|
|
945
777
|
const offM = pad(Math.abs(offset) % 60);
|
|
946
778
|
return `${year}-${month}-${day}T${hrs}:${mins}:00${sign}${offH}:${offM}`;
|
|
947
779
|
}
|
|
948
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UtilityService, deps: [{ token: i1.Platform }, { token:
|
|
780
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UtilityService, deps: [{ token: i1.Platform }, { token: RequestService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
949
781
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UtilityService, providedIn: 'root' });
|
|
950
782
|
}
|
|
951
783
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UtilityService, decorators: [{
|
|
@@ -953,7 +785,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
953
785
|
args: [{
|
|
954
786
|
providedIn: 'root'
|
|
955
787
|
}]
|
|
956
|
-
}], ctorParameters: () => [{ type: i1.Platform }, { type:
|
|
788
|
+
}], ctorParameters: () => [{ type: i1.Platform }, { type: RequestService }] });
|
|
957
789
|
|
|
958
790
|
class CardComponent {
|
|
959
791
|
utilityService;
|
|
@@ -2543,6 +2375,239 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
2543
2375
|
args: [{ selector: 'vl-time', standalone: true, template: "<p>time works!</p>\r\n" }]
|
|
2544
2376
|
}] });
|
|
2545
2377
|
|
|
2378
|
+
class Couchdb {
|
|
2379
|
+
utilityService;
|
|
2380
|
+
couchDbBaseUrl = 'https://couchdb.yomotech.de';
|
|
2381
|
+
constructor(utilityService) {
|
|
2382
|
+
this.utilityService = utilityService;
|
|
2383
|
+
}
|
|
2384
|
+
async getTenantDatabases(tenantKey) {
|
|
2385
|
+
if (!tenantKey || !tenantKey.trim()) {
|
|
2386
|
+
throw new Error('Missing tenantKey');
|
|
2387
|
+
}
|
|
2388
|
+
const response = await fetch(`https://couchdb.yomotech.de/tenant-dbs`, {
|
|
2389
|
+
method: 'GET',
|
|
2390
|
+
headers: {
|
|
2391
|
+
Accept: 'application/json',
|
|
2392
|
+
'X-Tenant-Key': tenantKey.trim(),
|
|
2393
|
+
},
|
|
2394
|
+
});
|
|
2395
|
+
const data = await this.parseJsonOrText(response);
|
|
2396
|
+
if (!response.ok) {
|
|
2397
|
+
throw new Error(`GET /tenant-dbs -> ${response.status} ${this.stringifyErrorDetails(data)}`);
|
|
2398
|
+
}
|
|
2399
|
+
return data;
|
|
2400
|
+
}
|
|
2401
|
+
async parseJsonOrText(response) {
|
|
2402
|
+
const rawText = await response.text();
|
|
2403
|
+
if (!rawText)
|
|
2404
|
+
return null;
|
|
2405
|
+
try {
|
|
2406
|
+
return JSON.parse(rawText);
|
|
2407
|
+
}
|
|
2408
|
+
catch {
|
|
2409
|
+
return rawText;
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
stringifyErrorDetails(data) {
|
|
2413
|
+
if (typeof data === 'string')
|
|
2414
|
+
return data;
|
|
2415
|
+
try {
|
|
2416
|
+
return JSON.stringify(data);
|
|
2417
|
+
}
|
|
2418
|
+
catch {
|
|
2419
|
+
return 'Unknown error';
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
async getFileContentFromCouchDb(couchDbName, filePath) {
|
|
2423
|
+
try {
|
|
2424
|
+
const dbName = couchDbName;
|
|
2425
|
+
const docId = filePath?.trim();
|
|
2426
|
+
if (!docId) {
|
|
2427
|
+
console.error('Missing file path');
|
|
2428
|
+
return null;
|
|
2429
|
+
}
|
|
2430
|
+
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
2431
|
+
method: 'GET',
|
|
2432
|
+
headers: await this.getReadHeaders(),
|
|
2433
|
+
});
|
|
2434
|
+
const doc = await this.parseJsonOrText(response);
|
|
2435
|
+
if (!response.ok) {
|
|
2436
|
+
console.error(`Failed to fetch file "${docId}" from "${dbName}": ${response.status}`, doc);
|
|
2437
|
+
return null;
|
|
2438
|
+
}
|
|
2439
|
+
if (!doc?.data) {
|
|
2440
|
+
console.error(`Document "${docId}" does not contain file data`);
|
|
2441
|
+
return null;
|
|
2442
|
+
}
|
|
2443
|
+
// do not decode images as utf8 text
|
|
2444
|
+
if (doc.type === 'media' ||
|
|
2445
|
+
doc.type === 'base64file' ||
|
|
2446
|
+
this.isBinaryMediaFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
2447
|
+
return {
|
|
2448
|
+
type: doc.type || 'base64file',
|
|
2449
|
+
mimeType: this.getMimeType(doc.name || doc.path || docId, doc.contentType),
|
|
2450
|
+
base64: doc.data,
|
|
2451
|
+
src: `data:${this.getMimeType(doc.name || doc.path || docId, doc.contentType)};base64,${doc.data}`,
|
|
2452
|
+
name: doc.name,
|
|
2453
|
+
path: doc.path,
|
|
2454
|
+
metadata: doc.metadata || {},
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
const decodedContent = this.fromBase64(doc.data);
|
|
2458
|
+
if (this.isJsonFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
2459
|
+
try {
|
|
2460
|
+
return JSON.parse(decodedContent);
|
|
2461
|
+
}
|
|
2462
|
+
catch (jsonError) {
|
|
2463
|
+
console.error(`Failed to parse JSON for file "${docId}"`, jsonError);
|
|
2464
|
+
return decodedContent;
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
return decodedContent;
|
|
2468
|
+
}
|
|
2469
|
+
catch (error) {
|
|
2470
|
+
console.error(`Unexpected error while fetching file "${filePath}" from "${couchDbName}"`, error);
|
|
2471
|
+
return null;
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
isBinaryMediaFile(fileNameOrPath, contentType) {
|
|
2475
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
2476
|
+
const type = contentType || '';
|
|
2477
|
+
return (type.startsWith('image/') ||
|
|
2478
|
+
type.startsWith('video/') ||
|
|
2479
|
+
type.startsWith('audio/') ||
|
|
2480
|
+
type === 'application/pdf' ||
|
|
2481
|
+
lower.endsWith('.png') ||
|
|
2482
|
+
lower.endsWith('.jpg') ||
|
|
2483
|
+
lower.endsWith('.jpeg') ||
|
|
2484
|
+
lower.endsWith('.ico') ||
|
|
2485
|
+
lower.endsWith('.svg') ||
|
|
2486
|
+
lower.endsWith('.webp') ||
|
|
2487
|
+
lower.endsWith('.gif') ||
|
|
2488
|
+
lower.endsWith('.mp4') ||
|
|
2489
|
+
lower.endsWith('.webm') ||
|
|
2490
|
+
lower.endsWith('.mp3') ||
|
|
2491
|
+
lower.endsWith('.wav') ||
|
|
2492
|
+
lower.endsWith('.m4a') ||
|
|
2493
|
+
lower.endsWith('.pdf'));
|
|
2494
|
+
}
|
|
2495
|
+
getMimeType(fileNameOrPath, contentType) {
|
|
2496
|
+
if (contentType)
|
|
2497
|
+
return contentType;
|
|
2498
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
2499
|
+
if (lower.endsWith('.png'))
|
|
2500
|
+
return 'image/png';
|
|
2501
|
+
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
2502
|
+
return 'image/jpeg';
|
|
2503
|
+
if (lower.endsWith('.ico'))
|
|
2504
|
+
return 'image/x-icon';
|
|
2505
|
+
if (lower.endsWith('.svg'))
|
|
2506
|
+
return 'image/svg+xml';
|
|
2507
|
+
if (lower.endsWith('.webp'))
|
|
2508
|
+
return 'image/webp';
|
|
2509
|
+
if (lower.endsWith('.gif'))
|
|
2510
|
+
return 'image/gif';
|
|
2511
|
+
if (lower.endsWith('.mp4'))
|
|
2512
|
+
return 'video/mp4';
|
|
2513
|
+
if (lower.endsWith('.webm'))
|
|
2514
|
+
return 'video/webm';
|
|
2515
|
+
if (lower.endsWith('.mp3'))
|
|
2516
|
+
return 'audio/mpeg';
|
|
2517
|
+
if (lower.endsWith('.wav'))
|
|
2518
|
+
return 'audio/wav';
|
|
2519
|
+
if (lower.endsWith('.m4a'))
|
|
2520
|
+
return 'audio/mp4';
|
|
2521
|
+
if (lower.endsWith('.pdf'))
|
|
2522
|
+
return 'application/pdf';
|
|
2523
|
+
return 'application/octet-stream';
|
|
2524
|
+
}
|
|
2525
|
+
getImageMimeType(fileNameOrPath) {
|
|
2526
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
2527
|
+
if (lower.endsWith('.png'))
|
|
2528
|
+
return 'image/png';
|
|
2529
|
+
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
2530
|
+
return 'image/jpeg';
|
|
2531
|
+
if (lower.endsWith('.ico'))
|
|
2532
|
+
return 'image/x-icon';
|
|
2533
|
+
if (lower.endsWith('.svg'))
|
|
2534
|
+
return 'image/svg+xml';
|
|
2535
|
+
return 'image/png';
|
|
2536
|
+
}
|
|
2537
|
+
fromBase64(base64) {
|
|
2538
|
+
try {
|
|
2539
|
+
return decodeURIComponent(escape(atob(base64)));
|
|
2540
|
+
}
|
|
2541
|
+
catch {
|
|
2542
|
+
return atob(base64);
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
isJsonFile(fileNameOrPath, contentType) {
|
|
2546
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
2547
|
+
return lower.endsWith('.json') || contentType === 'application/json';
|
|
2548
|
+
}
|
|
2549
|
+
getDocumentUrl(dbName, docId) {
|
|
2550
|
+
return `${this.getDbUrl(dbName)}/${encodeURIComponent(docId)}`;
|
|
2551
|
+
}
|
|
2552
|
+
getDbUrl(dbName) {
|
|
2553
|
+
return `${this.couchDbBaseUrl}/${dbName}`;
|
|
2554
|
+
}
|
|
2555
|
+
async getReadHeaders() {
|
|
2556
|
+
return {
|
|
2557
|
+
Accept: 'application/json',
|
|
2558
|
+
...(await this.buildTenantHeaders()),
|
|
2559
|
+
};
|
|
2560
|
+
}
|
|
2561
|
+
async buildTenantHeaders() {
|
|
2562
|
+
const tenantKey = await this.utilityService.getStorage('tenantKey');
|
|
2563
|
+
const tenantName = await this.utilityService.getStorage('tenantName');
|
|
2564
|
+
if (tenantKey) {
|
|
2565
|
+
if (typeof tenantKey !== 'string' || !tenantKey.trim()) {
|
|
2566
|
+
throw new Error('Missing tenantKey');
|
|
2567
|
+
}
|
|
2568
|
+
return {
|
|
2569
|
+
'X-Tenant-Key': tenantKey.trim(),
|
|
2570
|
+
};
|
|
2571
|
+
}
|
|
2572
|
+
else {
|
|
2573
|
+
if (typeof tenantName !== 'string' || !tenantName.trim()) {
|
|
2574
|
+
throw new Error('Missing tenantName');
|
|
2575
|
+
}
|
|
2576
|
+
return {
|
|
2577
|
+
'X-Tenant': tenantName.trim(),
|
|
2578
|
+
};
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
async getImageSrcFromCouchDb(couchDbName, filePath) {
|
|
2582
|
+
const dbName = couchDbName;
|
|
2583
|
+
const docId = filePath?.trim();
|
|
2584
|
+
if (!docId) {
|
|
2585
|
+
throw new Error('Missing file path');
|
|
2586
|
+
}
|
|
2587
|
+
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
2588
|
+
method: 'GET',
|
|
2589
|
+
headers: await this.getReadHeaders(),
|
|
2590
|
+
});
|
|
2591
|
+
const doc = await this.parseJsonOrText(response);
|
|
2592
|
+
if (!response.ok) {
|
|
2593
|
+
throw new Error(`Failed to fetch image "${docId}" from "${dbName}": ${response.status} ${this.stringifyErrorDetails(doc)}`);
|
|
2594
|
+
}
|
|
2595
|
+
if (!doc?.data) {
|
|
2596
|
+
throw new Error(`Document "${docId}" does not contain image data`);
|
|
2597
|
+
}
|
|
2598
|
+
const mimeType = doc.contentType || 'image/png';
|
|
2599
|
+
return `data:${mimeType};base64,${doc.data}`;
|
|
2600
|
+
}
|
|
2601
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Couchdb, deps: [{ token: UtilityService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2602
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Couchdb, providedIn: 'root' });
|
|
2603
|
+
}
|
|
2604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Couchdb, decorators: [{
|
|
2605
|
+
type: Injectable,
|
|
2606
|
+
args: [{
|
|
2607
|
+
providedIn: 'root',
|
|
2608
|
+
}]
|
|
2609
|
+
}], ctorParameters: () => [{ type: UtilityService }] });
|
|
2610
|
+
|
|
2546
2611
|
class ConfigService {
|
|
2547
2612
|
couchdbService;
|
|
2548
2613
|
utilityService;
|