@@ -24,13 +24,17 @@ class JsonFileCRUD {
2424 * @param {string } filePath - Path to the JSON file
2525 * @param {Object } options - Configuration options
2626 * @param {string } options.idField - Name of the ID field (default: 'id')
27+ * @param {boolean } options.autoId - Enable auto-ID assignment (default: true)
28+ * @param {string[] } options.uniqueFields - Array of field names that should be unique
2729 */
2830 constructor ( filePath , options = { } ) {
2931 if ( ! filePath ) {
3032 throw new Error ( ERROR_MESSAGES . FILE_PATH_REQUIRED ) ;
3133 }
3234 this . filePath = path . resolve ( filePath ) ;
3335 this . idField = options . idField || DEFAULT_CONFIG . ID_FIELD ;
36+ this . autoId = options . autoId !== false ; // default to true
37+ this . uniqueFields = options . uniqueFields || [ ] ; // Array of field names that should be unique
3438 this . queueManager = new QueueManager ( this . filePath ) ;
3539 }
3640
@@ -49,17 +53,31 @@ class JsonFileCRUD {
4953 }
5054
5155 this . queueManager . queueOperation ( OPERATION_TYPES . CREATE , { item } , callback , ( items ) => {
52- // Auto-assign ID if not provided
53- if ( ! item [ this . idField ] ) {
56+ // Auto-assign ID if enabled and not provided
57+ if ( this . autoId && ! item [ this . idField ] ) {
5458 item [ this . idField ] = this . _generateNextId ( items ) ;
5559 }
5660
5761 // Check for duplicate ID
58- const existingItem = items . find ( existingItem =>
59- existingItem [ this . idField ] === item [ this . idField ]
60- ) ;
61- if ( existingItem ) {
62- return callback ( createDuplicateIdError ( this . idField , item [ this . idField ] ) ) ;
62+ if ( item [ this . idField ] ) {
63+ const existingItem = items . find ( existingItem =>
64+ existingItem [ this . idField ] === item [ this . idField ]
65+ ) ;
66+ if ( existingItem ) {
67+ return callback ( createDuplicateIdError ( this . idField , item [ this . idField ] ) ) ;
68+ }
69+ }
70+
71+ // Check for duplicates in unique fields
72+ for ( const fieldName of this . uniqueFields ) {
73+ if ( item [ fieldName ] !== undefined && item [ fieldName ] !== null ) {
74+ const duplicate = items . find ( existingItem =>
75+ existingItem [ fieldName ] === item [ fieldName ]
76+ ) ;
77+ if ( duplicate ) {
78+ return callback ( new Error ( `Item with ${ fieldName } '${ item [ fieldName ] } ' already exists` ) ) ;
79+ }
80+ }
6381 }
6482
6583 // Add new item to array
@@ -171,6 +189,18 @@ class JsonFileCRUD {
171189 return callback ( createNotFoundError ( this . idField , id ) ) ;
172190 }
173191
192+ // Check for duplicates in unique fields (exclude current item)
193+ for ( const fieldName of this . uniqueFields ) {
194+ if ( data [ fieldName ] !== undefined && data [ fieldName ] !== null ) {
195+ const duplicate = items . find ( ( existingItem , index ) =>
196+ index !== itemIndex && existingItem [ fieldName ] === data [ fieldName ]
197+ ) ;
198+ if ( duplicate ) {
199+ return callback ( new Error ( `Item with ${ fieldName } '${ data [ fieldName ] } ' already exists` ) ) ;
200+ }
201+ }
202+ }
203+
174204 // Update item (merge data with existing item)
175205 const updatedItem = { ...items [ itemIndex ] , ...data } ;
176206 items [ itemIndex ] = updatedItem ;
@@ -208,6 +238,18 @@ class JsonFileCRUD {
208238
209239 //#endregion DELETE
210240
241+ //#region BULK OPERATIONS
242+
243+ /**
244+ * Delete all items from the JSON file
245+ * @param {Function } callback - Called with (error)
246+ */
247+ deleteAll ( callback ) {
248+ this . writeAll ( [ ] , callback ) ;
249+ }
250+
251+ //#endregion BULK OPERATIONS
252+
211253 //#region UTILITY METHODS
212254
213255 /**
@@ -254,3 +296,13 @@ class JsonFileCRUD {
254296}
255297
256298export default JsonFileCRUD ;
299+
300+ /**
301+ * Convenience function to create a new JsonFileCRUD instance
302+ * @param {string } filePath - Path to the JSON file
303+ * @param {Object } options - Configuration options
304+ * @returns {JsonFileCRUD } New JsonFileCRUD instance
305+ */
306+ export function createCrud ( filePath , options = { } ) {
307+ return new JsonFileCRUD ( filePath , options ) ;
308+ }
0 commit comments