@cyberskill/shared 3.10.0 → 3.11.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.
Files changed (41) hide show
  1. package/dist/config/env/env.util.js.map +1 -1
  2. package/dist/config/vitest/vitest.e2e.js +1 -1
  3. package/dist/config/vitest/vitest.unit.js +1 -1
  4. package/dist/constant/response-status.d.ts +4 -0
  5. package/dist/constant/response-status.js.map +1 -1
  6. package/dist/node/express/express.util.d.ts +6 -0
  7. package/dist/node/express/express.util.js.map +1 -1
  8. package/dist/node/mongo/mongo.controller.helpers.d.ts +43 -0
  9. package/dist/node/mongo/mongo.controller.helpers.js +20 -0
  10. package/dist/node/mongo/mongo.controller.helpers.js.map +1 -0
  11. package/dist/node/mongo/mongo.controller.native.js +65 -93
  12. package/dist/node/mongo/mongo.controller.native.js.map +1 -1
  13. package/dist/node/mongo/mongo.util.js.map +1 -1
  14. package/dist/node/storage/index.js +3 -3
  15. package/dist/node/storage/storage.constant.d.ts +0 -3
  16. package/dist/node/storage/storage.constant.js +2 -2
  17. package/dist/node/storage/storage.constant.js.map +1 -1
  18. package/dist/node/storage/storage.type.d.ts +0 -11
  19. package/dist/node/storage/storage.util.d.ts +1 -1
  20. package/dist/node/storage/storage.util.js +60 -68
  21. package/dist/node/storage/storage.util.js.map +1 -1
  22. package/dist/node/upload/upload.type.d.ts +2 -0
  23. package/dist/node/upload/upload.type.js.map +1 -1
  24. package/dist/node/upload/upload.util.js +10 -2
  25. package/dist/node/upload/upload.util.js.map +1 -1
  26. package/dist/node_modules/.pnpm/vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.1_@types_nod_5f6c16f4d4385f16c87b17afc93c851f/node_modules/vitest/dist/config.js +8 -0
  27. package/dist/node_modules/.pnpm/{vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.0_@noble_hashes@1.8.0__vite@8.0.1_@types_nod_36acd00c2670b611b011192023dc5bd9 → vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.1_@types_nod_5f6c16f4d4385f16c87b17afc93c851f}/node_modules/vitest/dist/config.js.map +1 -1
  28. package/dist/react/storage/storage.hook.d.ts +1 -1
  29. package/dist/react/storage/storage.hook.js.map +1 -1
  30. package/dist/react/storage/storage.util.d.ts +6 -7
  31. package/dist/react/storage/storage.util.js +15 -10
  32. package/dist/react/storage/storage.util.js.map +1 -1
  33. package/dist/util/common/common.util.d.ts +15 -2
  34. package/dist/util/common/common.util.js +22 -9
  35. package/dist/util/common/common.util.js.map +1 -1
  36. package/dist/util/common/index.js +2 -2
  37. package/dist/util/index.js +7 -7
  38. package/dist/util/object/object.util.d.ts +7 -3
  39. package/dist/util/object/object.util.js.map +1 -1
  40. package/package.json +5 -6
  41. package/dist/node_modules/.pnpm/vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.0_@noble_hashes@1.8.0__vite@8.0.1_@types_nod_36acd00c2670b611b011192023dc5bd9/node_modules/vitest/dist/config.js +0 -8
@@ -1 +1 @@
1
- {"version":3,"file":"storage.hook.js","names":[],"sources":["../../../src/react/storage/storage.hook.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\n\nimport type { I_Serializer } from '#util/serializer/index.js';\n\nimport { serializer as defaultSerializer } from '#util/serializer/index.js';\n\nimport { catchError } from '../log/index.js';\nimport { storage } from './storage.util.js';\n\n/**\n * React hook that provides persistent storage functionality with automatic serialization.\n * This hook manages state that persists across browser sessions using localForage,\n * with automatic serialization/deserialization of complex data types. It provides\n * a React-friendly interface for storage operations with proper error handling.\n *\n * Features:\n * - Automatic data serialization and deserialization\n * - Persistent storage across browser sessions\n * - Initial value handling and fallback\n * - Error handling with graceful degradation\n * - Automatic storage synchronization\n * - Support for complex data types via custom serializers\n *\n * @param key - The unique storage key for the data.\n * @param initialValue - Optional initial value to use if no stored value exists.\n * @param serializer - Optional custom serializer for complex data types (defaults to JSON serializer).\n * @returns An object containing the current value, set function, and remove function.\n */\nexport function useStorage<T>(\n key: string,\n initialValue?: T,\n serializer: I_Serializer<T> = defaultSerializer as I_Serializer<T>,\n) {\n const [value, setValue] = useState<T | undefined>(initialValue);\n const [isLoaded, setIsLoaded] = useState(false);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadValue = async () => {\n try {\n const valueFound = await storage.get<string>(key);\n\n if (isMounted) {\n if (valueFound !== null) {\n const parsedValue = serializer.deserialize(valueFound);\n setValue(parsedValue);\n }\n else if (initialValue !== undefined) {\n const serialized = serializer.serialize(initialValue);\n await storage.set(key, serialized);\n setValue(initialValue);\n }\n else {\n setValue(undefined);\n }\n }\n }\n catch (error) {\n catchError(error);\n\n if (isMounted) {\n setValue(initialValue);\n }\n }\n finally {\n if (isMounted)\n setIsLoaded(true);\n }\n };\n\n loadValue();\n\n return () => {\n isMounted = false;\n setIsLoaded(false);\n };\n }, [key, initialValue, serializer]);\n\n useEffect(() => {\n if (!isLoaded)\n return;\n\n const saveValue = async () => {\n try {\n if (value !== undefined) {\n const serialized = serializer.serialize(value);\n await storage.set(key, serialized);\n }\n }\n catch (error) {\n catchError(error);\n }\n };\n\n saveValue();\n }, [value, key, serializer, isLoaded]);\n\n const set = useCallback(\n (newValue: T | ((val: T | undefined) => T)) => {\n setValue((prev) => {\n if (typeof newValue === 'function') {\n return (newValue as (val: T | undefined) => T)(prev);\n }\n return newValue;\n });\n },\n [],\n );\n\n const remove = useCallback(async () => {\n try {\n await storage.remove(key);\n setValue(undefined);\n }\n catch (error) {\n catchError(error);\n }\n }, [key]);\n\n return { value, set, remove };\n}\n"],"mappings":";;;;;AA4BA,SAAgB,EACZ,GACA,GACA,IAA8B,GAChC;CACE,IAAM,CAAC,GAAO,KAAY,EAAwB,EAAa,EACzD,CAAC,GAAU,KAAe,EAAS,GAAM;AAsF/C,QApFA,QAAgB;EACZ,IAAI,IAAY;AAoChB,UAlCkB,YAAY;AAC1B,OAAI;IACA,IAAM,IAAa,MAAM,EAAQ,IAAY,EAAI;AAEjD,QAAI,EACA,KAAI,MAAe,KAEf,GADoB,EAAW,YAAY,EAAW,CACjC;aAEhB,MAAiB,KAAA,GAAW;KACjC,IAAM,IAAa,EAAW,UAAU,EAAa;AAErD,KADA,MAAM,EAAQ,IAAI,GAAK,EAAW,EAClC,EAAS,EAAa;UAGtB,GAAS,KAAA,EAAU;YAIxB,GAAO;AAGV,IAFA,EAAW,EAAM,EAEb,KACA,EAAS,EAAa;aAGtB;AACJ,IAAI,KACA,EAAY,GAAK;;MAIlB,QAEE;AAET,GADA,IAAY,IACZ,EAAY,GAAM;;IAEvB;EAAC;EAAK;EAAc;EAAW,CAAC,EAEnC,QAAgB;AACP,QAGa,YAAY;AAC1B,OAAI;AACA,QAAI,MAAU,KAAA,GAAW;KACrB,IAAM,IAAa,EAAW,UAAU,EAAM;AAC9C,WAAM,EAAQ,IAAI,GAAK,EAAW;;YAGnC,GAAO;AACV,MAAW,EAAM;;MAId;IACZ;EAAC;EAAO;EAAK;EAAY;EAAS,CAAC,EAwB/B;EAAE;EAAO,KAtBJ,GACP,MAA8C;AAC3C,MAAU,MACF,OAAO,KAAa,aACZ,EAAuC,EAAK,GAEjD,EACT;KAEN,EAAE,CACL;EAYoB,QAVN,EAAY,YAAY;AACnC,OAAI;AAEA,IADA,MAAM,EAAQ,OAAO,EAAI,EACzB,EAAS,KAAA,EAAU;YAEhB,GAAO;AACV,MAAW,EAAM;;KAEtB,CAAC,EAAI,CAAC;EAEoB"}
1
+ {"version":3,"file":"storage.hook.js","names":[],"sources":["../../../src/react/storage/storage.hook.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\n\nimport type { I_Serializer } from '#util/serializer/index.js';\n\nimport { serializer as defaultSerializer } from '#util/serializer/index.js';\n\nimport { catchError } from '../log/index.js';\nimport { storage } from './storage.util.js';\n\n/**\n * React hook that provides persistent storage functionality with automatic serialization.\n * This hook manages state that persists across browser sessions using localStorage,\n * with automatic serialization/deserialization of complex data types. It provides\n * a React-friendly interface for storage operations with proper error handling.\n *\n * Features:\n * - Automatic data serialization and deserialization\n * - Persistent storage across browser sessions\n * - Initial value handling and fallback\n * - Error handling with graceful degradation\n * - Automatic storage synchronization\n * - Support for complex data types via custom serializers\n *\n * @param key - The unique storage key for the data.\n * @param initialValue - Optional initial value to use if no stored value exists.\n * @param serializer - Optional custom serializer for complex data types (defaults to JSON serializer).\n * @returns An object containing the current value, set function, and remove function.\n */\nexport function useStorage<T>(\n key: string,\n initialValue?: T,\n serializer: I_Serializer<T> = defaultSerializer as I_Serializer<T>,\n) {\n const [value, setValue] = useState<T | undefined>(initialValue);\n const [isLoaded, setIsLoaded] = useState(false);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadValue = async () => {\n try {\n const valueFound = await storage.get<string>(key);\n\n if (isMounted) {\n if (valueFound !== null) {\n const parsedValue = serializer.deserialize(valueFound);\n setValue(parsedValue);\n }\n else if (initialValue !== undefined) {\n const serialized = serializer.serialize(initialValue);\n await storage.set(key, serialized);\n setValue(initialValue);\n }\n else {\n setValue(undefined);\n }\n }\n }\n catch (error) {\n catchError(error);\n\n if (isMounted) {\n setValue(initialValue);\n }\n }\n finally {\n if (isMounted)\n setIsLoaded(true);\n }\n };\n\n loadValue();\n\n return () => {\n isMounted = false;\n setIsLoaded(false);\n };\n }, [key, initialValue, serializer]);\n\n useEffect(() => {\n if (!isLoaded)\n return;\n\n const saveValue = async () => {\n try {\n if (value !== undefined) {\n const serialized = serializer.serialize(value);\n await storage.set(key, serialized);\n }\n }\n catch (error) {\n catchError(error);\n }\n };\n\n saveValue();\n }, [value, key, serializer, isLoaded]);\n\n const set = useCallback(\n (newValue: T | ((val: T | undefined) => T)) => {\n setValue((prev) => {\n if (typeof newValue === 'function') {\n return (newValue as (val: T | undefined) => T)(prev);\n }\n return newValue;\n });\n },\n [],\n );\n\n const remove = useCallback(async () => {\n try {\n await storage.remove(key);\n setValue(undefined);\n }\n catch (error) {\n catchError(error);\n }\n }, [key]);\n\n return { value, set, remove };\n}\n"],"mappings":";;;;;AA4BA,SAAgB,EACZ,GACA,GACA,IAA8B,GAChC;CACE,IAAM,CAAC,GAAO,KAAY,EAAwB,EAAa,EACzD,CAAC,GAAU,KAAe,EAAS,GAAM;AAsF/C,QApFA,QAAgB;EACZ,IAAI,IAAY;AAoChB,UAlCkB,YAAY;AAC1B,OAAI;IACA,IAAM,IAAa,MAAM,EAAQ,IAAY,EAAI;AAEjD,QAAI,EACA,KAAI,MAAe,KAEf,GADoB,EAAW,YAAY,EAAW,CACjC;aAEhB,MAAiB,KAAA,GAAW;KACjC,IAAM,IAAa,EAAW,UAAU,EAAa;AAErD,KADA,MAAM,EAAQ,IAAI,GAAK,EAAW,EAClC,EAAS,EAAa;UAGtB,GAAS,KAAA,EAAU;YAIxB,GAAO;AAGV,IAFA,EAAW,EAAM,EAEb,KACA,EAAS,EAAa;aAGtB;AACJ,IAAI,KACA,EAAY,GAAK;;MAIlB,QAEE;AAET,GADA,IAAY,IACZ,EAAY,GAAM;;IAEvB;EAAC;EAAK;EAAc;EAAW,CAAC,EAEnC,QAAgB;AACP,QAGa,YAAY;AAC1B,OAAI;AACA,QAAI,MAAU,KAAA,GAAW;KACrB,IAAM,IAAa,EAAW,UAAU,EAAM;AAC9C,WAAM,EAAQ,IAAI,GAAK,EAAW;;YAGnC,GAAO;AACV,MAAW,EAAM;;MAId;IACZ;EAAC;EAAO;EAAK;EAAY;EAAS,CAAC,EAwB/B;EAAE;EAAO,KAtBJ,GACP,MAA8C;AAC3C,MAAU,MACF,OAAO,KAAa,aACZ,EAAuC,EAAK,GAEjD,EACT;KAEN,EAAE,CACL;EAYoB,QAVN,EAAY,YAAY;AACnC,OAAI;AAEA,IADA,MAAM,EAAQ,OAAO,EAAI,EACzB,EAAS,KAAA,EAAU;YAEhB,GAAO;AACV,MAAW,EAAM;;KAEtB,CAAC,EAAI,CAAC;EAEoB"}
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Browser storage utility object using localForage for cross-browser compatibility.
3
- * This object provides a unified interface for browser storage operations using localForage,
4
- * which automatically chooses the best available storage method (IndexedDB, WebSQL, or localStorage)
5
- * based on browser capabilities. It includes comprehensive error handling and type safety.
2
+ * Browser storage utility object using native localStorage.
3
+ * This object provides a unified interface for browser storage operations
4
+ * with comprehensive error handling and type safety.
5
+ * Values are stored as JSON strings for consistent serialization.
6
6
  */
