@chance722/dsh-inbox 0.2.2 → 0.2.4
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/LICENSE +21 -21
- package/README.md +141 -134
- package/README.zh.md +141 -134
- package/cordis.patch.yml +11 -11
- package/lib/client.js +179 -48
- package/lib/index.js +171 -54
- package/lib/types/client/messages.d.ts +42 -18
- package/lib/types/host/remote/merge.d.ts +17 -1
- package/lib/types/host/remote/pull.d.ts +27 -3
- package/lib/types/host/s3/client.d.ts +25 -1
- package/lib/types/host/webdav/config.d.ts +4 -0
- package/lib/types/shared/panel-wire.d.ts +79 -0
- package/package.json +1 -1
|
@@ -28,6 +28,7 @@ export declare const WebdavSettingsSchema: z<Schemastery.ObjectS<{
|
|
|
28
28
|
protocol: z<"webdav" | "s3", "webdav" | "s3">;
|
|
29
29
|
baseUrl: z<string, string>;
|
|
30
30
|
directory: z<string, string>;
|
|
31
|
+
adoptForeignRoots: z<boolean, boolean>;
|
|
31
32
|
username: z<string, string>;
|
|
32
33
|
endpoint: z<string, string>;
|
|
33
34
|
bucket: z<string, string>;
|
|
@@ -40,6 +41,7 @@ export declare const WebdavSettingsSchema: z<Schemastery.ObjectS<{
|
|
|
40
41
|
protocol: z<"webdav" | "s3", "webdav" | "s3">;
|
|
41
42
|
baseUrl: z<string, string>;
|
|
42
43
|
directory: z<string, string>;
|
|
44
|
+
adoptForeignRoots: z<boolean, boolean>;
|
|
43
45
|
username: z<string, string>;
|
|
44
46
|
endpoint: z<string, string>;
|
|
45
47
|
bucket: z<string, string>;
|
|
@@ -75,6 +77,8 @@ export interface WebdavPatch {
|
|
|
75
77
|
protocol?: string;
|
|
76
78
|
baseUrl?: string;
|
|
77
79
|
directory?: string;
|
|
80
|
+
/** Merge other sync trees in the same bucket, not just this directory's. */
|
|
81
|
+
adoptForeignRoots?: boolean;
|
|
78
82
|
username?: string;
|
|
79
83
|
/** Empty string clears the stored password; undefined leaves it. */
|
|
80
84
|
password?: string;
|
|
@@ -48,6 +48,8 @@ export interface WebdavRequest {
|
|
|
48
48
|
protocol?: RemoteProtocol;
|
|
49
49
|
baseUrl?: string;
|
|
50
50
|
directory?: string;
|
|
51
|
+
/** Merge other sync trees in the same bucket, not just this directory's. */
|
|
52
|
+
adoptForeignRoots?: boolean;
|
|
51
53
|
username?: string;
|
|
52
54
|
/** Empty string clears the stored password; absent leaves it alone. */
|
|
53
55
|
password?: string;
|
|
@@ -82,6 +84,18 @@ export interface WebdavSettings {
|
|
|
82
84
|
baseUrl: string;
|
|
83
85
|
/** Folder under the base URL; the convention every device drops into. */
|
|
84
86
|
directory: string;
|
|
87
|
+
/**
|
|
88
|
+
* Also merge `…/sync` trees found **outside** the configured directory.
|
|
89
|
+
*
|
|
90
|
+
* Off by default, because the directory is what tells two vaults apart and a
|
|
91
|
+
* bucket can be shared. On, this is what a person means by "it is all my
|
|
92
|
+
* cloud drive": a machine that used to sync somewhere else leaves its records
|
|
93
|
+
* behind, and they come back (asked 2026-09-21, 19 records). Merging settles
|
|
94
|
+
* per record by `id` + `updatedAt`, so an older tree cannot overwrite a newer
|
|
95
|
+
* copy — but it *can* bring back a record that was purged here, because a
|
|
96
|
+
* purge leaves nothing local to outrank it.
|
|
97
|
+
*/
|
|
98
|
+
adoptForeignRoots: boolean;
|
|
85
99
|
username: string;
|
|
86
100
|
/** S3: endpoint host, e.g. `https://s3.cstcloud.cn`. */
|
|
87
101
|
endpoint: string;
|
|
@@ -123,6 +137,33 @@ export interface WebdavStatus {
|
|
|
123
137
|
credentialsAvailable: boolean;
|
|
124
138
|
}
|
|
125
139
|
/** What one pull did, for the panel and for the log. */
|
|
140
|
+
/** The directory a sync uses when the user never named one. */
|
|
141
|
+
export declare const DEFAULT_SYNC_DIRECTORY = "inbox";
|
|
142
|
+
/**
|
|
143
|
+
* The directory a sync actually uses, decided in one place.
|
|
144
|
+
*
|
|
145
|
+
* `/`, an empty string and "never named one" all mean the default. They used to
|
|
146
|
+
* mean different things depending on which path read them: `syncRoot()` turned a
|
|
147
|
+
* stripped-empty directory into the *bucket root* (`sync/`) while the
|
|
148
|
+
* drop-folder ingest defaulted to `/inbox`, so two machines set up through the
|
|
149
|
+
* same dialog could write to `sync/` and `inbox/sync/` respectively — and the
|
|
150
|
+
* merge, which reads its own prefix, then found nothing and reported nothing new
|
|
151
|
+
* (measured 2026-09-20).
|
|
152
|
+
*
|
|
153
|
+
* @param raw - whatever the settings hold, if anything.
|
|
154
|
+
* @returns the directory without leading or trailing slashes; never empty.
|
|
155
|
+
*/
|
|
156
|
+
export declare function syncDirectory(raw: string | undefined): string;
|
|
157
|
+
/**
|
|
158
|
+
* Where the vault's own objects live: `<directory>/sync`.
|
|
159
|
+
*
|
|
160
|
+
* Shared by the writer, the drop-folder ingest and the display, so "which
|
|
161
|
+
* prefix is mine" has one answer on both sides of the wire.
|
|
162
|
+
*
|
|
163
|
+
* @param raw - the configured directory, if any.
|
|
164
|
+
* @returns the sync root, e.g. `inbox/sync`.
|
|
165
|
+
*/
|
|
166
|
+
export declare function syncRootFor(raw: string | undefined): string;
|
|
126
167
|
export interface PullResult {
|
|
127
168
|
status: 'ok' | 'unconfigured' | 'failed';
|
|
128
169
|
reason?: string;
|
|
@@ -132,11 +173,49 @@ export interface PullResult {
|
|
|
132
173
|
* than the local copy). Only the merge half of a pull can produce these.
|
|
133
174
|
*/
|
|
134
175
|
merged?: number;
|
|
176
|
+
/** How many of {@link merged} were ids this vault did not have at all. */
|
|
177
|
+
added?: number;
|
|
135
178
|
/** Attachment objects the merge had to fetch and admit locally. */
|
|
136
179
|
attachments?: number;
|
|
180
|
+
/**
|
|
181
|
+
* Records the cloud holds that this vault **already had** (same id, not older).
|
|
182
|
+
*
|
|
183
|
+
* This is the answer to "why is the cloud's copy not coming over?": it is the
|
|
184
|
+
* same record, and the merge settles per record by `id` + `updatedAt` rather
|
|
185
|
+
* than by which machine uploaded it — a record this machine pushed comes back
|
|
186
|
+
* with the timestamp it left with, so it is kept, not re-filed.
|
|
187
|
+
*/
|
|
188
|
+
kept?: number;
|
|
137
189
|
failed: number;
|
|
138
190
|
/** Files the server listed but we skipped as already-seen. */
|
|
139
191
|
skipped: number;
|
|
192
|
+
/**
|
|
193
|
+
* How many of {@link skipped} were the vault's own upload queue (`sync/…`).
|
|
194
|
+
*
|
|
195
|
+
* Optional because the older shape of this result (and every test that builds
|
|
196
|
+
* one by hand) predates the split.
|
|
197
|
+
*/
|
|
198
|
+
skippedSync?: number;
|
|
199
|
+
/** How many of {@link skipped} were older than the last pull's cursor. */
|
|
200
|
+
skippedOlder?: number;
|
|
201
|
+
/**
|
|
202
|
+
* How many of {@link skipped} sat under a `…/sync/` prefix that is **not**
|
|
203
|
+
* ours — another machine syncing under a different directory.
|
|
204
|
+
*/
|
|
205
|
+
skippedForeign?: number;
|
|
206
|
+
/** Those other prefixes, e.g. `['inbox/sync']`; the panel warns about them. */
|
|
207
|
+
foreignSyncRoots?: string[];
|
|
208
|
+
/** How many `items/*.json` records those other prefixes hold together. */
|
|
209
|
+
foreignRecords?: number;
|
|
210
|
+
/** This machine's own sync root, so the warning can name both sides. */
|
|
211
|
+
syncRoot?: string;
|
|
212
|
+
/**
|
|
213
|
+
* How many **records** the cloud holds, as opposed to how many objects that
|
|
214
|
+
* takes: `items/<id>.json` files under this machine's own sync root.
|
|
215
|
+
*/
|
|
216
|
+
remoteRecords?: number;
|
|
217
|
+
/** How many attachments the cloud holds (`attachments/<id>.<ext>`, no descriptors). */
|
|
218
|
+
remoteAttachments?: number;
|
|
140
219
|
/** How many entries the remote listed at all: distinguishes "empty folder"
|
|
141
220
|
* from "everything already ingested". */
|
|
142
221
|
listed: number;
|