From 04bf70c6293e3a12f3edb8b43aa694067703e0a5 Mon Sep 17 00:00:00 2001 From: Mara Date: Sun, 25 Jan 2026 21:22:42 +0100 Subject: [PATCH 1/6] refactor: use undefined --- src/index.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/index.ts b/src/index.ts index a05c89f..45c8056 100644 --- a/src/index.ts +++ b/src/index.ts @@ -229,10 +229,10 @@ export default class Enmap { * * const someSubValue = enmap.get("anObjectKey", "someprop.someOtherSubProp"); */ - get(key: string): V | null; - get

>(key: string, path: P): PathValue | null; - get

>(key: string, path: P | undefined): V | PathValue | null; - get

>(key: string, path?: P): V | PathValue | null { + get(key: string): V | undefined; + get

>(key: string, path: P): PathValue | undefined; + get

>(key: string, path: P | undefined): V | PathValue | undefined; + get

>(key: string, path?: P): V | PathValue | undefined { this.#keycheck(key); if (!isNil(this.#autoEnsure) && !this.has(key)) { @@ -242,8 +242,8 @@ export default class Enmap { const data = this.#db .prepare(`SELECT value FROM ${this.#name} WHERE key = ?`) .get(key) as { value: string } | undefined; - const parsed = data ? this.#parse(data.value, key) : null; - if (isNil(parsed)) return null; + const parsed = data ? this.#parse(data.value, key) : undefined; + if (isNil(parsed)) return undefined; if (path) { this.#check(key, ['Object']); @@ -508,7 +508,7 @@ export default class Enmap { operation: MathOps, operand: number, path?: Path, - ): number | null { + ): number | undefined { this.#keycheck(key); this.#check(key, ['Number'], path); const data = this.get(key, path); @@ -580,17 +580,17 @@ export default class Enmap { * console.log(settings) // enmap's value for "1234567890" if it exists, otherwise the defaultSettings value. * @return {*} The value from the database for the key, or the default value provided for a new key. */ - ensure(key: string, defaultValue: any): V | null; + ensure(key: string, defaultValue: any): V | undefined; ensure

>( key: string, defaultValue: any, path: P, - ): PathValue | null; + ): PathValue | undefined; ensure

>( key: string, defaultValue: any, path?: P, - ): V | PathValue | null { + ): V | PathValue | undefined { this.#keycheck(key); if (!isNil(this.#autoEnsure)) { @@ -911,7 +911,7 @@ export default class Enmap { find( pathOrFn: ((val: V, key: string) => boolean) | string, value?: any, - ): V | null { + ): V | undefined { const stmt = this.#db.prepare(`SELECT key, value FROM ${this.#name}`); for (const row of stmt.iterate() as IterableIterator<{ key: string; @@ -925,7 +925,7 @@ export default class Enmap { return parsed; } } - return null; + return undefined; } /** @@ -943,7 +943,7 @@ export default class Enmap { findIndex( pathOrFn: ((val: V, key: string) => boolean) | string, value?: any, - ): string | null { + ): string | undefined { const stmt = this.#db.prepare(`SELECT key, value FROM ${this.#name}`); for (const row of stmt.iterate() as IterableIterator<{ key: string; @@ -957,7 +957,7 @@ export default class Enmap { return row.key; } } - return null; + return undefined; } /** @@ -1207,7 +1207,7 @@ export default class Enmap { } } - #math(base: number, op: MathOps, opand: number): number | null { + #math(base: number, op: MathOps, opand: number): number | undefined { if (base == undefined || op == undefined || opand == undefined) throw new Err( 'Math Operation requires base and operation', @@ -1242,6 +1242,6 @@ export default class Enmap { case 'random': return Math.floor(Math.random() * Math.floor(opand)); } - return null; + return undefined; } } From 4b07280bb07cbdaeece329e65d647fbc62af2a62 Mon Sep 17 00:00:00 2001 From: Mara Date: Mon, 26 Jan 2026 01:15:28 +0100 Subject: [PATCH 2/6] fix: `has` doesn't works with path. --- src/index.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index 45c8056..6be1ba3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -254,19 +254,35 @@ export default class Enmap { /** * Returns whether or not the key exists in the Enmap. - * @param key Required. The key of the element to add to The Enmap or array. + * @param {string} key Required. The key of the element to add to The Enmap or array. + * @param {string} path Optional. The name of the property to check inside the object or array. + * Should be a path with dot notation, such as "prop1.subprop2.subprop3" * @example * if(enmap.has("myKey")) { * // key is there * } + * + * if(!enmap.has("myOtherKey", "oneProp.otherProp.SubProp")) return false; * @returns {boolean} */ - has(key: string): boolean { + has(key: string, path?: string): boolean { this.#keycheck(key); + + // Check if the key exists const data = this.#db .prepare(`SELECT count(*) FROM ${this.#name} WHERE key = ?`) .get(key) as { 'count(*)': number }; - return data['count(*)'] > 0; + + if (data['count(*)'] === 0) return false; + + // If path is provided, check if the path exists within the value + if (path) { + this.#check(key, ['Object']); + const value = this.get(key); + return _get(value, path) !== undefined; + } + + return true; } /** From 3a2acfbe6b1acf096fc9f7a847a45a3638aa726a Mon Sep 17 00:00:00 2001 From: Mara Date: Tue, 27 Jan 2026 12:39:45 +0100 Subject: [PATCH 3/6] fix: use `Path` for the dot notation --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6be1ba3..2b7af42 100644 --- a/src/index.ts +++ b/src/index.ts @@ -255,7 +255,7 @@ export default class Enmap { /** * Returns whether or not the key exists in the Enmap. * @param {string} key Required. The key of the element to add to The Enmap or array. - * @param {string} path Optional. The name of the property to check inside the object or array. + * @param {Path} path Optional. The name of the property to check inside the object or array. * Should be a path with dot notation, such as "prop1.subprop2.subprop3" * @example * if(enmap.has("myKey")) { @@ -265,7 +265,7 @@ export default class Enmap { * if(!enmap.has("myOtherKey", "oneProp.otherProp.SubProp")) return false; * @returns {boolean} */ - has(key: string, path?: string): boolean { + has(key: string, path?: Path): boolean { this.#keycheck(key); // Check if the key exists From 2f95f0ca1de069a522042334221eff0a5cd1842d Mon Sep 17 00:00:00 2001 From: Mara Date: Tue, 27 Jan 2026 12:44:39 +0100 Subject: [PATCH 4/6] fix: test to use undefined instead of null --- test/index.spec.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/index.spec.js b/test/index.spec.js index 7cf031d..e026432 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -107,10 +107,10 @@ describe('Enmap', () => { expect(enmap.get('setNumber')).toBe(1); }); - test('should set a value w/ null', () => { - enmap.set('setNull', null); + test('should set a value w/ undefined', () => { + enmap.set('setNull', undefined); - expect(enmap.get('setNull')).toBe(null); + expect(enmap.get('setNull')).toBe(undefined); }); test('should set a value w/ boolean', () => { @@ -380,7 +380,7 @@ describe('Enmap', () => { enmap.set('huh', 1); enmap.math('huh', 'huh', 1); - expect(enmap.get('huh')).toBe(null); + expect(enmap.get('huh')).toBe(undefined); }); test('should math value w/ path', () => { @@ -512,7 +512,7 @@ describe('Enmap', () => { enmap.set('delete', 'value'); enmap.delete('delete'); - expect(enmap.get('delete')).toBe(null); + expect(enmap.get('delete')).toBe(undefined); }); test('should delete a path', () => { @@ -530,7 +530,7 @@ describe('Enmap', () => { enmap.set('clear', 'value'); enmap.clear(); - expect(enmap.get('clear')).toBe(null); + expect(enmap.get('clear')).toBe(undefined); }); }); @@ -827,11 +827,11 @@ describe('Enmap', () => { expect(enmap.find('sub', 'value')).toEqual({ sub: 'value' }); }); - test('should return null if not found', () => { + test('should return undefined if not found', () => { enmap.set('find', 'value'); enmap.set('find2', 'value2'); - expect(enmap.find((val) => val === 'value3')).toBe(null); + expect(enmap.find((val) => val === 'value3')).toBe(undefined); }); }); @@ -852,11 +852,11 @@ describe('Enmap', () => { expect(enmap.findIndex('sub', 'value')).toBe('find'); }); - test('should return null if not found', () => { + test('should return undefined if not found', () => { enmap.set('find', 'value'); enmap.set('find2', 'value2'); - expect(enmap.findIndex((val) => val === 'value3')).toBe(null); + expect(enmap.findIndex((val) => val === 'value3')).toBe(undefined); }); }); From ba3cc39aab66c2b620aa568062665362924d0c48 Mon Sep 17 00:00:00 2001 From: Mara Date: Wed, 28 Jan 2026 18:59:35 +0100 Subject: [PATCH 5/6] test: add nested path test --- test/index.spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/index.spec.js b/test/index.spec.js index e026432..31f1c06 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -484,6 +484,12 @@ describe('Enmap', () => { expect(enmap.has('has')).toBe(true); }); + test('should return true if key and path exists', () =>{ + enmap.set('hasPath', 'value', 'nested'); + + expect(enmap.has('hasPath', 'nested')).toBe(true); + }); + test("should return false if key doesn't exist", () => { expect(enmap.has('unknown')).toBe(false); }); From a48a5d853b067d04ea9c15bbd798f04095ebf85d Mon Sep 17 00:00:00 2001 From: Mara Date: Wed, 28 Jan 2026 20:19:47 +0100 Subject: [PATCH 6/6] test: add more test around has and subpath key --- test/index.spec.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/index.spec.js b/test/index.spec.js index 31f1c06..94971e8 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -493,6 +493,16 @@ describe('Enmap', () => { test("should return false if key doesn't exist", () => { expect(enmap.has('unknown')).toBe(false); }); + + test("Should return false if the subkey doesn't exists", () => { + enmap.set('hasPath2', undefined, 'nested'); + expect(enmap.has('hasPath2', 'nested')).toBe(false); + }); + + test("should return false if key exists but path doesn't", () => { + enmap.set('hasPath3', 'value', 'nested'); + expect(enmap.has('hasPath3', 'other')).toBe(false); + }); }); describe('includes', () => {