UNPKG

decap-cms-backend-test

Version:

Development testing backend for Decap CMS

365 lines (364 loc) 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.getFolderFiles = getFolderFiles; var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty")); var _unset2 = _interopRequireDefault(require("lodash/unset")); var _take2 = _interopRequireDefault(require("lodash/take")); var _isError2 = _interopRequireDefault(require("lodash/isError")); var _attempt2 = _interopRequireDefault(require("lodash/attempt")); var _uuid = require("uuid"); var _decapCmsLibUtil = require("decap-cms-lib-util"); var _path = require("path"); var _AuthenticationPage = _interopRequireDefault(require("./AuthenticationPage")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } window.repoFiles = window.repoFiles || {}; window.repoFilesUnpublished = window.repoFilesUnpublished || []; function getFile(path, tree) { const segments = path.split('/'); let obj = tree; while (obj && segments.length) { obj = obj[segments.shift()]; } return obj || {}; } function writeFile(path, content, tree) { const segments = path.split('/'); let obj = tree; while (segments.length > 1) { const segment = segments.shift(); obj[segment] = obj[segment] || {}; obj = obj[segment]; } obj[segments.shift()] = { content, path }; } function deleteFile(path, tree) { (0, _unset2.default)(tree, path.split('/')); } const pageSize = 10; function getCursor(folder, extension, entries, index, depth) { const count = entries.length; const pageCount = Math.floor(count / pageSize); return _decapCmsLibUtil.Cursor.create({ actions: [...(index < pageCount ? ['next', 'last'] : []), ...(index > 0 ? ['prev', 'first'] : [])], meta: { index, count, pageSize, pageCount }, data: { folder, extension, index, pageCount, depth } }); } function getFolderFiles(tree, folder, extension, depth, files = [], path = folder) { if (depth <= 0) { return files; } Object.keys(tree[folder] || {}).forEach(key => { if ((0, _path.extname)(key)) { const file = tree[folder][key]; if (!extension || key.endsWith(`.${extension}`)) { files.unshift({ content: file.content, path: `${path}/${key}` }); } } else { const subTree = tree[folder]; return getFolderFiles(subTree, key, extension, depth - 1, files, `${path}/${key}`); } }); return files; } class TestBackend { constructor(config, options = {}) { _defineProperty(this, "mediaFolder", void 0); _defineProperty(this, "options", void 0); this.options = options; this.mediaFolder = config.media_folder; } isGitBackend() { return false; } status() { return Promise.resolve({ auth: { status: true }, api: { status: true, statusPage: '' } }); } authComponent() { return _AuthenticationPage.default; } restoreUser() { return this.authenticate(); } authenticate() { return Promise.resolve(); } logout() { return null; } getToken() { return Promise.resolve(''); } traverseCursor(cursor, action) { const { folder, extension, index, pageCount, depth } = cursor.data.toObject(); const newIndex = (() => { if (action === 'next') { return index + 1; } if (action === 'prev') { return index - 1; } if (action === 'first') { return 0; } if (action === 'last') { return pageCount; } return 0; })(); // TODO: stop assuming cursors are for collections const allFiles = getFolderFiles(window.repoFiles, folder, extension, depth); const allEntries = allFiles.map(f => ({ data: f.content, file: { path: f.path, id: f.path } })); const entries = allEntries.slice(newIndex * pageSize, newIndex * pageSize + pageSize); const newCursor = getCursor(folder, extension, allEntries, newIndex, depth); return Promise.resolve({ entries, cursor: newCursor }); } entriesByFolder(folder, extension, depth) { const files = folder ? getFolderFiles(window.repoFiles, folder, extension, depth) : []; const entries = files.map(f => ({ data: f.content, file: { path: f.path, id: f.path } })); const cursor = getCursor(folder, extension, entries, 0, depth); const ret = (0, _take2.default)(entries, pageSize); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ret[_decapCmsLibUtil.CURSOR_COMPATIBILITY_SYMBOL] = cursor; return Promise.resolve(ret); } entriesByFiles(files) { return Promise.all(files.map(file => ({ file, data: getFile(file.path, window.repoFiles).content }))); } getEntry(path) { return Promise.resolve({ file: { path, id: null }, data: getFile(path, window.repoFiles).content }); } unpublishedEntries() { return Promise.resolve(Object.keys(window.repoFilesUnpublished)); } unpublishedEntry({ id, collection, slug }) { if (id) { const parts = id.split('/'); collection = parts[0]; slug = parts[1]; } const entry = window.repoFilesUnpublished[`${collection}/${slug}`]; if (!entry) { return Promise.reject(new _decapCmsLibUtil.EditorialWorkflowError('content is not under editorial workflow', true)); } return Promise.resolve(entry); } async unpublishedEntryDataFile(collection, slug, path) { const entry = window.repoFilesUnpublished[`${collection}/${slug}`]; const file = entry.diffs.find(d => d.path === path); return file === null || file === void 0 ? void 0 : file.content; } async unpublishedEntryMediaFile(collection, slug, path) { const entry = window.repoFilesUnpublished[`${collection}/${slug}`]; const file = entry.diffs.find(d => d.path === path); return this.normalizeAsset(file === null || file === void 0 ? void 0 : file.content); } deleteUnpublishedEntry(collection, slug) { delete window.repoFilesUnpublished[`${collection}/${slug}`]; return Promise.resolve(); } async addOrUpdateUnpublishedEntry(key, dataFiles, assetProxies, slug, collection, status) { const diffs = []; dataFiles.forEach(dataFile => { var _window$repoFilesUnpu; const { path, newPath, raw } = dataFile; const currentDataFile = (_window$repoFilesUnpu = window.repoFilesUnpublished[key]) === null || _window$repoFilesUnpu === void 0 ? void 0 : _window$repoFilesUnpu.diffs.find(d => d.path === path); const originalPath = currentDataFile ? currentDataFile.originalPath : path; diffs.push({ originalPath, id: newPath || path, path: newPath || path, newFile: (0, _isEmpty2.default)(getFile(originalPath, window.repoFiles)), status: 'added', content: raw }); }); assetProxies.forEach(a => { const asset = this.normalizeAsset(a); diffs.push({ id: asset.id, path: asset.path, newFile: true, status: 'added', content: asset }); }); window.repoFilesUnpublished[key] = { slug, collection, status, diffs, updatedAt: new Date().toISOString() }; } async persistEntry(entry, options) { if (options.useWorkflow) { const slug = entry.dataFiles[0].slug; const key = `${options.collectionName}/${slug}`; const currentEntry = window.repoFilesUnpublished[key]; const status = (currentEntry === null || currentEntry === void 0 ? void 0 : currentEntry.status) || options.status || this.options.initialWorkflowStatus; this.addOrUpdateUnpublishedEntry(key, entry.dataFiles, entry.assets, slug, options.collectionName, status); return Promise.resolve(); } entry.dataFiles.forEach(dataFile => { const { path, raw } = dataFile; writeFile(path, raw, window.repoFiles); }); entry.assets.forEach(a => { writeFile(a.path, a, window.repoFiles); }); return Promise.resolve(); } updateUnpublishedEntryStatus(collection, slug, newStatus) { window.repoFilesUnpublished[`${collection}/${slug}`].status = newStatus; return Promise.resolve(); } publishUnpublishedEntry(collection, slug) { const key = `${collection}/${slug}`; const unpubEntry = window.repoFilesUnpublished[key]; delete window.repoFilesUnpublished[key]; const tree = window.repoFiles; unpubEntry.diffs.forEach(d => { if (d.originalPath && !d.newFile) { const originalPath = d.originalPath; const sourceDir = (0, _path.dirname)(originalPath); const destDir = (0, _path.dirname)(d.path); const toMove = getFolderFiles(tree, originalPath.split('/')[0], '', 100).filter(f => f.path.startsWith(sourceDir)); toMove.forEach(f => { deleteFile(f.path, tree); writeFile(f.path.replace(sourceDir, destDir), f.content, tree); }); } writeFile(d.path, d.content, tree); }); return Promise.resolve(); } getMedia(mediaFolder = this.mediaFolder) { const files = getFolderFiles(window.repoFiles, mediaFolder.split('/')[0], '', 100).filter(f => f.path.startsWith(mediaFolder)); const assets = files.map(f => this.normalizeAsset(f.content)); return Promise.resolve(assets); } async getMediaFile(path) { const asset = getFile(path, window.repoFiles).content; const url = asset.toString(); const name = (0, _decapCmsLibUtil.basename)(path); const blob = await fetch(url).then(res => res.blob()); const fileObj = new File([blob], name); return { id: url, displayURL: url, path, name, size: fileObj.size, file: fileObj, url }; } normalizeAsset(assetProxy) { const fileObj = assetProxy.fileObj; const { name, size } = fileObj; const objectUrl = (0, _attempt2.default)(window.URL.createObjectURL, fileObj); const url = (0, _isError2.default)(objectUrl) ? '' : objectUrl; const normalizedAsset = { id: (0, _uuid.v4)(), name, size, path: assetProxy.path, url, displayURL: url, fileObj }; return normalizedAsset; } persistMedia(assetProxy) { const normalizedAsset = this.normalizeAsset(assetProxy); writeFile(assetProxy.path, assetProxy, window.repoFiles); return Promise.resolve(normalizedAsset); } deleteFiles(paths) { paths.forEach(path => { deleteFile(path, window.repoFiles); }); return Promise.resolve(); } async getDeployPreview() { return null; } } exports.default = TestBackend;