hazo_files 1.4.4 → 1.4.6

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/README.md CHANGED
@@ -45,13 +45,20 @@ For the NamingRuleConfigurator component (drag-and-drop interface), also install
45
45
  npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
46
46
  ```
47
47
 
48
+ For cloud storage providers (install only what you need):
49
+
50
+ ```bash
51
+ npm install googleapis # Google Drive support
52
+ npm install dropbox # Dropbox support
53
+ ```
54
+
48
55
  For database tracking and LLM extraction features (optional):
49
56
 
50
57
  ```bash
51
58
  npm install hazo_connect # Database tracking
52
59
  npm install hazo_llm_api # LLM document extraction
53
60
  npm install server-only # Server-side safety (recommended)
54
- # Note: xxhash-wasm is included automatically as a dependency
61
+ npm install xxhash-wasm # File change detection (optional)
55
62
  ```
56
63
 
57
64
  ### Tailwind CSS v4 Setup (Required for UI Components)
@@ -1566,6 +1573,51 @@ import { registerModule } from 'hazo_files';
1566
1573
  registerModule('s3', () => new S3StorageModule());
1567
1574
  ```
1568
1575
 
1576
+ ## Debug Integration (hazo_debug)
1577
+
1578
+ hazo_files emits structured `file_operation` log entries with timing, storage provider, and operation type on every file operation. You can forward these to `hazo_debug` for a visual Files tab in the debug panel.
1579
+
1580
+ The integration uses the existing `logger` option — no direct dependency on hazo_debug is needed:
1581
+
1582
+ ```typescript
1583
+ import { createHazoFilesServer } from 'hazo_files/server';
1584
+ import { use_debug_files } from 'hazo_debug/client';
1585
+
1586
+ // In your server setup:
1587
+ const { log_file_op } = use_debug_files();
1588
+
1589
+ const { fileManager } = await createHazoFilesServer({
1590
+ config: { provider: 'local', local: { basePath: './files' } },
1591
+ logger: {
1592
+ info: (msg, data) => {
1593
+ if (msg === 'file_operation') log_file_op(data);
1594
+ },
1595
+ error: (msg, data) => {
1596
+ if (msg === 'file_operation') log_file_op(data);
1597
+ },
1598
+ },
1599
+ });
1600
+ ```
1601
+
1602
+ Every `file_operation` log entry includes:
1603
+
1604
+ | Field | Type | Description |
1605
+ |-------|------|-------------|
1606
+ | `operation` | `string` | `'upload'` \| `'download'` \| `'delete'` \| `'move'` \| `'list'` \| `'extract'` |
1607
+ | `file_name` | `string?` | File name |
1608
+ | `file_path` | `string?` | Virtual file path |
1609
+ | `mime_type` | `string?` | MIME type |
1610
+ | `size_bytes` | `number?` | File size in bytes |
1611
+ | `storage` | `string?` | Storage provider (`'local'`, `'google_drive'`, etc.) |
1612
+ | `duration_ms` | `number` | Operation duration in milliseconds |
1613
+ | `success` | `boolean` | Whether the operation succeeded |
1614
+ | `error` | `string?` | Error message (on failure) |
1615
+ | `metadata` | `object?` | Extra context (e.g., `{ type: 'rename', new_name }`) |
1616
+
1617
+ Logging is emitted at two levels:
1618
+ - **FileManager** logs the storage-level operation (actual file I/O timing)
1619
+ - **FileMetadataService** logs the database tracking operation (if tracking is enabled)
1620
+
1569
1621
  ## Testing
1570
1622
 
1571
1623
  The package includes a test application in `test-app/` demonstrating:
@@ -1,8 +1,9 @@
1
1
  ; Hazo Files Configuration
2
2
  ; This file configures the file management system
3
+ ; Copy to hazo_files_config.ini and fill in your values
3
4
 
4
5
  [general]
5
- ; Available providers: local, google_drive
6
+ ; Available providers: local, google_drive, dropbox
6
7
  provider = local
7
8
 
8
9
  [local]
@@ -25,6 +26,18 @@ access_token =
25
26
  ; Optional: Root folder ID to use as base (empty = root of Drive)
26
27
  root_folder_id =
27
28
 
