@yomotech/view-toolkit 0.0.78 → 0.0.79
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.
|
@@ -6,7 +6,7 @@ import * as i3 from '@angular/forms';
|
|
|
6
6
|
import { FormsModule } from '@angular/forms';
|
|
7
7
|
import * as i1$1 from '@angular/common/http';
|
|
8
8
|
import { HttpHeaders, HttpParams } from '@angular/common/http';
|
|
9
|
-
import {
|
|
9
|
+
import { CapacitorHttp, Capacitor } from '@capacitor/core';
|
|
10
10
|
import * as i11 from 'ng-zorro-antd/icon';
|
|
11
11
|
import { NzIconModule } from 'ng-zorro-antd/icon';
|
|
12
12
|
import * as i13 from 'ng-zorro-antd/button';
|
|
@@ -1035,278 +1035,103 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
1035
1035
|
|
|
1036
1036
|
class Couchdb {
|
|
1037
1037
|
utilityService;
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
webProxyBaseUrl = '/couchdb-api';
|
|
1041
|
-
constructor(utilityService, platform) {
|
|
1038
|
+
couchDbBaseUrl = 'https://couchdb.yomotech.de';
|
|
1039
|
+
constructor(utilityService) {
|
|
1042
1040
|
this.utilityService = utilityService;
|
|
1043
|
-
this.platform = platform;
|
|
1044
1041
|
}
|
|
1045
1042
|
async getTenantDatabases(tenantKey) {
|
|
1046
|
-
|
|
1047
|
-
if (!normalizedTenantKey) {
|
|
1043
|
+
if (!tenantKey || !tenantKey.trim()) {
|
|
1048
1044
|
throw new Error('Missing tenantKey');
|
|
1049
1045
|
}
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1052
|
-
|
|
1046
|
+
const response = await fetch(`https://couchdb.yomotech.de/tenant-dbs`, {
|
|
1047
|
+
method: 'GET',
|
|
1048
|
+
headers: {
|
|
1049
|
+
Accept: 'application/json',
|
|
1050
|
+
'X-Tenant-Key': tenantKey.trim(),
|
|
1051
|
+
},
|
|
1053
1052
|
});
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1053
|
+
const data = await this.parseJsonOrText(response);
|
|
1054
|
+
if (!response.ok) {
|
|
1055
|
+
throw new Error(`GET /tenant-dbs -> ${response.status} ${this.stringifyErrorDetails(data)}`);
|
|
1056
|
+
}
|
|
1057
|
+
return data;
|
|
1058
|
+
}
|
|
1059
|
+
async parseJsonOrText(response) {
|
|
1060
|
+
const rawText = await response.text();
|
|
1061
|
+
if (!rawText)
|
|
1062
|
+
return null;
|
|
1063
|
+
try {
|
|
1064
|
+
return JSON.parse(rawText);
|
|
1065
|
+
}
|
|
1066
|
+
catch {
|
|
1067
|
+
return rawText;
|
|
1057
1068
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1069
|
+
}
|
|
1070
|
+
stringifyErrorDetails(data) {
|
|
1071
|
+
if (typeof data === 'string')
|
|
1072
|
+
return data;
|
|
1073
|
+
try {
|
|
1074
|
+
return JSON.stringify(data);
|
|
1060
1075
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
return result.data;
|
|
1076
|
+
catch {
|
|
1077
|
+
return 'Unknown error';
|
|
1064
1078
|
}
|
|
1065
|
-
throw new Error(`Invalid /tenant-dbs response: ` +
|
|
1066
|
-
`${this.stringifyErrorDetails(result.data)}`);
|
|
1067
1079
|
}
|
|
1068
1080
|
async getFileContentFromCouchDb(couchDbName, filePath) {
|
|
1069
1081
|
try {
|
|
1070
|
-
const dbName = couchDbName?.
|
|
1082
|
+
const dbName = couchDbName?.toLowerCase();
|
|
1071
1083
|
const docId = filePath?.trim();
|
|
1072
|
-
if (!dbName) {
|
|
1073
|
-
console.error('Missing CouchDB database name');
|
|
1074
|
-
return null;
|
|
1075
|
-
}
|
|
1076
1084
|
if (!docId) {
|
|
1077
1085
|
console.error('Missing file path');
|
|
1078
1086
|
return null;
|
|
1079
1087
|
}
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1088
|
+
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
1089
|
+
method: 'GET',
|
|
1090
|
+
headers: await this.getReadHeaders(),
|
|
1091
|
+
});
|
|
1092
|
+
const doc = await this.parseJsonOrText(response);
|
|
1093
|
+
if (!response.ok) {
|
|
1094
|
+
console.error(`Failed to fetch file "${docId}" from "${dbName}": ${response.status}`, doc);
|
|
1085
1095
|
return null;
|
|
1086
1096
|
}
|
|
1087
1097
|
if (!doc?.data) {
|
|
1088
|
-
console.error(`Document "${docId}"
|
|
1098
|
+
console.error(`Document "${docId}" does not contain file data`);
|
|
1089
1099
|
return null;
|
|
1090
1100
|
}
|
|
1091
|
-
|
|
1092
|
-
if (doc.type === 'media' ||
|
|
1093
|
-
|
|
1101
|
+
// do not decode images as utf8 text
|
|
1102
|
+
if (doc.type === 'media' ||
|
|
1103
|
+
doc.type === 'base64file' ||
|
|
1104
|
+
this.isBinaryMediaFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
1094
1105
|
return {
|
|
1095
1106
|
type: doc.type || 'base64file',
|
|
1096
|
-
mimeType,
|
|
1107
|
+
mimeType: this.getMimeType(doc.name || doc.path || docId, doc.contentType),
|
|
1097
1108
|
base64: doc.data,
|
|
1098
|
-
src: `data:${
|
|
1109
|
+
src: `data:${this.getMimeType(doc.name || doc.path || docId, doc.contentType)};base64,${doc.data}`,
|
|
1099
1110
|
name: doc.name,
|
|
1100
1111
|
path: doc.path,
|
|
1101
1112
|
metadata: doc.metadata || {},
|
|
1102
1113
|
};
|
|
1103
1114
|
}
|
|
1104
1115
|
const decodedContent = this.fromBase64(doc.data);
|
|
1105
|
-
if (this.isJsonFile(
|
|
1116
|
+
if (this.isJsonFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
1106
1117
|
try {
|
|
1107
1118
|
return JSON.parse(decodedContent);
|
|
1108
1119
|
}
|
|
1109
1120
|
catch (jsonError) {
|
|
1110
|
-
console.error(`Failed to parse JSON
|
|
1111
|
-
`for file "${docId}"`, jsonError);
|
|
1121
|
+
console.error(`Failed to parse JSON for file "${docId}"`, jsonError);
|
|
1112
1122
|
return decodedContent;
|
|
1113
1123
|
}
|
|
1114
1124
|
}
|
|
1115
1125
|
return decodedContent;
|
|
1116
1126
|
}
|
|
1117
1127
|
catch (error) {
|
|
1118
|
-
console.error(`Unexpected error while fetching
|
|
1119
|
-
`file "${filePath}" from ` +
|
|
1120
|
-
`"${couchDbName}"`, error);
|
|
1121
|
-
return null;
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
async getImageSrcFromCouchDb(couchDbName, filePath) {
|
|
1125
|
-
const dbName = couchDbName?.trim().toLowerCase();
|
|
1126
|
-
const docId = filePath?.trim();
|
|
1127
|
-
if (!dbName) {
|
|
1128
|
-
throw new Error('Missing CouchDB database name');
|
|
1129
|
-
}
|
|
1130
|
-
if (!docId) {
|
|
1131
|
-
throw new Error('Missing file path');
|
|
1132
|
-
}
|
|
1133
|
-
const path = this.getDocumentPath(dbName, docId);
|
|
1134
|
-
const result = await this.sendGetRequest(path, await this.getReadHeaders());
|
|
1135
|
-
const doc = result.data;
|
|
1136
|
-
if (!result.ok) {
|
|
1137
|
-
throw new Error(`Failed to fetch image ` +
|
|
1138
|
-
`"${docId}" from "${dbName}": ` +
|
|
1139
|
-
`${result.status} ` +
|
|
1140
|
-
`${this.stringifyErrorDetails(doc)}`);
|
|
1141
|
-
}
|
|
1142
|
-
if (!doc?.data) {
|
|
1143
|
-
throw new Error(`Document "${docId}" ` +
|
|
1144
|
-
`does not contain image data`);
|
|
1145
|
-
}
|
|
1146
|
-
const mimeType = this.getMimeType(doc.name ||
|
|
1147
|
-
doc.path ||
|
|
1148
|
-
docId, doc.contentType);
|
|
1149
|
-
return (`data:${mimeType};base64,` +
|
|
1150
|
-
`${doc.data}`);
|
|
1151
|
-
}
|
|
1152
|
-
async sendGetRequest(path, headers) {
|
|
1153
|
-
const normalizedPath = path.startsWith('/')
|
|
1154
|
-
? path
|
|
1155
|
-
: `/${path}`;
|
|
1156
|
-
if (Capacitor.isNativePlatform()) {
|
|
1157
|
-
return this.sendNativeGetRequest(normalizedPath, headers);
|
|
1158
|
-
}
|
|
1159
|
-
return this.sendWebGetRequest(normalizedPath, headers);
|
|
1160
|
-
}
|
|
1161
|
-
async sendNativeGetRequest(path, headers) {
|
|
1162
|
-
const url = `${this.remoteCouchDbBaseUrl}${path}`;
|
|
1163
|
-
try {
|
|
1164
|
-
const response = await CapacitorHttp.get({
|
|
1165
|
-
url,
|
|
1166
|
-
headers,
|
|
1167
|
-
connectTimeout: 15000,
|
|
1168
|
-
readTimeout: 30000,
|
|
1169
|
-
});
|
|
1170
|
-
const data = this.normalizeNativeResponseData(response.data);
|
|
1171
|
-
return {
|
|
1172
|
-
ok: response.status >= 200 &&
|
|
1173
|
-
response.status < 300,
|
|
1174
|
-
status: response.status,
|
|
1175
|
-
data: data,
|
|
1176
|
-
};
|
|
1177
|
-
}
|
|
1178
|
-
catch (error) {
|
|
1179
|
-
console.log('[CouchDB][Native] Request failed:', error);
|
|
1180
|
-
return {
|
|
1181
|
-
ok: false,
|
|
1182
|
-
status: this.extractNativeErrorStatus(error),
|
|
1183
|
-
data: this.extractNativeErrorData(error),
|
|
1184
|
-
};
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
async sendWebGetRequest(path, headers) {
|
|
1188
|
-
const url = `${this.webProxyBaseUrl}${path}`;
|
|
1189
|
-
try {
|
|
1190
|
-
const response = await fetch(url, { method: 'GET', cache: 'no-store', headers, });
|
|
1191
|
-
const data = await this.parseJsonOrText(response);
|
|
1192
|
-
return { ok: response.ok, status: response.status, data: data };
|
|
1193
|
-
}
|
|
1194
|
-
catch (error) {
|
|
1195
|
-
console.error('[CouchDB][Web] Request failed:', error);
|
|
1196
|
-
return { ok: false, status: 0, data: error, };
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
normalizeNativeResponseData(data) {
|
|
1200
|
-
if (typeof data !== 'string') {
|
|
1201
|
-
return data;
|
|
1202
|
-
}
|
|
1203
|
-
if (!data.trim()) {
|
|
1204
|
-
return null;
|
|
1205
|
-
}
|
|
1206
|
-
try {
|
|
1207
|
-
return JSON.parse(data);
|
|
1208
|
-
}
|
|
1209
|
-
catch {
|
|
1210
|
-
return data;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
extractNativeErrorStatus(error) {
|
|
1214
|
-
const status = error?.status ??
|
|
1215
|
-
error?.response?.status ??
|
|
1216
|
-
error?.data?.status;
|
|
1217
|
-
return Number.isFinite(Number(status))
|
|
1218
|
-
? Number(status)
|
|
1219
|
-
: 0;
|
|
1220
|
-
}
|
|
1221
|
-
extractNativeErrorData(error) {
|
|
1222
|
-
return (error?.data ??
|
|
1223
|
-
error?.response?.data ??
|
|
1224
|
-
error?.message ??
|
|
1225
|
-
error);
|
|
1226
|
-
}
|
|
1227
|
-
getDocumentPath(dbName, docId) {
|
|
1228
|
-
const encodedDbName = encodeURIComponent(dbName.trim().toLowerCase());
|
|
1229
|
-
const encodedDocId = encodeURIComponent(docId.trim());
|
|
1230
|
-
return (`/${encodedDbName}/` + `${encodedDocId}`);
|
|
1231
|
-
}
|
|
1232
|
-
async getReadHeaders() {
|
|
1233
|
-
return {
|
|
1234
|
-
Accept: 'application/json',
|
|
1235
|
-
...(await this.buildTenantHeaders()),
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
async buildTenantHeaders() {
|
|
1239
|
-
let tenantKey = "";
|
|
1240
|
-
let tenantName = "";
|
|
1241
|
-
if (this.platform.ANDROID || this.platform.IOS) {
|
|
1242
|
-
tenantKey = await this.utilityService.getLocalStorage('tenantKey');
|
|
1243
|
-
tenantName = await this.utilityService.getLocalStorage('tenantName');
|
|
1244
|
-
}
|
|
1245
|
-
else {
|
|
1246
|
-
tenantKey = await this.utilityService.getStorage('tenantKey');
|
|
1247
|
-
tenantName = await this.utilityService.getStorage('tenantName');
|
|
1248
|
-
}
|
|
1249
|
-
const selectedTenant = await this.utilityService.getLocalStorage('selectedTenant');
|
|
1250
|
-
if (typeof tenantKey === 'string' && tenantKey.trim()) {
|
|
1251
|
-
return { 'X-Tenant-Key': tenantKey.trim() };
|
|
1252
|
-
}
|
|
1253
|
-
const normalizedTenantName = typeof tenantName === 'string' ? tenantName.trim() : '';
|
|
1254
|
-
const normalizedSelectedTenant = typeof selectedTenant === 'string' ? selectedTenant.trim() : '';
|
|
1255
|
-
const tenant = normalizedTenantName || normalizedSelectedTenant;
|
|
1256
|
-
if (!tenant) {
|
|
1257
|
-
throw new Error('Missing tenantKey, tenantName, ' + 'or selectedTenant');
|
|
1258
|
-
}
|
|
1259
|
-
return { 'X-Tenant': tenant, };
|
|
1260
|
-
}
|
|
1261
|
-
async parseJsonOrText(response) {
|
|
1262
|
-
const rawText = await response.text();
|
|
1263
|
-
if (!rawText) {
|
|
1128
|
+
console.error(`Unexpected error while fetching file "${filePath}" from "${couchDbName}"`, error);
|
|
1264
1129
|
return null;
|
|
1265
1130
|
}
|
|
1266
|
-
try {
|
|
1267
|
-
return JSON.parse(rawText);
|
|
1268
|
-
}
|
|
1269
|
-
catch {
|
|
1270
|
-
return rawText;
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
stringifyErrorDetails(data) {
|
|
1274
|
-
if (typeof data === 'string') {
|
|
1275
|
-
return data;
|
|
1276
|
-
}
|
|
1277
|
-
try {
|
|
1278
|
-
return JSON.stringify(data);
|
|
1279
|
-
}
|
|
1280
|
-
catch {
|
|
1281
|
-
return 'Unknown error';
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
fromBase64(base64) {
|
|
1285
|
-
try {
|
|
1286
|
-
const binaryString = atob(base64);
|
|
1287
|
-
const bytes = Uint8Array.from(binaryString, character => character.charCodeAt(0));
|
|
1288
|
-
return new TextDecoder('utf-8').decode(bytes);
|
|
1289
|
-
}
|
|
1290
|
-
catch {
|
|
1291
|
-
return atob(base64);
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
isJsonFile(fileNameOrPath, contentType) {
|
|
1295
|
-
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1296
|
-
const normalizedContentType = (contentType || '')
|
|
1297
|
-
.toLowerCase()
|
|
1298
|
-
.split(';')[0]
|
|
1299
|
-
.trim();
|
|
1300
|
-
return (lower.endsWith('.json') ||
|
|
1301
|
-
normalizedContentType ===
|
|
1302
|
-
'application/json');
|
|
1303
1131
|
}
|
|
1304
1132
|
isBinaryMediaFile(fileNameOrPath, contentType) {
|
|
1305
1133
|
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1306
|
-
const type =
|
|
1307
|
-
.toLowerCase()
|
|
1308
|
-
.split(';')[0]
|
|
1309
|
-
.trim();
|
|
1134
|
+
const type = contentType || '';
|
|
1310
1135
|
return (type.startsWith('image/') ||
|
|
1311
1136
|
type.startsWith('video/') ||
|
|
1312
1137
|
type.startsWith('audio/') ||
|
|
@@ -1326,53 +1151,113 @@ class Couchdb {
|
|
|
1326
1151
|
lower.endsWith('.pdf'));
|
|
1327
1152
|
}
|
|
1328
1153
|
getMimeType(fileNameOrPath, contentType) {
|
|
1329
|
-
if (contentType
|
|
1330
|
-
contentType
|
|
1331
|
-
return contentType
|
|
1332
|
-
.split(';')[0]
|
|
1333
|
-
.trim();
|
|
1334
|
-
}
|
|
1154
|
+
if (contentType)
|
|
1155
|
+
return contentType;
|
|
1335
1156
|
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1336
|
-
if (lower.endsWith('.png'))
|
|
1157
|
+
if (lower.endsWith('.png'))
|
|
1337
1158
|
return 'image/png';
|
|
1338
|
-
|
|
1339
|
-
if (lower.endsWith('.jpg') ||
|
|
1340
|
-
lower.endsWith('.jpeg')) {
|
|
1159
|
+
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
1341
1160
|
return 'image/jpeg';
|
|
1342
|
-
|
|
1343
|
-
if (lower.endsWith('.ico')) {
|
|
1161
|
+
if (lower.endsWith('.ico'))
|
|
1344
1162
|
return 'image/x-icon';
|
|
1345
|
-
|
|
1346
|
-
if (lower.endsWith('.svg')) {
|
|
1163
|
+
if (lower.endsWith('.svg'))
|
|
1347
1164
|
return 'image/svg+xml';
|
|
1348
|
-
|
|
1349
|
-
if (lower.endsWith('.webp')) {
|
|
1165
|
+
if (lower.endsWith('.webp'))
|
|
1350
1166
|
return 'image/webp';
|
|
1351
|
-
|
|
1352
|
-
if (lower.endsWith('.gif')) {
|
|
1167
|
+
if (lower.endsWith('.gif'))
|
|
1353
1168
|
return 'image/gif';
|
|
1354
|
-
|
|
1355
|
-
if (lower.endsWith('.mp4')) {
|
|
1169
|
+
if (lower.endsWith('.mp4'))
|
|
1356
1170
|
return 'video/mp4';
|
|
1357
|
-
|
|
1358
|
-
if (lower.endsWith('.webm')) {
|
|
1171
|
+
if (lower.endsWith('.webm'))
|
|
1359
1172
|
return 'video/webm';
|
|
1360
|
-
|
|
1361
|
-
if (lower.endsWith('.mp3')) {
|
|
1173
|
+
if (lower.endsWith('.mp3'))
|
|
1362
1174
|
return 'audio/mpeg';
|
|
1363
|
-
|
|
1364
|
-
if (lower.endsWith('.wav')) {
|
|
1175
|
+
if (lower.endsWith('.wav'))
|
|
1365
1176
|
return 'audio/wav';
|
|
1366
|
-
|
|
1367
|
-
if (lower.endsWith('.m4a')) {
|
|
1177
|
+
if (lower.endsWith('.m4a'))
|
|
1368
1178
|
return 'audio/mp4';
|
|
1369
|
-
|
|
1370
|
-
if (lower.endsWith('.pdf')) {
|
|
1179
|
+
if (lower.endsWith('.pdf'))
|
|
1371
1180
|
return 'application/pdf';
|
|
1372
|
-
}
|
|
1373
1181
|
return 'application/octet-stream';
|
|
1374
1182
|
}
|
|
1375
|
-
|
|
1183
|
+
getImageMimeType(fileNameOrPath) {
|
|
1184
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1185
|
+
if (lower.endsWith('.png'))
|
|
1186
|
+
return 'image/png';
|
|
1187
|
+
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
1188
|
+
return 'image/jpeg';
|
|
1189
|
+
if (lower.endsWith('.ico'))
|
|
1190
|
+
return 'image/x-icon';
|
|
1191
|
+
if (lower.endsWith('.svg'))
|
|
1192
|
+
return 'image/svg+xml';
|
|
1193
|
+
return 'image/png';
|
|
1194
|
+
}
|
|
1195
|
+
fromBase64(base64) {
|
|
1196
|
+
try {
|
|
1197
|
+
return decodeURIComponent(escape(atob(base64)));
|
|
1198
|
+
}
|
|
1199
|
+
catch {
|
|
1200
|
+
return atob(base64);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
isJsonFile(fileNameOrPath, contentType) {
|
|
1204
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1205
|
+
return lower.endsWith('.json') || contentType === 'application/json';
|
|
1206
|
+
}
|
|
1207
|
+
getDocumentUrl(dbName, docId) {
|
|
1208
|
+
return `${this.getDbUrl(dbName)}/${encodeURIComponent(docId)}`;
|
|
1209
|
+
}
|
|
1210
|
+
getDbUrl(dbName) {
|
|
1211
|
+
return `${this.couchDbBaseUrl}/${dbName}`;
|
|
1212
|
+
}
|
|
1213
|
+
async getReadHeaders() {
|
|
1214
|
+
return {
|
|
1215
|
+
Accept: 'application/json',
|
|
1216
|
+
...(await this.buildTenantHeaders()),
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
async buildTenantHeaders() {
|
|
1220
|
+
const tenantKey = await this.utilityService.getStorage('tenantKey');
|
|
1221
|
+
const tenantName = await this.utilityService.getStorage('tenantName');
|
|
1222
|
+
const selectedTenant = await this.utilityService.getLocalStorage('selectedTenant');
|
|
1223
|
+
if (tenantKey) {
|
|
1224
|
+
if (typeof tenantKey !== 'string' || !tenantKey.trim()) {
|
|
1225
|
+
throw new Error('Missing tenantKey');
|
|
1226
|
+
}
|
|
1227
|
+
return {
|
|
1228
|
+
'X-Tenant-Key': tenantKey.trim(),
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
else {
|
|
1232
|
+
if (!tenantName && !selectedTenant) {
|
|
1233
|
+
throw new Error('Missing tenantName');
|
|
1234
|
+
}
|
|
1235
|
+
return {
|
|
1236
|
+
'X-Tenant': tenantName ? tenantName.trim() : selectedTenant.trim(),
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
async getImageSrcFromCouchDb(couchDbName, filePath) {
|
|
1241
|
+
const dbName = couchDbName?.toLowerCase();
|
|
1242
|
+
const docId = filePath?.trim();
|
|
1243
|
+
if (!docId) {
|
|
1244
|
+
throw new Error('Missing file path');
|
|
1245
|
+
}
|
|
1246
|
+
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
1247
|
+
method: 'GET',
|
|
1248
|
+
headers: await this.getReadHeaders(),
|
|
1249
|
+
});
|
|
1250
|
+
const doc = await this.parseJsonOrText(response);
|
|
1251
|
+
if (!response.ok) {
|
|
1252
|
+
throw new Error(`Failed to fetch image "${docId}" from "${dbName}": ${response.status} ${this.stringifyErrorDetails(doc)}`);
|
|
1253
|
+
}
|
|
1254
|
+
if (!doc?.data) {
|
|
1255
|
+
throw new Error(`Document "${docId}" does not contain image data`);
|
|
1256
|
+
}
|
|
1257
|
+
const mimeType = doc.contentType || 'image/png';
|
|
1258
|
+
return `data:${mimeType};base64,${doc.data}`;
|
|
1259
|
+
}
|
|
1260
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: Couchdb, deps: [{ token: UtilityService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1376
1261
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: Couchdb, providedIn: 'root' });
|
|
1377
1262
|
}
|
|
1378
1263
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: Couchdb, decorators: [{
|
|
@@ -1380,7 +1265,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
1380
1265
|
args: [{
|
|
1381
1266
|
providedIn: 'root',
|
|
1382
1267
|
}]
|
|
1383
|
-
}], ctorParameters: () => [{ type: UtilityService }
|
|
1268
|
+
}], ctorParameters: () => [{ type: UtilityService }] });
|
|
1384
1269
|
|
|
1385
1270
|
class ConfigService {
|
|
1386
1271
|
couchdbService;
|