From d2884799123695ad7dfb7ec1b306b2956347ee26 Mon Sep 17 00:00:00 2001 From: Bryan Lundberg Date: Sat, 10 May 2025 05:49:19 -0600 Subject: [PATCH 1/6] test: Add unit tests for Naro's set method Add comprehensive tests to cover the set method functionality. Includes cases for setting, overwriting, and handling invalid IDs in the users collection. Ensures reliable behavior and error handling for future changes. --- __test__/unit/base/Naro.test.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/__test__/unit/base/Naro.test.ts b/__test__/unit/base/Naro.test.ts index 67e5985..4099688 100644 --- a/__test__/unit/base/Naro.test.ts +++ b/__test__/unit/base/Naro.test.ts @@ -304,3 +304,34 @@ test("writeToDisk, should write multiple collections to disk", async () => { }); }); +test("set, should set a document in the users collection", async () => { + const db = new Naro(dbName); + const newDoc = await db.set(`users/999`, { name: "Jane Doe" }); + + expect(newDoc.id).toBe("999"); + expect(newDoc.name).toBe("Jane Doe"); + expect(newDoc.path).toBe("users/999"); +}) + +test("set, should overwrite a document in the users collection", async () => { + const db = new Naro(dbName); + await db.set(`users/999`, { name: "Jane Doe" }); + const updatedDoc = await db.set(`users/999`, { name: "John", age: 30 }); + + expect(updatedDoc.id).toBe("999"); + expect(updatedDoc.name).toBe("John"); + expect(updatedDoc.age).toBe(30); +}) + +test("set, should throw an error if trying to set a document with an invalid ID", async () => { + const db = new Naro(dbName); + await expect(async () => await db.set(`users/invalid/id`, { name: "Jane Doe" })).rejects.toThrowError(); +}); + +test("set, should throw an error if trying to set a document with an invalid ID", async () => { + const db = new Naro(dbName); + await expect(async () => await db.set(`users/invalid/id/fake`, { name: "Jane Doe" })).rejects.toThrowError(); +}); + + + From 4a2a7da77b8dc2706c6af7baa60715a27843627c Mon Sep 17 00:00:00 2001 From: Bryan Lundberg Date: Sat, 10 May 2025 05:49:31 -0600 Subject: [PATCH 2/6] feat: Add `set` method to overwrite documents in a collection This method allows users to overwrite a document in a specified collection using provided data. It validates the path, ensures no sub-collections are used, and updates the collection accordingly. --- src/base/Naro.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/base/Naro.ts b/src/base/Naro.ts index 1dd85c3..caa6e00 100644 --- a/src/base/Naro.ts +++ b/src/base/Naro.ts @@ -78,6 +78,33 @@ export class Naro { return _.cloneDeep(newItem); } + /** + * Overwrite a document in the specified collection using the provided data. + * + * @param {string} path - The name of the collection to set the data in. + * @param {DocData} data - The data to be set as a document. + * @return {Promise} A promise that resolves to the newly set document. + * + * @example + * const db = new Naro("myDatabase"); + * + * const updatedUser = await db.set("users", { id: "123", createdAt: Date.now(), name: "Jane Doe", age: 28 }); + * console.log(updatedUser); + * // Output: { id: "123", createdAt: 1696872345000, name: "Jane Doe", age: 28 } + */ + async set(path: string, data: DocData): Promise { + const { collectionName, collectionId, subCollectionName, subCollectionId } = NaroPath.validate(path); + if (!collectionId) throw new Error("Collection ID is required"); + if (subCollectionName) throw new Error("Sub-collection is not supported in set method"); + if (subCollectionId) throw new Error("Sub-collection ID is not supported in set method"); + const collection = this.core.getCollection(collectionName); + const source = { path: `${collectionName}/${collectionId}`, createdAt: Date.now(), id: collectionId}; + const newItem: NaroDocument = Object.assign(data, source); + collection.push(newItem); + this.core.updateCollection(collectionName, collection); + return _.cloneDeep(newItem); + } + /** * Retrieves all documents from a specified collection, optionally applying filters and limits, * and populates specified fields with referenced documents from other collections. From ccc0c47ef3129ed1c11edca41a43e30d30e3d3fd Mon Sep 17 00:00:00 2001 From: Bryan Lundberg Date: Sat, 10 May 2025 06:03:57 -0600 Subject: [PATCH 3/6] docs: Add 'set' endpoint to API reference sidebar Updated the API reference sidebar to include the 'set' endpoint. This ensures users can easily navigate to documentation for the new endpoint. --- docs/.vitepress/config.mts | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index f3408b2..78d63d0 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -48,6 +48,7 @@ export default defineConfig({ { text: 'get', link: '/api-reference/get' }, { text: 'getAll', link: '/api-reference/getAll' }, { text: 'add', link: '/api-reference/add' }, + { text: 'set', link: '/api-reference/set' }, { text: 'update', link: '/api-reference/update' }, { text: 'delete', link: '/api-reference/delete' }, { text: 'populate', link: '/api-reference/populate' }, From 7d4e0849599a49e4cdccdb278ba6bf356fd160d7 Mon Sep 17 00:00:00 2001 From: Bryan Lundberg Date: Sat, 10 May 2025 06:04:11 -0600 Subject: [PATCH 4/6] docs: Add API reference for the `set` method Introduces documentation for the `set` method, detailing its purpose, parameters, and example usage. This improves clarity for developers using the API. --- docs/api-reference/set.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 docs/api-reference/set.md diff --git a/docs/api-reference/set.md b/docs/api-reference/set.md new file mode 100644 index 0000000..a08725e --- /dev/null +++ b/docs/api-reference/set.md @@ -0,0 +1,32 @@ +# API reference + +## set + +Overwrite a document in the specified collection using the provided data. + +> [!IMPORTANT] +> This method is particularly useful for customizing default NaroDB IDs. However, it should be used with caution as it +> can be risky. + +### Parameters + +| Prop | Type | Description | +|--------|-----------|--------------------------------------------------------------------------------------------| +| `path` | `string` | The collection name where the data will be set. | +| `data` | `DocData` | The document data to set.
Note: The `id` property is mandatory in the provided data. | + +### Returns + +- Returns a promise that resolves to the newly document: [NaroDocument](../types-reference/naro-document.md). + +## Example + +```js{17} +const newDoc = await db.set("users", { + id: "123", + name: "Jane Doe", age: 28 +}); + +console.log(newDoc); +// Output: { id: "123", createdAt: 1696872345000, name: "Jane Doe", age: 28 } +``` From 18ddea0047d5217b808f82a137dafc0e8eb3c9f4 Mon Sep 17 00:00:00 2001 From: Bryan Lundberg Date: Sat, 10 May 2025 06:15:33 -0600 Subject: [PATCH 5/6] feat: Update set method to handle existing items in collection Previously, the set method only added new items to the collection. This update checks if an item with the given ID already exists and replaces it; otherwise, it pushes a new item. This ensures better handling of item updates within collections. --- src/base/Naro.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base/Naro.ts b/src/base/Naro.ts index caa6e00..168692e 100644 --- a/src/base/Naro.ts +++ b/src/base/Naro.ts @@ -98,9 +98,10 @@ export class Naro { if (subCollectionName) throw new Error("Sub-collection is not supported in set method"); if (subCollectionId) throw new Error("Sub-collection ID is not supported in set method"); const collection = this.core.getCollection(collectionName); - const source = { path: `${collectionName}/${collectionId}`, createdAt: Date.now(), id: collectionId}; + const source = { path: `${collectionName}/${collectionId}`, createdAt: Date.now(), id: collectionId }; const newItem: NaroDocument = Object.assign(data, source); - collection.push(newItem); + const existingIndex = _.findIndex(collection, (item) => item.id === collectionId); + existingIndex !== -1 ? collection[existingIndex] = newItem : collection.push(newItem); this.core.updateCollection(collectionName, collection); return _.cloneDeep(newItem); } From 9160309a7ee795574236bdf6387f5bac28c30ad3 Mon Sep 17 00:00:00 2001 From: Bryan Lundberg Date: Sat, 10 May 2025 06:15:43 -0600 Subject: [PATCH 6/6] test: update tests to verify document retrieval after set Revised the test to validate document retrieval using `db.get` after calling `db.set`. This ensures the data is correctly stored and retrievable, improving test accuracy. --- __test__/unit/base/Naro.test.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/__test__/unit/base/Naro.test.ts b/__test__/unit/base/Naro.test.ts index 4099688..a61873c 100644 --- a/__test__/unit/base/Naro.test.ts +++ b/__test__/unit/base/Naro.test.ts @@ -316,11 +316,13 @@ test("set, should set a document in the users collection", async () => { test("set, should overwrite a document in the users collection", async () => { const db = new Naro(dbName); await db.set(`users/999`, { name: "Jane Doe" }); - const updatedDoc = await db.set(`users/999`, { name: "John", age: 30 }); + await db.set(`users/999`, { name: "John", age: 30 }); - expect(updatedDoc.id).toBe("999"); - expect(updatedDoc.name).toBe("John"); - expect(updatedDoc.age).toBe(30); + const doc = await db.get(`users/999`); + + expect(doc.id).toBe("999"); + expect(doc.name).toBe("John"); + expect(doc.age).toBe(30); }) test("set, should throw an error if trying to set a document with an invalid ID", async () => {