| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import { readFile, writeFile } from 'fs/promises';
- import path from 'path';
- import { fileURLToPath } from 'url';
- import { LibraryItem, LibraryItems } from '@excalidraw/excalidraw/types'
- // 如果新增了自定义素材,则需要运行这个脚本将素材同步到lib文件夹,以便下次合成素材库时,不会清除新增素材
- const __filename = fileURLToPath(import.meta.url);
- const __dirname = path.dirname(__filename);
- const inputFile = path.resolve(__dirname, '../library.excalidrawlib'); // 输入目录
- const outputFile = path.resolve(__dirname, '../lib/library.excalidrawlib'); // 输出文件路径
- interface ExportedLibraryData {
- type: string;
- version: number;
- source: string;
- libraryItems: LibraryItems;
- }
- function isExcalidrawlibFile(fileName: string): boolean {
- return fileName.endsWith('.excalidrawlib');
- }
- /**
- * checks if library item does not exist already in current library
- */
- const isUniqueItem = (
- existingLibraryItems: LibraryItems,
- targetLibraryItem: LibraryItem,
- ) => {
- return !existingLibraryItems.find((libraryItem) => {
- if (libraryItem.elements.length !== targetLibraryItem.elements.length) {
- return false;
- }
- // detect z-index difference by checking the excalidraw elements
- // are in order
- return libraryItem.elements.every((libItemExcalidrawItem, idx) => {
- return (
- libItemExcalidrawItem.id === targetLibraryItem.elements[idx].id &&
- libItemExcalidrawItem.versionNonce ===
- targetLibraryItem.elements[idx].versionNonce
- );
- });
- });
- };
- function positionError(obj: any, msg?: string): false {
- console.error({
- error_msg: msg,
- error_obj: obj
- })
- return false
- }
- function isLibraryItem(obj: any): obj is LibraryItem {
- if (!obj) return positionError(obj, "LibraryItem obj does not exist")
- if (!obj.id || !obj.status || !obj.elements || !obj.created) return positionError(obj, "obj missing fields")
- if (typeof obj.id !== 'string') return positionError(obj, "obj.id type is not string")
- if (obj.status !== "published" && obj.status !== "unpublished") return positionError(obj, "obj.status value is wrong")
- if (!Array.isArray(obj.elements)) return positionError(obj, "obj.elements is not an array")
- if (typeof obj.created !== 'number') return positionError(obj, "obj.created type is not number")
- return true
- }
- function isLibraryItems(obj: any): obj is LibraryItems {
- if (!obj) return positionError(obj, "LibraryItems obj does not exist")
- if (!Array.isArray(obj)) return positionError(obj, "obj is not an array")
- for (const item of obj) {
- if (!isLibraryItem(item)) return positionError(obj, "LibraryItems is not an array")
- }
- return true
- }
- function isExportedLibraryData(obj: any): obj is ExportedLibraryData {
- if (!obj) return positionError(obj, "ExportedLibraryData obj does not exist")
- if (obj.type !== "excalidrawlib") return positionError(obj, "obj.type value is not excalidrawlib")
- if (typeof obj.version !== "number") return positionError(obj, "obj.version type is not number")
- if (!obj.libraryItems || !isLibraryItems(obj.libraryItems)) return positionError(obj, "The library array does not exist or is wrong")
- return true
- }
- async function readExcalidrawlibFile(filePath: string): Promise<ExportedLibraryData> {
- const content = await readFile(filePath, 'utf-8');
- const parsed = JSON.parse(content);
- if (!isExportedLibraryData(parsed)) {
- console.error({filePath, parsed})
- throw new Error(`Invalid excalidrawlib file: ${filePath}`);
- }
- return parsed;
- }
- async function updateExcalidrawlibFile(inputFilePath: string, outputFilePath: string): Promise<ExportedLibraryData | undefined> {
- if (!isExcalidrawlibFile(inputFilePath)) return undefined
- if (!isExcalidrawlibFile(outputFilePath)) return undefined
- const originalData = await readExcalidrawlibFile(outputFilePath);
- const inputData = await readExcalidrawlibFile(inputFilePath);
- const exportedLibraryData: ExportedLibraryData = {
- type: originalData.type,
- version: originalData.version,
- source: originalData.source,
- libraryItems: []
- }
- inputData.libraryItems.map(item => {
- if (item.status === 'unpublished' && isUniqueItem(originalData.libraryItems, item)) {
- exportedLibraryData.libraryItems = [
- ...exportedLibraryData.libraryItems,
- {...item}
- ]
- }
- })
- return exportedLibraryData;
- }
- async function saveUpdatedExcalidrawlib(data: ExportedLibraryData, filePath: string) {
- const jsonString = JSON.stringify(data, null, 2); // 缩进美化
- await writeFile(filePath, jsonString, 'utf-8');
- console.log(`✅ 更新完成,已保存到 ${filePath}`);
- }
- // 执行流程
- const updated = await updateExcalidrawlibFile(inputFile, outputFile);
- if (updated !== undefined) {
- saveUpdatedExcalidrawlib(updated, outputFile);
- }
|