@filen/sync 0.1.1

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.
@@ -0,0 +1 @@
1
+ export declare const SYNC_INTERVAL = 5000;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SYNC_INTERVAL = void 0;
4
+ exports.SYNC_INTERVAL = 5000;
5
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG,IAAI,CAAA"}
@@ -0,0 +1,41 @@
1
+ import type { SyncPair } from "./types";
2
+ import { type FilenSDKConfig } from "@filen/sdk";
3
+ /**
4
+ * SyncWorker
5
+ * @date 2/23/2024 - 5:50:56 AM
6
+ *
7
+ * @export
8
+ * @class SyncWorker
9
+ * @typedef {SyncWorker}
10
+ */
11
+ export declare class SyncWorker {
12
+ private readonly syncPairs;
13
+ private readonly syncs;
14
+ private readonly dbPath;
15
+ private readonly sdkConfig;
16
+ /**
17
+ * Creates an instance of SyncWorker.
18
+ *
19
+ * @constructor
20
+ * @public
21
+ * @param {{ syncPairs: SyncPair[]; dbPath: string; sdkConfig: FilenSDKConfig }} param0
22
+ * @param {{}} param0.syncPairs
23
+ * @param {string} param0.dbPath
24
+ * @param {FilenSDKConfig} param0.sdkConfig
25
+ */
26
+ constructor({ syncPairs, dbPath, sdkConfig }: {
27
+ syncPairs: SyncPair[];
28
+ dbPath: string;
29
+ sdkConfig: FilenSDKConfig;
30
+ });
31
+ /**
32
+ * Initialize the Sync worker.
33
+ * @date 2/23/2024 - 5:51:12 AM
34
+ *
35
+ * @public
36
+ * @async
37
+ * @returns {Promise<void>}
38
+ */
39
+ initialize(): Promise<void>;
40
+ }
41
+ export default SyncWorker;
package/dist/index.js ADDED
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SyncWorker = void 0;
7
+ const sync_1 = __importDefault(require("./lib/sync"));
8
+ /**
9
+ * SyncWorker
10
+ * @date 2/23/2024 - 5:50:56 AM
11
+ *
12
+ * @export
13
+ * @class SyncWorker
14
+ * @typedef {SyncWorker}
15
+ */
16
+ class SyncWorker {
17
+ /**
18
+ * Creates an instance of SyncWorker.
19
+ *
20
+ * @constructor
21
+ * @public
22
+ * @param {{ syncPairs: SyncPair[]; dbPath: string; sdkConfig: FilenSDKConfig }} param0
23
+ * @param {{}} param0.syncPairs
24
+ * @param {string} param0.dbPath
25
+ * @param {FilenSDKConfig} param0.sdkConfig
26
+ */
27
+ constructor({ syncPairs, dbPath, sdkConfig }) {
28
+ this.syncs = {};
29
+ this.syncPairs = syncPairs;
30
+ this.dbPath = dbPath;
31
+ this.sdkConfig = sdkConfig;
32
+ }
33
+ /**
34
+ * Initialize the Sync worker.
35
+ * @date 2/23/2024 - 5:51:12 AM
36
+ *
37
+ * @public
38
+ * @async
39
+ * @returns {Promise<void>}
40
+ */
41
+ async initialize() {
42
+ const promises = [];
43
+ for (const pair of this.syncPairs) {
44
+ if (!this.syncs[pair.uuid]) {
45
+ this.syncs[pair.uuid] = new sync_1.default({
46
+ syncPair: pair,
47
+ dbPath: this.dbPath,
48
+ sdkConfig: this.sdkConfig
49
+ });
50
+ promises.push(this.syncs[pair.uuid].initialize());
51
+ }
52
+ }
53
+ await Promise.all(promises);
54
+ }
55
+ }
56
+ exports.SyncWorker = SyncWorker;
57
+ exports.default = SyncWorker;
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,sDAA6B;AAG7B;;;;;;;GAOG;AACH,MAAa,UAAU;IAMtB;;;;;;;;;OASG;IACH,YAAmB,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAwE;QAdxG,UAAK,GAAyB,EAAE,CAAA;QAehD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC3B,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,UAAU;QACtB,MAAM,QAAQ,GAAoB,EAAE,CAAA;QAEpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,cAAI,CAAC;oBAChC,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;iBACzB,CAAC,CAAA;gBAEF,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC,UAAU,EAAE,CAAC,CAAA;YACnD,CAAC;QACF,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC5B,CAAC;CACD;AA/CD,gCA+CC;AAED,kBAAe,UAAU,CAAA"}
@@ -0,0 +1,106 @@
1
+ import type Sync from "./sync";
2
+ import type { LocalTree } from "./filesystems/local";
3
+ import type { RemoteTree } from "./filesystems/remote";
4
+ export type Delta = {
5
+ path: string;
6
+ } & ({
7
+ type: "uploadFile";
8
+ } | {
9
+ type: "createRemoteDirectory";
10
+ } | {
11
+ type: "createLocalDirectory";
12
+ } | {
13
+ type: "deleteLocalFile";
14
+ } | {
15
+ type: "deleteRemoteFile";
16
+ } | {
17
+ type: "deleteLocalDirectory";
18
+ } | {
19
+ type: "deleteRemoteDirectory";
20
+ } | {
21
+ type: "downloadFile";
22
+ } | {
23
+ type: "moveLocalFile";
24
+ from: string;
25
+ to: string;
26
+ } | {
27
+ type: "renameLocalFile";
28
+ from: string;
29
+ to: string;
30
+ } | {
31
+ type: "moveRemoteFile";
32
+ from: string;
33
+ to: string;
34
+ } | {
35
+ type: "renameRemoteFile";
36
+ from: string;
37
+ to: string;
38
+ } | {
39
+ type: "renameRemoteDirectory";
40
+ from: string;
41
+ to: string;
42
+ } | {
43
+ type: "renameLocalDirectory";
44
+ from: string;
45
+ to: string;
46
+ } | {
47
+ type: "moveRemoteDirectory";
48
+ from: string;
49
+ to: string;
50
+ } | {
51
+ type: "moveLocalFile";
52
+ from: string;
53
+ to: string;
54
+ } | {
55
+ type: "moveLocalDirectory";
56
+ from: string;
57
+ to: string;
58
+ });
59
+ /**
60
+ * Deltas
61
+ * @date 3/1/2024 - 11:11:32 PM
62
+ *
63
+ * @export
64
+ * @class Deltas
65
+ * @typedef {Deltas}
66
+ */
67
+ export declare class Deltas {
68
+ private readonly sync;
69
+ /**
70
+ * Creates an instance of Deltas.
71
+ * @date 3/1/2024 - 11:11:36 PM
72
+ *
73
+ * @constructor
74
+ * @public
75
+ * @param {{ sync: Sync }} param0
76
+ * @param {Sync} param0.sync
77
+ */
78
+ constructor({ sync }: {
79
+ sync: Sync;
80
+ });
81
+ /**
82
+ * Process the directory trees and return all sync deltas.
83
+ * @date 3/2/2024 - 8:42:25 AM
84
+ *
85
+ * @public
86
+ * @async
87
+ * @param {{
88
+ * currentLocalTree: LocalTree
89
+ * currentRemoteTree: RemoteTree
90
+ * previousLocalTree: LocalTree
91
+ * previousRemoteTree: RemoteTree
92
+ * }} param0
93
+ * @param {LocalTree} param0.currentLocalTree
94
+ * @param {RemoteTree} param0.currentRemoteTree
95
+ * @param {LocalTree} param0.previousLocalTree
96
+ * @param {RemoteTree} param0.previousRemoteTree
97
+ * @returns {Promise<Delta[]>}
98
+ */
99
+ process({ currentLocalTree, currentRemoteTree, previousLocalTree, previousRemoteTree }: {
100
+ currentLocalTree: LocalTree;
101
+ currentRemoteTree: RemoteTree;
102
+ previousLocalTree: LocalTree;
103
+ previousRemoteTree: RemoteTree;
104
+ }): Promise<Delta[]>;
105
+ }
106
+ export default Deltas;
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Deltas = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ /**
9
+ * Deltas
10
+ * @date 3/1/2024 - 11:11:32 PM
11
+ *
12
+ * @export
13
+ * @class Deltas
14
+ * @typedef {Deltas}
15
+ */
16
+ class Deltas {
17
+ /**
18
+ * Creates an instance of Deltas.
19
+ * @date 3/1/2024 - 11:11:36 PM
20
+ *
21
+ * @constructor
22
+ * @public
23
+ * @param {{ sync: Sync }} param0
24
+ * @param {Sync} param0.sync
25
+ */
26
+ constructor({ sync }) {
27
+ this.sync = sync;
28
+ }
29
+ /**
30
+ * Process the directory trees and return all sync deltas.
31
+ * @date 3/2/2024 - 8:42:25 AM
32
+ *
33
+ * @public
34
+ * @async
35
+ * @param {{
36
+ * currentLocalTree: LocalTree
37
+ * currentRemoteTree: RemoteTree
38
+ * previousLocalTree: LocalTree
39
+ * previousRemoteTree: RemoteTree
40
+ * }} param0
41
+ * @param {LocalTree} param0.currentLocalTree
42
+ * @param {RemoteTree} param0.currentRemoteTree
43
+ * @param {LocalTree} param0.previousLocalTree
44
+ * @param {RemoteTree} param0.previousRemoteTree
45
+ * @returns {Promise<Delta[]>}
46
+ */
47
+ async process({ currentLocalTree, currentRemoteTree, previousLocalTree, previousRemoteTree }) {
48
+ const deltas = [];
49
+ const pathsAdded = {};
50
+ // Local file/directory move/rename
51
+ for (const inode in currentLocalTree.inodes) {
52
+ const currentItem = currentLocalTree.inodes[inode];
53
+ const previousItem = previousLocalTree.inodes[inode];
54
+ if (!currentItem || !previousItem || pathsAdded[currentItem.path] || pathsAdded[previousItem.path]) {
55
+ continue;
56
+ }
57
+ // Path from current item changed, it was either renamed or moved
58
+ if (currentItem.path !== previousItem.path) {
59
+ const currentItemParentPath = path_1.default.posix.dirname(currentItem.path);
60
+ const previousItemParentPath = path_1.default.posix.dirname(previousItem.path);
61
+ const currentItemParent = currentLocalTree.tree[currentItemParentPath];
62
+ const previousItemParent = previousLocalTree.tree[previousItemParentPath];
63
+ const currentItemName = path_1.default.posix.basename(currentItem.path);
64
+ const previousItemName = path_1.default.posix.basename(previousItem.path);
65
+ // Names changed
66
+ if (currentItemName !== previousItemName) {
67
+ deltas.push({
68
+ type: currentItem.type === "directory" ? "renameRemoteDirectory" : "renameRemoteFile",
69
+ path: currentItem.path,
70
+ from: previousItem.path,
71
+ to: currentItem.path
72
+ });
73
+ }
74
+ pathsAdded[currentItem.path] = true;
75
+ pathsAdded[previousItem.path] = true;
76
+ // Parents did not change, continue
77
+ if ((currentItemParent === null || currentItemParent === void 0 ? void 0 : currentItemParent.inode) === (previousItemParent === null || previousItemParent === void 0 ? void 0 : previousItemParent.inode)) {
78
+ continue;
79
+ }
80
+ // Item was also moved
81
+ deltas.push({
82
+ type: currentItem.type === "directory" ? "moveRemoteDirectory" : "moveRemoteFile",
83
+ path: currentItem.path,
84
+ from: previousItem.path,
85
+ to: currentItem.path
86
+ });
87
+ }
88
+ }
89
+ // Remote file/directory move/rename
90
+ for (const uuid in currentRemoteTree.uuids) {
91
+ const currentItem = currentRemoteTree.uuids[uuid];
92
+ const previousItem = currentRemoteTree.uuids[uuid];
93
+ if (!currentItem || !previousItem || pathsAdded[currentItem.path] || pathsAdded[previousItem.path]) {
94
+ continue;
95
+ }
96
+ // Path from current item changed, it was either renamed or moved
97
+ if (currentItem.path !== previousItem.path) {
98
+ const currentItemParentPath = path_1.default.posix.dirname(currentItem.path);
99
+ const previousItemParentPath = path_1.default.posix.dirname(previousItem.path);
100
+ const currentItemParent = currentRemoteTree.tree[currentItemParentPath];
101
+ const previousItemParent = previousRemoteTree.tree[previousItemParentPath];
102
+ const currentItemName = path_1.default.posix.basename(currentItem.path);
103
+ const previousItemName = path_1.default.posix.basename(previousItem.path);
104
+ // Names changed
105
+ if (currentItemName !== previousItemName) {
106
+ deltas.push({
107
+ type: currentItem.type === "directory" ? "renameRemoteDirectory" : "renameRemoteFile",
108
+ path: currentItem.path,
109
+ from: previousItem.path,
110
+ to: currentItem.path
111
+ });
112
+ }
113
+ pathsAdded[currentItem.path] = true;
114
+ pathsAdded[previousItem.path] = true;
115
+ // Parents did not change, continue
116
+ if ((currentItemParent === null || currentItemParent === void 0 ? void 0 : currentItemParent.uuid) === (previousItemParent === null || previousItemParent === void 0 ? void 0 : previousItemParent.uuid)) {
117
+ continue;
118
+ }
119
+ // Item was also moved
120
+ deltas.push({
121
+ type: currentItem.type === "directory" ? "moveRemoteDirectory" : "moveRemoteFile",
122
+ path: currentItem.path,
123
+ from: previousItem.path,
124
+ to: currentItem.path
125
+ });
126
+ }
127
+ }
128
+ // Local deletions
129
+ for (const path in previousLocalTree.tree) {
130
+ if (pathsAdded[path]) {
131
+ continue;
132
+ }
133
+ const previousLocalItem = previousLocalTree.tree[path];
134
+ const currentLocalItem = currentLocalTree.tree[path];
135
+ if (!currentLocalItem && previousLocalItem) {
136
+ deltas.push({
137
+ type: previousLocalItem.type === "directory" ? "deleteRemoteDirectory" : "deleteRemoteFile",
138
+ path
139
+ });
140
+ pathsAdded[path] = true;
141
+ }
142
+ }
143
+ // Remote deletions
144
+ for (const path in previousRemoteTree.tree) {
145
+ if (pathsAdded[path]) {
146
+ continue;
147
+ }
148
+ const previousRemoteItem = previousRemoteTree.tree[path];
149
+ const currentRemoteItem = currentRemoteTree.tree[path];
150
+ if (!currentRemoteItem && previousRemoteItem) {
151
+ deltas.push({
152
+ type: previousRemoteItem.type === "directory" ? "deleteLocalDirectory" : "deleteLocalFile",
153
+ path
154
+ });
155
+ pathsAdded[path] = true;
156
+ }
157
+ }
158
+ // Local additions/changes
159
+ for (const path in currentLocalTree.tree) {
160
+ if (pathsAdded[path]) {
161
+ continue;
162
+ }
163
+ const currentLocalItem = currentLocalTree.tree[path];
164
+ const currentRemoteItem = currentRemoteTree.tree[path];
165
+ if (!currentRemoteItem && currentLocalItem) {
166
+ deltas.push({
167
+ type: currentLocalItem.type === "directory" ? "createRemoteDirectory" : "uploadFile",
168
+ path
169
+ });
170
+ pathsAdded[path] = true;
171
+ continue;
172
+ }
173
+ if (currentRemoteItem && currentRemoteItem.type === "file") {
174
+ if (currentLocalItem && currentLocalItem.lastModified > currentRemoteItem.lastModified) {
175
+ const itemLocalPath = path_1.default.join(this.sync.syncPair.localPath, currentLocalItem.path);
176
+ if ((await this.sync.localFileSystem.createFileHash({ relativePath: path, algorithm: "sha512" })) !==
177
+ this.sync.localFileHashes[itemLocalPath]) {
178
+ deltas.push({
179
+ type: "uploadFile",
180
+ path
181
+ });
182
+ pathsAdded[path] = true;
183
+ }
184
+ }
185
+ }
186
+ }
187
+ // Remote additions/changes
188
+ for (const path in currentRemoteTree.tree) {
189
+ if (pathsAdded[path]) {
190
+ continue;
191
+ }
192
+ const currentLocalItem = currentLocalTree.tree[path];
193
+ const currentRemoteItem = currentRemoteTree.tree[path];
194
+ if (!currentLocalItem && currentRemoteItem) {
195
+ deltas.push({
196
+ type: currentRemoteItem.type === "directory" ? "createLocalDirectory" : "downloadFile",
197
+ path
198
+ });
199
+ pathsAdded[path] = true;
200
+ continue;
201
+ }
202
+ if (currentRemoteItem && currentRemoteItem.type === "file") {
203
+ if (currentLocalItem && currentRemoteItem.lastModified > currentLocalItem.lastModified) {
204
+ deltas.push({
205
+ type: "downloadFile",
206
+ path
207
+ });
208
+ pathsAdded[path] = true;
209
+ }
210
+ }
211
+ }
212
+ return deltas;
213
+ }
214
+ }
215
+ exports.Deltas = Deltas;
216
+ exports.default = Deltas;
217
+ //# sourceMappingURL=deltas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltas.js","sourceRoot":"","sources":["../../src/lib/deltas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ /// <reference types="node" />
2
+ import fs from "fs-extra";
3
+ import type Sync from "../sync";
4
+ import type { CloudItem } from "@filen/sdk";
5
+ export type LocalItem = {
6
+ lastModified: number;
7
+ type: "file" | "directory";
8
+ path: string;
9
+ size: number;
10
+ creation: number;
11
+ inode: number;
12
+ };
13
+ export type LocalDirectoryTree = Record<string, LocalItem>;
14
+ export type LocalDirectoryINodes = Record<number, LocalItem>;
15
+ export type LocalTree = {
16
+ tree: LocalDirectoryTree;
17
+ inodes: LocalDirectoryINodes;
18
+ };
19
+ /**
20
+ * LocalFileSystem
21
+ * @date 3/2/2024 - 12:38:22 PM
22
+ *
23
+ * @export
24
+ * @class LocalFileSystem
25
+ * @typedef {LocalFileSystem}
26
+ */
27
+ export declare class LocalFileSystem {
28
+ private readonly sync;
29
+ lastDirectoryChangeTimestamp: number;
30
+ getDirectoryTreeCache: {
31
+ timestamp: number;
32
+ tree: LocalDirectoryTree;
33
+ inodes: LocalDirectoryINodes;
34
+ };
35
+ watcherRunning: boolean;
36
+ private watcherInstance;
37
+ /**
38
+ * Creates an instance of LocalFileSystem.
39
+ * @date 3/2/2024 - 12:38:20 PM
40
+ *
41
+ * @constructor
42
+ * @public
43
+ * @param {{ sync: Sync }} param0
44
+ * @param {Sync} param0.sync
45
+ */
46
+ constructor({ sync }: {
47
+ sync: Sync;
48
+ });
49
+ /**
50
+ * Get the local directory tree.
51
+ * @date 3/2/2024 - 12:38:13 PM
52
+ *
53
+ * @public
54
+ * @async
55
+ * @returns {Promise<LocalTree>}
56
+ */
57
+ getDirectoryTree(): Promise<LocalTree>;
58
+ /**
59
+ * Start the local sync directory watcher.
60
+ * @date 3/2/2024 - 12:38:00 PM
61
+ *
62
+ * @public
63
+ * @async
64
+ * @returns {Promise<void>}
65
+ */
66
+ startDirectoryWatcher(): Promise<void>;
67
+ /**
68
+ * Stop the local sync directory watcher.
69
+ * @date 3/2/2024 - 12:37:48 PM
70
+ *
71
+ * @public
72
+ * @async
73
+ * @returns {Promise<void>}
74
+ */
75
+ stopDirectoryWatcher(): Promise<void>;
76
+ /**
77
+ * Wait for local directory updates to be done.
78
+ * Sometimes the user might copy a lot of new files, folders etc.
79
+ * We want to wait (or at least try) until all local operations are done until we start syncing.
80
+ * This can save a lot of sync cycles.
81
+ * @date 3/1/2024 - 10:40:14 PM
82
+ *
83
+ * @public
84
+ * @async
85
+ * @returns {Promise<void>}
86
+ */
87
+ waitForLocalDirectoryChanges(): Promise<void>;
88
+ /**
89
+ * Creates a hash of a file using streams.
90
+ * @date 3/2/2024 - 9:29:48 AM
91
+ *
92
+ * @public
93
+ * @async
94
+ * @param {{ relativePath: string; algorithm: "sha512" }} param0
95
+ * @param {string} param0.relativePath
96
+ * @param {"sha512"} param0.algorithm
97
+ * @returns {Promise<string>}
98
+ */
99
+ createFileHash({ relativePath, algorithm }: {
100
+ relativePath: string;
101
+ algorithm: "sha512";
102
+ }): Promise<string>;
103
+ /**
104
+ * Create a directory inside the local sync path. Recursively creates intermediate directories if needed.
105
+ * @date 3/2/2024 - 12:36:23 PM
106
+ *
107
+ * @public
108
+ * @async
109
+ * @param {{ relativePath: string }} param0
110
+ * @param {string} param0.relativePath
111
+ * @returns {Promise<fs.Stats>}
112
+ */
113
+ mkdir({ relativePath }: {
114
+ relativePath: string;
115
+ }): Promise<fs.Stats>;
116
+ /**
117
+ * Delete a file/directory inside the local sync path.
118
+ * @date 3/3/2024 - 10:05:55 PM
119
+ *
120
+ * @public
121
+ * @async
122
+ * @param {{ relativePath: string; permanent?: boolean }} param0
123
+ * @param {string} param0.relativePath
124
+ * @param {boolean} [param0.permanent=false]
125
+ * @returns {Promise<void>}
126
+ */
127
+ unlink({ relativePath, permanent }: {
128
+ relativePath: string;
129
+ permanent?: boolean;
130
+ }): Promise<void>;
131
+ /**
132
+ * Rename a file/directory inside the local sync path. Recursively creates intermediate directories if needed.
133
+ * @date 3/2/2024 - 12:41:15 PM
134
+ *
135
+ * @public
136
+ * @async
137
+ * @param {{ fromRelativePath: string; toRelativePath: string }} param0
138
+ * @param {string} param0.fromRelativePath
139
+ * @param {string} param0.toRelativePath
140
+ * @returns {Promise<fs.Stats>}
141
+ */
142
+ rename({ fromRelativePath, toRelativePath }: {
143
+ fromRelativePath: string;
144
+ toRelativePath: string;
145
+ }): Promise<fs.Stats>;
146
+ /**
147
+ * Upload a local file.
148
+ * @date 3/2/2024 - 9:43:58 PM
149
+ *
150
+ * @public
151
+ * @async
152
+ * @param {{ relativePath: string }} param0
153
+ * @param {string} param0.relativePath
154
+ * @returns {Promise<void>}
155
+ */
156
+ upload({ relativePath }: {
157
+ relativePath: string;
158
+ }): Promise<CloudItem>;
159
+ }
160
+ export default LocalFileSystem;