UNPKG

@fontoxml/fontoxml-development-tools

Version:

Development tools for Fonto.

162 lines (136 loc) 4.03 kB
import fs from 'fs-extra'; import path from 'path'; import utf8 from 'to-utf-8'; import mergeItems from './mergeItems.js'; /** @typedef {import('../../../src/getAppConfig.js').DevCmsConfig} DevCmsConfig */ export default class FileSystemStore { /** * @param {DevCmsConfig} config * @param {{[ extension: string]: string }} assetTypeByExtension */ constructor(config, assetTypeByExtension) { this._filesRootPath = path.join(config.root, 'dev-cms', 'files'); this._uploadsRootPath = path.join(config.root, 'dev-cms', 'uploads'); this._assetTypeByExtension = assetTypeByExtension; this._documentTemplateMetadataByFilename = {}; const documentTemplateMetadataJsonPath = path.join( config.root, 'dev-cms', 'stubs', 'document-template-metadata.json', ); if (fs.existsSync(documentTemplateMetadataJsonPath)) { try { this._documentTemplateMetadataByFilename = fs.readJsonSync( documentTemplateMetadataJsonPath, ); } catch (error) { console.error( `\nError reading document-template-metadata.json file at "${documentTemplateMetadataJsonPath}"`, error, ); throw error; } } } _getPathForFile(fileRelativePath) { if (!fileRelativePath || fileRelativePath === '.') { return null; } const pathInUploads = path.join(this._uploadsRootPath, fileRelativePath); if (fs.existsSync(pathInUploads)) { return pathInUploads; } const pathInFiles = path.join(this._filesRootPath, fileRelativePath); if (fs.existsSync(pathInFiles)) { return pathInFiles; } return null; } getPathSync(filePath) { return this._getPathForFile(filePath); } existsSync(filePath) { return !!this.getPathSync(filePath); } load(filePath) { return new Promise((resolve, reject) => { const absoluteFilePath = this.getPathSync(filePath); if (!absoluteFilePath) { resolve(null); return; } const stream = fs.createReadStream(absoluteFilePath); let isDone = false; let data = ''; stream.on('data', (dataPart) => (data += dataPart)); stream.on('end', () => { if (isDone) { return; } isDone = true; resolve(data); }); // Register the `error` event handler before starting the stream: stream.on('error', (error) => { if (isDone) { return; } isDone = true; reject(error); }); stream.pipe(utf8({ newline: false, detectSize: 10485760 })); }); } async save(filePath, content) { // Save file to disk (in dev-cms/uploads) const filePathInUploads = path.join(this._uploadsRootPath, filePath); await fs.outputFile(filePathInUploads, content); } removeSync(filePath) { // Only remove from uploads, files is read-only fs.removeSync(path.join(this._uploadsRootPath, filePath)); } _getFileType(filePath) { if (fs.lstatSync(filePath).isDirectory()) { return 'folder'; } const fileExtension = path.extname(filePath).substring(1).toLowerCase(); return this._assetTypeByExtension[fileExtension] || 'unknown'; } _listPathSync(rootPath, folderPath, metadata) { const folderPathInRoot = path.join(rootPath, folderPath); if (!fs.existsSync(folderPathInRoot)) { return null; } return fs .readdirSync(folderPathInRoot) .filter((filename) => !filename.startsWith('.')) .map((filename) => { const filePath = path.join(folderPathInRoot, filename); let fileId = path.relative(rootPath, filePath); if (path.sep === '\\') { fileId = fileId.replace(/\\/g, '/'); } return { id: fileId, type: this._getFileType(filePath), label: filename, metadata: { ...metadata, ...this._documentTemplateMetadataByFilename[filename], }, }; }); } listSync(folderPath) { const filesItems = this._listPathSync(this._filesRootPath, folderPath, {}); const uploadsItems = this._listPathSync(this._uploadsRootPath, folderPath, { isCmsUpload: true, }); if (!filesItems && !uploadsItems) { return null; } return mergeItems(filesItems, uploadsItems); } }