in apps/chat/src/utils/app/import-export.ts [110:382]
folderId: getConversationRootId(),
})),
prompts: [],
isError: false,
};
}
if (isExportFormatV3(data)) {
return {
history: cleanConversationHistory(data.history),
folders: [...data.folders],
version: 5,
prompts: [],
isError: false,
};
}
if (isExportFormatV4(data)) {
return {
...data,
version: 5,
history: cleanConversationHistory(data.history),
prompts: data.prompts || [],
isError: false,
};
}
if (isExportFormatV5(data)) {
return {
...data,
history: cleanConversationHistory(data.history),
prompts: data.prompts || [],
isError: false,
};
}
return {
version: 5,
history: [],
folders: [],
prompts: [],
isError: true,
};
}
export function currentDate() {
const date = new Date();
const month = date.getMonth() + 1;
const day = date.getDate();
return `${month}-${day}`;
}
type ExportType =
| 'conversation'
| 'conversations_history'
| 'prompt'
| 'prompts_history';
export const getDownloadFileName = (fileName?: string): string =>
!fileName ? 'ai_dial' : fileName.toLowerCase().replaceAll(' ', '_');
function downloadChatPromptData(
data: LatestExportConversationsFormat | Prompt[] | PromptsHistory,
exportType: ExportType,
fileName?: string,
) {
const blob = new Blob([JSON.stringify(data, null, 2)], {
type: 'application/json',
});
const url = URL.createObjectURL(blob);
const downloadName = getDownloadFileName(fileName);
triggerDownload(
url,
`${downloadName}_chat_${exportType}_${currentDate()}.json`,
);
}
export function downloadApplicationLogs(data: string, fileName?: string) {
const exportedFileName = [fileName, 'application_logs', currentDate()]
.filter(Boolean)
.join('_');
const blob = new Blob([data], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
triggerDownload(url, exportedFileName);
}
const triggerDownloadConversation = (
data: LatestExportConversationsFormat,
appName?: string,
) => {
downloadChatPromptData(data, 'conversation', appName);
};
const triggerDownloadConversationsHistory = (
data: LatestExportConversationsFormat,
appName?: string,
) => {
downloadChatPromptData(data, 'conversations_history', appName);
};
const triggerDownloadPromptsHistory = (
data: PromptsHistory,
appName?: string,
) => {
downloadChatPromptData(data, 'prompts_history', appName);
};
const triggerDownloadPrompt = (data: PromptsHistory, appName?: string) => {
downloadChatPromptData(data, 'prompt', appName);
};
export const exportConversation = (
conversation: Conversation,
folders: FolderInterface[],
appName?: string,
) => {
const data: LatestExportConversationsFormat = {
version: 5,
history: [excludePublicationInfo(conversation)],
folders: folders,
};
triggerDownloadConversation(data, appName);
};
interface PrepareConversationsForExport {
conversations: Conversation[];
folders: FolderInterface[];
}
export const prepareConversationsForExport = ({
conversations,
folders,
}: PrepareConversationsForExport) => {
const data = {
version: 5,
history: conversations?.map(excludePublicationInfo) || [],
folders: folders || [],
} as LatestExportConversationsFormat;
return data;
};
export const exportConversations = (
conversations: Conversation[],
folders: FolderInterface[],
appName?: string,
version = 5,
) => {
const data = {
version,
history: conversations?.map(excludePublicationInfo) || [],
folders: folders || [],
} as LatestExportConversationsFormat;
triggerDownloadConversationsHistory(data, appName);
};
export const exportPrompts = (
prompts: Prompt[],
folders: FolderInterface[],
appName?: string,
) => {
const data = {
prompts: prompts.map(excludePublicationInfo),
folders,
};
triggerDownloadPromptsHistory(data, appName);
};
export const exportPrompt = (
prompt: Prompt,
folders: FolderInterface[],
appName?: string,
) => {
const promptsToExport: Prompt[] = [excludePublicationInfo(prompt)];
const data: PromptsHistory = {
prompts: promptsToExport,
folders,
};
triggerDownloadPrompt(data, appName);
};
export const updateAttachment = ({
oldAttachment,
uploadedAttachments,
}: {
oldAttachment: Attachment;
uploadedAttachments: UploadedAttachment[];
}) => {
const oldAttachmentUrl = oldAttachment.url || oldAttachment.reference_url;
if (!oldAttachmentUrl) {
return oldAttachment;
}
const oldAttachmentDecodedUrl = ApiUtils.decodeApiUrl(oldAttachmentUrl);
const { name, parentPath } = splitEntityId(oldAttachmentDecodedUrl);
const oldAttachmentRelativePath = constructPath(parentPath, name);
const splitByHash = (stringToSplit: string) => {
const nameArr = stringToSplit.split('#');
const oldName = nameArr[0];
const oldHash = nameArr[nameArr.length - 1];
return {
oldName,
oldHash,
};
};
const { oldHash } = splitByHash(name);
const { oldName: cleanOldAttachmentRelativePath } = splitByHash(
oldAttachmentRelativePath,
);
const newAttachmentFile = uploadedAttachments.find(({ oldRelativePath }) => {
return oldRelativePath === cleanOldAttachmentRelativePath;
});
const newAttachmentUrl =
(oldAttachment.url || oldAttachment.reference_url) &&
(newAttachmentFile
? constructPath(newAttachmentFile.absolutePath, newAttachmentFile.name)
: constructPath(getFileRootId(), parentPath, name));
const encodedNewAttachmentUrl =
newAttachmentUrl && ApiUtils.encodeApiUrl(newAttachmentUrl);
const newReferenceUrl =
oldAttachment.reference_url &&
encodedNewAttachmentUrl &&
`${encodedNewAttachmentUrl}#${oldHash}`;
const newType = oldAttachment.type ?? newAttachmentFile?.contentType;
const newTitle =
oldAttachment.type === PLOTLY_CONTENT_TYPE
? (oldAttachment.title ?? newAttachmentFile?.name)
: (newAttachmentFile?.name ?? oldAttachment.title);
const updatedAttachment: Attachment = {
...oldAttachment,
title: newTitle,
type: newType,
url: encodedNewAttachmentUrl,
reference_url: newReferenceUrl,
};
return updatedAttachment;
};
export const getDuplicatedConversations = (
preparedConversations: Conversation[],
): Observable<{
newConversations: Conversation[];
duplicatedConversations: Conversation[];
}> => {
return ConversationService.getConversations(undefined, true).pipe(
map((conversationsListing) => {
const existedImportNamesConversations = preparedConversations.filter(
(importConv) =>
!isImportEntityNameOnSameLevelUnique({
entity: importConv,
entities: conversationsListing,
}),
);
const nonExistedImportNamesConversations = preparedConversations.filter(
(importConv) => {
return isImportEntityNameOnSameLevelUnique({