obsidian-dev-utils 83.2.0 → 84.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/dev/main.js +2463 -1744
- package/dist/lib/cjs/generated-during-build.cjs +2 -2
- package/dist/lib/cjs/obsidian/components/plugin-notice-component.cjs +139 -8
- package/dist/lib/cjs/obsidian/components/plugin-notice-component.d.cts +94 -0
- package/dist/lib/cjs/obsidian/components/rename-delete-handler-component.cjs +10 -10
- package/dist/lib/cjs/obsidian/components/rename-delete-handler-component.d.cts +3 -3
- package/dist/lib/cjs/obsidian/css-class.cjs +2 -1
- package/dist/lib/cjs/obsidian/css-class.d.cts +5 -0
- package/dist/lib/cjs/obsidian/editor.cjs +1 -1
- package/dist/lib/cjs/obsidian/editor.d.cts +2 -2
- package/dist/lib/cjs/obsidian/file-manager.cjs +9 -9
- package/dist/lib/cjs/obsidian/file-manager.d.cts +9 -9
- package/dist/lib/cjs/obsidian/i18n/locales/en.cjs +8 -8
- package/dist/lib/cjs/obsidian/i18n/locales/en.d.cts +7 -7
- package/dist/lib/cjs/obsidian/i18n/locales/translations-map.d.cts +7 -7
- package/dist/lib/cjs/obsidian/index.cjs +7 -4
- package/dist/lib/cjs/obsidian/index.d.cts +2 -1
- package/dist/lib/cjs/obsidian/markdown-code-block-processor.cjs +7 -7
- package/dist/lib/cjs/obsidian/markdown-code-block-processor.d.cts +9 -9
- package/dist/lib/cjs/obsidian/plugin/plugin.cjs +21 -21
- package/dist/lib/cjs/obsidian/plugin/plugin.d.cts +15 -15
- package/dist/lib/cjs/obsidian/resource-lock.cjs +899 -0
- package/dist/lib/cjs/obsidian/resource-lock.d.cts +227 -0
- package/dist/lib/cjs/obsidian/vault-transaction.cjs +371 -0
- package/dist/lib/cjs/obsidian/vault-transaction.d.cts +146 -0
- package/dist/lib/cjs/obsidian/vault.cjs +4 -4
- package/dist/lib/cjs/obsidian/vault.d.cts +3 -3
- package/dist/lib/esm/generated-during-build.mjs +2 -2
- package/dist/lib/esm/obsidian/components/plugin-notice-component.d.mts +94 -0
- package/dist/lib/esm/obsidian/components/plugin-notice-component.mjs +143 -9
- package/dist/lib/esm/obsidian/components/rename-delete-handler-component.d.mts +3 -3
- package/dist/lib/esm/obsidian/components/rename-delete-handler-component.mjs +10 -10
- package/dist/lib/esm/obsidian/css-class.d.mts +5 -0
- package/dist/lib/esm/obsidian/css-class.mjs +2 -1
- package/dist/lib/esm/obsidian/editor.d.mts +2 -2
- package/dist/lib/esm/obsidian/editor.mjs +1 -1
- package/dist/lib/esm/obsidian/file-manager.d.mts +9 -9
- package/dist/lib/esm/obsidian/file-manager.mjs +9 -9
- package/dist/lib/esm/obsidian/i18n/locales/en.d.mts +7 -7
- package/dist/lib/esm/obsidian/i18n/locales/en.mjs +8 -8
- package/dist/lib/esm/obsidian/i18n/locales/translations-map.d.mts +7 -7
- package/dist/lib/esm/obsidian/index.d.mts +2 -1
- package/dist/lib/esm/obsidian/index.mjs +5 -3
- package/dist/lib/esm/obsidian/markdown-code-block-processor.d.mts +9 -9
- package/dist/lib/esm/obsidian/markdown-code-block-processor.mjs +7 -7
- package/dist/lib/esm/obsidian/plugin/plugin.d.mts +15 -15
- package/dist/lib/esm/obsidian/plugin/plugin.mjs +21 -21
- package/dist/lib/esm/obsidian/resource-lock.d.mts +227 -0
- package/dist/lib/esm/obsidian/resource-lock.mjs +799 -0
- package/dist/lib/esm/obsidian/vault-transaction.d.mts +146 -0
- package/dist/lib/esm/obsidian/vault-transaction.mjs +271 -0
- package/dist/lib/esm/obsidian/vault.d.mts +3 -3
- package/dist/lib/esm/obsidian/vault.mjs +4 -4
- package/dist/styles.css +8 -1
- package/obsidian/resource-lock/package.json +6 -0
- package/obsidian/vault-transaction/package.json +6 -0
- package/package.json +2 -2
- package/dist/lib/cjs/obsidian/editor-lock.cjs +0 -545
- package/dist/lib/cjs/obsidian/editor-lock.d.cts +0 -142
- package/dist/lib/esm/obsidian/editor-lock.d.mts +0 -142
- package/dist/lib/esm/obsidian/editor-lock.mjs +0 -442
- package/obsidian/editor-lock/package.json +0 -6
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/// <reference path="../library.d.mts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* A reversible, transactional log of vault mutations. Each mutation records how to undo itself;
|
|
6
|
+
* {@link VaultTransaction.rollback} reverses the completed steps in reverse order and
|
|
7
|
+
* {@link VaultTransaction.commit} finalizes them. It is built on the `*Safe` vault wrappers so it
|
|
8
|
+
* inherits their case-insensitive / retry / missing-file handling.
|
|
9
|
+
*
|
|
10
|
+
* A deletion is performed as a **soft-delete**: the resource is moved aside into a dot-prefixed
|
|
11
|
+
* staging folder (a folder moves its whole subtree in a single rename, so subtree rollback is cheap
|
|
12
|
+
* and faithful). Because Obsidian's vault file-tree and file watcher ignore any `.`-prefixed path,
|
|
13
|
+
* staged resources are **untracked** — they do not churn the metadata cache, flash in the file
|
|
14
|
+
* explorer, or get propagated by sync while the transaction is in flight. The flip side is that
|
|
15
|
+
* `vault.*` methods cannot see the staging area, so ALL staging I/O goes through
|
|
16
|
+
* {@link App.vault.adapter} (`mkdir`/`rename`/`exists`/`trashSystem`/`rmdir`).
|
|
17
|
+
* {@link VaultTransaction.commit} then trashes the staged resources for real; {@link VaultTransaction.rollback}
|
|
18
|
+
* moves them back.
|
|
19
|
+
*/
|
|
20
|
+
import type { App, TFile } from 'obsidian';
|
|
21
|
+
import type { PathOrAbstractFile } from './file-system.mjs';
|
|
22
|
+
/**
|
|
23
|
+
* Parameters for the {@link VaultTransaction} constructor.
|
|
24
|
+
*/
|
|
25
|
+
export interface VaultTransactionConstructorParams {
|
|
26
|
+
/**
|
|
27
|
+
* The Obsidian application instance.
|
|
28
|
+
*/
|
|
29
|
+
readonly app: App;
|
|
30
|
+
/**
|
|
31
|
+
* Opens an ambient mutation-bypass scope covering the paths this transaction touches, so the
|
|
32
|
+
* transaction's own writes pass a `shouldBlockMutations` lock that the owning operation holds. It is
|
|
33
|
+
* called once when the transaction is constructed, and the returned {@link Disposable} is disposed
|
|
34
|
+
* when the transaction settles (on `commit`, `rollback`, or `await using` disposal) — so the bypass
|
|
35
|
+
* stays active through rollback, including auto-rollback, which a caller managing the scope itself
|
|
36
|
+
* could easily get wrong. Typically
|
|
37
|
+
* `() => resourceLockComponent.bypassBlockedMutations(lockedPathsOrFiles)`. Omit it for the common
|
|
38
|
+
* standalone case where the transaction operates on unlocked paths.
|
|
39
|
+
*
|
|
40
|
+
* @returns A {@link Disposable} that ends the bypass scope.
|
|
41
|
+
*/
|
|
42
|
+
openMutationBypass?(this: void): Disposable;
|
|
43
|
+
/**
|
|
44
|
+
* The dot-prefixed folder that soft-deleted resources are moved into until the transaction is
|
|
45
|
+
* committed or rolled back. It must stay `.`-prefixed so Obsidian leaves the staged resources
|
|
46
|
+
* untracked.
|
|
47
|
+
*
|
|
48
|
+
* @default `'.obsidian-dev-utils-temp'`
|
|
49
|
+
*/
|
|
50
|
+
readonly stagingFolderPath?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A reversible log of vault mutations. Perform mutations through its methods, then call
|
|
54
|
+
* {@link VaultTransaction.commit} on success or {@link VaultTransaction.rollback} on failure. It is
|
|
55
|
+
* `await using`-friendly: if neither is called, disposal rolls back.
|
|
56
|
+
*/
|
|
57
|
+
export declare class VaultTransaction {
|
|
58
|
+
private readonly app;
|
|
59
|
+
private hasStagingFolder;
|
|
60
|
+
private mutationBypass;
|
|
61
|
+
private readonly stagedTrashPaths;
|
|
62
|
+
private readonly stagingFolderPath;
|
|
63
|
+
private state;
|
|
64
|
+
private readonly undoSteps;
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new vault transaction.
|
|
67
|
+
*
|
|
68
|
+
* @param params - The parameters.
|
|
69
|
+
*/
|
|
70
|
+
constructor(params: VaultTransactionConstructorParams);
|
|
71
|
+
/**
|
|
72
|
+
* Commits the transaction: finalizes soft-deletes by trashing the staged resources for real and
|
|
73
|
+
* removes the staging folder. After this the transaction can no longer be mutated or rolled back.
|
|
74
|
+
*
|
|
75
|
+
* @returns A {@link Promise} that resolves when the commit completes.
|
|
76
|
+
*/
|
|
77
|
+
commit(): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Creates a file with the given content, recording its removal as the inverse.
|
|
80
|
+
*
|
|
81
|
+
* @param path - The path of the file to create.
|
|
82
|
+
* @param data - The content of the file.
|
|
83
|
+
* @returns A {@link Promise} resolving to the created {@link TFile}.
|
|
84
|
+
*/
|
|
85
|
+
create(path: string, data: string): Promise<TFile>;
|
|
86
|
+
/**
|
|
87
|
+
* Creates a folder (including missing ancestors), recording its removal as the inverse. A no-op if
|
|
88
|
+
* the folder already exists.
|
|
89
|
+
*
|
|
90
|
+
* @param path - The path of the folder to create.
|
|
91
|
+
* @returns A {@link Promise} that resolves when the folder exists.
|
|
92
|
+
*/
|
|
93
|
+
createFolder(path: string): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Replaces the content of a file, capturing the old content so it can be restored on rollback.
|
|
96
|
+
*
|
|
97
|
+
* @param pathOrFile - The path or file to modify.
|
|
98
|
+
* @param newContent - The new content.
|
|
99
|
+
* @returns A {@link Promise} that resolves when the file is modified.
|
|
100
|
+
*/
|
|
101
|
+
modify(pathOrFile: PathOrAbstractFile, newContent: string): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Transforms the content of a file, capturing the old content so it can be restored on rollback.
|
|
104
|
+
*
|
|
105
|
+
* @param pathOrFile - The path or file to process.
|
|
106
|
+
* @param newContentProvider - Maps the current content to the new content.
|
|
107
|
+
* @returns A {@link Promise} that resolves when the file is processed.
|
|
108
|
+
*/
|
|
109
|
+
process(pathOrFile: PathOrAbstractFile, newContentProvider: (content: string) => string): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Renames or moves a resource, recording the reverse rename as the inverse.
|
|
112
|
+
*
|
|
113
|
+
* @param oldPathOrFile - The resource to rename.
|
|
114
|
+
* @param newPath - The desired new path (an available path is chosen if it is taken).
|
|
115
|
+
* @returns A {@link Promise} resolving to the actual new path.
|
|
116
|
+
*/
|
|
117
|
+
rename(oldPathOrFile: PathOrAbstractFile, newPath: string): Promise<string>;
|
|
118
|
+
/**
|
|
119
|
+
* Rolls back the transaction: undoes the completed steps in reverse order and removes the staging
|
|
120
|
+
* folder. Idempotent.
|
|
121
|
+
*
|
|
122
|
+
* @returns A {@link Promise} that resolves when the rollback completes.
|
|
123
|
+
*/
|
|
124
|
+
rollback(): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Rolls back the transaction on disposal unless it was already committed or rolled back.
|
|
127
|
+
*/
|
|
128
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Soft-deletes a resource by moving it into the staging folder, recording the move-back as the
|
|
131
|
+
* inverse. The real trash happens on {@link VaultTransaction.commit}. A no-op if the resource does
|
|
132
|
+
* not exist.
|
|
133
|
+
*
|
|
134
|
+
* @param pathOrFile - The path or resource to trash.
|
|
135
|
+
* @returns A {@link Promise} that resolves when the resource has been staged.
|
|
136
|
+
*/
|
|
137
|
+
trash(pathOrFile: PathOrAbstractFile): Promise<void>;
|
|
138
|
+
private assertNotCommitted;
|
|
139
|
+
private assertOpen;
|
|
140
|
+
private disposeMutationBypass;
|
|
141
|
+
private ensureStagingFolder;
|
|
142
|
+
private getAvailableStagedPath;
|
|
143
|
+
private hardDelete;
|
|
144
|
+
private pushUndo;
|
|
145
|
+
private removeStagingFolder;
|
|
146
|
+
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function initEsm() {
|
|
7
|
+
// eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
|
|
8
|
+
if (globalThis.process) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const browserProcess = {
|
|
13
|
+
browser: true,
|
|
14
|
+
cwd() {
|
|
15
|
+
return '/';
|
|
16
|
+
},
|
|
17
|
+
env: {},
|
|
18
|
+
platform: 'android'
|
|
19
|
+
};
|
|
20
|
+
// eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
|
|
21
|
+
globalThis.process = browserProcess;
|
|
22
|
+
})();
|
|
23
|
+
|
|
24
|
+
import { assertNonNullable } from "../type-guards.mjs";
|
|
25
|
+
import {
|
|
26
|
+
getAbstractFileOrNull,
|
|
27
|
+
getPath
|
|
28
|
+
} from "./file-system.mjs";
|
|
29
|
+
import {
|
|
30
|
+
createFolderSafe,
|
|
31
|
+
process,
|
|
32
|
+
readSafe,
|
|
33
|
+
renameSafe
|
|
34
|
+
} from "./vault.mjs";
|
|
35
|
+
const DEFAULT_STAGING_FOLDER_PATH = ".obsidian-dev-utils-temp";
|
|
36
|
+
class VaultTransaction {
|
|
37
|
+
app;
|
|
38
|
+
hasStagingFolder = false;
|
|
39
|
+
mutationBypass = null;
|
|
40
|
+
stagedTrashPaths = [];
|
|
41
|
+
stagingFolderPath;
|
|
42
|
+
state = "open";
|
|
43
|
+
undoSteps = [];
|
|
44
|
+
/**
|
|
45
|
+
* Creates a new vault transaction.
|
|
46
|
+
*
|
|
47
|
+
* @param params - The parameters.
|
|
48
|
+
*/
|
|
49
|
+
constructor(params) {
|
|
50
|
+
this.app = params.app;
|
|
51
|
+
this.stagingFolderPath = params.stagingFolderPath ?? DEFAULT_STAGING_FOLDER_PATH;
|
|
52
|
+
this.mutationBypass = params.openMutationBypass?.() ?? null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Commits the transaction: finalizes soft-deletes by trashing the staged resources for real and
|
|
56
|
+
* removes the staging folder. After this the transaction can no longer be mutated or rolled back.
|
|
57
|
+
*
|
|
58
|
+
* @returns A {@link Promise} that resolves when the commit completes.
|
|
59
|
+
*/
|
|
60
|
+
async commit() {
|
|
61
|
+
this.assertOpen();
|
|
62
|
+
this.state = "committed";
|
|
63
|
+
const adapter = this.app.vault.adapter;
|
|
64
|
+
for (const stagedPath of this.stagedTrashPaths) {
|
|
65
|
+
const wasTrashedToSystem = await adapter.trashSystem(stagedPath);
|
|
66
|
+
if (!wasTrashedToSystem) {
|
|
67
|
+
await adapter.trashLocal(stagedPath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
await this.removeStagingFolder();
|
|
71
|
+
this.disposeMutationBypass();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Creates a file with the given content, recording its removal as the inverse.
|
|
75
|
+
*
|
|
76
|
+
* @param path - The path of the file to create.
|
|
77
|
+
* @param data - The content of the file.
|
|
78
|
+
* @returns A {@link Promise} resolving to the created {@link TFile}.
|
|
79
|
+
*/
|
|
80
|
+
async create(path, data) {
|
|
81
|
+
this.assertOpen();
|
|
82
|
+
const file = await this.app.vault.create(path, data);
|
|
83
|
+
const createdPath = file.path;
|
|
84
|
+
this.pushUndo(async () => {
|
|
85
|
+
await this.hardDelete(createdPath);
|
|
86
|
+
});
|
|
87
|
+
return file;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Creates a folder (including missing ancestors), recording its removal as the inverse. A no-op if
|
|
91
|
+
* the folder already exists.
|
|
92
|
+
*
|
|
93
|
+
* @param path - The path of the folder to create.
|
|
94
|
+
* @returns A {@link Promise} that resolves when the folder exists.
|
|
95
|
+
*/
|
|
96
|
+
async createFolder(path) {
|
|
97
|
+
this.assertOpen();
|
|
98
|
+
const wasCreated = await createFolderSafe(this.app, path);
|
|
99
|
+
if (wasCreated) {
|
|
100
|
+
this.pushUndo(async () => {
|
|
101
|
+
await this.hardDelete(path);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Replaces the content of a file, capturing the old content so it can be restored on rollback.
|
|
107
|
+
*
|
|
108
|
+
* @param pathOrFile - The path or file to modify.
|
|
109
|
+
* @param newContent - The new content.
|
|
110
|
+
* @returns A {@link Promise} that resolves when the file is modified.
|
|
111
|
+
*/
|
|
112
|
+
async modify(pathOrFile, newContent) {
|
|
113
|
+
await this.process(pathOrFile, () => newContent);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Transforms the content of a file, capturing the old content so it can be restored on rollback.
|
|
117
|
+
*
|
|
118
|
+
* @param pathOrFile - The path or file to process.
|
|
119
|
+
* @param newContentProvider - Maps the current content to the new content.
|
|
120
|
+
* @returns A {@link Promise} that resolves when the file is processed.
|
|
121
|
+
*/
|
|
122
|
+
async process(pathOrFile, newContentProvider) {
|
|
123
|
+
this.assertOpen();
|
|
124
|
+
const path = getPath(this.app, pathOrFile);
|
|
125
|
+
const oldContent = await readSafe(this.app, path);
|
|
126
|
+
await process({
|
|
127
|
+
app: this.app,
|
|
128
|
+
newContentProvider: ({ content }) => newContentProvider(content),
|
|
129
|
+
pathOrFile: path,
|
|
130
|
+
resourceLockComponent: null
|
|
131
|
+
});
|
|
132
|
+
assertNonNullable(oldContent);
|
|
133
|
+
this.pushUndo(async () => {
|
|
134
|
+
await process({
|
|
135
|
+
app: this.app,
|
|
136
|
+
newContentProvider: oldContent,
|
|
137
|
+
pathOrFile: path,
|
|
138
|
+
resourceLockComponent: null
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Renames or moves a resource, recording the reverse rename as the inverse.
|
|
144
|
+
*
|
|
145
|
+
* @param oldPathOrFile - The resource to rename.
|
|
146
|
+
* @param newPath - The desired new path (an available path is chosen if it is taken).
|
|
147
|
+
* @returns A {@link Promise} resolving to the actual new path.
|
|
148
|
+
*/
|
|
149
|
+
async rename(oldPathOrFile, newPath) {
|
|
150
|
+
this.assertOpen();
|
|
151
|
+
const oldPath = getPath(this.app, oldPathOrFile);
|
|
152
|
+
const actualNewPath = await renameSafe({ app: this.app, newPath, oldPathOrAbstractFile: oldPathOrFile });
|
|
153
|
+
this.pushUndo(async () => {
|
|
154
|
+
await renameSafe({ app: this.app, newPath: oldPath, oldPathOrAbstractFile: actualNewPath });
|
|
155
|
+
});
|
|
156
|
+
return actualNewPath;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Rolls back the transaction: undoes the completed steps in reverse order and removes the staging
|
|
160
|
+
* folder. Idempotent.
|
|
161
|
+
*
|
|
162
|
+
* @returns A {@link Promise} that resolves when the rollback completes.
|
|
163
|
+
*/
|
|
164
|
+
async rollback() {
|
|
165
|
+
if (this.state === "rolledBack") {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
this.assertNotCommitted();
|
|
169
|
+
this.state = "rolledBack";
|
|
170
|
+
for (const step of [...this.undoSteps].reverse()) {
|
|
171
|
+
await step.undo();
|
|
172
|
+
}
|
|
173
|
+
await this.removeStagingFolder();
|
|
174
|
+
this.disposeMutationBypass();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Rolls back the transaction on disposal unless it was already committed or rolled back.
|
|
178
|
+
*/
|
|
179
|
+
async [Symbol.asyncDispose]() {
|
|
180
|
+
if (this.state === "open") {
|
|
181
|
+
await this.rollback();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Soft-deletes a resource by moving it into the staging folder, recording the move-back as the
|
|
186
|
+
* inverse. The real trash happens on {@link VaultTransaction.commit}. A no-op if the resource does
|
|
187
|
+
* not exist.
|
|
188
|
+
*
|
|
189
|
+
* @param pathOrFile - The path or resource to trash.
|
|
190
|
+
* @returns A {@link Promise} that resolves when the resource has been staged.
|
|
191
|
+
*/
|
|
192
|
+
async trash(pathOrFile) {
|
|
193
|
+
this.assertOpen();
|
|
194
|
+
const file = getAbstractFileOrNull({ app: this.app, pathOrFile });
|
|
195
|
+
if (!file) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const originalPath = file.path;
|
|
199
|
+
await this.ensureStagingFolder();
|
|
200
|
+
const stagedPath = await this.getAvailableStagedPath(file.name);
|
|
201
|
+
const adapter = this.app.vault.adapter;
|
|
202
|
+
await adapter.rename(originalPath, stagedPath);
|
|
203
|
+
this.stagedTrashPaths.push(stagedPath);
|
|
204
|
+
this.pushUndo(async () => {
|
|
205
|
+
if (await adapter.exists(stagedPath)) {
|
|
206
|
+
await adapter.rename(stagedPath, originalPath);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
assertNotCommitted() {
|
|
211
|
+
if (this.state === "committed") {
|
|
212
|
+
throw new Error("Cannot roll back a committed transaction.");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
assertOpen() {
|
|
216
|
+
if (this.state !== "open") {
|
|
217
|
+
throw new Error(`Cannot mutate a ${this.state} transaction.`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
disposeMutationBypass() {
|
|
221
|
+
this.mutationBypass?.[Symbol.dispose]();
|
|
222
|
+
this.mutationBypass = null;
|
|
223
|
+
}
|
|
224
|
+
async ensureStagingFolder() {
|
|
225
|
+
if (this.hasStagingFolder) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const adapter = this.app.vault.adapter;
|
|
229
|
+
if (!await adapter.exists(this.stagingFolderPath)) {
|
|
230
|
+
await adapter.mkdir(this.stagingFolderPath);
|
|
231
|
+
}
|
|
232
|
+
this.hasStagingFolder = true;
|
|
233
|
+
}
|
|
234
|
+
async getAvailableStagedPath(name) {
|
|
235
|
+
const adapter = this.app.vault.adapter;
|
|
236
|
+
const dotIndex = name.lastIndexOf(".");
|
|
237
|
+
const hasExtension = dotIndex > 0;
|
|
238
|
+
const baseName = hasExtension ? name.slice(0, dotIndex) : name;
|
|
239
|
+
const extension = hasExtension ? name.slice(dotIndex) : "";
|
|
240
|
+
let candidate = `${this.stagingFolderPath}/${name}`;
|
|
241
|
+
let counter = 1;
|
|
242
|
+
while (await adapter.exists(candidate)) {
|
|
243
|
+
candidate = `${this.stagingFolderPath}/${baseName} ${counter.toString()}${extension}`;
|
|
244
|
+
counter++;
|
|
245
|
+
}
|
|
246
|
+
return candidate;
|
|
247
|
+
}
|
|
248
|
+
async hardDelete(path) {
|
|
249
|
+
const file = getAbstractFileOrNull({ app: this.app, pathOrFile: path });
|
|
250
|
+
if (file) {
|
|
251
|
+
await this.app.vault.delete(file, true);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
pushUndo(undo) {
|
|
255
|
+
this.undoSteps.push({ undo });
|
|
256
|
+
}
|
|
257
|
+
async removeStagingFolder() {
|
|
258
|
+
if (!this.hasStagingFolder) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
this.hasStagingFolder = false;
|
|
262
|
+
const adapter = this.app.vault.adapter;
|
|
263
|
+
if (await adapter.exists(this.stagingFolderPath)) {
|
|
264
|
+
await adapter.rmdir(this.stagingFolderPath, true);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export {
|
|
269
|
+
VaultTransaction
|
|
270
|
+
};
|
|
271
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL3ZhdWx0LXRyYW5zYWN0aW9uLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQSByZXZlcnNpYmxlLCB0cmFuc2FjdGlvbmFsIGxvZyBvZiB2YXVsdCBtdXRhdGlvbnMuIEVhY2ggbXV0YXRpb24gcmVjb3JkcyBob3cgdG8gdW5kbyBpdHNlbGY7XG4gKiB7QGxpbmsgVmF1bHRUcmFuc2FjdGlvbi5yb2xsYmFja30gcmV2ZXJzZXMgdGhlIGNvbXBsZXRlZCBzdGVwcyBpbiByZXZlcnNlIG9yZGVyIGFuZFxuICoge0BsaW5rIFZhdWx0VHJhbnNhY3Rpb24uY29tbWl0fSBmaW5hbGl6ZXMgdGhlbS4gSXQgaXMgYnVpbHQgb24gdGhlIGAqU2FmZWAgdmF1bHQgd3JhcHBlcnMgc28gaXRcbiAqIGluaGVyaXRzIHRoZWlyIGNhc2UtaW5zZW5zaXRpdmUgLyByZXRyeSAvIG1pc3NpbmctZmlsZSBoYW5kbGluZy5cbiAqXG4gKiBBIGRlbGV0aW9uIGlzIHBlcmZvcm1lZCBhcyBhICoqc29mdC1kZWxldGUqKjogdGhlIHJlc291cmNlIGlzIG1vdmVkIGFzaWRlIGludG8gYSBkb3QtcHJlZml4ZWRcbiAqIHN0YWdpbmcgZm9sZGVyIChhIGZvbGRlciBtb3ZlcyBpdHMgd2hvbGUgc3VidHJlZSBpbiBhIHNpbmdsZSByZW5hbWUsIHNvIHN1YnRyZWUgcm9sbGJhY2sgaXMgY2hlYXBcbiAqIGFuZCBmYWl0aGZ1bCkuIEJlY2F1c2UgT2JzaWRpYW4ncyB2YXVsdCBmaWxlLXRyZWUgYW5kIGZpbGUgd2F0Y2hlciBpZ25vcmUgYW55IGAuYC1wcmVmaXhlZCBwYXRoLFxuICogc3RhZ2VkIHJlc291cmNlcyBhcmUgKip1bnRyYWNrZWQqKiBcdTIwMTQgdGhleSBkbyBub3QgY2h1cm4gdGhlIG1ldGFkYXRhIGNhY2hlLCBmbGFzaCBpbiB0aGUgZmlsZVxuICogZXhwbG9yZXIsIG9yIGdldCBwcm9wYWdhdGVkIGJ5IHN5bmMgd2hpbGUgdGhlIHRyYW5zYWN0aW9uIGlzIGluIGZsaWdodC4gVGhlIGZsaXAgc2lkZSBpcyB0aGF0XG4gKiBgdmF1bHQuKmAgbWV0aG9kcyBjYW5ub3Qgc2VlIHRoZSBzdGFnaW5nIGFyZWEsIHNvIEFMTCBzdGFnaW5nIEkvTyBnb2VzIHRocm91Z2hcbiAqIHtAbGluayBBcHAudmF1bHQuYWRhcHRlcn0gKGBta2RpcmAvYHJlbmFtZWAvYGV4aXN0c2AvYHRyYXNoU3lzdGVtYC9gcm1kaXJgKS5cbiAqIHtAbGluayBWYXVsdFRyYW5zYWN0aW9uLmNvbW1pdH0gdGhlbiB0cmFzaGVzIHRoZSBzdGFnZWQgcmVzb3VyY2VzIGZvciByZWFsOyB7QGxpbmsgVmF1bHRUcmFuc2FjdGlvbi5yb2xsYmFja31cbiAqIG1vdmVzIHRoZW0gYmFjay5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIEFwcCxcbiAgVEZpbGVcbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgdHlwZSB7IFBhdGhPckFic3RyYWN0RmlsZSB9IGZyb20gJy4vZmlsZS1zeXN0ZW0udHMnO1xuXG5pbXBvcnQgeyBhc3NlcnROb25OdWxsYWJsZSB9IGZyb20gJy4uL3R5cGUtZ3VhcmRzLnRzJztcbmltcG9ydCB7XG4gIGdldEFic3RyYWN0RmlsZU9yTnVsbCxcbiAgZ2V0UGF0aFxufSBmcm9tICcuL2ZpbGUtc3lzdGVtLnRzJztcbmltcG9ydCB7XG4gIGNyZWF0ZUZvbGRlclNhZmUsXG4gIHByb2Nlc3MsXG4gIHJlYWRTYWZlLFxuICByZW5hbWVTYWZlXG59IGZyb20gJy4vdmF1bHQudHMnO1xuXG5jb25zdCBERUZBVUxUX1NUQUdJTkdfRk9MREVSX1BBVEggPSAnLm9ic2lkaWFuLWRldi11dGlscy10ZW1wJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB0aGUge0BsaW5rIFZhdWx0VHJhbnNhY3Rpb259IGNvbnN0cnVjdG9yLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhdWx0VHJhbnNhY3Rpb25Db25zdHJ1Y3RvclBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgT2JzaWRpYW4gYXBwbGljYXRpb24gaW5zdGFuY2UuXG4gICAqL1xuICByZWFkb25seSBhcHA6IEFwcDtcblxuICAvKipcbiAgICogT3BlbnMgYW4gYW1iaWVudCBtdXRhdGlvbi1ieXBhc3Mgc2NvcGUgY292ZXJpbmcgdGhlIHBhdGhzIHRoaXMgdHJhbnNhY3Rpb24gdG91Y2hlcywgc28gdGhlXG4gICAqIHRyYW5zYWN0aW9uJ3Mgb3duIHdyaXRlcyBwYXNzIGEgYHNob3VsZEJsb2NrTXV0YXRpb25zYCBsb2NrIHRoYXQgdGhlIG93bmluZyBvcGVyYXRpb24gaG9sZHMuIEl0IGlzXG4gICAqIGNhbGxlZCBvbmNlIHdoZW4gdGhlIHRyYW5zYWN0aW9uIGlzIGNvbnN0cnVjdGVkLCBhbmQgdGhlIHJldHVybmVkIHtAbGluayBEaXNwb3NhYmxlfSBpcyBkaXNwb3NlZFxuICAgKiB3aGVuIHRoZSB0cmFuc2FjdGlvbiBzZXR0bGVzIChvbiBgY29tbWl0YCwgYHJvbGxiYWNrYCwgb3IgYGF3YWl0IHVzaW5nYCBkaXNwb3NhbCkgXHUyMDE0IHNvIHRoZSBieXBhc3NcbiAgICogc3RheXMgYWN0aXZlIHRocm91Z2ggcm9sbGJhY2ssIGluY2x1ZGluZyBhdXRvLXJvbGxiYWNrLCB3aGljaCBhIGNhbGxlciBtYW5hZ2luZyB0aGUgc2NvcGUgaXRzZWxmXG4gICAqIGNvdWxkIGVhc2lseSBnZXQgd3JvbmcuIFR5cGljYWxseVxuICAgKiBgKCkgPT4gcmVzb3VyY2VMb2NrQ29tcG9uZW50LmJ5cGFzc0Jsb2NrZWRNdXRhdGlvbnMobG9ja2VkUGF0aHNPckZpbGVzKWAuIE9taXQgaXQgZm9yIHRoZSBjb21tb25cbiAgICogc3RhbmRhbG9uZSBjYXNlIHdoZXJlIHRoZSB0cmFuc2FjdGlvbiBvcGVyYXRlcyBvbiB1bmxvY2tlZCBwYXRocy5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgRGlzcG9zYWJsZX0gdGhhdCBlbmRzIHRoZSBieXBhc3Mgc2NvcGUuXG4gICAqL1xuICBvcGVuTXV0YXRpb25CeXBhc3M/KHRoaXM6IHZvaWQpOiBEaXNwb3NhYmxlO1xuXG4gIC8qKlxuICAgKiBUaGUgZG90LXByZWZpeGVkIGZvbGRlciB0aGF0IHNvZnQtZGVsZXRlZCByZXNvdXJjZXMgYXJlIG1vdmVkIGludG8gdW50aWwgdGhlIHRyYW5zYWN0aW9uIGlzXG4gICAqIGNvbW1pdHRlZCBvciByb2xsZWQgYmFjay4gSXQgbXVzdCBzdGF5IGAuYC1wcmVmaXhlZCBzbyBPYnNpZGlhbiBsZWF2ZXMgdGhlIHN0YWdlZCByZXNvdXJjZXNcbiAgICogdW50cmFja2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJy5vYnNpZGlhbi1kZXYtdXRpbHMtdGVtcCdgXG4gICAqL1xuICByZWFkb25seSBzdGFnaW5nRm9sZGVyUGF0aD86IHN0cmluZztcbn1cblxudHlwZSBUcmFuc2FjdGlvblN0YXRlID0gJ2NvbW1pdHRlZCcgfCAnb3BlbicgfCAncm9sbGVkQmFjayc7XG5cbmludGVyZmFjZSBVbmRvU3RlcCB7XG4gIHVuZG8odGhpczogdm9pZCk6IFByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICogQSByZXZlcnNpYmxlIGxvZyBvZiB2YXVsdCBtdXRhdGlvbnMuIFBlcmZvcm0gbXV0YXRpb25zIHRocm91Z2ggaXRzIG1ldGhvZHMsIHRoZW4gY2FsbFxuICoge0BsaW5rIFZhdWx0VHJhbnNhY3Rpb24uY29tbWl0fSBvbiBzdWNjZXNzIG9yIHtAbGluayBWYXVsdFRyYW5zYWN0aW9uLnJvbGxiYWNrfSBvbiBmYWlsdXJlLiBJdCBpc1xuICogYGF3YWl0IHVzaW5nYC1mcmllbmRseTogaWYgbmVpdGhlciBpcyBjYWxsZWQsIGRpc3Bvc2FsIHJvbGxzIGJhY2suXG4gKi9cbmV4cG9ydCBjbGFzcyBWYXVsdFRyYW5zYWN0aW9uIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhcHA6IEFwcDtcbiAgcHJpdmF0ZSBoYXNTdGFnaW5nRm9sZGVyID0gZmFsc2U7XG4gIHByaXZhdGUgbXV0YXRpb25CeXBhc3M6IERpc3Bvc2FibGUgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGFnZWRUcmFzaFBhdGhzOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YWdpbmdGb2xkZXJQYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgc3RhdGU6IFRyYW5zYWN0aW9uU3RhdGUgPSAnb3Blbic7XG4gIHByaXZhdGUgcmVhZG9ubHkgdW5kb1N0ZXBzOiBVbmRvU3RlcFtdID0gW107XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgdmF1bHQgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycy5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihwYXJhbXM6IFZhdWx0VHJhbnNhY3Rpb25Db25zdHJ1Y3RvclBhcmFtcykge1xuICAgIHRoaXMuYXBwID0gcGFyYW1zLmFwcDtcbiAgICB0aGlzLnN0YWdpbmdGb2xkZXJQYXRoID0gcGFyYW1zLnN0YWdpbmdGb2xkZXJQYXRoID8/IERFRkFVTFRfU1RBR0lOR19GT0xERVJfUEFUSDtcbiAgICB0aGlzLm11dGF0aW9uQnlwYXNzID0gcGFyYW1zLm9wZW5NdXRhdGlvbkJ5cGFzcz8uKCkgPz8gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21taXRzIHRoZSB0cmFuc2FjdGlvbjogZmluYWxpemVzIHNvZnQtZGVsZXRlcyBieSB0cmFzaGluZyB0aGUgc3RhZ2VkIHJlc291cmNlcyBmb3IgcmVhbCBhbmRcbiAgICogcmVtb3ZlcyB0aGUgc3RhZ2luZyBmb2xkZXIuIEFmdGVyIHRoaXMgdGhlIHRyYW5zYWN0aW9uIGNhbiBubyBsb25nZXIgYmUgbXV0YXRlZCBvciByb2xsZWQgYmFjay5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjb21taXQgY29tcGxldGVzLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNvbW1pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmFzc2VydE9wZW4oKTtcbiAgICB0aGlzLnN0YXRlID0gJ2NvbW1pdHRlZCc7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXI7XG4gICAgZm9yIChjb25zdCBzdGFnZWRQYXRoIG9mIHRoaXMuc3RhZ2VkVHJhc2hQYXRocykge1xuICAgICAgY29uc3Qgd2FzVHJhc2hlZFRvU3lzdGVtID0gYXdhaXQgYWRhcHRlci50cmFzaFN5c3RlbShzdGFnZWRQYXRoKTtcbiAgICAgIGlmICghd2FzVHJhc2hlZFRvU3lzdGVtKSB7XG4gICAgICAgIGF3YWl0IGFkYXB0ZXIudHJhc2hMb2NhbChzdGFnZWRQYXRoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgdGhpcy5yZW1vdmVTdGFnaW5nRm9sZGVyKCk7XG4gICAgdGhpcy5kaXNwb3NlTXV0YXRpb25CeXBhc3MoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgZmlsZSB3aXRoIHRoZSBnaXZlbiBjb250ZW50LCByZWNvcmRpbmcgaXRzIHJlbW92YWwgYXMgdGhlIGludmVyc2UuXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIC0gVGhlIHBhdGggb2YgdGhlIGZpbGUgdG8gY3JlYXRlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBjb250ZW50IG9mIHRoZSBmaWxlLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSByZXNvbHZpbmcgdG8gdGhlIGNyZWF0ZWQge0BsaW5rIFRGaWxlfS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBjcmVhdGUocGF0aDogc3RyaW5nLCBkYXRhOiBzdHJpbmcpOiBQcm9taXNlPFRGaWxlPiB7XG4gICAgdGhpcy5hc3NlcnRPcGVuKCk7XG4gICAgY29uc3QgZmlsZSA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmNyZWF0ZShwYXRoLCBkYXRhKTtcbiAgICBjb25zdCBjcmVhdGVkUGF0aCA9IGZpbGUucGF0aDtcbiAgICB0aGlzLnB1c2hVbmRvKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMuaGFyZERlbGV0ZShjcmVhdGVkUGF0aCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbGU7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGZvbGRlciAoaW5jbHVkaW5nIG1pc3NpbmcgYW5jZXN0b3JzKSwgcmVjb3JkaW5nIGl0cyByZW1vdmFsIGFzIHRoZSBpbnZlcnNlLiBBIG5vLW9wIGlmXG4gICAqIHRoZSBmb2xkZXIgYWxyZWFkeSBleGlzdHMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIC0gVGhlIHBhdGggb2YgdGhlIGZvbGRlciB0byBjcmVhdGUuXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgZm9sZGVyIGV4aXN0cy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBjcmVhdGVGb2xkZXIocGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRPcGVuKCk7XG4gICAgY29uc3Qgd2FzQ3JlYXRlZCA9IGF3YWl0IGNyZWF0ZUZvbGRlclNhZmUodGhpcy5hcHAsIHBhdGgpO1xuICAgIGlmICh3YXNDcmVhdGVkKSB7XG4gICAgICB0aGlzLnB1c2hVbmRvKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5oYXJkRGVsZXRlKHBhdGgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIHRoZSBjb250ZW50IG9mIGEgZmlsZSwgY2FwdHVyaW5nIHRoZSBvbGQgY29udGVudCBzbyBpdCBjYW4gYmUgcmVzdG9yZWQgb24gcm9sbGJhY2suXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoT3JGaWxlIC0gVGhlIHBhdGggb3IgZmlsZSB0byBtb2RpZnkuXG4gICAqIEBwYXJhbSBuZXdDb250ZW50IC0gVGhlIG5ldyBjb250ZW50LlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGZpbGUgaXMgbW9kaWZpZWQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgbW9kaWZ5KHBhdGhPckZpbGU6IFBhdGhPckFic3RyYWN0RmlsZSwgbmV3Q29udGVudDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5wcm9jZXNzKHBhdGhPckZpbGUsICgpID0+IG5ld0NvbnRlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybXMgdGhlIGNvbnRlbnQgb2YgYSBmaWxlLCBjYXB0dXJpbmcgdGhlIG9sZCBjb250ZW50IHNvIGl0IGNhbiBiZSByZXN0b3JlZCBvbiByb2xsYmFjay5cbiAgICpcbiAgICogQHBhcmFtIHBhdGhPckZpbGUgLSBUaGUgcGF0aCBvciBmaWxlIHRvIHByb2Nlc3MuXG4gICAqIEBwYXJhbSBuZXdDb250ZW50UHJvdmlkZXIgLSBNYXBzIHRoZSBjdXJyZW50IGNvbnRlbnQgdG8gdGhlIG5ldyBjb250ZW50LlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGZpbGUgaXMgcHJvY2Vzc2VkLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHByb2Nlc3MocGF0aE9yRmlsZTogUGF0aE9yQWJzdHJhY3RGaWxlLCBuZXdDb250ZW50UHJvdmlkZXI6IChjb250ZW50OiBzdHJpbmcpID0+IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXNzZXJ0T3BlbigpO1xuICAgIGNvbnN0IHBhdGggPSBnZXRQYXRoKHRoaXMuYXBwLCBwYXRoT3JGaWxlKTtcbiAgICBjb25zdCBvbGRDb250ZW50ID0gYXdhaXQgcmVhZFNhZmUodGhpcy5hcHAsIHBhdGgpO1xuICAgIGF3YWl0IHByb2Nlc3Moe1xuICAgICAgYXBwOiB0aGlzLmFwcCxcbiAgICAgIG5ld0NvbnRlbnRQcm92aWRlcjogKHsgY29udGVudCB9KSA9PiBuZXdDb250ZW50UHJvdmlkZXIoY29udGVudCksXG4gICAgICBwYXRoT3JGaWxlOiBwYXRoLFxuICAgICAgcmVzb3VyY2VMb2NrQ29tcG9uZW50OiBudWxsXG4gICAgfSk7XG4gICAgLy8gUmVhY2hpbmcgdGhpcyBsaW5lIG1lYW5zIGBwcm9jZXNzYCBzdWNjZWVkZWQuIEEgbWlzc2luZyBmaWxlIHdvdWxkIGhhdmUgdGhyb3duIGFib3ZlIChpdHNcbiAgICAvLyBgc2hvdWxkRmFpbE9uTWlzc2luZ0ZpbGVgIGRlZmF1bHQpLCBzbyB0aGUgcHJlLWltYWdlIHdhcyBjYXB0dXJlZCBhbmQgY2FuIGJlIHJlc3RvcmVkIG9uIHJvbGxiYWNrLlxuICAgIGFzc2VydE5vbk51bGxhYmxlKG9sZENvbnRlbnQpO1xuICAgIHRoaXMucHVzaFVuZG8oYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcHJvY2Vzcyh7XG4gICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgIG5ld0NvbnRlbnRQcm92aWRlcjogb2xkQ29udGVudCxcbiAgICAgICAgcGF0aE9yRmlsZTogcGF0aCxcbiAgICAgICAgcmVzb3VyY2VMb2NrQ29tcG9uZW50OiBudWxsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5hbWVzIG9yIG1vdmVzIGEgcmVzb3VyY2UsIHJlY29yZGluZyB0aGUgcmV2ZXJzZSByZW5hbWUgYXMgdGhlIGludmVyc2UuXG4gICAqXG4gICAqIEBwYXJhbSBvbGRQYXRoT3JGaWxlIC0gVGhlIHJlc291cmNlIHRvIHJlbmFtZS5cbiAgICogQHBhcmFtIG5ld1BhdGggLSBUaGUgZGVzaXJlZCBuZXcgcGF0aCAoYW4gYXZhaWxhYmxlIHBhdGggaXMgY2hvc2VuIGlmIGl0IGlzIHRha2VuKS5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gcmVzb2x2aW5nIHRvIHRoZSBhY3R1YWwgbmV3IHBhdGguXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVuYW1lKG9sZFBhdGhPckZpbGU6IFBhdGhPckFic3RyYWN0RmlsZSwgbmV3UGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICB0aGlzLmFzc2VydE9wZW4oKTtcbiAgICBjb25zdCBvbGRQYXRoID0gZ2V0UGF0aCh0aGlzLmFwcCwgb2xkUGF0aE9yRmlsZSk7XG4gICAgY29uc3QgYWN0dWFsTmV3UGF0aCA9IGF3YWl0IHJlbmFtZVNhZmUoeyBhcHA6IHRoaXMuYXBwLCBuZXdQYXRoLCBvbGRQYXRoT3JBYnN0cmFjdEZpbGU6IG9sZFBhdGhPckZpbGUgfSk7XG4gICAgdGhpcy5wdXNoVW5kbyhhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCByZW5hbWVTYWZlKHsgYXBwOiB0aGlzLmFwcCwgbmV3UGF0aDogb2xkUGF0aCwgb2xkUGF0aE9yQWJzdHJhY3RGaWxlOiBhY3R1YWxOZXdQYXRoIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBhY3R1YWxOZXdQYXRoO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxzIGJhY2sgdGhlIHRyYW5zYWN0aW9uOiB1bmRvZXMgdGhlIGNvbXBsZXRlZCBzdGVwcyBpbiByZXZlcnNlIG9yZGVyIGFuZCByZW1vdmVzIHRoZSBzdGFnaW5nXG4gICAqIGZvbGRlci4gSWRlbXBvdGVudC5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSByb2xsYmFjayBjb21wbGV0ZXMuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcm9sbGJhY2soKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT09ICdyb2xsZWRCYWNrJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmFzc2VydE5vdENvbW1pdHRlZCgpO1xuICAgIHRoaXMuc3RhdGUgPSAncm9sbGVkQmFjayc7XG4gICAgZm9yIChjb25zdCBzdGVwIG9mIFsuLi50aGlzLnVuZG9TdGVwc10ucmV2ZXJzZSgpKSB7XG4gICAgICBhd2FpdCBzdGVwLnVuZG8oKTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5yZW1vdmVTdGFnaW5nRm9sZGVyKCk7XG4gICAgdGhpcy5kaXNwb3NlTXV0YXRpb25CeXBhc3MoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xscyBiYWNrIHRoZSB0cmFuc2FjdGlvbiBvbiBkaXNwb3NhbCB1bmxlc3MgaXQgd2FzIGFscmVhZHkgY29tbWl0dGVkIG9yIHJvbGxlZCBiYWNrLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5zdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICBhd2FpdCB0aGlzLnJvbGxiYWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNvZnQtZGVsZXRlcyBhIHJlc291cmNlIGJ5IG1vdmluZyBpdCBpbnRvIHRoZSBzdGFnaW5nIGZvbGRlciwgcmVjb3JkaW5nIHRoZSBtb3ZlLWJhY2sgYXMgdGhlXG4gICAqIGludmVyc2UuIFRoZSByZWFsIHRyYXNoIGhhcHBlbnMgb24ge0BsaW5rIFZhdWx0VHJhbnNhY3Rpb24uY29tbWl0fS4gQSBuby1vcCBpZiB0aGUgcmVzb3VyY2UgZG9lc1xuICAgKiBub3QgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoT3JGaWxlIC0gVGhlIHBhdGggb3IgcmVzb3VyY2UgdG8gdHJhc2guXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgcmVzb3VyY2UgaGFzIGJlZW4gc3RhZ2VkLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHRyYXNoKHBhdGhPckZpbGU6IFBhdGhPckFic3RyYWN0RmlsZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXNzZXJ0T3BlbigpO1xuICAgIGNvbnN0IGZpbGUgPSBnZXRBYnN0cmFjdEZpbGVPck51bGwoeyBhcHA6IHRoaXMuYXBwLCBwYXRoT3JGaWxlIH0pO1xuICAgIGlmICghZmlsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBvcmlnaW5hbFBhdGggPSBmaWxlLnBhdGg7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVTdGFnaW5nRm9sZGVyKCk7XG4gICAgY29uc3Qgc3RhZ2VkUGF0aCA9IGF3YWl0IHRoaXMuZ2V0QXZhaWxhYmxlU3RhZ2VkUGF0aChmaWxlLm5hbWUpO1xuICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLmFwcC52YXVsdC5hZGFwdGVyO1xuICAgIC8vIE1vdmUgdGhyb3VnaCB0aGUgYWRhcHRlciwgbm90IGB2YXVsdC5yZW5hbWVgOiB0aGUgc3RhZ2luZyBmb2xkZXIgaXMgZG90LXByZWZpeGVkIGFuZCB0aGVyZWZvcmVcbiAgICAvLyBVbnRyYWNrZWQsIHNvIGEgYHZhdWx0LipgIG1vdmUgY2Fubm90IHRhcmdldCBpdCAobm9yIHNob3VsZCBpdCByZXdyaXRlIGxpbmtzIHRvIGEgc29mdC1kZWxldGUpLlxuICAgIGF3YWl0IGFkYXB0ZXIucmVuYW1lKG9yaWdpbmFsUGF0aCwgc3RhZ2VkUGF0aCk7XG4gICAgdGhpcy5zdGFnZWRUcmFzaFBhdGhzLnB1c2goc3RhZ2VkUGF0aCk7XG4gICAgdGhpcy5wdXNoVW5kbyhhc3luYyAoKSA9PiB7XG4gICAgICBpZiAoYXdhaXQgYWRhcHRlci5leGlzdHMoc3RhZ2VkUGF0aCkpIHtcbiAgICAgICAgYXdhaXQgYWRhcHRlci5yZW5hbWUoc3RhZ2VkUGF0aCwgb3JpZ2luYWxQYXRoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXNzZXJ0Tm90Q29tbWl0dGVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0YXRlID09PSAnY29tbWl0dGVkJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3Qgcm9sbCBiYWNrIGEgY29tbWl0dGVkIHRyYW5zYWN0aW9uLicpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXNzZXJ0T3BlbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdGF0ZSAhPT0gJ29wZW4nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBtdXRhdGUgYSAke3RoaXMuc3RhdGV9IHRyYW5zYWN0aW9uLmApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGlzcG9zZU11dGF0aW9uQnlwYXNzKCk6IHZvaWQge1xuICAgIHRoaXMubXV0YXRpb25CeXBhc3M/LltTeW1ib2wuZGlzcG9zZV0oKTtcbiAgICB0aGlzLm11dGF0aW9uQnlwYXNzID0gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlU3RhZ2luZ0ZvbGRlcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5oYXNTdGFnaW5nRm9sZGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLmFwcC52YXVsdC5hZGFwdGVyO1xuICAgIGlmICghYXdhaXQgYWRhcHRlci5leGlzdHModGhpcy5zdGFnaW5nRm9sZGVyUGF0aCkpIHtcbiAgICAgIGF3YWl0IGFkYXB0ZXIubWtkaXIodGhpcy5zdGFnaW5nRm9sZGVyUGF0aCk7XG4gICAgfVxuICAgIHRoaXMuaGFzU3RhZ2luZ0ZvbGRlciA9IHRydWU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEF2YWlsYWJsZVN0YWdlZFBhdGgobmFtZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5hcHAudmF1bHQuYWRhcHRlcjtcbiAgICBjb25zdCBkb3RJbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTtcbiAgICBjb25zdCBoYXNFeHRlbnNpb24gPSBkb3RJbmRleCA+IDA7XG4gICAgY29uc3QgYmFzZU5hbWUgPSBoYXNFeHRlbnNpb24gPyBuYW1lLnNsaWNlKDAsIGRvdEluZGV4KSA6IG5hbWU7XG4gICAgY29uc3QgZXh0ZW5zaW9uID0gaGFzRXh0ZW5zaW9uID8gbmFtZS5zbGljZShkb3RJbmRleCkgOiAnJztcbiAgICBsZXQgY2FuZGlkYXRlID0gYCR7dGhpcy5zdGFnaW5nRm9sZGVyUGF0aH0vJHtuYW1lfWA7XG4gICAgbGV0IGNvdW50ZXIgPSAxO1xuICAgIHdoaWxlIChhd2FpdCBhZGFwdGVyLmV4aXN0cyhjYW5kaWRhdGUpKSB7XG4gICAgICBjYW5kaWRhdGUgPSBgJHt0aGlzLnN0YWdpbmdGb2xkZXJQYXRofS8ke2Jhc2VOYW1lfSAke2NvdW50ZXIudG9TdHJpbmcoKX0ke2V4dGVuc2lvbn1gO1xuICAgICAgY291bnRlcisrO1xuICAgIH1cbiAgICByZXR1cm4gY2FuZGlkYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYXJkRGVsZXRlKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGZpbGUgPSBnZXRBYnN0cmFjdEZpbGVPck51bGwoeyBhcHA6IHRoaXMuYXBwLCBwYXRoT3JGaWxlOiBwYXRoIH0pO1xuICAgIGlmIChmaWxlKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JzaWRpYW5tZC9wcmVmZXItZmlsZS1tYW5hZ2VyLXRyYXNoLWZpbGUgLS0gVW5kb2luZyBhIHRyYW5zYWN0aW9uLWxvY2FsIGNyZWF0ZSBtdXN0IHZhbmlzaCBpdCBlbnRpcmVseSwgbm90IGxhbmQgaXQgaW4gdGhlIHVzZXIncyB0cmFzaC5cbiAgICAgIGF3YWl0IHRoaXMuYXBwLnZhdWx0LmRlbGV0ZShmaWxlLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHB1c2hVbmRvKHVuZG86ICgpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkIHtcbiAgICB0aGlzLnVuZG9TdGVwcy5wdXNoKHsgdW5kbyB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVtb3ZlU3RhZ2luZ0ZvbGRlcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuaGFzU3RhZ2luZ0ZvbGRlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmhhc1N0YWdpbmdGb2xkZXIgPSBmYWxzZTtcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5hcHAudmF1bHQuYWRhcHRlcjtcbiAgICBpZiAoYXdhaXQgYWRhcHRlci5leGlzdHModGhpcy5zdGFnaW5nRm9sZGVyUGF0aCkpIHtcbiAgICAgIGF3YWl0IGFkYXB0ZXIucm1kaXIodGhpcy5zdGFnaW5nRm9sZGVyUGF0aCwgdHJ1ZSk7XG4gICAgfVxuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBCQSxTQUFTLHlCQUF5QjtBQUNsQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFFUCxNQUFNLDhCQUE4QjtBQThDN0IsTUFBTSxpQkFBaUI7QUFBQSxFQUNYO0FBQUEsRUFDVCxtQkFBbUI7QUFBQSxFQUNuQixpQkFBb0M7QUFBQSxFQUMzQixtQkFBNkIsQ0FBQztBQUFBLEVBQzlCO0FBQUEsRUFDVCxRQUEwQjtBQUFBLEVBQ2pCLFlBQXdCLENBQUM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPbkMsWUFBWSxRQUEyQztBQUM1RCxTQUFLLE1BQU0sT0FBTztBQUNsQixTQUFLLG9CQUFvQixPQUFPLHFCQUFxQjtBQUNyRCxTQUFLLGlCQUFpQixPQUFPLHFCQUFxQixLQUFLO0FBQUEsRUFDekQ7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWEsU0FBd0I7QUFDbkMsU0FBSyxXQUFXO0FBQ2hCLFNBQUssUUFBUTtBQUNiLFVBQU0sVUFBVSxLQUFLLElBQUksTUFBTTtBQUMvQixlQUFXLGNBQWMsS0FBSyxrQkFBa0I7QUFDOUMsWUFBTSxxQkFBcUIsTUFBTSxRQUFRLFlBQVksVUFBVTtBQUMvRCxVQUFJLENBQUMsb0JBQW9CO0FBQ3ZCLGNBQU0sUUFBUSxXQUFXLFVBQVU7QUFBQSxNQUNyQztBQUFBLElBQ0Y7QUFDQSxVQUFNLEtBQUssb0JBQW9CO0FBQy9CLFNBQUssc0JBQXNCO0FBQUEsRUFDN0I7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFB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
|
|
@@ -8,8 +8,8 @@ import type { App, ListedFiles } from 'obsidian';
|
|
|
8
8
|
import { TAbstractFile, TFile, TFolder } from 'obsidian';
|
|
9
9
|
import type { RetryOptions } from '../async.mjs';
|
|
10
10
|
import type { ValueProvider } from '../value-provider.mjs';
|
|
11
|
-
import type { EditorLockComponent } from './editor-lock.mjs';
|
|
12
11
|
import type { PathOrAbstractFile, PathOrFile, PathOrFolder } from './file-system.mjs';
|
|
12
|
+
import type { ResourceLockComponent } from './resource-lock.mjs';
|
|
13
13
|
import { FileSystemType } from './file-system.mjs';
|
|
14
14
|
/**
|
|
15
15
|
* Arguments for {@link process}.
|
|
@@ -143,11 +143,11 @@ export interface IsChildParams {
|
|
|
143
143
|
*/
|
|
144
144
|
export interface ProcessOptions extends RetryOptions {
|
|
145
145
|
/**
|
|
146
|
-
* An
|
|
146
|
+
* An resource-lock component used to lock the file's editor read-only for the duration of
|
|
147
147
|
* processing. The lock is reference-counted, so it composes with any outer operation-level lock
|
|
148
148
|
* on the same note.
|
|
149
149
|
*/
|
|
150
|
-
readonly
|
|
150
|
+
readonly resourceLockComponent: null | ResourceLockComponent;
|
|
151
151
|
/**
|
|
152
152
|
* Whether to fail if the file is missing or deleted.
|
|
153
153
|
*
|