| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /* eslint-disable
- no-return-assign,
- */
- // TODO: This file was created by bulk-decaffeinate.
- // Fix any style issues and re-enable lint.
- /*
- * decaffeinate suggestions:
- * DS101: Remove unnecessary use of Array.from
- * DS102: Remove unnecessary code created because of implicit returns
- * DS207: Consider shorter variations of null checks
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
- */
- import Core from 'overleaf-editor-core'
- import logger from '@overleaf/logger'
- import * as Errors from './Errors.js'
- const { MoveFileOperation, AddFileOperation, EditFileOperation } = Core
- export function buildDiff(chunk, fromVersion, toVersion) {
- chunk = Core.Chunk.fromRaw(chunk.chunk)
- const chunkStartVersion = chunk.getStartVersion()
- const diff = _getInitialDiffSnapshot(chunk, fromVersion)
- const changes = chunk
- .getChanges()
- .slice(fromVersion - chunkStartVersion, toVersion - chunkStartVersion)
- for (let i = 0; i < changes.length; i++) {
- const change = changes[i]
- for (const operation of Array.from(change.getOperations())) {
- if (operation.pathname === null || operation.pathname === '') {
- // skip operations for missing files
- logger.warn({ diff, operation }, 'invalid pathname in operation')
- } else if (operation instanceof EditFileOperation) {
- _applyEditFileToDiff(diff, operation)
- } else if (operation instanceof AddFileOperation) {
- _applyAddFileToDiff(diff, operation)
- } else if (operation instanceof MoveFileOperation) {
- if (operation.isRemoveFile()) {
- const deletedAtV = fromVersion + i
- _applyDeleteFileToDiff(diff, operation, deletedAtV)
- } else {
- _applyMoveFileToDiff(diff, operation)
- }
- }
- }
- }
- return Object.values(diff)
- }
- function _getInitialDiffSnapshot(chunk, fromVersion) {
- // Start with a 'diff' which is snapshot of the filetree at the beginning,
- // with nothing in the diff marked as changed.
- // Use a bare object to protect against reserved names.
- const diff = Object.create(null)
- const files = _getInitialFiles(chunk, fromVersion)
- for (const [pathname, file] of Object.entries(files)) {
- diff[pathname] = { pathname, editable: file.isEditable() }
- }
- return diff
- }
- function _getInitialFiles(chunk, fromVersion) {
- const snapshot = chunk.getSnapshot()
- const changes = chunk
- .getChanges()
- .slice(0, fromVersion - chunk.getStartVersion())
- snapshot.applyAll(changes)
- return snapshot.fileMap.files
- }
- function _applyAddFileToDiff(diff, operation) {
- return (diff[operation.pathname] = {
- pathname: operation.pathname,
- operation: 'added',
- editable: operation.file.isEditable(),
- })
- }
- function _applyEditFileToDiff(diff, operation) {
- const change = diff[operation.pathname]
- if ((change != null ? change.operation : undefined) == null) {
- // avoid exception for non-existent change
- return (diff[operation.pathname] = {
- pathname: operation.pathname,
- operation: 'edited',
- })
- }
- }
- function _applyMoveFileToDiff(diff, operation) {
- if (
- diff[operation.newPathname] != null &&
- diff[operation.newPathname].operation !== 'removed'
- ) {
- const err = new Errors.InconsistentChunkError(
- 'trying to move to file that already exists',
- { diff, operation }
- )
- throw err
- }
- const change = diff[operation.pathname]
- if (change == null) {
- logger.warn({ diff, operation }, 'tried to rename non-existent file')
- return
- }
- change.newPathname = operation.newPathname
- if (change.operation === 'added') {
- // If this file was added this time, just leave it as an add, but
- // at the new name.
- change.pathname = operation.newPathname
- delete change.newPathname
- } else {
- change.operation = 'renamed'
- }
- diff[operation.newPathname] = change
- return delete diff[operation.pathname]
- }
- function _applyDeleteFileToDiff(diff, operation, deletedAtV) {
- // avoid exception for non-existent change
- if (diff[operation.pathname] != null) {
- diff[operation.pathname].operation = 'removed'
- }
- return diff[operation.pathname] != null
- ? (diff[operation.pathname].deletedAtV = deletedAtV)
- : undefined
- }
|