T24: Add try/catch to export functions, use shared types, return ExportResult
This commit is contained in:
@@ -1,64 +1,14 @@
|
||||
import type { YjsDocument } from '../crdt/YjsDocument';
|
||||
import type {
|
||||
CADLayer,
|
||||
CADProperties,
|
||||
CADElement,
|
||||
ExportData,
|
||||
ExportOptions,
|
||||
ExportResult,
|
||||
} from '../types/cad.types';
|
||||
|
||||
// ── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
interface CADLayer {
|
||||
id: string;
|
||||
name: string;
|
||||
visible: boolean;
|
||||
locked: boolean;
|
||||
color?: string;
|
||||
lineType?: string;
|
||||
transparency?: number;
|
||||
sortOrder?: number;
|
||||
}
|
||||
|
||||
interface CADProperties {
|
||||
fill?: string;
|
||||
stroke?: string;
|
||||
strokeWidth?: number;
|
||||
rotation?: number;
|
||||
lineType?: 'solid' | 'dashed' | 'dotted';
|
||||
radius?: number;
|
||||
x1?: number;
|
||||
y1?: number;
|
||||
x2?: number;
|
||||
y2?: number;
|
||||
points?: Array<{ x: number; y: number }>;
|
||||
text?: string;
|
||||
fontSize?: number;
|
||||
startAngle?: number;
|
||||
endAngle?: number;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
interface CADElement {
|
||||
id: string;
|
||||
type: string;
|
||||
layerId: string;
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
properties: CADProperties;
|
||||
}
|
||||
|
||||
interface ExportData {
|
||||
version: string;
|
||||
exportedAt: number;
|
||||
projectMeta: Record<string, unknown>;
|
||||
layers: CADLayer[];
|
||||
elements: CADElement[];
|
||||
}
|
||||
|
||||
interface ExportOptions {
|
||||
includeHiddenLayers?: boolean;
|
||||
includeInvisibleElements?: boolean;
|
||||
pageSize?: 'a4' | 'a3' | 'letter';
|
||||
landscape?: boolean;
|
||||
}
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
function hexToRgb(hex: string): { r: number; g: number; b: number } {
|
||||
const clean = hex.replace('#', '');
|
||||
@@ -150,22 +100,39 @@ function downloadBlob(content: string | Blob, filename: string, mimeType: string
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
// ── JSON Export ──────────────────────────────────────────────────────────────
|
||||
// ── JSON Export ───────────────────────────────────────────────────────────────
|
||||
|
||||
export function exportJSON(yjsDoc: YjsDocument, filename = 'cad-export.json'): void {
|
||||
export function exportJSON(yjsDoc: YjsDocument, filename = 'cad-export.json'): ExportResult {
|
||||
try {
|
||||
const data = collectExportData(yjsDoc, {});
|
||||
const json = JSON.stringify(data, null, 2);
|
||||
downloadBlob(json, filename, 'application/json');
|
||||
return { success: true, data: json };
|
||||
} catch (e) {
|
||||
return {
|
||||
success: false,
|
||||
error: `exportJSON failed: ${(e as Error).message}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function exportJSONString(yjsDoc: YjsDocument): string {
|
||||
export function exportJSONString(yjsDoc: YjsDocument): ExportResult {
|
||||
try {
|
||||
const data = collectExportData(yjsDoc, {});
|
||||
return JSON.stringify(data, null, 2);
|
||||
const json = JSON.stringify(data, null, 2);
|
||||
return { success: true, data: json };
|
||||
} catch (e) {
|
||||
return {
|
||||
success: false,
|
||||
error: `exportJSONString failed: ${(e as Error).message}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ── SVG Export ───────────────────────────────────────────────────────────────
|
||||
// ── SVG Export ────────────────────────────────────────────────────────────────
|
||||
|
||||
export function exportSVG(yjsDoc: YjsDocument, filename = 'cad-export.svg', options: ExportOptions = {}): void {
|
||||
export function exportSVG(yjsDoc: YjsDocument, filename = 'cad-export.svg', options: ExportOptions = {}): ExportResult {
|
||||
try {
|
||||
const data = collectExportData(yjsDoc, options);
|
||||
|
||||
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
||||
@@ -262,11 +229,19 @@ export function exportSVG(yjsDoc: YjsDocument, filename = 'cad-export.svg', opti
|
||||
svgParts.push('</svg>');
|
||||
const svg = svgParts.join('\n');
|
||||
downloadBlob(svg, filename, 'image/svg+xml');
|
||||
return { success: true, data: svg };
|
||||
} catch (e) {
|
||||
return {
|
||||
success: false,
|
||||
error: `exportSVG failed: ${(e as Error).message}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ── DXF Export ───────────────────────────────────────────────────────────────
|
||||
// ── DXF Export ────────────────────────────────────────────────────────────────
|
||||
|
||||
export function exportDXF(yjsDoc: YjsDocument, filename = 'cad-export.dxf', options: ExportOptions = {}): void {
|
||||
export function exportDXF(yjsDoc: YjsDocument, filename = 'cad-export.dxf', options: ExportOptions = {}): ExportResult {
|
||||
try {
|
||||
const data = collectExportData(yjsDoc, options);
|
||||
const lines: string[] = [];
|
||||
|
||||
@@ -424,15 +399,23 @@ export function exportDXF(yjsDoc: YjsDocument, filename = 'cad-export.dxf', opti
|
||||
|
||||
const dxf = lines.join('\n');
|
||||
downloadBlob(dxf, filename, 'application/dxf');
|
||||
return { success: true, data: dxf };
|
||||
} catch (e) {
|
||||
return {
|
||||
success: false,
|
||||
error: `exportDXF failed: ${(e as Error).message}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ── PDF Export ───────────────────────────────────────────────────────────────
|
||||
// ── PDF Export ────────────────────────────────────────────────────────────────
|
||||
|
||||
export async function exportPDF(
|
||||
yjsDoc: YjsDocument,
|
||||
filename = 'cad-export.pdf',
|
||||
options: ExportOptions = {}
|
||||
): Promise<void> {
|
||||
): Promise<ExportResult> {
|
||||
try {
|
||||
const data = collectExportData(yjsDoc, options);
|
||||
|
||||
const { jsPDF } = await import('jspdf');
|
||||
@@ -553,9 +536,16 @@ export async function exportPDF(
|
||||
);
|
||||
|
||||
pdf.save(filename);
|
||||
return { success: true };
|
||||
} catch (e) {
|
||||
return {
|
||||
success: false,
|
||||
error: `exportPDF failed: ${(e as Error).message}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ── Unified Export ───────────────────────────────────────────────────────────
|
||||
// ── Unified Export ─────────────────────────────────────────────────────────────
|
||||
|
||||
export type ExportFormat = 'json' | 'svg' | 'dxf' | 'pdf';
|
||||
|
||||
@@ -564,7 +554,7 @@ export async function exportDrawing(
|
||||
format: ExportFormat,
|
||||
filename?: string,
|
||||
options?: ExportOptions
|
||||
): Promise<void> {
|
||||
): Promise<ExportResult> {
|
||||
const ext = format;
|
||||
const name = filename || `cad-export.${ext}`;
|
||||
|
||||
@@ -578,6 +568,9 @@ export async function exportDrawing(
|
||||
case 'pdf':
|
||||
return exportPDF(yjsDoc, name, options);
|
||||
default:
|
||||
throw new Error(`Unsupported export format: ${format}`);
|
||||
return {
|
||||
success: false,
|
||||
error: `Unsupported export format: ${format}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user