7
7
  export declare const storage: {
8
8
  /**
@@ -17,11 +17,10 @@ export declare const storage: {
17
17
  /**
18
18
  * Stores a value in browser storage with a unique key.
19
19
  * This method saves data that can be retrieved later using the get method.
20
- * The data is automatically handled by localForage which chooses the optimal
21
- * storage method for the browser environment.
20
+ * The data is automatically serialized to JSON.
22
21
  *
23
22
  * @param key - The unique identifier for the value to store.
24
- * @param value - The data to store (will be automatically handled by localForage).
23
+ * @param value - The data to store (will be automatically serialized to JSON).
25
24
  * @returns A promise that resolves when the storage operation is complete.
26
25
  */
27
26
  set<T = unknown>(key: string, value: T): Promise<void>;
@@ -1,37 +1,42 @@
1
1
  import { catchError as e } from "../log/log.util.js";
2
- import t from "localforage";
3
2
  //#region src/react/storage/storage.util.ts
4
- var n = {
5
- async get(n) {
3
+ var t = {
4
+ async get(t) {
6
5
  try {
7
- return await t.getItem(n);
6
+ let e = localStorage.getItem(t);
7
+ return e === null ? null : JSON.parse(e);
8
8
  } catch (t) {
9
9
  return e(t, { returnValue: null });
10
10
  }
11
11
  },
12
- async set(n, r) {
12
+ async set(t, n) {
13
13
  try {
14
- await t.setItem(n, r);
14
+ localStorage.setItem(t, JSON.stringify(n));
15
15
  } catch (t) {
16
16
  e(t);
17
17
  }
18
18
  },
19
- async remove(n) {
19
+ async remove(t) {
20
20
  try {
21
- await t.removeItem(n);
21
+ localStorage.removeItem(t);
22
22
  } catch (t) {
23
23
  e(t);
24
24
  }
25
25
  },
26
26
  async keys() {
27
27
  try {
28
- return await t.keys() ?? [];
28
+ let e = [];
29
+ for (let t = 0; t < localStorage.length; t++) {
30
+ let n = localStorage.key(t);
31
+ n !== null && e.push(n);
32
+ }
33
+ return e;
29
34
  } catch (t) {
30
35
  return e(t, { returnValue: [] });
31
36
  }
32
37
  }
33
38
  };
34
39
  //#endregion
35
- export { n as storage };
40
+ export { t as storage };
36
41
 
37
42
  //# sourceMappingURL=storage.util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.util.js","names":[],"sources":["../../../src/react/storage/storage.util.ts"],"sourcesContent":["import localForage from 'localforage';\n\nimport { catchError } from '../log/index.js';\n\n/**\n * Browser storage utility object using localForage for cross-browser compatibility.\n * This object provides a unified interface for browser storage operations using localForage,\n * which automatically chooses the best available storage method (IndexedDB, WebSQL, or localStorage)\n * based on browser capabilities. It includes comprehensive error handling and type safety.\n */\nexport const storage = {\n /**\n * Retrieves a value from browser storage by key.\n * This method fetches data that was previously stored using the set method.\n * Returns null if the key doesn't exist or if an error occurs during retrieval.\n *\n * @param key - The unique identifier for the stored value.\n * @returns A promise that resolves to the stored value or null if not found.\n */\n async get<T = unknown>(key: string): Promise<T | null> {\n try {\n return await localForage.getItem<T>(key);\n }\n catch (error) {\n return catchError(error, { returnValue: null });\n }\n },\n /**\n * Stores a value in browser storage with a unique key.\n * This method saves data that can be retrieved later using the get method.\n * The data is automatically handled by localForage which chooses the optimal\n * storage method for the browser environment.\n *\n * @param key - The unique identifier for the value to store.\n * @param value - The data to store (will be automatically handled by localForage).\n * @returns A promise that resolves when the storage operation is complete.\n */\n async set<T = unknown>(key: string, value: T): Promise<void> {\n try {\n await localForage.setItem(key, value);\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Removes a value from browser storage by key.\n * This method permanently deletes the stored data associated with the specified key.\n * If the key doesn't exist, the operation completes successfully without error.\n *\n * @param key - The unique identifier of the value to remove.\n * @returns A promise that resolves when the removal operation is complete.\n */\n async remove(key: string): Promise<void> {\n try {\n await localForage.removeItem(key);\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Retrieves all storage keys.\n * This method returns an array of all keys that currently have stored values.\n * Returns an empty array if no keys exist or if an error occurs during retrieval.\n *\n * @returns A promise that resolves to an array of storage keys.\n */\n async keys(): Promise<string[]> {\n try {\n const keys = await localForage.keys();\n\n return keys ?? [];\n }\n catch (error) {\n return catchError(error, { returnValue: [] });\n }\n },\n};\n"],"mappings":";;;AAUA,IAAa,IAAU;CASnB,MAAM,IAAiB,GAAgC;AACnD,MAAI;AACA,UAAO,MAAM,EAAY,QAAW,EAAI;WAErC,GAAO;AACV,UAAO,EAAW,GAAO,EAAE,aAAa,MAAM,CAAC;;;CAavD,MAAM,IAAiB,GAAa,GAAyB;AACzD,MAAI;AACA,SAAM,EAAY,QAAQ,GAAK,EAAM;WAElC,GAAO;AACV,KAAW,EAAM;;;CAWzB,MAAM,OAAO,GAA4B;AACrC,MAAI;AACA,SAAM,EAAY,WAAW,EAAI;WAE9B,GAAO;AACV,KAAW,EAAM;;;CAUzB,MAAM,OAA0B;AAC5B,MAAI;AAGA,UAFa,MAAM,EAAY,MAAM,IAEtB,EAAE;WAEd,GAAO;AACV,UAAO,EAAW,GAAO,EAAE,aAAa,EAAE,EAAE,CAAC;;;CAGxD"}
1
+ {"version":3,"file":"storage.util.js","names":[],"sources":["../../../src/react/storage/storage.util.ts"],"sourcesContent":["import { catchError } from '../log/index.js';\n\n/**\n * Browser storage utility object using native localStorage.\n * This object provides a unified interface for browser storage operations\n * with comprehensive error handling and type safety.\n * Values are stored as JSON strings for consistent serialization.\n */\nexport const storage = {\n /**\n * Retrieves a value from browser storage by key.\n * This method fetches data that was previously stored using the set method.\n * Returns null if the key doesn't exist or if an error occurs during retrieval.\n *\n * @param key - The unique identifier for the stored value.\n * @returns A promise that resolves to the stored value or null if not found.\n */\n async get<T = unknown>(key: string): Promise<T | null> {\n try {\n const raw = localStorage.getItem(key);\n\n if (raw === null) {\n return null;\n }\n\n return JSON.parse(raw) as T;\n }\n catch (error) {\n return catchError(error, { returnValue: null });\n }\n },\n /**\n * Stores a value in browser storage with a unique key.\n * This method saves data that can be retrieved later using the get method.\n * The data is automatically serialized to JSON.\n *\n * @param key - The unique identifier for the value to store.\n * @param value - The data to store (will be automatically serialized to JSON).\n * @returns A promise that resolves when the storage operation is complete.\n */\n async set<T = unknown>(key: string, value: T): Promise<void> {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Removes a value from browser storage by key.\n * This method permanently deletes the stored data associated with the specified key.\n * If the key doesn't exist, the operation completes successfully without error.\n *\n * @param key - The unique identifier of the value to remove.\n * @returns A promise that resolves when the removal operation is complete.\n */\n async remove(key: string): Promise<void> {\n try {\n localStorage.removeItem(key);\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Retrieves all storage keys.\n * This method returns an array of all keys that currently have stored values.\n * Returns an empty array if no keys exist or if an error occurs during retrieval.\n *\n * @returns A promise that resolves to an array of storage keys.\n */\n async keys(): Promise<string[]> {\n try {\n const keys: string[] = [];\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n\n if (key !== null) {\n keys.push(key);\n }\n }\n\n return keys;\n }\n catch (error) {\n return catchError(error, { returnValue: [] });\n }\n },\n};\n"],"mappings":";;AAQA,IAAa,IAAU;CASnB,MAAM,IAAiB,GAAgC;AACnD,MAAI;GACA,IAAM,IAAM,aAAa,QAAQ,EAAI;AAMrC,UAJI,MAAQ,OACD,OAGJ,KAAK,MAAM,EAAI;WAEnB,GAAO;AACV,UAAO,EAAW,GAAO,EAAE,aAAa,MAAM,CAAC;;;CAYvD,MAAM,IAAiB,GAAa,GAAyB;AACzD,MAAI;AACA,gBAAa,QAAQ,GAAK,KAAK,UAAU,EAAM,CAAC;WAE7C,GAAO;AACV,KAAW,EAAM;;;CAWzB,MAAM,OAAO,GAA4B;AACrC,MAAI;AACA,gBAAa,WAAW,EAAI;WAEzB,GAAO;AACV,KAAW,EAAM;;;CAUzB,MAAM,OAA0B;AAC5B,MAAI;GACA,IAAM,IAAiB,EAAE;AAEzB,QAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;IAC1C,IAAM,IAAM,aAAa,IAAI,EAAE;AAE/B,IAAI,MAAQ,QACR,EAAK,KAAK,EAAI;;AAItB,UAAO;WAEJ,GAAO;AACV,UAAO,EAAW,GAAO,EAAE,aAAa,EAAE,EAAE,CAAC;;;CAGxD"}
@@ -15,8 +15,8 @@ export declare function escapeRegExp(str: string): string;
15
15
  *
16
16
  * Optimization: Uses pre-computed regex and map to perform replacement in a single pass (O(N)),
17
17
  * instead of iterating through all character groups (O(K*N)).
18
- * Removed unnecessary NFD normalization which improves performance and fixes
19
- * matching against NFC target strings.
18
+ * Results are cached in an LRU cache (max 128 entries) to avoid redundant computation
19
+ * for repeated search terms.
20
20
  *
21
21
  * @param str - The string to convert to a regex pattern.
22
22
  * @returns The regex pattern as a string that matches the original string and its accented variations.
@@ -54,7 +54,20 @@ export declare function mapEnvironment(env: I_NodeEnvInput): I_EnvFlags;
54
54
  * Checks if value is object-like (e.g., objects, arrays, etc.), not null.
55
55
  * Re-exported from util for general use across the codebase.
56
56
  *
57
+ * @remarks
58
+ * Returns `true` for arrays, Dates, Maps, Sets, and class instances.
59
+ * Use {@link isPlainObject} when you specifically need to check for plain objects only.
60
+ *
57
61
  * @param value - The value to check.
58
62
  * @returns True if the value is an object and not null.
59
63
  */
60
64
  export declare function isObject(value: unknown): value is object;
65
+ /**
66
+ * Checks if a value is a plain object (created by `{}`, `Object.create(null)`, or `new Object()`).
67
+ * Unlike {@link isObject}, this returns `false` for arrays, Dates, Maps, Sets, RegExps,
68
+ * and other class instances.
69
+ *
70
+ * @param value - The value to check.
71
+ * @returns True if the value is a plain object, false otherwise.
72
+ */
73
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
@@ -94,14 +94,22 @@ var o = [...a].join(""), s = RegExp(`[${o}]`, "g"), c = /[.*+?^${}()|[\]\\]/g;
94
94
  function l(e) {
95
95
  return e.replace(c, "\\$&");
96
96
  }
97
- function u(e) {
98
- return e = l(e), e.replace(s, (e) => i.get(e) || e);
99
- }
100
- var d = /\p{Diacritic}/gu;
97
+ var u = /* @__PURE__ */ new Map(), d = 128;
101
98
  function f(e) {
102
- return e.normalize("NFD").replace(d, "");
99
+ let t = u.get(e);
100
+ if (t !== void 0) return t;
101
+ let n = l(e).replace(s, (e) => i.get(e) || e);
102
+ if (u.size >= d) {
103
+ let e = u.keys().next().value;
104
+ e !== void 0 && u.delete(e);
105
+ }
106
+ return u.set(e, n), n;
103
107
  }
104
- function p(e, t) {
108
+ var p = /\p{Diacritic}/gu;
109
+ function m(e) {
110
+ return e.normalize("NFD").replace(p, "");
111
+ }
112
+ function h(e, t) {
105
113
  if (!t) return [...new Set(e)];
106
114
  let n = /* @__PURE__ */ new Set(), r = [];
107
115
  for (let i of e) {
@@ -110,7 +118,7 @@ function p(e, t) {
110
118
  }
111
119
  return r;
112
120
  }
113
- function m(t) {
121
+ function g(t) {
114
122
  let { NODE_ENV: n = e.DEVELOPMENT, NODE_ENV_MODE: r = e.DEVELOPMENT } = t, i = n === e.DEVELOPMENT && r === e.DEVELOPMENT, a = n === e.PRODUCTION && r === e.STAGING, o = n === e.PRODUCTION && r === e.PRODUCTION;
115
123
  if (n === e.PRODUCTION && r === e.DEVELOPMENT) throw Error("NODE_ENV_MODE must be set to staging or production in production environment");
116
124
  return {
@@ -119,10 +127,15 @@ function m(t) {
119
127
  IS_PROD: o
120
128
  };
121
129
  }
122
- function h(e) {
130
+ function _(e) {
123
131
  return typeof e == "object" && !!e;
124
132
  }
133
+ function v(e) {
134
+ if (typeof e != "object" || !e) return !1;
135
+ let t = Object.getPrototypeOf(e);
136
+ return t === Object.prototype || t === null;
137
+ }
125
138
  //#endregion
126
- export { l as escapeRegExp, h as isObject, m as mapEnvironment, u as regexSearchMapper, f as removeAccent, p as uniqueArray };
139
+ export { l as escapeRegExp, _ as isObject, v as isPlainObject, g as mapEnvironment, f as regexSearchMapper, m as removeAccent, h as uniqueArray };
127
140
 
128
141
  //# sourceMappingURL=common.util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.util.js","names":[],"sources":["../../../src/util/common/common.util.ts"],"sourcesContent":["import { E_Environment } from '#typescript/index.js';\n\nimport type { I_EnvFlags, I_NodeEnvInput } from './common.type.js';\n\nconst charMap: Record<string, string[]> = {\n a: ['à', 'á', 'ạ', 'ả', 'ã', 'â', 'ầ', 'ấ', 'ậ', 'ẩ', 'ẫ', 'ă', 'ằ', 'ắ', 'ặ', 'ẳ', 'ẵ'],\n e: ['è', 'é', 'ẹ', 'ẻ', 'ẽ', 'ê', 'ề', 'ế', 'ệ', 'ể', 'ễ'],\n i: ['ì', 'í', 'ị', 'ỉ', 'ĩ'],\n o: ['ò', 'ó', 'ọ', 'ỏ', 'õ', 'ô', 'ồ', 'ố', 'ộ', 'ổ', 'ỗ', 'ơ', 'ờ', 'ớ', 'ợ', 'ở', 'ỡ'],\n u: ['ù', 'ú', 'ụ', 'ủ', 'ũ', 'ư', 'ừ', 'ứ', 'ự', 'ử', 'ữ'],\n y: ['ỳ', 'ý', 'ỵ', 'ỷ', 'ỹ'],\n d: ['đ'],\n};\n\nconst upperCharMap: Record<string, string[]> = Object.entries(charMap).reduce(\n (map, [key, value]) => {\n map[key.toUpperCase()] = value.map(char => char.toUpperCase());\n return map;\n },\n {} as Record<string, string[]>,\n);\n\nconst combinedMap = { ...charMap, ...upperCharMap };\n\n// Pre-compute replacement map and search regex for better performance\n// This avoids rebuilding regexes and maps on every function call\nconst replacementMap = new Map<string, string>();\nconst charsToMatch = new Set<string>();\n\nObject.entries(combinedMap).forEach(([baseChar, variations]) => {\n // The replacement pattern is the same for the base char and all its variations\n // Example: 'a', 'à', 'á'... all map to '(a|à|á...)'\n const replacement = `(${[baseChar, ...variations].join('|')})`;\n\n [baseChar, ...variations].forEach((char) => {\n replacementMap.set(char, replacement);\n charsToMatch.add(char);\n });\n});\n\n// Construct a single regex that matches any character in our map\nconst patternString = [...charsToMatch].join('');\n// We use a character class regex: [abc...]\n// eslint-disable-next-line regexp/no-empty-character-class -- regex is built dynamically from precomputed charMap\nconst searchRegex = new RegExp(`[${patternString}]`, 'g');\n\nconst RE_ESCAPE_REGEXP = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * Escapes special characters in a string for use in a regular expression.\n * This function escapes characters that have special meaning in regex (e.g., ., *, +, ?, etc.)\n * so they are treated as literal characters.\n *\n * @param str - The string to escape.\n * @returns The escaped string safe for use in a RegExp.\n */\nexport function escapeRegExp(str: string): string {\n return str.replace(RE_ESCAPE_REGEXP, '\\\\$&');\n}\n\n/**\n * Convert a string to a regex pattern that matches the string and its accented variations.\n * This function normalizes the input string and creates a regex pattern that can match\n * both the original characters and their accented equivalents.\n *\n * Optimization: Uses pre-computed regex and map to perform replacement in a single pass (O(N)),\n * instead of iterating through all character groups (O(K*N)).\n * Removed unnecessary NFD normalization which improves performance and fixes\n * matching against NFC target strings.\n *\n * @param str - The string to convert to a regex pattern.\n * @returns The regex pattern as a string that matches the original string and its accented variations.\n */\nexport function regexSearchMapper(str: string) {\n str = escapeRegExp(str);\n return str.replace(searchRegex, match => replacementMap.get(match) || match);\n}\n\nconst RE_DIACRITIC = /\\p{Diacritic}/gu;\n\n/**\n * Remove accents from a string.\n * This function normalizes the string using NFD normalization and removes all diacritical marks.\n *\n * @param str - The string to remove accents from.\n * @returns The string without any accents or diacritical marks.\n */\nexport function removeAccent(str: string) {\n return str.normalize('NFD').replace(RE_DIACRITIC, '');\n}\n\n/**\n * Remove duplicates from an array based on a key function.\n * This function can remove duplicates either by comparing values directly (when no keyFn is provided)\n * or by using a custom key function to determine uniqueness.\n *\n * @param arr - The array to remove duplicates from.\n * @param keyFn - Optional function that returns a unique key for each item in the array.\n * @returns A new array with duplicates removed, maintaining the original order.\n */\nexport function uniqueArray<T>(\n arr: T[],\n keyFn?: (item: T) => string | number,\n): T[] {\n if (!keyFn) {\n return [...new Set(arr)];\n }\n\n const seen = new Set<string | number>();\n const result: T[] = [];\n\n for (const item of arr) {\n const key = keyFn(item);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(item);\n }\n }\n\n return result;\n}\n\n/**\n * Map environment variables to boolean flags indicating the current environment.\n * This function takes NODE_ENV and NODE_ENV_MODE variables and returns flags\n * indicating whether the current environment is development, staging, or production.\n *\n * @param env - The environment variables object containing NODE_ENV and NODE_ENV_MODE.\n * @returns An object containing boolean flags for the environment (IS_DEV, IS_STAG, IS_PROD).\n * @throws {Error} When NODE_ENV is production but NODE_ENV_MODE is development.\n */\nexport function mapEnvironment(env: I_NodeEnvInput): I_EnvFlags {\n const { NODE_ENV = E_Environment.DEVELOPMENT, NODE_ENV_MODE = E_Environment.DEVELOPMENT } = env;\n\n const IS_DEV = NODE_ENV === E_Environment.DEVELOPMENT && NODE_ENV_MODE === E_Environment.DEVELOPMENT;\n const IS_STAG = NODE_ENV === E_Environment.PRODUCTION && NODE_ENV_MODE === E_Environment.STAGING;\n const IS_PROD = NODE_ENV === E_Environment.PRODUCTION && NODE_ENV_MODE === E_Environment.PRODUCTION;\n\n if (NODE_ENV === E_Environment.PRODUCTION && NODE_ENV_MODE === E_Environment.DEVELOPMENT) {\n throw new Error('NODE_ENV_MODE must be set to staging or production in production environment');\n }\n\n return { IS_DEV, IS_STAG, IS_PROD };\n}\n\n/**\n * Checks if value is object-like (e.g., objects, arrays, etc.), not null.\n * Re-exported from util for general use across the codebase.\n *\n * @param value - The value to check.\n * @returns True if the value is an object and not null.\n */\nexport function isObject(value: unknown): value is object {\n return value != null && typeof value === 'object';\n}\n"],"mappings":";;AAIA,IAAM,IAAoC;CACtC,GAAG;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAI;CACxF,GAAG;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAI;CAC1D,GAAG;EAAC;EAAK;EAAK;EAAK;EAAK;EAAI;CAC5B,GAAG;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAI;CACxF,GAAG;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAI;CAC1D,GAAG;EAAC;EAAK;EAAK;EAAK;EAAK;EAAI;CAC5B,GAAG,CAAC,IAAI;CACX,EAEK,IAAyC,OAAO,QAAQ,EAAQ,CAAC,QAClE,GAAK,CAAC,GAAK,QACR,EAAI,EAAI,aAAa,IAAI,EAAM,KAAI,MAAQ,EAAK,aAAa,CAAC,EACvD,IAEX,EAAE,CACL,EAEK,IAAc;CAAE,GAAG;CAAS,GAAG;CAAc,EAI7C,oBAAiB,IAAI,KAAqB,EAC1C,oBAAe,IAAI,KAAa;AAEtC,OAAO,QAAQ,EAAY,CAAC,SAAS,CAAC,GAAU,OAAgB;CAG5D,IAAM,IAAc,IAAI,CAAC,GAAU,GAAG,EAAW,CAAC,KAAK,IAAI,CAAC;AAE5D,EAAC,GAAU,GAAG,EAAW,CAAC,SAAS,MAAS;AAExC,EADA,EAAe,IAAI,GAAM,EAAY,EACrC,EAAa,IAAI,EAAK;GACxB;EACJ;AAGF,IAAM,IAAgB,CAAC,GAAG,EAAa,CAAC,KAAK,GAAG,EAG1C,IAAkB,OAAO,IAAI,EAAc,IAAI,IAAI,EAEnD,IAAmB;AAUzB,SAAgB,EAAa,GAAqB;AAC9C,QAAO,EAAI,QAAQ,GAAkB,OAAO;;AAgBhD,SAAgB,EAAkB,GAAa;AAE3C,QADA,IAAM,EAAa,EAAI,EAChB,EAAI,QAAQ,IAAa,MAAS,EAAe,IAAI,EAAM,IAAI,EAAM;;AAGhF,IAAM,IAAe;AASrB,SAAgB,EAAa,GAAa;AACtC,QAAO,EAAI,UAAU,MAAM,CAAC,QAAQ,GAAc,GAAG;;AAYzD,SAAgB,EACZ,GACA,GACG;AACH,KAAI,CAAC,EACD,QAAO,CAAC,GAAG,IAAI,IAAI,EAAI,CAAC;CAG5B,IAAM,oBAAO,IAAI,KAAsB,EACjC,IAAc,EAAE;AAEtB,MAAK,IAAM,KAAQ,GAAK;EACpB,IAAM,IAAM,EAAM,EAAK;AACvB,EAAK,EAAK,IAAI,EAAI,KACd,EAAK,IAAI,EAAI,EACb,EAAO,KAAK,EAAK;;AAIzB,QAAO;;AAYX,SAAgB,EAAe,GAAiC;CAC5D,IAAM,EAAE,cAAW,EAAc,aAAa,mBAAgB,EAAc,gBAAgB,GAEtF,IAAS,MAAa,EAAc,eAAe,MAAkB,EAAc,aACnF,IAAU,MAAa,EAAc,cAAc,MAAkB,EAAc,SACnF,IAAU,MAAa,EAAc,cAAc,MAAkB,EAAc;AAEzF,KAAI,MAAa,EAAc,cAAc,MAAkB,EAAc,YACzE,OAAU,MAAM,+EAA+E;AAGnG,QAAO;EAAE;EAAQ;EAAS;EAAS;;AAUvC,SAAgB,EAAS,GAAiC;AACtD,QAAwB,OAAO,KAAU,cAAlC"}
1
+ {"version":3,"file":"common.util.js","names":[],"sources":["../../../src/util/common/common.util.ts"],"sourcesContent":["import { E_Environment } from '#typescript/index.js';\n\nimport type { I_EnvFlags, I_NodeEnvInput } from './common.type.js';\n\nconst charMap: Record<string, string[]> = {\n a: ['à', 'á', 'ạ', 'ả', 'ã', 'â', 'ầ', 'ấ', 'ậ', 'ẩ', 'ẫ', 'ă', 'ằ', 'ắ', 'ặ', 'ẳ', 'ẵ'],\n e: ['è', 'é', 'ẹ', 'ẻ', 'ẽ', 'ê', 'ề', 'ế', 'ệ', 'ể', 'ễ'],\n i: ['ì', 'í', 'ị', 'ỉ', 'ĩ'],\n o: ['ò', 'ó', 'ọ', 'ỏ', 'õ', 'ô', 'ồ', 'ố', 'ộ', 'ổ', 'ỗ', 'ơ', 'ờ', 'ớ', 'ợ', 'ở', 'ỡ'],\n u: ['ù', 'ú', 'ụ', 'ủ', 'ũ', 'ư', 'ừ', 'ứ', 'ự', 'ử', 'ữ'],\n y: ['ỳ', 'ý', 'ỵ', 'ỷ', 'ỹ'],\n d: ['đ'],\n};\n\nconst upperCharMap: Record<string, string[]> = Object.entries(charMap).reduce(\n (map, [key, value]) => {\n map[key.toUpperCase()] = value.map(char => char.toUpperCase());\n return map;\n },\n {} as Record<string, string[]>,\n);\n\nconst combinedMap = { ...charMap, ...upperCharMap };\n\n// Pre-compute replacement map and search regex for better performance\n// This avoids rebuilding regexes and maps on every function call\nconst replacementMap = new Map<string, string>();\nconst charsToMatch = new Set<string>();\n\nObject.entries(combinedMap).forEach(([baseChar, variations]) => {\n // The replacement pattern is the same for the base char and all its variations\n // Example: 'a', 'à', 'á'... all map to '(a|à|á...)'\n const replacement = `(${[baseChar, ...variations].join('|')})`;\n\n [baseChar, ...variations].forEach((char) => {\n replacementMap.set(char, replacement);\n charsToMatch.add(char);\n });\n});\n\n// Construct a single regex that matches any character in our map\nconst patternString = [...charsToMatch].join('');\n// We use a character class regex: [abc...]\n// eslint-disable-next-line regexp/no-empty-character-class -- regex is built dynamically from precomputed charMap\nconst searchRegex = new RegExp(`[${patternString}]`, 'g');\n\nconst RE_ESCAPE_REGEXP = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * Escapes special characters in a string for use in a regular expression.\n * This function escapes characters that have special meaning in regex (e.g., ., *, +, ?, etc.)\n * so they are treated as literal characters.\n *\n * @param str - The string to escape.\n * @returns The escaped string safe for use in a RegExp.\n */\nexport function escapeRegExp(str: string): string {\n return str.replace(RE_ESCAPE_REGEXP, '\\\\$&');\n}\n\n/**\n * Simple LRU cache for regex search patterns.\n * Avoids redundant accent alternation and regex compilation for repeated search terms.\n */\nconst regexPatternCache = new Map<string, string>();\nconst REGEX_CACHE_MAX_SIZE = 128;\n\n/**\n * Convert a string to a regex pattern that matches the string and its accented variations.\n * This function normalizes the input string and creates a regex pattern that can match\n * both the original characters and their accented equivalents.\n *\n * Optimization: Uses pre-computed regex and map to perform replacement in a single pass (O(N)),\n * instead of iterating through all character groups (O(K*N)).\n * Results are cached in an LRU cache (max 128 entries) to avoid redundant computation\n * for repeated search terms.\n *\n * @param str - The string to convert to a regex pattern.\n * @returns The regex pattern as a string that matches the original string and its accented variations.\n */\nexport function regexSearchMapper(str: string) {\n const cached = regexPatternCache.get(str);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const escaped = escapeRegExp(str);\n const result = escaped.replace(searchRegex, match => replacementMap.get(match) || match);\n\n // Evict oldest entry if cache is full\n if (regexPatternCache.size >= REGEX_CACHE_MAX_SIZE) {\n const oldestKey = regexPatternCache.keys().next().value;\n if (oldestKey !== undefined) {\n regexPatternCache.delete(oldestKey);\n }\n }\n\n regexPatternCache.set(str, result);\n return result;\n}\n\nconst RE_DIACRITIC = /\\p{Diacritic}/gu;\n\n/**\n * Remove accents from a string.\n * This function normalizes the string using NFD normalization and removes all diacritical marks.\n *\n * @param str - The string to remove accents from.\n * @returns The string without any accents or diacritical marks.\n */\nexport function removeAccent(str: string) {\n return str.normalize('NFD').replace(RE_DIACRITIC, '');\n}\n\n/**\n * Remove duplicates from an array based on a key function.\n * This function can remove duplicates either by comparing values directly (when no keyFn is provided)\n * or by using a custom key function to determine uniqueness.\n *\n * @param arr - The array to remove duplicates from.\n * @param keyFn - Optional function that returns a unique key for each item in the array.\n * @returns A new array with duplicates removed, maintaining the original order.\n */\nexport function uniqueArray<T>(\n arr: T[],\n keyFn?: (item: T) => string | number,\n): T[] {\n if (!keyFn) {\n return [...new Set(arr)];\n }\n\n const seen = new Set<string | number>();\n const result: T[] = [];\n\n for (const item of arr) {\n const key = keyFn(item);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(item);\n }\n }\n\n return result;\n}\n\n/**\n * Map environment variables to boolean flags indicating the current environment.\n * This function takes NODE_ENV and NODE_ENV_MODE variables and returns flags\n * indicating whether the current environment is development, staging, or production.\n *\n * @param env - The environment variables object containing NODE_ENV and NODE_ENV_MODE.\n * @returns An object containing boolean flags for the environment (IS_DEV, IS_STAG, IS_PROD).\n * @throws {Error} When NODE_ENV is production but NODE_ENV_MODE is development.\n */\nexport function mapEnvironment(env: I_NodeEnvInput): I_EnvFlags {\n const { NODE_ENV = E_Environment.DEVELOPMENT, NODE_ENV_MODE = E_Environment.DEVELOPMENT } = env;\n\n const IS_DEV = NODE_ENV === E_Environment.DEVELOPMENT && NODE_ENV_MODE === E_Environment.DEVELOPMENT;\n const IS_STAG = NODE_ENV === E_Environment.PRODUCTION && NODE_ENV_MODE === E_Environment.STAGING;\n const IS_PROD = NODE_ENV === E_Environment.PRODUCTION && NODE_ENV_MODE === E_Environment.PRODUCTION;\n\n if (NODE_ENV === E_Environment.PRODUCTION && NODE_ENV_MODE === E_Environment.DEVELOPMENT) {\n throw new Error('NODE_ENV_MODE must be set to staging or production in production environment');\n }\n\n return { IS_DEV, IS_STAG, IS_PROD };\n}\n\n/**\n * Checks if value is object-like (e.g., objects, arrays, etc.), not null.\n * Re-exported from util for general use across the codebase.\n *\n * @remarks\n * Returns `true` for arrays, Dates, Maps, Sets, and class instances.\n * Use {@link isPlainObject} when you specifically need to check for plain objects only.\n *\n * @param value - The value to check.\n * @returns True if the value is an object and not null.\n */\nexport function isObject(value: unknown): value is object {\n return value != null && typeof value === 'object';\n}\n\n/**\n * Checks if a value is a plain object (created by `{}`, `Object.create(null)`, or `new Object()`).\n * Unlike {@link isObject}, this returns `false` for arrays, Dates, Maps, Sets, RegExps,\n * and other class instances.\n *\n * @param value - The value to check.\n * @returns True if the value is a plain object, false otherwise.\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value == null || typeof value !== 'object') {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n\n return proto === Object.prototype || proto === null;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { escapeRegExp as e, isObject as t, mapEnvironment as n, regexSearchMapper as r, removeAccent as i, uniqueArray as a } from "./common.util.js";
2
- export { e as escapeRegExp, t as isObject, n as mapEnvironment, r as regexSearchMapper, i as removeAccent, a as uniqueArray };
1
+ import { escapeRegExp as e, isObject as t, isPlainObject as n, mapEnvironment as r, regexSearchMapper as i, removeAccent as a, uniqueArray as o } from "./common.util.js";
2
+ export { e as escapeRegExp, t as isObject, n as isPlainObject, r as mapEnvironment, i as regexSearchMapper, a as removeAccent, o as uniqueArray };
@@ -1,7 +1,7 @@
1
- import { escapeRegExp as e, isObject as t, mapEnvironment as n, regexSearchMapper as r, removeAccent as i, uniqueArray as a } from "./common/common.util.js";
2
- import { baseCatchError as o } from "./log/log.util.js";
3
- import { deepClone as s, deepMerge as c, getNestedValue as l, isJSON as u, normalizeMongoFilter as d, setNestedValue as f } from "./object/object.util.js";
4
- import { serializer as p } from "./serializer/serializer.util.js";
5
- import { generateRandomPassword as m, generateRandomString as h, generateShortId as g, generateSlug as _, getFileName as v, substringBetween as y } from "./string/string.util.js";
6
- import { validate as b } from "./validate/validate.util.js";
7
- export { o as baseCatchError, s as deepClone, c as deepMerge, e as escapeRegExp, m as generateRandomPassword, h as generateRandomString, g as generateShortId, _ as generateSlug, v as getFileName, l as getNestedValue, u as isJSON, t as isObject, n as mapEnvironment, d as normalizeMongoFilter, r as regexSearchMapper, i as removeAccent, p as serializer, f as setNestedValue, y as substringBetween, a as uniqueArray, b as validate };
1
+ import { escapeRegExp as e, isObject as t, isPlainObject as n, mapEnvironment as r, regexSearchMapper as i, removeAccent as a, uniqueArray as o } from "./common/common.util.js";
2
+ import { baseCatchError as s } from "./log/log.util.js";
3
+ import { deepClone as c, deepMerge as l, getNestedValue as u, isJSON as d, normalizeMongoFilter as f, setNestedValue as p } from "./object/object.util.js";
4
+ import { serializer as m } from "./serializer/serializer.util.js";
5
+ import { generateRandomPassword as h, generateRandomString as g, generateShortId as _, generateSlug as v, getFileName as y, substringBetween as b } from "./string/string.util.js";
6
+ import { validate as x } from "./validate/validate.util.js";
7
+ export { s as baseCatchError, c as deepClone, l as deepMerge, e as escapeRegExp, h as generateRandomPassword, g as generateRandomString, _ as generateShortId, v as generateSlug, y as getFileName, u as getNestedValue, d as isJSON, t as isObject, n as isPlainObject, r as mapEnvironment, f as normalizeMongoFilter, i as regexSearchMapper, a as removeAccent, m as serializer, p as setNestedValue, b as substringBetween, o as uniqueArray, x as validate };
@@ -32,11 +32,15 @@ export declare function setNestedValue<T>(obj: T, path: (string | number)[], val
32
32
  * Deep clones an object or array.
33
33
  * This function creates a deep copy of the input, recursively cloning objects and arrays.
34
34
  * Primitive values, dates, and other non-plain objects are returned as is (or cloned if supported).
35
- * Note: This implementation focuses on plain objects and arrays. For complex types like Map/Set/Buffer/ObjectId,
36
- * it returns the reference or handles them according to specific logic.
35
+ *
36
+ * @remarks
37
+ * **Non-POJO objects are NOT cloned.** Objects with custom prototypes (e.g., Mongoose ObjectId,
38
+ * class instances, Map, Set, Buffer) are returned **by reference** to preserve driver
39
+ * compatibility. Mutations to these nested references will affect the original.
40
+ * If you need full deep cloning of complex types, use `structuredClone()` or a dedicated library.
37
41
  *
38
42
  * @param obj - The object to clone.
39
- * @returns A deep copy of the object.
43
+ * @returns A deep copy of the object (with non-POJO objects returned by reference).
40
44
  */
41
45
  export declare function deepClone<T>(obj: T): T;
42
46
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"object.util.js","names":[],"sources":["../../../src/util/object/object.util.ts"],"sourcesContent":["/**\n * Check if a string is a valid JSON string.\n * This function attempts to parse the string as JSON and returns true if successful,\n * false if the string is not valid JSON.\n *\n * @param str - The string to check for valid JSON format.\n * @returns True if the string is a valid JSON string, false otherwise.\n */\nexport function isJSON(str: string): boolean {\n try {\n JSON.parse(str);\n return true;\n }\n catch {\n return false;\n }\n}\n\n/**\n * Gets a nested value from an object using a path array.\n * This function traverses the object following the provided path and returns\n * the value at the specified location, or undefined if the path doesn't exist.\n *\n * @param obj - The object to get the value from.\n * @param path - An array of keys representing the path to the desired value.\n * @returns The value at the specified path, or undefined if the path doesn't exist.\n */\nexport function getNestedValue<T>(obj: T, path: (string | number)[]): unknown {\n // Optimization: Loop is faster than reduce and allows early exit\n let current: unknown = obj;\n const len = path.length;\n\n for (let i = 0; i < len; i++) {\n // Optimization: Early return if current value is null/undefined or not an object\n // This avoids unnecessary key lookups and type checks\n if (current == null || typeof current !== 'object') {\n return undefined;\n }\n\n const key = path[i];\n\n if (key !== undefined && key in (current as Record<string | number, unknown>)) {\n current = (current as Record<string | number, unknown>)[key];\n }\n else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Recursively sets a value at a nested path within an object, creating intermediate objects as needed.\n *\n * @param obj - The source object.\n * @param path - Array of keys forming the path.\n * @param value - The value to set.\n * @param index - Current recursion depth.\n * @returns A new object with the value set at the specified path.\n */\nfunction setNestedValueHelper<T>(obj: T, path: (string | number)[], value: unknown, index: number): T {\n if (index >= path.length)\n return obj;\n\n const head = path[index];\n\n if (index === path.length - 1) {\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number]: value,\n } as T;\n }\n\n const current = (obj as Record<string | number, unknown>)[head as string | number];\n\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number | symbol]: setNestedValueHelper(\n typeof current === 'object' && current !== null\n ? (current as object)\n : {},\n path,\n value,\n index + 1,\n ),\n } as T;\n}\n\n/**\n * Sets a nested value in an object using a path array.\n * This function creates the path if it doesn't exist and sets the value at the specified location.\n * The function returns a new object with the updated value, maintaining immutability.\n *\n * @param obj - The object to set the value in.\n * @param path - An array of keys representing the path to the desired location.\n * @param value - The value to set at the specified path.\n * @returns A new object with the updated value at the specified path.\n */\nexport function setNestedValue<T>(obj: T, path: (string | number)[], value: unknown): T {\n if (path.length === 0)\n return obj;\n\n return setNestedValueHelper(obj, path, value, 0);\n}\n\n/**\n * Deep clones an object or array.\n * This function creates a deep copy of the input, recursively cloning objects and arrays.\n * Primitive values, dates, and other non-plain objects are returned as is (or cloned if supported).\n * Note: This implementation focuses on plain objects and arrays. For complex types like Map/Set/Buffer/ObjectId,\n * it returns the reference or handles them according to specific logic.\n *\n * @param obj - The object to clone.\n * @returns A deep copy of the object.\n */\nexport function deepClone<T>(obj: T): T {\n return deepCloneInternal(obj, new WeakSet<object>());\n}\n\n/**\n * Internal recursive implementation of deepClone with circular reference detection.\n *\n * @param obj - The value to clone.\n * @param seen - A WeakSet tracking already-visited objects to prevent infinite recursion.\n * @returns A deep copy of the value.\n */\nfunction deepCloneInternal<T>(obj: T, seen: WeakSet<object>): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (seen.has(obj as object)) {\n throw new Error('deepClone: Circular reference detected.');\n }\n seen.add(obj as object);\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as unknown as T;\n }\n\n if (Array.isArray(obj)) {\n // Optimization: `new Array(len)` + `for` loop is ~10-15% faster than `Array.map` or `Array.from`\n // for large arrays since it avoids callback overhead and pre-allocates memory.\n const len = obj.length;\n // eslint-disable-next-line unicorn/no-new-array -- Pre-allocating array size for performance\n const arr = new Array(len);\n for (let i = 0; i < len; i++) {\n arr[i] = deepCloneInternal(obj[i], seen);\n }\n return arr as unknown as T;\n }\n\n // Handle Mongoose ObjectId and other custom classes by returning reference.\n // structuredClone is not used here because it silently corrupts nested non-POJO\n // types (e.g., ObjectId → plain object) and Date instances in jsdom environments.\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) {\n return obj;\n }\n\n const result = {} as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n result[key] = deepCloneInternal((obj as Record<string, unknown>)[key], seen);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep merges multiple objects into a single object.\n * @param args - The objects to merge. Can be empty, in which case returns an empty object.\n * @returns The merged object.\n */\nexport function deepMerge<T = Record<string, unknown>>(\n ...args: (object | null | undefined)[]\n): T;\n\n/**\n * Deep merges multiple arrays into a single array.\n * @param args - The arrays to merge. Can be empty, in which case returns an empty array.\n * @returns The merged array.\n */\nexport function deepMerge<T = unknown[]>(\n ...args: (unknown[] | null | undefined)[]\n): T;\n\n/**\n * Implementation of deepMerge function.\n * @param args - The objects or arrays to merge.\n * @returns The merged result.\n */\nexport function deepMerge<T = Record<string, unknown> | unknown[]>(\n ...args: (object | unknown[] | null | undefined)[]\n): T {\n const MAX_DEPTH = 20;\n\n /** Recursively merges an array of objects with depth and circular-reference tracking. */\n function mergeRecursive(\n validArgs: object[],\n depth: number,\n seen: WeakSet<object>,\n ): unknown {\n // Depth guard\n if (depth > MAX_DEPTH) {\n throw new Error(`deepMerge: Maximum depth of ${MAX_DEPTH} exceeded. Possible circular reference or excessively nested objects.`);\n }\n\n // Handle empty arguments\n if (validArgs.length === 0) {\n return {};\n }\n\n // If only one argument, return it directly\n if (validArgs.length === 1) {\n return validArgs[0];\n }\n\n // Check if all arguments are arrays\n if (validArgs.every(Array.isArray)) {\n return (validArgs as unknown[][]).flat();\n }\n\n // Check if all arguments are objects (but not arrays)\n if (validArgs.every(arg => typeof arg === 'object' && arg !== null && !Array.isArray(arg))) {\n const result = {} as Record<string, unknown>;\n\n for (const arg of validArgs) {\n // Circular reference protection (per-arg scope prevents false\n // positives when the same object appears in multiple branches)\n if (seen.has(arg)) {\n throw new Error('deepMerge: Circular reference detected.');\n }\n\n const obj = arg as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n const value = obj[key];\n if (Object.hasOwn(result, key)) {\n const existingValue = result[key];\n if (\n typeof value === 'object' && value !== null\n && typeof existingValue === 'object' && existingValue !== null\n ) {\n if (Array.isArray(value) && Array.isArray(existingValue)) {\n result[key] = [...existingValue, ...value];\n }\n else if (!Array.isArray(value) && !Array.isArray(existingValue)) {\n result[key] = mergeRecursive(\n [existingValue as Record<string, unknown>, value as Record<string, unknown>],\n depth + 1,\n new WeakSet<object>(),\n );\n }\n else {\n // One is array, other is object — overwrite\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n }\n }\n return result;\n }\n\n // Check if all arguments are primitive values\n if (validArgs.every(arg => typeof arg !== 'object' || arg === null)) {\n throw new Error(\n 'deepMerge: Cannot merge primitive values. All arguments must be objects or arrays.',\n );\n }\n\n // Mixed types error\n const hasArrays = validArgs.some(Array.isArray);\n const hasObjects = validArgs.some(arg =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg),\n );\n\n if (hasArrays && hasObjects) {\n throw new Error(\n 'deepMerge: Cannot mix arrays and objects. All arguments must be either arrays or objects.',\n );\n }\n\n // Fallback for unexpected cases\n throw new Error(\n 'deepMerge: Invalid arguments provided. All arguments must be objects or arrays of the same type.',\n );\n }\n\n // Filter out null/undefined\n const validArgs = args.filter((arg): arg is object => arg !== null && arg !== undefined);\n\n return mergeRecursive(validArgs, 0, new WeakSet<object>()) as T;\n}\n\n/**\n * Normalizes MongoDB filters to support both dot notation strings and nested objects.\n * This function converts nested object filters to dot notation format while preserving\n * MongoDB operators to ensure consistent behavior across different filter input formats.\n *\n * @param filter - The filter object to normalize.\n * @returns A normalized filter object with nested objects converted to dot notation,\n * while preserving MongoDB operators as nested objects.\n *\n * @example\n * ```typescript\n * // Both of these will work the same way:\n * normalizeMongoFilter({ \"location.countryId\": \"240\" })\n * normalizeMongoFilter({ location: { countryId: \"240\" } })\n * // Both return: { \"location.countryId\": \"240\" }\n *\n * // MongoDB operators are preserved:\n * normalizeMongoFilter({ id: { $in: [\"240\", \"59\"] } })\n * // Returns: { id: { $in: [\"240\", \"59\"] } }\n * ```\n */\nexport function normalizeMongoFilter<T extends Record<string, unknown>>(filter: T): T {\n if (!filter || typeof filter !== 'object') {\n return filter;\n }\n\n const normalized: Record<string, unknown> = {};\n\n /**\n * Recursively flattens nested objects into dot-notation keys, preserving MongoDB operators.\n */\n function flatten(current: Record<string, unknown>, prefix: string) {\n for (const key in current) {\n if (!Object.hasOwn(current, key))\n continue;\n\n const value = current[key];\n const newKey = prefix ? `${prefix}.${key}` : key;\n\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n // Fast-path POJO check: `.constructor` is safe even on null-prototype objects\n // (returns undefined, so the === Object check simply fails and falls through\n // to the getPrototypeOf check which correctly identifies it as a POJO).\n const isPojo = (value as object).constructor === Object\n || Object.getPrototypeOf(value) === null;\n\n if (!isPojo) {\n normalized[newKey] = value;\n continue;\n }\n\n // Check for Mongo operator\n let hasMongoOperator = false;\n for (const subKey in value as Record<string, unknown>) {\n if (Object.hasOwn(value, subKey) && subKey.startsWith('$')) {\n hasMongoOperator = true;\n break;\n }\n }\n\n if (hasMongoOperator) {\n normalized[newKey] = value;\n }\n else {\n flatten(value as Record<string, unknown>, newKey);\n }\n }\n else {\n normalized[newKey] = value;\n }\n }\n }\n\n flatten(filter, '');\n\n return normalized as T;\n}\n"],"mappings":";AAQA,SAAgB,EAAO,GAAsB;AACzC,KAAI;AAEA,SADA,KAAK,MAAM,EAAI,EACR;SAEL;AACF,SAAO;;;AAaf,SAAgB,EAAkB,GAAQ,GAAoC;CAE1E,IAAI,IAAmB,GACjB,IAAM,EAAK;AAEjB,MAAK,IAAI,IAAI,GAAG,IAAI,GAAK,KAAK;AAG1B,MAAuB,OAAO,KAAY,aAAtC,EACA;EAGJ,IAAM,IAAM,EAAK;AAEjB,MAAI,MAAQ,KAAA,KAAa,KAAQ,EAC7B,KAAW,EAA6C;MAGxD;;AAIR,QAAO;;AAYX,SAAS,EAAwB,GAAQ,GAA2B,GAAgB,GAAkB;AAClG,KAAI,KAAS,EAAK,OACd,QAAO;CAEX,IAAM,IAAO,EAAK;AAElB,KAAI,MAAU,EAAK,SAAS,EACxB,QAAO;EACH,GAAI;GACH,IAA0B;EAC9B;CAGL,IAAM,IAAW,EAAyC;AAE1D,QAAO;EACH,GAAI;GACH,IAAmC,EAChC,OAAO,KAAY,YAAY,IACxB,IACD,EAAE,EACR,GACA,GACA,IAAQ,EACX;EACJ;;AAaL,SAAgB,EAAkB,GAAQ,GAA2B,GAAmB;AAIpF,QAHI,EAAK,WAAW,IACT,IAEJ,EAAqB,GAAK,GAAM,GAAO,EAAE;;AAapD,SAAgB,EAAa,GAAW;AACpC,QAAO,EAAkB,mBAAK,IAAI,SAAiB,CAAC;;AAUxD,SAAS,EAAqB,GAAQ,GAA0B;AAC5D,KAAoB,OAAO,KAAQ,aAA/B,EACA,QAAO;AAGX,KAAI,EAAK,IAAI,EAAc,CACvB,OAAU,MAAM,0CAA0C;AAI9D,KAFA,EAAK,IAAI,EAAc,EAEnB,aAAe,KACf,QAAO,IAAI,KAAK,EAAI,SAAS,CAAC;AAGlC,KAAI,aAAe,OACf,QAAO,IAAI,OAAO,EAAI,QAAQ,EAAI,MAAM;AAG5C,KAAI,MAAM,QAAQ,EAAI,EAAE;EAGpB,IAAM,IAAM,EAAI,QAEV,IAAU,MAAM,EAAI;AAC1B,OAAK,IAAI,IAAI,GAAG,IAAI,GAAK,IACrB,GAAI,KAAK,EAAkB,EAAI,IAAI,EAAK;AAE5C,SAAO;;CAMX,IAAM,IAAQ,OAAO,eAAe,EAAI;AACxC,KAAI,MAAU,OAAO,aAAa,MAAU,KACxC,QAAO;CAGX,IAAM,IAAS,EAAE;AACjB,MAAK,IAAM,KAAO,EACd,CAAI,OAAO,OAAO,GAAK,EAAI,KACvB,EAAO,KAAO,EAAmB,EAAgC,IAAM,EAAK;AAIpF,QAAO;;AA0BX,SAAgB,EACZ,GAAG,GACF;CAID,SAAS,EACL,GACA,GACA,GACO;AAEP,MAAI,IAAQ,GACR,OAAU,MAAM,sGAAgH;AAIpI,MAAI,EAAU,WAAW,EACrB,QAAO,EAAE;AAIb,MAAI,EAAU,WAAW,EACrB,QAAO,EAAU;AAIrB,MAAI,EAAU,MAAM,MAAM,QAAQ,CAC9B,QAAQ,EAA0B,MAAM;AAI5C,MAAI,EAAU,OAAM,MAAO,OAAO,KAAQ,cAAY,KAAgB,CAAC,MAAM,QAAQ,EAAI,CAAC,EAAE;GACxF,IAAM,IAAS,EAAE;AAEjB,QAAK,IAAM,KAAO,GAAW;AAGzB,QAAI,EAAK,IAAI,EAAI,CACb,OAAU,MAAM,0CAA0C;IAG9D,IAAM,IAAM;AACZ,SAAK,IAAM,KAAO,EACd,KAAI,OAAO,OAAO,GAAK,EAAI,EAAE;KACzB,IAAM,IAAQ,EAAI;AAClB,SAAI,OAAO,OAAO,GAAQ,EAAI,EAAE;MAC5B,IAAM,IAAgB,EAAO;AAC7B,MACI,OAAO,KAAU,YAAY,KAC1B,OAAO,KAAkB,YAAY,IAEpC,MAAM,QAAQ,EAAM,IAAI,MAAM,QAAQ,EAAc,GACpD,EAAO,KAAO,CAAC,GAAG,GAAe,GAAG,EAAM,GAErC,CAAC,MAAM,QAAQ,EAAM,IAAI,CAAC,MAAM,QAAQ,EAAc,GAC3D,EAAO,KAAO,EACV,CAAC,GAA0C,EAAiC,EAC5E,IAAQ,mBACR,IAAI,SAAiB,CACxB,GAID,EAAO,KAAO,IAIlB,EAAO,KAAO;WAIlB,GAAO,KAAO;;;AAK9B,UAAO;;AAIX,MAAI,EAAU,OAAM,MAAO,OAAO,KAAQ,aAAY,EAAa,CAC/D,OAAU,MACN,qFACH;EAIL,IAAM,IAAY,EAAU,KAAK,MAAM,QAAQ,EACzC,IAAa,EAAU,MAAK,MAC9B,OAAO,KAAQ,cAAY,KAAgB,CAAC,MAAM,QAAQ,EAAI,CACjE;AASD,QANc,MADV,KAAa,IAET,8FAMJ,mGALC;;AAYT,QAAO,EAFW,EAAK,QAAQ,MAAuB,KAAQ,KAA0B,EAEvD,mBAAG,IAAI,SAAiB,CAAC;;AAwB9D,SAAgB,EAAwD,GAAc;AAClF,KAAI,CAAC,KAAU,OAAO,KAAW,SAC7B,QAAO;CAGX,IAAM,IAAsC,EAAE;CAK9C,SAAS,EAAQ,GAAkC,GAAgB;AAC/D,OAAK,IAAM,KAAO,GAAS;AACvB,OAAI,CAAC,OAAO,OAAO,GAAS,EAAI,CAC5B;GAEJ,IAAM,IAAQ,EAAQ,IAChB,IAAS,IAAS,GAAG,EAAO,GAAG,MAAQ;AAE7C,OAAI,KAAS,OAAO,KAAU,YAAY,CAAC,MAAM,QAAQ,EAAM,EAAE;AAO7D,QAAI,EAHY,EAAiB,gBAAgB,UAC1C,OAAO,eAAe,EAAM,KAAK,OAE3B;AACT,OAAW,KAAU;AACrB;;IAIJ,IAAI,IAAmB;AACvB,SAAK,IAAM,KAAU,EACjB,KAAI,OAAO,OAAO,GAAO,EAAO,IAAI,EAAO,WAAW,IAAI,EAAE;AACxD,SAAmB;AACnB;;AAIR,IAAI,IACA,EAAW,KAAU,IAGrB,EAAQ,GAAkC,EAAO;SAIrD,GAAW,KAAU;;;AAOjC,QAFA,EAAQ,GAAQ,GAAG,EAEZ"}
1
+ {"version":3,"file":"object.util.js","names":[],"sources":["../../../src/util/object/object.util.ts"],"sourcesContent":["/**\n * Check if a string is a valid JSON string.\n * This function attempts to parse the string as JSON and returns true if successful,\n * false if the string is not valid JSON.\n *\n * @param str - The string to check for valid JSON format.\n * @returns True if the string is a valid JSON string, false otherwise.\n */\nexport function isJSON(str: string): boolean {\n try {\n JSON.parse(str);\n return true;\n }\n catch {\n return false;\n }\n}\n\n/**\n * Gets a nested value from an object using a path array.\n * This function traverses the object following the provided path and returns\n * the value at the specified location, or undefined if the path doesn't exist.\n *\n * @param obj - The object to get the value from.\n * @param path - An array of keys representing the path to the desired value.\n * @returns The value at the specified path, or undefined if the path doesn't exist.\n */\nexport function getNestedValue<T>(obj: T, path: (string | number)[]): unknown {\n // Optimization: Loop is faster than reduce and allows early exit\n let current: unknown = obj;\n const len = path.length;\n\n for (let i = 0; i < len; i++) {\n // Optimization: Early return if current value is null/undefined or not an object\n // This avoids unnecessary key lookups and type checks\n if (current == null || typeof current !== 'object') {\n return undefined;\n }\n\n const key = path[i];\n\n if (key !== undefined && key in (current as Record<string | number, unknown>)) {\n current = (current as Record<string | number, unknown>)[key];\n }\n else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Recursively sets a value at a nested path within an object, creating intermediate objects as needed.\n *\n * @param obj - The source object.\n * @param path - Array of keys forming the path.\n * @param value - The value to set.\n * @param index - Current recursion depth.\n * @returns A new object with the value set at the specified path.\n */\nfunction setNestedValueHelper<T>(obj: T, path: (string | number)[], value: unknown, index: number): T {\n if (index >= path.length)\n return obj;\n\n const head = path[index];\n\n if (index === path.length - 1) {\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number]: value,\n } as T;\n }\n\n const current = (obj as Record<string | number, unknown>)[head as string | number];\n\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number | symbol]: setNestedValueHelper(\n typeof current === 'object' && current !== null\n ? (current as object)\n : {},\n path,\n value,\n index + 1,\n ),\n } as T;\n}\n\n/**\n * Sets a nested value in an object using a path array.\n * This function creates the path if it doesn't exist and sets the value at the specified location.\n * The function returns a new object with the updated value, maintaining immutability.\n *\n * @param obj - The object to set the value in.\n * @param path - An array of keys representing the path to the desired location.\n * @param value - The value to set at the specified path.\n * @returns A new object with the updated value at the specified path.\n */\nexport function setNestedValue<T>(obj: T, path: (string | number)[], value: unknown): T {\n if (path.length === 0)\n return obj;\n\n return setNestedValueHelper(obj, path, value, 0);\n}\n\n/**\n * Deep clones an object or array.\n * This function creates a deep copy of the input, recursively cloning objects and arrays.\n * Primitive values, dates, and other non-plain objects are returned as is (or cloned if supported).\n *\n * @remarks\n * **Non-POJO objects are NOT cloned.** Objects with custom prototypes (e.g., Mongoose ObjectId,\n * class instances, Map, Set, Buffer) are returned **by reference** to preserve driver\n * compatibility. Mutations to these nested references will affect the original.\n * If you need full deep cloning of complex types, use `structuredClone()` or a dedicated library.\n *\n * @param obj - The object to clone.\n * @returns A deep copy of the object (with non-POJO objects returned by reference).\n */\nexport function deepClone<T>(obj: T): T {\n return deepCloneInternal(obj, new WeakSet<object>());\n}\n\n/**\n * Internal recursive implementation of deepClone with circular reference detection.\n *\n * @param obj - The value to clone.\n * @param seen - A WeakSet tracking already-visited objects to prevent infinite recursion.\n * @returns A deep copy of the value.\n */\nfunction deepCloneInternal<T>(obj: T, seen: WeakSet<object>): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (seen.has(obj as object)) {\n throw new Error('deepClone: Circular reference detected.');\n }\n seen.add(obj as object);\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as unknown as T;\n }\n\n if (Array.isArray(obj)) {\n // Optimization: `new Array(len)` + `for` loop is ~10-15% faster than `Array.map` or `Array.from`\n // for large arrays since it avoids callback overhead and pre-allocates memory.\n const len = obj.length;\n // eslint-disable-next-line unicorn/no-new-array -- Pre-allocating array size for performance\n const arr = new Array(len);\n for (let i = 0; i < len; i++) {\n arr[i] = deepCloneInternal(obj[i], seen);\n }\n return arr as unknown as T;\n }\n\n // Handle Mongoose ObjectId and other custom classes by returning reference.\n // structuredClone is not used here because it silently corrupts nested non-POJO\n // types (e.g., ObjectId → plain object) and Date instances in jsdom environments.\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) {\n return obj;\n }\n\n const result = {} as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n result[key] = deepCloneInternal((obj as Record<string, unknown>)[key], seen);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep merges multiple objects into a single object.\n * @param args - The objects to merge. Can be empty, in which case returns an empty object.\n * @returns The merged object.\n */\nexport function deepMerge<T = Record<string, unknown>>(\n ...args: (object | null | undefined)[]\n): T;\n\n/**\n * Deep merges multiple arrays into a single array.\n * @param args - The arrays to merge. Can be empty, in which case returns an empty array.\n * @returns The merged array.\n */\nexport function deepMerge<T = unknown[]>(\n ...args: (unknown[] | null | undefined)[]\n): T;\n\n/**\n * Implementation of deepMerge function.\n * @param args - The objects or arrays to merge.\n * @returns The merged result.\n */\nexport function deepMerge<T = Record<string, unknown> | unknown[]>(\n ...args: (object | unknown[] | null | undefined)[]\n): T {\n const MAX_DEPTH = 20;\n\n /** Recursively merges an array of objects with depth and circular-reference tracking. */\n function mergeRecursive(\n validArgs: object[],\n depth: number,\n seen: WeakSet<object>,\n ): unknown {\n // Depth guard\n if (depth > MAX_DEPTH) {\n throw new Error(`deepMerge: Maximum depth of ${MAX_DEPTH} exceeded. Possible circular reference or excessively nested objects.`);\n }\n\n // Handle empty arguments\n if (validArgs.length === 0) {\n return {};\n }\n\n // If only one argument, return it directly\n if (validArgs.length === 1) {\n return validArgs[0];\n }\n\n // Check if all arguments are arrays\n if (validArgs.every(Array.isArray)) {\n return (validArgs as unknown[][]).flat();\n }\n\n // Check if all arguments are objects (but not arrays)\n if (validArgs.every(arg => typeof arg === 'object' && arg !== null && !Array.isArray(arg))) {\n const result = {} as Record<string, unknown>;\n\n for (const arg of validArgs) {\n // Circular reference protection (per-arg scope prevents false\n // positives when the same object appears in multiple branches)\n if (seen.has(arg)) {\n throw new Error('deepMerge: Circular reference detected.');\n }\n\n const obj = arg as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n const value = obj[key];\n if (Object.hasOwn(result, key)) {\n const existingValue = result[key];\n if (\n typeof value === 'object' && value !== null\n && typeof existingValue === 'object' && existingValue !== null\n ) {\n if (Array.isArray(value) && Array.isArray(existingValue)) {\n result[key] = [...existingValue, ...value];\n }\n else if (!Array.isArray(value) && !Array.isArray(existingValue)) {\n result[key] = mergeRecursive(\n [existingValue as Record<string, unknown>, value as Record<string, unknown>],\n depth + 1,\n new WeakSet<object>(),\n );\n }\n else {\n // One is array, other is object — overwrite\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n }\n }\n return result;\n }\n\n // Check if all arguments are primitive values\n if (validArgs.every(arg => typeof arg !== 'object' || arg === null)) {\n throw new Error(\n 'deepMerge: Cannot merge primitive values. All arguments must be objects or arrays.',\n );\n }\n\n // Mixed types error\n const hasArrays = validArgs.some(Array.isArray);\n const hasObjects = validArgs.some(arg =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg),\n );\n\n if (hasArrays && hasObjects) {\n throw new Error(\n 'deepMerge: Cannot mix arrays and objects. All arguments must be either arrays or objects.',\n );\n }\n\n // Fallback for unexpected cases\n throw new Error(\n 'deepMerge: Invalid arguments provided. All arguments must be objects or arrays of the same type.',\n );\n }\n\n // Filter out null/undefined\n const validArgs = args.filter((arg): arg is object => arg !== null && arg !== undefined);\n\n return mergeRecursive(validArgs, 0, new WeakSet<object>()) as T;\n}\n\n/**\n * Normalizes MongoDB filters to support both dot notation strings and nested objects.\n * This function converts nested object filters to dot notation format while preserving\n * MongoDB operators to ensure consistent behavior across different filter input formats.\n *\n * @param filter - The filter object to normalize.\n * @returns A normalized filter object with nested objects converted to dot notation,\n * while preserving MongoDB operators as nested objects.\n *\n * @example\n * ```typescript\n * // Both of these will work the same way:\n * normalizeMongoFilter({ \"location.countryId\": \"240\" })\n * normalizeMongoFilter({ location: { countryId: \"240\" } })\n * // Both return: { \"location.countryId\": \"240\" }\n *\n * // MongoDB operators are preserved:\n * normalizeMongoFilter({ id: { $in: [\"240\", \"59\"] } })\n * // Returns: { id: { $in: [\"240\", \"59\"] } }\n * ```\n */\nexport function normalizeMongoFilter<T extends Record<string, unknown>>(filter: T): T {\n if (!filter || typeof filter !== 'object') {\n return filter;\n }\n\n const normalized: Record<string, unknown> = {};\n\n /**\n * Recursively flattens nested objects into dot-notation keys, preserving MongoDB operators.\n */\n function flatten(current: Record<string, unknown>, prefix: string) {\n for (const key in current) {\n if (!Object.hasOwn(current, key))\n continue;\n\n const value = current[key];\n const newKey = prefix ? `${prefix}.${key}` : key;\n\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n // Fast-path POJO check: `.constructor` is safe even on null-prototype objects\n // (returns undefined, so the === Object check simply fails and falls through\n // to the getPrototypeOf check which correctly identifies it as a POJO).\n const isPojo = (value as object).constructor === Object\n || Object.getPrototypeOf(value) === null;\n\n if (!isPojo) {\n normalized[newKey] = value;\n continue;\n }\n\n // Check for Mongo operator\n let hasMongoOperator = false;\n for (const subKey in value as Record<string, unknown>) {\n if (Object.hasOwn(value, subKey) && subKey.startsWith('$')) {\n hasMongoOperator = true;\n break;\n }\n }\n\n if (hasMongoOperator) {\n normalized[newKey] = value;\n }\n else {\n flatten(value as Record<string, unknown>, newKey);\n }\n }\n else {\n normalized[newKey] = value;\n }\n }\n }\n\n flatten(filter, '');\n\n return normalized as T;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cyberskill/shared",
3
3
  "type": "module",
4
- "version": "3.10.0",
4
+ "version": "3.11.0",
5
5
  "description": "CyberSkill Shared",
6
6
  "author": "Stephen Cheng",
7
7
  "license": "MIT",
@@ -234,7 +234,7 @@
234
234
  "@apollo/client-integration-nextjs": "0.14.4",
235
235
  "@apollo/server": "5.4.0",
236
236
  "@as-integrations/express5": "1.1.2",
237
- "@dotenvx/dotenvx": "1.56.0",
237
+ "@dotenvx/dotenvx": "1.57.0",
238
238
  "@eddeee888/gcg-typescript-resolver-files": "0.15.0",
239
239
  "@eslint-react/eslint-plugin": "2.13.0",
240
240
  "@graphql-codegen/cli": "6.2.1",
@@ -268,12 +268,11 @@
268
268
  "graphql-ws": "6.0.7",
269
269
  "helmet": "8.1.0",
270
270
  "i18next": "25.8.20",
271
- "localforage": "1.10.0",
272
271
  "migrate-mongo": "14.0.7",
273
272
  "mongodb": "7.1.0",
274
273
  "mongoose": "9.3.1",
275
274
  "mongoose-aggregate-paginate-v2": "1.1.4",
276
- "mongoose-paginate-v2": "1.9.1",
275
+ "mongoose-paginate-v2": "1.9.3",
277
276
  "next-intl": "4.8.3",
278
277
  "qs": "6.15.0",
279
278
  "react": "19.2.4",
@@ -316,9 +315,9 @@
316
315
  "@vitest/browser": "4.1.0",
317
316
  "@vitest/coverage-istanbul": "4.1.0",
318
317
  "conventional-changelog-conventionalcommits": "9.3.0",
319
- "eslint": "10.0.3",
318
+ "eslint": "10.1.0",
320
319
  "glob": "13.0.6",
321
- "jsdom": "29.0.0",
320
+ "jsdom": "29.0.1",
322
321
  "lint-staged": "16.4.0",
323
322
  "node-modules-inspector": "1.4.2",
324
323
  "npm-run-all2": "8.0.4",
@@ -1,8 +0,0 @@
1
- //#region node_modules/.pnpm/vitest@4.1.0_@types+node@25.5.0_jsdom@29.0.0_@noble+hashes@1.8.0__vite@8.0.1_@types+nod_36acd00c2670b611b011192023dc5bd9/node_modules/vitest/dist/config.js
2
- function e(e) {
3
- return e;
4
- }
5
- //#endregion
6
- export { e as defineConfig };
7
-
8
- //# sourceMappingURL=config.js.map