import useDatabase from "~/composables/useDatabase"; import { extname, basename } from 'node:path'; import type { FileType } from '~/types/content'; import type { CanvasColor, CanvasContent } from "~/types/canvas"; import { explorerContentTable } from "~/db/schema"; import { convertToStorableLinks } from "../api/file.post"; const typeMapping: Record = { ".md": "markdown", ".canvas": "canvas" }; export default defineTask({ meta: { name: 'pull', description: 'Pull the data from Git', }, async run(event) { try { const tree = await $fetch('https://git.peaceultime.com/api/v1/repos/peaceultime/system-aspect/git/trees/master', { method: 'get', headers: { accept: 'application/json', }, params: { recursive: true, per_page: 1000, } }) as { tree: any[] } & Record; const files: typeof explorerContentTable.$inferInsert[] = await Promise.all(tree.tree.filter((e: any) => !e.path.startsWith(".")).map(async (e, i) => { if(e.type === 'tree') { const title = basename(e.path); const order = /(\d+)\. ?(.+)/gsmi.exec(title); const path = (e.path as string).split('/').map(f => { const check = /(\d+)\. ?(.+)/gsmi.exec(f); return check && check[2] ? check[2] : f }).join('/'); return { path: path.toLowerCase().replaceAll(" ", "-").normalize("NFD").replace(/[\u0300-\u036f]/g, ""), order: i, title: order && order[2] ? order[2] : title, type: 'folder', content: null, owner: '1', navigable: true, private: e.path.startsWith('98.Privé'), } } const extension = extname(e.path); const title = basename(e.path, extension); const order = /(\d+)\. ?(.+)/gsmi.exec(title); const path = (e.path as string).split('/').map(f => { const check = /(\d+)\. ?(.+)/gsmi.exec(f); return check && check[2] ? check[2] : f }).join('/'); const content = (await $fetch(`https://git.peaceultime.com/api/v1/repos/peaceultime/system-aspect/raw/${encodeURIComponent(e.path)}`)); return { path: (extension === '.md' ? path.replace(extension, '') : path).toLowerCase().replaceAll(" ", "-").normalize("NFD").replace(/[\u0300-\u036f]/g, ""), order: i, title: order && order[2] ? order[2] : title, type: (typeMapping[extension] ?? 'file'), content: reshapeContent(content as string, typeMapping[extension] ?? 'File'), owner: '1', navigable: true, private: e.path.startsWith('98.Privé') } })); const pathList = files.map(e => e.path); files.forEach(e => { if(e.type !== 'folder' && e.content) { e.content = Buffer.from(convertToStorableLinks(e.content.toString('utf-8'), files.map(e => e.path)), 'utf-8'); } }) const db = useDatabase(); db.delete(explorerContentTable).run(); db.insert(explorerContentTable).values(files).run(); return { result: true }; } catch(e) { console.error(e); return { result: false, error: e }; } }, }) function reshapeContent(content: string, type: FileType): string | null { switch(type) { case "markdown": return content.replaceAll(/!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/g, (e: string, a1?: string, a2?: string , a3?: string) => { return `[[${a1?.split('/').map(f => { const check = /(\d+)\. ?(.+)/gsmi.exec(f); return check && check[2] ? check[2] : f }).join('/') ?? ''}${a2 ?? ''}${a3 ?? ''}]]`; }); case "file": return content; case "canvas": const data = JSON.parse(content) as CanvasContent; data.edges.forEach(e => e.color = typeof e.color === 'string' ? getColor(e.color) : undefined); data.nodes.forEach(e => e.color = typeof e.color === 'string' ? getColor(e.color) : undefined); return JSON.stringify(data); default: case 'folder': return null; } } function getColor(color: string): CanvasColor { const colors: Record = { '1': 'red', '2': 'orange', '3': 'yellow', '4': 'green', '5': 'cyan', '6': 'purple', }; if(colors.hasOwnProperty(color)) return { class: colors[color] }; else return { hex: color }; }