29
+ [dropbox]
30
+ ; Dropbox OAuth credentials
31
+ ; These can also be set via environment variables:
32
+ ; HAZO_DROPBOX_CLIENT_ID, HAZO_DROPBOX_CLIENT_SECRET, etc.
33
+ client_id =
34
+ client_secret =
35
+ redirect_uri = http://localhost:3000/api/auth/callback/dropbox
36
+ refresh_token =
37
+ access_token =
38
+ ; Optional: Root folder path within Dropbox (empty = root)
39
+ root_path =
40
+
28
41
  [naming]
29
42
  ; Comma-separated list of supported date format tokens for naming rules
30
43
  ; Available: YYYY, YY, MM, M, DD, D, MMM, MMMM, YYYY-MM-DD, YYYY-MMM-DD, DD-MM-YYYY, MM-DD-YYYY
package/dist/index.d.mts CHANGED
@@ -657,152 +657,6 @@ interface StorageModule {
657
657
  getFolderTree(path?: string, depth?: number): Promise<OperationResult<TreeNode[]>>;
658
658
  }
659
659
 
660
- /**
661
- * File Manager Service
662
- * Main service that provides a unified API for file operations
663
- * Delegates to the appropriate storage module based on configuration
664
- */
665
-
666
- interface FileManagerOptions {
667
- /** Path to configuration file */
668
- configPath?: string;
669
- /** Configuration object (takes precedence over configPath) */
670
- config?: HazoFilesConfig;
671
- /** Auto-initialize on creation */
672
- autoInit?: boolean;
673
- }
674
- /**
675
- * FileManager - Main service class for file operations
676
- */
677
- declare class FileManager {
678
- private module;
679
- private config;
680
- private initialized;
681
- private options;
682
- constructor(options?: FileManagerOptions);
683
- /**
684
- * Initialize the file manager with configuration
685
- */
686
- initialize(config?: HazoFilesConfig): Promise<void>;
687
- /**
688
- * Initialize synchronously (uses sync config loading)
689
- */
690
- initializeSync(config?: HazoFilesConfig): void;
691
- /**
692
- * Check if manager is initialized
693
- */
694
- isInitialized(): boolean;
695
- /**
696
- * Get the current configuration
697
- */
698
- getConfig(): HazoFilesConfig | null;
699
- /**
700
- * Get the current provider
701
- */
702
- getProvider(): StorageProvider | null;
703
- /**
704
- * Get the underlying storage module
705
- */
706
- getModule(): StorageModule;
707
- /**
708
- * Ensure manager is initialized
709
- */
710
- private ensureInitialized;
711
- /**
712
- * Create a directory at the specified path
713
- */
714
- createDirectory(path: string): Promise<OperationResult<FolderItem>>;
715
- /**
716
- * Remove a directory
717
- * @param path - Directory path
718
- * @param recursive - If true, remove directory and all contents
719
- */
720
- removeDirectory(path: string, recursive?: boolean): Promise<OperationResult>;
721
- /**
722
- * Upload/save a file
723
- * @param source - File path, Buffer, or ReadableStream
724
- * @param remotePath - Destination path in storage
725
- * @param options - Upload options
726
- */
727
- uploadFile(source: string | Buffer | ReadableStream, remotePath: string, options?: UploadOptions): Promise<OperationResult<FileItem>>;
728
- /**
729
- * Download a file
730
- * @param remotePath - Path in storage
731
- * @param localPath - Optional local destination path
732
- * @param options - Download options
733
- */
734
- downloadFile(remotePath: string, localPath?: string, options?: DownloadOptions): Promise<OperationResult<Buffer | string>>;
735
- /**
736
- * Move a file or folder
737
- * @param sourcePath - Current path
738
- * @param destinationPath - New path
739
- * @param options - Move options
740
- */
741
- moveItem(sourcePath: string, destinationPath: string, options?: MoveOptions): Promise<OperationResult<FileSystemItem>>;
742
- /**
743
- * Delete a file
744
- */
745
- deleteFile(path: string): Promise<OperationResult>;
746
- /**
747
- * Rename a file
748
- * @param path - Current file path
749
- * @param newName - New filename (not full path)
750
- * @param options - Rename options
751
- */
752
- renameFile(path: string, newName: string, options?: RenameOptions): Promise<OperationResult<FileItem>>;
753
- /**
754
- * Rename a folder
755
- * @param path - Current folder path
756
- * @param newName - New folder name (not full path)
757
- * @param options - Rename options
758
- */
759
- renameFolder(path: string, newName: string, options?: RenameOptions): Promise<OperationResult<FolderItem>>;
760
- /**
761
- * List contents of a directory
762
- * @param path - Directory path
763
- * @param options - List options
764
- */
765
- listDirectory(path: string, options?: ListOptions): Promise<OperationResult<FileSystemItem[]>>;
766
- /**
767
- * Get information about a file or folder
768
- */
769
- getItem(path: string): Promise<OperationResult<FileSystemItem>>;
770
- /**
771
- * Check if a file or folder exists
772
- */
773
- exists(path: string): Promise<boolean>;
774
- /**
775
- * Get folder tree structure
776
- * @param path - Starting path (default: root)
777
- * @param depth - Maximum depth to traverse
778
- */
779
- getFolderTree(path?: string, depth?: number): Promise<OperationResult<TreeNode[]>>;
780
- /**
781
- * Create a file with string content
782
- */
783
- writeFile(path: string, content: string, options?: UploadOptions): Promise<OperationResult<FileItem>>;
784
- /**
785
- * Read a file as string
786
- */
787
- readFile(path: string): Promise<OperationResult<string>>;
788
- /**
789
- * Copy a file to a new location
790
- */
791
- copyFile(sourcePath: string, destinationPath: string, options?: UploadOptions): Promise<OperationResult<FileItem>>;
792
- /**
793
- * Ensure a directory exists (creates if needed)
794
- */
795
- ensureDirectory(path: string): Promise<OperationResult<FolderItem>>;
796
- }
797
- /**
798
- * Create a new FileManager instance
799
- */
800
- declare function createFileManager(options?: FileManagerOptions): FileManager;
801
- /**
802
- * Create and initialize a FileManager instance
803
- */
804
- declare function createInitializedFileManager(options?: FileManagerOptions): Promise<FileManager>;
805
-
806
660
  /**
807
661
  * File Metadata Service
808
662
  * Handles database operations for tracking file metadata
@@ -1046,6 +900,159 @@ declare class FileMetadataService {
1046
900
  */
