/** * This Source Code is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright (c) Infonomic Company Limited */ import type { DocumentLifecycleContext } from './context.js'; export interface DuplicateDocumentResult { revision: number; sourceRevision: number; /** The newly-created document's id. */ documentId: string; /** The newly-created version id (every duplicate starts at version 1). */ documentVersionId: string; /** The id of the document this duplicate was cloned from. */ sourceDocumentId: string; /** * Final `path` written into `byline_document_paths` for the new document. * Surfaced in the result so the UI can include it in success toasts / * navigate to it directly. */ newPath: string; /** * `true` when the candidate path collided with an existing row and the * lifecycle retried with a short-UUID suffix. UIs can surface a hint that * the auto-generated path is uglier than usual so the editor knows to * adjust it via the path widget. */ pathRetried: boolean; } /** * Duplicate a document, cloning all of its locales into a brand-new * document atomically. * * Flow: * 1. `assertActorCanPerform('create')` — duplicating is a create at the * ability level. The source must be readable (any RBAC scoping the * caller has applies via the storage read). * 2. Fetch the source with `locale: 'all'` so a single read carries the * full multi-locale tree forward. * 3. Deep-clone the source fields; strip block / array-item `_id` meta * so the new doc gets fresh identities. * 4. Append `" (copy)"` to the `useAsTitle` field's value(s). * 5. Derive a candidate path from the default-locale suffixed title. * 6. `hooks.beforeCreate({ data, collectionPath, duplicate })`. * 7. `db.commands.documents.createDocumentVersion(...)` with `locale: * 'all'`, `action: 'create'`, no `documentId` → fresh document_id. * On `ERR_PATH_CONFLICT` retry once with the candidate path plus a * 4-char UUID suffix; bounded to two attempts, no existence * pre-check, no TOCTOU race. * 8. `hooks.afterCreate({ data, collectionPath, documentId, * documentVersionId, duplicate })`. * * The write is atomic at the storage layer — a partial duplicate is * structurally impossible. Editors are expected to rename both the * title and the system path after the operation; the UI surfaces a * confirmation modal that calls this out. */ export declare function duplicateDocument(ctx: DocumentLifecycleContext, params: { sourceDocumentId: string; expectedRevision: number; }): Promise;