hazo_files 1.0.1 → 1.1.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/.env.example +23 -0
- package/README.md +33 -1
- package/dist/index.d.mts +271 -1
- package/dist/index.d.ts +271 -1
- package/dist/index.js +458 -8
- package/dist/index.mjs +453 -8
- package/dist/ui/index.d.mts +635 -0
- package/dist/ui/index.d.ts +635 -0
- package/dist/ui/index.js +1024 -456
- package/dist/ui/index.mjs +994 -423
- package/package.json +15 -2
- package/.cursor/rules/db_schema.mdc +0 -0
- package/.cursor/rules/design.mdc +0 -0
- package/.cursor/rules/general.mdc +0 -0
- package/CHANGE_LOG.md +0 -341
- package/CLAUDE.md +0 -926
- package/SETUP_CHECKLIST.md +0 -931
- package/TECHDOC.md +0 -325
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/ui/index.js.map +0 -1
- package/dist/ui/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ __export(index_exports, {
|
|
|
39
39
|
DirectoryNotFoundError: () => DirectoryNotFoundError,
|
|
40
40
|
FileExistsError: () => FileExistsError,
|
|
41
41
|
FileManager: () => FileManager,
|
|
42
|
+
FileMetadataService: () => FileMetadataService,
|
|
42
43
|
FileNotFoundError: () => FileNotFoundError,
|
|
43
44
|
FileTooLargeError: () => FileTooLargeError,
|
|
44
45
|
GoogleDriveAuth: () => GoogleDriveAuth,
|
|
@@ -52,18 +53,22 @@ __export(index_exports, {
|
|
|
52
53
|
SYSTEM_COUNTER_VARIABLES: () => SYSTEM_COUNTER_VARIABLES,
|
|
53
54
|
SYSTEM_DATE_VARIABLES: () => SYSTEM_DATE_VARIABLES,
|
|
54
55
|
SYSTEM_FILE_VARIABLES: () => SYSTEM_FILE_VARIABLES,
|
|
56
|
+
TrackedFileManager: () => TrackedFileManager,
|
|
55
57
|
clonePattern: () => clonePattern,
|
|
56
58
|
createAndInitializeModule: () => createAndInitializeModule,
|
|
57
59
|
createEmptyNamingRuleSchema: () => createEmptyNamingRuleSchema,
|
|
58
60
|
createFileItem: () => createFileItem,
|
|
59
61
|
createFileManager: () => createFileManager,
|
|
62
|
+
createFileMetadataService: () => createFileMetadataService,
|
|
60
63
|
createFolderItem: () => createFolderItem,
|
|
61
64
|
createGoogleDriveAuth: () => createGoogleDriveAuth,
|
|
62
65
|
createGoogleDriveModule: () => createGoogleDriveModule,
|
|
63
66
|
createInitializedFileManager: () => createInitializedFileManager,
|
|
67
|
+
createInitializedTrackedFileManager: () => createInitializedTrackedFileManager,
|
|
64
68
|
createLiteralSegment: () => createLiteralSegment,
|
|
65
69
|
createLocalModule: () => createLocalModule,
|
|
66
70
|
createModule: () => createModule,
|
|
71
|
+
createTrackedFileManager: () => createTrackedFileManager,
|
|
67
72
|
createVariableSegment: () => createVariableSegment,
|
|
68
73
|
errorResult: () => errorResult,
|
|
69
74
|
filterItems: () => filterItems,
|
|
@@ -141,12 +146,12 @@ function parseConfig(configContent) {
|
|
|
141
146
|
}
|
|
142
147
|
if (parsed.google_drive) {
|
|
143
148
|
config.google_drive = {
|
|
144
|
-
clientId: parsed.google_drive.client_id || process.env.
|
|
145
|
-
clientSecret: parsed.google_drive.client_secret || process.env.
|
|
146
|
-
redirectUri: parsed.google_drive.redirect_uri || process.env.
|
|
147
|
-
refreshToken: parsed.google_drive.refresh_token || process.env.
|
|
148
|
-
accessToken: parsed.google_drive.access_token || process.env.
|
|
149
|
-
rootFolderId: parsed.google_drive.root_folder_id || process.env.
|
|
149
|
+
clientId: parsed.google_drive.client_id || process.env.HAZO_GOOGLE_DRIVE_CLIENT_ID || "",
|
|
150
|
+
clientSecret: parsed.google_drive.client_secret || process.env.HAZO_GOOGLE_DRIVE_CLIENT_SECRET || "",
|
|
151
|
+
redirectUri: parsed.google_drive.redirect_uri || process.env.HAZO_GOOGLE_DRIVE_REDIRECT_URI || "",
|
|
152
|
+
refreshToken: parsed.google_drive.refresh_token || process.env.HAZO_GOOGLE_DRIVE_REFRESH_TOKEN,
|
|
153
|
+
accessToken: parsed.google_drive.access_token || process.env.HAZO_GOOGLE_DRIVE_ACCESS_TOKEN,
|
|
154
|
+
rootFolderId: parsed.google_drive.root_folder_id || process.env.HAZO_GOOGLE_DRIVE_ROOT_FOLDER_ID
|
|
150
155
|
};
|
|
151
156
|
}
|
|
152
157
|
return config;
|
|
@@ -202,7 +207,7 @@ max_file_size = 0
|
|
|
202
207
|
[google_drive]
|
|
203
208
|
; Google Drive OAuth credentials
|
|
204
209
|
; These can also be set via environment variables:
|
|
205
|
-
;
|
|
210
|
+
; HAZO_GOOGLE_DRIVE_CLIENT_ID, HAZO_GOOGLE_DRIVE_CLIENT_SECRET, etc.
|
|
206
211
|
client_id =
|
|
207
212
|
client_secret =
|
|
208
213
|
redirect_uri = http://localhost:3000/api/auth/callback/google
|
|
@@ -2043,6 +2048,447 @@ async function createInitializedFileManager(options) {
|
|
|
2043
2048
|
return manager;
|
|
2044
2049
|
}
|
|
2045
2050
|
|
|
2051
|
+
// src/services/file-metadata-service.ts
|
|
2052
|
+
var FileMetadataService = class {
|
|
2053
|
+
constructor(crudService, options = {}) {
|
|
2054
|
+
this.crud = crudService;
|
|
2055
|
+
this.logger = options.logger;
|
|
2056
|
+
this.logErrors = options.logErrors !== false;
|
|
2057
|
+
}
|
|
2058
|
+
/**
|
|
2059
|
+
* Generate ISO timestamp
|
|
2060
|
+
*/
|
|
2061
|
+
now() {
|
|
2062
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* Log an error if logging is enabled
|
|
2066
|
+
*/
|
|
2067
|
+
logError(operation, error) {
|
|
2068
|
+
if (this.logErrors) {
|
|
2069
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2070
|
+
this.logger?.error?.(`FileMetadataService.${operation} failed`, { error: message });
|
|
2071
|
+
if (!this.logger) {
|
|
2072
|
+
console.error(`[FileMetadataService] ${operation} failed:`, message);
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
/**
|
|
2077
|
+
* Record a file upload
|
|
2078
|
+
*/
|
|
2079
|
+
async recordUpload(input) {
|
|
2080
|
+
try {
|
|
2081
|
+
const timestamp = this.now();
|
|
2082
|
+
const record = {
|
|
2083
|
+
filename: input.filename,
|
|
2084
|
+
file_type: input.file_type,
|
|
2085
|
+
file_data: JSON.stringify(input.file_data || {}),
|
|
2086
|
+
file_path: input.file_path,
|
|
2087
|
+
storage_type: input.storage_type,
|
|
2088
|
+
created_at: timestamp,
|
|
2089
|
+
changed_at: timestamp
|
|
2090
|
+
};
|
|
2091
|
+
const results = await this.crud.insert(record);
|
|
2092
|
+
this.logger?.debug?.("Recorded file upload", { path: input.file_path });
|
|
2093
|
+
return results[0] || null;
|
|
2094
|
+
} catch (error) {
|
|
2095
|
+
this.logError("recordUpload", error);
|
|
2096
|
+
return null;
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
/**
|
|
2100
|
+
* Record a directory creation
|
|
2101
|
+
*/
|
|
2102
|
+
async recordDirectoryCreation(path3, storageType, metadata) {
|
|
2103
|
+
return this.recordUpload({
|
|
2104
|
+
filename: getBaseName(path3),
|
|
2105
|
+
file_type: "folder",
|
|
2106
|
+
file_data: metadata,
|
|
2107
|
+
file_path: path3,
|
|
2108
|
+
storage_type: storageType
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
/**
|
|
2112
|
+
* Record a file access (download)
|
|
2113
|
+
*/
|
|
2114
|
+
async recordAccess(path3, storageType) {
|
|
2115
|
+
try {
|
|
2116
|
+
const existing = await this.findByPath(path3, storageType);
|
|
2117
|
+
if (existing) {
|
|
2118
|
+
await this.crud.updateById(existing.id, {
|
|
2119
|
+
changed_at: this.now()
|
|
2120
|
+
});
|
|
2121
|
+
this.logger?.debug?.("Recorded file access", { path: path3 });
|
|
2122
|
+
return true;
|
|
2123
|
+
}
|
|
2124
|
+
return false;
|
|
2125
|
+
} catch (error) {
|
|
2126
|
+
this.logError("recordAccess", error);
|
|
2127
|
+
return false;
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
/**
|
|
2131
|
+
* Record a file deletion
|
|
2132
|
+
*/
|
|
2133
|
+
async recordDelete(path3, storageType) {
|
|
2134
|
+
try {
|
|
2135
|
+
const existing = await this.findByPath(path3, storageType);
|
|
2136
|
+
if (existing) {
|
|
2137
|
+
await this.crud.deleteById(existing.id);
|
|
2138
|
+
this.logger?.debug?.("Recorded file deletion", { path: path3 });
|
|
2139
|
+
return true;
|
|
2140
|
+
}
|
|
2141
|
+
return false;
|
|
2142
|
+
} catch (error) {
|
|
2143
|
+
this.logError("recordDelete", error);
|
|
2144
|
+
return false;
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Record a directory deletion (recursive)
|
|
2149
|
+
*/
|
|
2150
|
+
async recordDirectoryDelete(path3, storageType, recursive) {
|
|
2151
|
+
try {
|
|
2152
|
+
if (recursive) {
|
|
2153
|
+
const records = await this.crud.findBy({ storage_type: storageType });
|
|
2154
|
+
const toDelete = records.filter(
|
|
2155
|
+
(r) => r.file_path === path3 || r.file_path.startsWith(path3 + "/")
|
|
2156
|
+
);
|
|
2157
|
+
for (const record of toDelete) {
|
|
2158
|
+
await this.crud.deleteById(record.id);
|
|
2159
|
+
}
|
|
2160
|
+
this.logger?.debug?.("Recorded recursive directory deletion", {
|
|
2161
|
+
path: path3,
|
|
2162
|
+
count: toDelete.length
|
|
2163
|
+
});
|
|
2164
|
+
return true;
|
|
2165
|
+
} else {
|
|
2166
|
+
return this.recordDelete(path3, storageType);
|
|
2167
|
+
}
|
|
2168
|
+
} catch (error) {
|
|
2169
|
+
this.logError("recordDirectoryDelete", error);
|
|
2170
|
+
return false;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
/**
|
|
2174
|
+
* Record a file or folder move
|
|
2175
|
+
*/
|
|
2176
|
+
async recordMove(sourcePath, destinationPath, storageType) {
|
|
2177
|
+
try {
|
|
2178
|
+
const existing = await this.findByPath(sourcePath, storageType);
|
|
2179
|
+
if (existing) {
|
|
2180
|
+
await this.crud.updateById(existing.id, {
|
|
2181
|
+
file_path: destinationPath,
|
|
2182
|
+
filename: getBaseName(destinationPath),
|
|
2183
|
+
changed_at: this.now()
|
|
2184
|
+
});
|
|
2185
|
+
this.logger?.debug?.("Recorded file move", { from: sourcePath, to: destinationPath });
|
|
2186
|
+
return true;
|
|
2187
|
+
}
|
|
2188
|
+
return false;
|
|
2189
|
+
} catch (error) {
|
|
2190
|
+
this.logError("recordMove", error);
|
|
2191
|
+
return false;
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Record a file or folder rename
|
|
2196
|
+
*/
|
|
2197
|
+
async recordRename(path3, newName, storageType) {
|
|
2198
|
+
try {
|
|
2199
|
+
const existing = await this.findByPath(path3, storageType);
|
|
2200
|
+
if (existing) {
|
|
2201
|
+
const parentPath = getDirName(path3);
|
|
2202
|
+
const newPath = parentPath === "/" ? `/${newName}` : `${parentPath}/${newName}`;
|
|
2203
|
+
await this.crud.updateById(existing.id, {
|
|
2204
|
+
filename: newName,
|
|
2205
|
+
file_path: newPath,
|
|
2206
|
+
changed_at: this.now()
|
|
2207
|
+
});
|
|
2208
|
+
this.logger?.debug?.("Recorded file rename", { path: path3, newName });
|
|
2209
|
+
return true;
|
|
2210
|
+
}
|
|
2211
|
+
return false;
|
|
2212
|
+
} catch (error) {
|
|
2213
|
+
this.logError("recordRename", error);
|
|
2214
|
+
return false;
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
/**
|
|
2218
|
+
* Find a record by path and storage type
|
|
2219
|
+
*/
|
|
2220
|
+
async findByPath(path3, storageType) {
|
|
2221
|
+
try {
|
|
2222
|
+
return await this.crud.findOneBy({
|
|
2223
|
+
file_path: path3,
|
|
2224
|
+
storage_type: storageType
|
|
2225
|
+
});
|
|
2226
|
+
} catch (error) {
|
|
2227
|
+
this.logError("findByPath", error);
|
|
2228
|
+
return null;
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
/**
|
|
2232
|
+
* Find all records for a storage type
|
|
2233
|
+
*/
|
|
2234
|
+
async findByStorageType(storageType) {
|
|
2235
|
+
try {
|
|
2236
|
+
return await this.crud.findBy({ storage_type: storageType });
|
|
2237
|
+
} catch (error) {
|
|
2238
|
+
this.logError("findByStorageType", error);
|
|
2239
|
+
return [];
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
/**
|
|
2243
|
+
* Find all records in a directory
|
|
2244
|
+
*/
|
|
2245
|
+
async findInDirectory(directoryPath, storageType) {
|
|
2246
|
+
try {
|
|
2247
|
+
const all = await this.findByStorageType(storageType);
|
|
2248
|
+
const prefix = directoryPath === "/" ? "/" : directoryPath + "/";
|
|
2249
|
+
return all.filter((r) => {
|
|
2250
|
+
if (directoryPath === "/") {
|
|
2251
|
+
const segments = r.file_path.split("/").filter(Boolean);
|
|
2252
|
+
return segments.length === 1;
|
|
2253
|
+
}
|
|
2254
|
+
if (!r.file_path.startsWith(prefix)) return false;
|
|
2255
|
+
const relativePath = r.file_path.slice(prefix.length);
|
|
2256
|
+
return !relativePath.includes("/");
|
|
2257
|
+
});
|
|
2258
|
+
} catch (error) {
|
|
2259
|
+
this.logError("findInDirectory", error);
|
|
2260
|
+
return [];
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
/**
|
|
2264
|
+
* Update custom metadata for a file
|
|
2265
|
+
*/
|
|
2266
|
+
async updateMetadata(path3, storageType, metadata) {
|
|
2267
|
+
try {
|
|
2268
|
+
const existing = await this.findByPath(path3, storageType);
|
|
2269
|
+
if (existing) {
|
|
2270
|
+
const currentData = JSON.parse(existing.file_data || "{}");
|
|
2271
|
+
const newData = { ...currentData, ...metadata };
|
|
2272
|
+
await this.crud.updateById(existing.id, {
|
|
2273
|
+
file_data: JSON.stringify(newData),
|
|
2274
|
+
changed_at: this.now()
|
|
2275
|
+
});
|
|
2276
|
+
this.logger?.debug?.("Updated file metadata", { path: path3 });
|
|
2277
|
+
return true;
|
|
2278
|
+
}
|
|
2279
|
+
return false;
|
|
2280
|
+
} catch (error) {
|
|
2281
|
+
this.logError("updateMetadata", error);
|
|
2282
|
+
return false;
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
};
|
|
2286
|
+
function createFileMetadataService(crudService, options) {
|
|
2287
|
+
return new FileMetadataService(crudService, options);
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
// src/services/tracked-file-manager.ts
|
|
2291
|
+
var TrackedFileManager = class extends FileManager {
|
|
2292
|
+
constructor(options = {}) {
|
|
2293
|
+
super(options);
|
|
2294
|
+
this.metadataService = null;
|
|
2295
|
+
this.trackingConfig = {
|
|
2296
|
+
enabled: options.tracking?.enabled ?? false,
|
|
2297
|
+
tableName: options.tracking?.tableName ?? "hazo_files",
|
|
2298
|
+
trackDownloads: options.tracking?.trackDownloads ?? true,
|
|
2299
|
+
logErrors: options.tracking?.logErrors ?? true
|
|
2300
|
+
};
|
|
2301
|
+
if (options.crudService && this.trackingConfig.enabled) {
|
|
2302
|
+
this.metadataService = new FileMetadataService(options.crudService, {
|
|
2303
|
+
tableName: this.trackingConfig.tableName,
|
|
2304
|
+
logErrors: this.trackingConfig.logErrors
|
|
2305
|
+
});
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* Check if tracking is enabled and service is available
|
|
2310
|
+
*/
|
|
2311
|
+
isTrackingEnabled() {
|
|
2312
|
+
return this.trackingConfig.enabled && this.metadataService !== null;
|
|
2313
|
+
}
|
|
2314
|
+
/**
|
|
2315
|
+
* Get the current storage provider type
|
|
2316
|
+
*/
|
|
2317
|
+
getStorageType() {
|
|
2318
|
+
return this.getProvider() || "local";
|
|
2319
|
+
}
|
|
2320
|
+
// ============ Tracked Directory Operations ============
|
|
2321
|
+
/**
|
|
2322
|
+
* Create a directory and record it in the database
|
|
2323
|
+
*/
|
|
2324
|
+
async createDirectory(path3) {
|
|
2325
|
+
const result = await super.createDirectory(path3);
|
|
2326
|
+
if (result.success && this.isTrackingEnabled()) {
|
|
2327
|
+
this.metadataService.recordDirectoryCreation(
|
|
2328
|
+
path3,
|
|
2329
|
+
this.getStorageType(),
|
|
2330
|
+
result.data?.metadata
|
|
2331
|
+
).catch(() => {
|
|
2332
|
+
});
|
|
2333
|
+
}
|
|
2334
|
+
return result;
|
|
2335
|
+
}
|
|
2336
|
+
/**
|
|
2337
|
+
* Remove a directory and delete its record from the database
|
|
2338
|
+
*/
|
|
2339
|
+
async removeDirectory(path3, recursive = false) {
|
|
2340
|
+
const result = await super.removeDirectory(path3, recursive);
|
|
2341
|
+
if (result.success && this.isTrackingEnabled()) {
|
|
2342
|
+
this.metadataService.recordDirectoryDelete(
|
|
2343
|
+
path3,
|
|
2344
|
+
this.getStorageType(),
|
|
2345
|
+
recursive
|
|
2346
|
+
).catch(() => {
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
2349
|
+
return result;
|
|
2350
|
+
}
|
|
2351
|
+
// ============ Tracked File Operations ============
|
|
2352
|
+
/**
|
|
2353
|
+
* Upload a file and record it in the database
|
|
2354
|
+
*/
|
|
2355
|
+
async uploadFile(source, remotePath, options) {
|
|
2356
|
+
const result = await super.uploadFile(source, remotePath, options);
|
|
2357
|
+
if (result.success && this.isTrackingEnabled() && result.data) {
|
|
2358
|
+
const fileItem = result.data;
|
|
2359
|
+
this.metadataService.recordUpload({
|
|
2360
|
+
filename: fileItem.name,
|
|
2361
|
+
file_type: fileItem.mimeType || getMimeType(fileItem.name),
|
|
2362
|
+
file_data: options?.metadata || fileItem.metadata,
|
|
2363
|
+
file_path: remotePath,
|
|
2364
|
+
storage_type: this.getStorageType()
|
|
2365
|
+
}).catch(() => {
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
return result;
|
|
2369
|
+
}
|
|
2370
|
+
/**
|
|
2371
|
+
* Download a file and optionally track access
|
|
2372
|
+
*/
|
|
2373
|
+
async downloadFile(remotePath, localPath, options) {
|
|
2374
|
+
const result = await super.downloadFile(remotePath, localPath, options);
|
|
2375
|
+
if (result.success && this.isTrackingEnabled() && this.trackingConfig.trackDownloads) {
|
|
2376
|
+
this.metadataService.recordAccess(
|
|
2377
|
+
remotePath,
|
|
2378
|
+
this.getStorageType()
|
|
2379
|
+
).catch(() => {
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
return result;
|
|
2383
|
+
}
|
|
2384
|
+
/**
|
|
2385
|
+
* Move a file or folder and update its path in the database
|
|
2386
|
+
*/
|
|
2387
|
+
async moveItem(sourcePath, destinationPath, options) {
|
|
2388
|
+
const result = await super.moveItem(sourcePath, destinationPath, options);
|
|
2389
|
+
if (result.success && this.isTrackingEnabled()) {
|
|
2390
|
+
this.metadataService.recordMove(
|
|
2391
|
+
sourcePath,
|
|
2392
|
+
destinationPath,
|
|
2393
|
+
this.getStorageType()
|
|
2394
|
+
).catch(() => {
|
|
2395
|
+
});
|
|
2396
|
+
}
|
|
2397
|
+
return result;
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* Delete a file and remove its record from the database
|
|
2401
|
+
*/
|
|
2402
|
+
async deleteFile(path3) {
|
|
2403
|
+
const result = await super.deleteFile(path3);
|
|
2404
|
+
if (result.success && this.isTrackingEnabled()) {
|
|
2405
|
+
this.metadataService.recordDelete(
|
|
2406
|
+
path3,
|
|
2407
|
+
this.getStorageType()
|
|
2408
|
+
).catch(() => {
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
return result;
|
|
2412
|
+
}
|
|
2413
|
+
/**
|
|
2414
|
+
* Rename a file and update its record in the database
|
|
2415
|
+
*/
|
|
2416
|
+
async renameFile(path3, newName, options) {
|
|
2417
|
+
const result = await super.renameFile(path3, newName, options);
|
|
2418
|
+
if (result.success && this.isTrackingEnabled()) {
|
|
2419
|
+
this.metadataService.recordRename(
|
|
2420
|
+
path3,
|
|
2421
|
+
newName,
|
|
2422
|
+
this.getStorageType()
|
|
2423
|
+
).catch(() => {
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2426
|
+
return result;
|
|
2427
|
+
}
|
|
2428
|
+
/**
|
|
2429
|
+
* Rename a folder and update its record in the database
|
|
2430
|
+
*/
|
|
2431
|
+
async renameFolder(path3, newName, options) {
|
|
2432
|
+
const result = await super.renameFolder(path3, newName, options);
|
|
2433
|
+
if (result.success && this.isTrackingEnabled()) {
|
|
2434
|
+
this.metadataService.recordRename(
|
|
2435
|
+
path3,
|
|
2436
|
+
newName,
|
|
2437
|
+
this.getStorageType()
|
|
2438
|
+
).catch(() => {
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
return result;
|
|
2442
|
+
}
|
|
2443
|
+
// ============ Tracked Convenience Methods ============
|
|
2444
|
+
/**
|
|
2445
|
+
* Write a file with string content and track it
|
|
2446
|
+
*/
|
|
2447
|
+
async writeFile(path3, content, options) {
|
|
2448
|
+
const buffer = Buffer.from(content, "utf-8");
|
|
2449
|
+
return this.uploadFile(buffer, path3, options);
|
|
2450
|
+
}
|
|
2451
|
+
/**
|
|
2452
|
+
* Read a file and optionally track access
|
|
2453
|
+
*/
|
|
2454
|
+
async readFile(path3) {
|
|
2455
|
+
return super.readFile(path3);
|
|
2456
|
+
}
|
|
2457
|
+
/**
|
|
2458
|
+
* Copy a file and track the new file
|
|
2459
|
+
*/
|
|
2460
|
+
async copyFile(sourcePath, destinationPath, options) {
|
|
2461
|
+
return super.copyFile(sourcePath, destinationPath, options);
|
|
2462
|
+
}
|
|
2463
|
+
// ============ Metadata Service Access ============
|
|
2464
|
+
/**
|
|
2465
|
+
* Get the metadata service for direct access
|
|
2466
|
+
*/
|
|
2467
|
+
getMetadataService() {
|
|
2468
|
+
return this.metadataService;
|
|
2469
|
+
}
|
|
2470
|
+
/**
|
|
2471
|
+
* Check if database tracking is enabled
|
|
2472
|
+
*/
|
|
2473
|
+
isTrackingActive() {
|
|
2474
|
+
return this.isTrackingEnabled();
|
|
2475
|
+
}
|
|
2476
|
+
/**
|
|
2477
|
+
* Get tracking configuration
|
|
2478
|
+
*/
|
|
2479
|
+
getTrackingConfig() {
|
|
2480
|
+
return { ...this.trackingConfig };
|
|
2481
|
+
}
|
|
2482
|
+
};
|
|
2483
|
+
function createTrackedFileManager(options) {
|
|
2484
|
+
return new TrackedFileManager(options);
|
|
2485
|
+
}
|
|
2486
|
+
async function createInitializedTrackedFileManager(options) {
|
|
2487
|
+
const manager = new TrackedFileManager(options);
|
|
2488
|
+
await manager.initialize();
|
|
2489
|
+
return manager;
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2046
2492
|
// src/common/naming-utils.ts
|
|
2047
2493
|
var DEFAULT_DATE_FORMATS = [
|
|
2048
2494
|
"YYYY",
|
|
@@ -2374,6 +2820,7 @@ function generatePreviewName(pattern, userVariables, options = {}) {
|
|
|
2374
2820
|
DirectoryNotFoundError,
|
|
2375
2821
|
FileExistsError,
|
|
2376
2822
|
FileManager,
|
|
2823
|
+
FileMetadataService,
|
|
2377
2824
|
FileNotFoundError,
|
|
2378
2825
|
FileTooLargeError,
|
|
2379
2826
|
GoogleDriveAuth,
|
|
@@ -2387,18 +2834,22 @@ function generatePreviewName(pattern, userVariables, options = {}) {
|
|
|
2387
2834
|
SYSTEM_COUNTER_VARIABLES,
|
|
2388
2835
|
SYSTEM_DATE_VARIABLES,
|
|
2389
2836
|
SYSTEM_FILE_VARIABLES,
|
|
2837
|
+
TrackedFileManager,
|
|
2390
2838
|
clonePattern,
|
|
2391
2839
|
createAndInitializeModule,
|
|
2392
2840
|
createEmptyNamingRuleSchema,
|
|
2393
2841
|
createFileItem,
|
|
2394
2842
|
createFileManager,
|
|
2843
|
+
createFileMetadataService,
|
|
2395
2844
|
createFolderItem,
|
|
2396
2845
|
createGoogleDriveAuth,
|
|
2397
2846
|
createGoogleDriveModule,
|
|
2398
2847
|
createInitializedFileManager,
|
|
2848
|
+
createInitializedTrackedFileManager,
|
|
2399
2849
|
createLiteralSegment,
|
|
2400
2850
|
createLocalModule,
|
|
2401
2851
|
createModule,
|
|
2852
|
+
createTrackedFileManager,
|
|
2402
2853
|
createVariableSegment,
|
|
2403
2854
|
errorResult,
|
|
2404
2855
|
filterItems,
|
|
@@ -2454,4 +2905,3 @@ function generatePreviewName(pattern, userVariables, options = {}) {
|
|
|
2454
2905
|
validateNamingRuleSchema,
|
|
2455
2906
|
validatePath
|
|
2456
2907
|
});
|
|
2457
|
-
//# sourceMappingURL=index.js.map
|