feat(ai): export assistant analysis result as markdown
This commit is contained in:
1 parent
ce3bb09796
commit
f64d363abe
15 files changed
+542
-62
No files matched your search
@@ -0,0 +1,28 @@
|
||||
import { compactLocalTimestamp, sanitizeExportBaseName } from "./saveTextFile";
|
||||
|
||||
export interface BuildAiAnalysisExportInput {
|
||||
connectionName?: string;
|
||||
content: string;
|
||||
analysisLabel: string;
|
||||
dateLabel: string;
|
||||
}
|
||||
|
||||
export interface BuildAiAnalysisExportOutput {
|
||||
markdown: string;
|
||||
defaultFileName: string;
|
||||
}
|
||||
|
||||
export function buildAiAnalysisExport(input: BuildAiAnalysisExportInput): BuildAiAnalysisExportOutput | null {
|
||||
if (!input.content.trim()) return null;
|
||||
|
||||
const rawName = input.connectionName || "";
|
||||
const sanitizedName = sanitizeExportBaseName(rawName) || "ai";
|
||||
const displayName = rawName || "AI";
|
||||
|
||||
const headerLines = [`# ${displayName} · ${input.analysisLabel}`, `${input.dateLabel}`, ""];
|
||||
const markdown = headerLines.join("\n") + input.content;
|
||||
|
||||
const defaultFileName = `${sanitizedName}_${compactLocalTimestamp()}.md`;
|
||||
|
||||
return { markdown, defaultFileName };
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
|
||||
|
||||
export async function saveTextFile(content: string, defaultFileName: string, filterName: string, filterExt: string) {
|
||||
if (isTauriRuntime()) {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
const path = await save({
|
||||
defaultPath: defaultFileName,
|
||||
filters: [{ name: filterName, extensions: [filterExt] }],
|
||||
});
|
||||
if (path) await writeTextFile(path, content);
|
||||
return;
|
||||
}
|
||||
|
||||
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = defaultFileName;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
export function sanitizeExportBaseName(value: string): string {
|
||||
return replaceControlCharacters(
|
||||
value
|
||||
.trim()
|
||||
.replace(/\.[sS][qQ][lL]$/, "")
|
||||
.replace(/[<>:"/\\|?*]/g, "_"),
|
||||
"_",
|
||||
)
|
||||
.replace(/\s+/g, " ")
|
||||
.replace(/[._\s-]+$/g, "")
|
||||
.slice(0, 120);
|
||||
}
|
||||
|
||||
function replaceControlCharacters(value: string, replacement: string): string {
|
||||
return Array.from(value)
|
||||
.map((char) => (char.charCodeAt(0) < 32 ? replacement : char))
|
||||
.join("");
|
||||
}
|
||||
|
||||
export function compactLocalTimestamp(date = new Date()): string {
|
||||
const yy = String(date.getFullYear() % 100).padStart(2, "0");
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
const hour = String(date.getHours()).padStart(2, "0");
|
||||
const minute = String(date.getMinutes()).padStart(2, "0");
|
||||
const second = String(date.getSeconds()).padStart(2, "0");
|
||||
return `${yy}${month}${day}${hour}${minute}${second}`;
|
||||
}
|
||||
Reference in new issue
Block a user