@yomotech/view-toolkit 0.0.78 → 0.0.80
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,105 @@ 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(
|
|
1056
|
+
// `GET /tenant-dbs -> ${response.status} ${this.stringifyErrorDetails(data)}`
|
|
1057
|
+
// );
|
|
1058
|
+
// }
|
|
1059
|
+
return data;
|
|
1060
|
+
}
|
|
1061
|
+
async parseJsonOrText(response) {
|
|
1062
|
+
const rawText = await response.text();
|
|
1063
|
+
if (!rawText)
|
|
1064
|
+
return null;
|
|
1065
|
+
try {
|
|
1066
|
+
return JSON.parse(rawText);
|
|
1067
|
+
}
|
|
1068
|
+
catch {
|
|
1069
|
+
return rawText;
|
|
1057
1070
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1071
|
+
}
|
|
1072
|
+
stringifyErrorDetails(data) {
|
|
1073
|
+
if (typeof data === 'string')
|
|
1074
|
+
return data;
|
|
1075
|
+
try {
|
|
1076
|
+
return JSON.stringify(data);
|
|
1060
1077
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
return result.data;
|
|
1078
|
+
catch {
|
|
1079
|
+
return 'Unknown error';
|
|
1064
1080
|
}
|
|
1065
|
-
throw new Error(`Invalid /tenant-dbs response: ` +
|
|
1066
|
-
`${this.stringifyErrorDetails(result.data)}`);
|
|
1067
1081
|
}
|
|
1068
1082
|
async getFileContentFromCouchDb(couchDbName, filePath) {
|
|
1069
1083
|
try {
|
|
1070
|
-
const dbName = couchDbName?.
|
|
1084
|
+
const dbName = couchDbName?.toLowerCase();
|
|
1071
1085
|
const docId = filePath?.trim();
|
|
1072
|
-
if (!dbName) {
|
|
1073
|
-
console.error('Missing CouchDB database name');
|
|
1074
|
-
return null;
|
|
1075
|
-
}
|
|
1076
1086
|
if (!docId) {
|
|
1077
1087
|
console.error('Missing file path');
|
|
1078
1088
|
return null;
|
|
1079
1089
|
}
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1090
|
+
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
1091
|
+
method: 'GET',
|
|
1092
|
+
headers: await this.getReadHeaders(),
|
|
1093
|
+
});
|
|
1094
|
+
const doc = await this.parseJsonOrText(response);
|
|
1095
|
+
if (!response.ok) {
|
|
1096
|
+
console.error(`Failed to fetch file "${docId}" from "${dbName}": ${response.status}`, doc);
|
|
1085
1097
|
return null;
|
|
1086
1098
|
}
|
|
1087
1099
|
if (!doc?.data) {
|
|
1088
|
-
console.error(`Document "${docId}"
|
|
1100
|
+
console.error(`Document "${docId}" does not contain file data`);
|
|
1089
1101
|
return null;
|
|
1090
1102
|
}
|
|
1091
|
-
|
|
1092
|
-
if (doc.type === 'media' ||
|
|
1093
|
-
|
|
1103
|
+
// do not decode images as utf8 text
|
|
1104
|
+
if (doc.type === 'media' ||
|
|
1105
|
+
doc.type === 'base64file' ||
|
|
1106
|
+
this.isBinaryMediaFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
1094
1107
|
return {
|
|
1095
1108
|
type: doc.type || 'base64file',
|
|
1096
|
-
mimeType,
|
|
1109
|
+
mimeType: this.getMimeType(doc.name || doc.path || docId, doc.contentType),
|
|
1097
1110
|
base64: doc.data,
|
|
1098
|
-
src: `data:${
|
|
1111
|
+
src: `data:${this.getMimeType(doc.name || doc.path || docId, doc.contentType)};base64,${doc.data}`,
|
|
1099
1112
|
name: doc.name,
|
|
1100
1113
|
path: doc.path,
|
|
1101
1114
|
metadata: doc.metadata || {},
|
|
1102
1115
|
};
|
|
1103
1116
|
}
|
|
1104
1117
|
const decodedContent = this.fromBase64(doc.data);
|
|
1105
|
-
if (this.isJsonFile(
|
|
1118
|
+
if (this.isJsonFile(doc.name || doc.path || docId, doc.contentType)) {
|
|
1106
1119
|
try {
|
|
1107
1120
|
return JSON.parse(decodedContent);
|
|
1108
1121
|
}
|
|
1109
1122
|
catch (jsonError) {
|
|
1110
|
-
console.error(`Failed to parse JSON
|
|
1111
|
-
`for file "${docId}"`, jsonError);
|
|
1123
|
+
console.error(`Failed to parse JSON for file "${docId}"`, jsonError);
|
|
1112
1124
|
return decodedContent;
|
|
1113
1125
|
}
|
|
1114
1126
|
}
|
|
1115
1127
|
return decodedContent;
|
|
1116
1128
|
}
|
|
1117
1129
|
catch (error) {
|
|
1118
|
-
console.error(`Unexpected error while fetching
|
|
1119
|
-
`file "${filePath}" from ` +
|
|
1120
|
-
`"${couchDbName}"`, error);
|
|
1130
|
+
console.error(`Unexpected error while fetching file "${filePath}" from "${couchDbName}"`, error);
|
|
1121
1131
|
return null;
|
|
1122
1132
|
}
|
|
1123
1133
|
}
|
|
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) {
|
|
1264
|
-
return null;
|
|
1265
|
-
}
|
|
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
|
-
}
|
|
1304
1134
|
isBinaryMediaFile(fileNameOrPath, contentType) {
|
|
1305
1135
|
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1306
|
-
const type =
|
|
1307
|
-
.toLowerCase()
|
|
1308
|
-
.split(';')[0]
|
|
1309
|
-
.trim();
|
|
1136
|
+
const type = contentType || '';
|
|
1310
1137
|
return (type.startsWith('image/') ||
|
|
1311
1138
|
type.startsWith('video/') ||
|
|
1312
1139
|
type.startsWith('audio/') ||
|
|
@@ -1326,53 +1153,113 @@ class Couchdb {
|
|
|
1326
1153
|
lower.endsWith('.pdf'));
|
|
1327
1154
|
}
|
|
1328
1155
|
getMimeType(fileNameOrPath, contentType) {
|
|
1329
|
-
if (contentType
|
|
1330
|
-
contentType
|
|
1331
|
-
return contentType
|
|
1332
|
-
.split(';')[0]
|
|
1333
|
-
.trim();
|
|
1334
|
-
}
|
|
1156
|
+
if (contentType)
|
|
1157
|
+
return contentType;
|
|
1335
1158
|
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1336
|
-
if (lower.endsWith('.png'))
|
|
1159
|
+
if (lower.endsWith('.png'))
|
|
1337
1160
|
return 'image/png';
|
|
1338
|
-
|
|
1339
|
-
if (lower.endsWith('.jpg') ||
|
|
1340
|
-
lower.endsWith('.jpeg')) {
|
|
1161
|
+
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
1341
1162
|
return 'image/jpeg';
|
|
1342
|
-
|
|
1343
|
-
if (lower.endsWith('.ico')) {
|
|
1163
|
+
if (lower.endsWith('.ico'))
|
|
1344
1164
|
return 'image/x-icon';
|
|
1345
|
-
|
|
1346
|
-
if (lower.endsWith('.svg')) {
|
|
1165
|
+
if (lower.endsWith('.svg'))
|
|
1347
1166
|
return 'image/svg+xml';
|
|
1348
|
-
|
|
1349
|
-
if (lower.endsWith('.webp')) {
|
|
1167
|
+
if (lower.endsWith('.webp'))
|
|
1350
1168
|
return 'image/webp';
|
|
1351
|
-
|
|
1352
|
-
if (lower.endsWith('.gif')) {
|
|
1169
|
+
if (lower.endsWith('.gif'))
|
|
1353
1170
|
return 'image/gif';
|
|
1354
|
-
|
|
1355
|
-
if (lower.endsWith('.mp4')) {
|
|
1171
|
+
if (lower.endsWith('.mp4'))
|
|
1356
1172
|
return 'video/mp4';
|
|
1357
|
-
|
|
1358
|
-
if (lower.endsWith('.webm')) {
|
|
1173
|
+
if (lower.endsWith('.webm'))
|
|
1359
1174
|
return 'video/webm';
|
|
1360
|
-
|
|
1361
|
-
if (lower.endsWith('.mp3')) {
|
|
1175
|
+
if (lower.endsWith('.mp3'))
|
|
1362
1176
|
return 'audio/mpeg';
|
|
1363
|
-
|
|
1364
|
-
if (lower.endsWith('.wav')) {
|
|
1177
|
+
if (lower.endsWith('.wav'))
|
|
1365
1178
|
return 'audio/wav';
|
|
1366
|
-
|
|
1367
|
-
if (lower.endsWith('.m4a')) {
|
|
1179
|
+
if (lower.endsWith('.m4a'))
|
|
1368
1180
|
return 'audio/mp4';
|
|
1369
|
-
|
|
1370
|
-
if (lower.endsWith('.pdf')) {
|
|
1181
|
+
if (lower.endsWith('.pdf'))
|
|
1371
1182
|
return 'application/pdf';
|
|
1372
|
-
}
|
|
1373
1183
|
return 'application/octet-stream';
|
|
1374
1184
|
}
|
|
1375
|
-
|
|
1185
|
+
getImageMimeType(fileNameOrPath) {
|
|
1186
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1187
|
+
if (lower.endsWith('.png'))
|
|
1188
|
+
return 'image/png';
|
|
1189
|
+
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
1190
|
+
return 'image/jpeg';
|
|
1191
|
+
if (lower.endsWith('.ico'))
|
|
1192
|
+
return 'image/x-icon';
|
|
1193
|
+
if (lower.endsWith('.svg'))
|
|
1194
|
+
return 'image/svg+xml';
|
|
1195
|
+
return 'image/png';
|
|
1196
|
+
}
|
|
1197
|
+
fromBase64(base64) {
|
|
1198
|
+
try {
|
|
1199
|
+
return decodeURIComponent(escape(atob(base64)));
|
|
1200
|
+
}
|
|
1201
|
+
catch {
|
|
1202
|
+
return atob(base64);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
isJsonFile(fileNameOrPath, contentType) {
|
|
1206
|
+
const lower = (fileNameOrPath || '').toLowerCase();
|
|
1207
|
+
return lower.endsWith('.json') || contentType === 'application/json';
|
|
1208
|
+
}
|
|
1209
|
+
getDocumentUrl(dbName, docId) {
|
|
1210
|
+
return `${this.getDbUrl(dbName)}/${encodeURIComponent(docId)}`;
|
|
1211
|
+
}
|
|
1212
|
+
getDbUrl(dbName) {
|
|
1213
|
+
return `${this.couchDbBaseUrl}/${dbName}`;
|
|
1214
|
+
}
|
|
1215
|
+
async getReadHeaders() {
|
|
1216
|
+
return {
|
|
1217
|
+
Accept: 'application/json',
|
|
1218
|
+
...(await this.buildTenantHeaders()),
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
async buildTenantHeaders() {
|
|
1222
|
+
const tenantKey = await this.utilityService.getStorage('tenantKey');
|
|
1223
|
+
const tenantName = await this.utilityService.getStorage('tenantName');
|
|
1224
|
+
const selectedTenant = await this.utilityService.getLocalStorage('selectedTenant');
|
|
1225
|
+
if (tenantKey) {
|
|
1226
|
+
if (typeof tenantKey !== 'string' || !tenantKey.trim()) {
|
|
1227
|
+
throw new Error('Missing tenantKey');
|
|
1228
|
+
}
|
|
1229
|
+
return {
|
|
1230
|
+
'X-Tenant-Key': tenantKey.trim(),
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
else {
|
|
1234
|
+
if (!tenantName && !selectedTenant) {
|
|
1235
|
+
throw new Error('Missing tenantName');
|
|
1236
|
+
}
|
|
1237
|
+
return {
|
|
1238
|
+
'X-Tenant': tenantName ? tenantName.trim() : selectedTenant.trim(),
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
async getImageSrcFromCouchDb(couchDbName, filePath) {
|
|
1243
|
+
const dbName = couchDbName?.toLowerCase();
|
|
1244
|
+
const docId = filePath?.trim();
|
|
1245
|
+
if (!docId) {
|
|
1246
|
+
throw new Error('Missing file path');
|
|
1247
|
+
}
|
|
1248
|
+
const response = await fetch(this.getDocumentUrl(dbName, docId), {
|
|
1249
|
+
method: 'GET',
|
|
1250
|
+
headers: await this.getReadHeaders(),
|
|
1251
|
+
});
|
|
1252
|
+
const doc = await this.parseJsonOrText(response);
|
|
1253
|
+
if (!response.ok) {
|
|
1254
|
+
throw new Error(`Failed to fetch image "${docId}" from "${dbName}": ${response.status} ${this.stringifyErrorDetails(doc)}`);
|
|
1255
|
+
}
|
|
1256
|
+
if (!doc?.data) {
|
|
1257
|
+
throw new Error(`Document "${docId}" does not contain image data`);
|
|
1258
|
+
}
|
|
1259
|
+
const mimeType = doc.contentType || 'image/png';
|
|
1260
|
+
return `data:${mimeType};base64,${doc.data}`;
|
|
1261
|
+
}
|
|
1262
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: Couchdb, deps: [{ token: UtilityService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1376
1263
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: Couchdb, providedIn: 'root' });
|
|
1377
1264
|
}
|
|
1378
1265
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: Couchdb, decorators: [{
|
|
@@ -1380,7 +1267,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
1380
1267
|
args: [{
|
|
1381
1268
|
providedIn: 'root',
|
|
1382
1269
|
}]
|
|
1383
|
-
}], ctorParameters: () => [{ type: UtilityService }
|
|
1270
|
+
}], ctorParameters: () => [{ type: UtilityService }] });
|
|
1384
1271
|
|
|
1385
1272
|
class ConfigService {
|
|
1386
1273
|
couchdbService;
|