UNPKG

@workspace-fs/core

Version:

Multi-project workspace manager for Firesystem with support for multiple sources

173 lines (153 loc) 4.25 kB
import type { WorkspaceConfig, ProjectConfig } from "../types"; export interface WorkspaceExport { version: string; exportedAt: Date; workspace: { settings?: any; activeProjectId?: string; }; projects: Array<{ id: string; name: string; type: "memory" | "indexeddb" | "s3"; config?: any; files?: Array<{ path: string; content: string; metadata?: Record<string, any>; }>; }>; } /** * Handles import/export of workspace configurations */ export class WorkspaceImporter { /** * Import workspace from JSON URL */ static async fromJsonUrl(url: string): Promise<WorkspaceConfig> { const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to fetch workspace: ${response.statusText}`); } const data: WorkspaceExport = await response.json(); return this.parseExport(data); } /** * Import workspace from GitHub Gist */ static async fromGitHubGist( gistId: string, token?: string, ): Promise<WorkspaceConfig> { const headers: Record<string, string> = { Accept: "application/vnd.github.v3+json", }; if (token) { headers["Authorization"] = `token ${token}`; } const response = await fetch(`https://api.github.com/gists/${gistId}`, { headers, }); if (!response.ok) { throw new Error(`Failed to fetch gist: ${response.statusText}`); } const gist = await response.json(); // Look for workspace.json file in the gist const workspaceFile = Object.values(gist.files).find( (file: any) => file.filename === "workspace.json", ) as any; if (!workspaceFile) { throw new Error("No workspace.json found in gist"); } const data: WorkspaceExport = JSON.parse(workspaceFile.content); return this.parseExport(data); } /** * Import workspace from API endpoint */ static async fromApi( url: string, options?: { headers?: Record<string, string>; method?: string; body?: any; }, ): Promise<WorkspaceConfig> { const response = await fetch(url, { method: options?.method || "GET", headers: { "Content-Type": "application/json", ...options?.headers, }, body: options?.body ? JSON.stringify(options.body) : undefined, }); if (!response.ok) { throw new Error(`Failed to fetch from API: ${response.statusText}`); } const data: WorkspaceExport = await response.json(); return this.parseExport(data); } /** * Parse export data into workspace config */ private static parseExport(data: WorkspaceExport): WorkspaceConfig { // Validate version if (!data.version || !data.version.startsWith("1.")) { throw new Error(`Unsupported workspace version: ${data.version}`); } const projects: ProjectConfig[] = data.projects.map((p) => { // Determine source based on type and presence of files let source: any; if (p.files && p.files.length > 0) { // If files are included, create memory source with initial data source = { type: "memory", config: { initialData: p.files.reduce( (acc, file) => { acc[file.path] = { content: file.content, metadata: file.metadata, }; return acc; }, {} as Record<string, any>, ), }, }; } else if (p.type === "indexeddb") { // IndexedDB reference source = { type: "indexeddb", config: { dbName: p.config?.dbName || `firesystem-${p.id}`, }, }; } else if (p.type === "s3") { // S3 reference source = { type: "s3", config: p.config, }; } else { // Default to empty memory source = { type: "memory", config: {}, }; } return { id: p.id, name: p.name, source, }; }); return { version: data.version, projects, activeProjectId: data.workspace.activeProjectId, settings: data.workspace.settings, }; } }