1047
901
  declare function createFileMetadataService(crudService: CrudServiceLike<FileMetadataRecord>, options?: FileMetadataServiceOptions): FileMetadataService;
1048
902
 
903
+ /**
904
+ * File Manager Service
905
+ * Main service that provides a unified API for file operations
906
+ * Delegates to the appropriate storage module based on configuration
907
+ */
908
+
909
+ interface FileManagerOptions {
910
+ /** Path to configuration file */
911
+ configPath?: string;
912
+ /** Configuration object (takes precedence over configPath) */
913
+ config?: HazoFilesConfig;
914
+ /** Auto-initialize on creation */
915
+ autoInit?: boolean;
916
+ /** Logger for structured file operation logging (compatible with MetadataLogger) */
917
+ logger?: MetadataLogger;
918
+ }
919
+ /**
920
+ * FileManager - Main service class for file operations
921
+ */
922
+ declare class FileManager {
923
+ private module;
924
+ private config;
925
+ private initialized;
926
+ private options;
927
+ protected logger?: MetadataLogger;
928
+ constructor(options?: FileManagerOptions);
929
+ /**
930
+ * Initialize the file manager with configuration
931
+ */
932
+ initialize(config?: HazoFilesConfig): Promise<void>;
933
+ /**
934
+ * @deprecated Storage modules require async initialization. Use initialize() instead.
935
+ */
936
+ initializeSync(_config?: HazoFilesConfig): void;
937
+ /**
938
+ * Check if manager is initialized
939
+ */
940
+ isInitialized(): boolean;
941
+ /**
942
+ * Get the current configuration
943
+ */
944
+ getConfig(): HazoFilesConfig | null;
945
+ /**
946
+ * Get the current provider
947
+ */
948
+ getProvider(): StorageProvider | null;
949
+ /**
950
+ * Get the underlying storage module
951
+ */
952
+ getModule(): StorageModule;
953
+ /**
954
+ * Ensure manager is initialized
955
+ */
956
+ private ensureInitialized;
957
+ /**
958
+ * Log a structured file operation event
959
+ */
960
+ private logFileOp;
961
+ /**
962
+ * Create a directory at the specified path
963
+ */
964
+ createDirectory(path: string): Promise<OperationResult<FolderItem>>;
965
+ /**
966
+ * Remove a directory
967
+ * @param path - Directory path
968
+ * @param recursive - If true, remove directory and all contents
969
+ */
970
+ removeDirectory(path: string, recursive?: boolean): Promise<OperationResult>;
971
+ /**
972
+ * Upload/save a file
973
+ * @param source - File path, Buffer, or ReadableStream
974
+ * @param remotePath - Destination path in storage
975
+ * @param options - Upload options
976
+ */
977
+ uploadFile(source: string | Buffer | ReadableStream, remotePath: string, options?: UploadOptions): Promise<OperationResult<FileItem>>;
978
+ /**
979
+ * Download a file
980
+ * @param remotePath - Path in storage
981
+ * @param localPath - Optional local destination path
982
+ * @param options - Download options
983
+ */
984
+ downloadFile(remotePath: string, localPath?: string, options?: DownloadOptions): Promise<OperationResult<Buffer | string>>;
985
+ /**
986
+ * Move a file or folder
987
+ * @param sourcePath - Current path
988
+ * @param destinationPath - New path
989
+ * @param options - Move options
990
+ */
991
+ moveItem(sourcePath: string, destinationPath: string, options?: MoveOptions): Promise<OperationResult<FileSystemItem>>;
992
+ /**
993
+ * Delete a file
994
+ */
995
+ deleteFile(path: string): Promise<OperationResult>;
996
+ /**
997
+ * Rename a file
998
+ * @param path - Current file path
999
+ * @param newName - New filename (not full path)
1000
+ * @param options - Rename options
1001
+ */
1002
+ renameFile(path: string, newName: string, options?: RenameOptions): Promise<OperationResult<FileItem>>;
1003
+ /**
1004
+ * Rename a folder
1005
+ * @param path - Current folder path
1006
+ * @param newName - New folder name (not full path)
1007
+ * @param options - Rename options
1008
+ */
1009
+ renameFolder(path: string, newName: string, options?: RenameOptions): Promise<OperationResult<FolderItem>>;
1010
+ /**
1011
+ * List contents of a directory
1012
+ * @param path - Directory path
1013
+ * @param options - List options
1014
+ */
1015
+ listDirectory(path: string, options?: ListOptions): Promise<OperationResult<FileSystemItem[]>>;
1016
+ /**
1017
+ * Get information about a file or folder
1018
+ */
1019
+ getItem(path: string): Promise<OperationResult<FileSystemItem>>;
1020
+ /**
1021
+ * Check if a file or folder exists
1022
+ */
1023
+ exists(path: string): Promise<boolean>;
1024
+ /**
1025
+ * Get folder tree structure
1026
+ * @param path - Starting path (default: root)
1027
+ * @param depth - Maximum depth to traverse
1028
+ */
1029
+ getFolderTree(path?: string, depth?: number): Promise<OperationResult<TreeNode[]>>;
1030
+ /**
1031
+ * Create a file with string content
1032
+ */
1033
+ writeFile(path: string, content: string, options?: UploadOptions): Promise<OperationResult<FileItem>>;
1034
+ /**
1035
+ * Read a file as string
1036
+ */
1037
+ readFile(path: string): Promise<OperationResult<string>>;
1038
+ /**
1039
+ * Copy a file to a new location
1040
+ */
1041
+ copyFile(sourcePath: string, destinationPath: string, options?: UploadOptions): Promise<OperationResult<FileItem>>;
1042
+ /**
1043
+ * Ensure a directory exists (creates if needed)
1044
+ */
1045
+ ensureDirectory(path: string): Promise<OperationResult<FolderItem>>;
1046
+ }
1047
+ /**
1048
+ * Create a new FileManager instance
1049
+ */
1050
+ declare function createFileManager(options?: FileManagerOptions): FileManager;
1051
+ /**
1052
+ * Create and initialize a FileManager instance
1053
+ */
1054
+ declare function createInitializedFileManager(options?: FileManagerOptions): Promise<FileManager>;
1055
+
1049
1056
  /**
1050
1057
  * Tracked File Manager
1051
1058
  * Extends FileManager to add database tracking of file operations
@@ -1059,6 +1066,8 @@ interface TrackedFileManagerFullOptions extends FileManagerOptions {
1059
1066
  crudService?: CrudServiceLike<FileMetadataRecord>;
1060
1067
  /** Database tracking configuration */
1061
1068
  tracking?: DatabaseTrackingConfig;
1069
+ /** Logger for structured file operation logging */
1070
+ logger?: MetadataLogger;
1062
1071
  }
1063
1072
  /**
1064
1073
  * Extended upload options with hash tracking