blackcat.js-database 1.0.0-test
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/index.d.mts +751 -0
- package/dist/index.d.ts +751 -0
- package/dist/index.js +995 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +969 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/isObject.function.ts","../src/utils/typeOf.function.ts","../src/utils/isNumber.function.ts","../src/utils/BlackCatError.ts","../src/utils/TypedObject.ts","../src/utils/Emitter.ts","../src/Database.ts","../src/drivers/JSONDriver.ts"],"sourcesContent":["export * from \"./Database.ts\";\nexport * from \"./drivers\";","/**\n * Checks for is the item object and returns it.\n * @param {any} item The item to check.\n * @returns {boolean} Is the item object or not.\n */\nexport const isObject = (item: any): boolean => !Array.isArray(item) && item !== null && typeof item == \"object\";","/**\n * Returns the exact type of a given input.\n * @param input - The value to check.\n * @returns A string representing the exact type of the input.\n */\nexport const typeOf = (input: any): string => {\n // ✅ Handle special cases: null, undefined, and NaN\n if (input == null || (typeof input === \"number\" && Number.isNaN(input))) return String(input);\n // ✅ If it's a class constructor (has a prototype)\n if (typeof input === \"function\" && input.prototype) return `${input.name} class instance`;\n // ✅ If it's an object or function, return the constructor name if available\n return input?.constructor?.name ?? typeof input;\n};","import { typeOf } from \"./typeOf.function\";\n\n/**\n * Determines if the specified value is a number.\n *\n * A small hack to actually determine if the input is a number since\n * empty strings and arrays are considered as numbers too.\n * @param {any} input The input to check.\n * @returns {boolean} Whether the specified input is a number.\n */\nexport const isNumber = (input: any): boolean => !isNaN(input as number) && input !== \"\" && input !== null && typeOf(input) !== \"Array\";","import { typeOf } from \"./typeOf.function\";\n\nexport type TargetParamType = \"string\" | \"number\" | \"object\" | \"array\" | `${string} class instance`;\n\nexport const errors = {\n DEVICE_IS_OFFLINE: 'Your device appears to be offline so it\\'s impossible to proceed with ' + 'connection to your online MongoDB cluster. Please connect your device to the internet or switch to the ' + 'local MongoDB database and try again.',\n CONNECTION_NOT_ESTABLISHED: 'Failed to connect to MongoDB. Please double-check the specified ' + 'connection URI and make sure that you\\'re performing the ' + 'database connection using the `QuickMongoClient.connect()` method.',\n CONNECTION_URI_NOT_SPECIFIED: 'The MongoDB connection URI must be specified.',\n INVALID_CONNECTION_URI: 'The specified MongoDB connection URI is invalid.',\n UNKNOWN_ERROR: 'Unknown error.',\n REQUIRED_PARAMETER_MISSING: '\\'{1}\\' parameter is required but is missing.',\n REQUIRED_CONSTRUCTOR_PARAMETER_MISSING: '\\'{1}\\' parameter in constructor \\'{2}\\' is required but is missing.',\n INVALID_CONSTRUCTOR_PARAMETER_TYPE: '\\'{1}\\' parameter in constructor \\'{2}\\' must be ' + 'a type of {3}. Received type: {4}.',\n INVALID_TYPE: '\\'{1}\\' must be a type of {2}. Received type: {3}.',\n ONE_OR_MORE_ARRAY_TYPES_INVALID: 'All specified elements from array in \\'{1}\\' parameter ' + 'must be a type of {2}. Received array of types: {3}.',\n INVALID_TARGET: 'The target in database must be a type of {1}. Received target type: {2}.',\n INVALID_KEY: \"{1}\",\n INVALID_PARAMETER: \"{1} {2}\",\n DATABASE_CONNECTION_FAILED: \"{1}\"\n}\n\nexport interface ErrorParams extends Record<keyof typeof errors, string[]> {\n CONNECTION_NOT_ESTABLISHED: [];\n UNKNOWN_ERROR: [];\n CONNECTION_URI_NOT_SPECIFIED: [];\n INVALID_CONNECTION_URI: [];\n REQUIRED_PARAMETER_MISSING: [missingParam: string];\n REQUIRED_CONSTRUCTOR_PARAMETER_MISSING: [missingParam: string, className: string];\n INVALID_TYPE: [paramName: string, targetType: TargetParamType, receivedType: string];\n INVALID_CONSTRUCTOR_PARAMETER_TYPE: [paramName: string, className: string, targetType: TargetParamType, receivedType: string];\n ONE_OR_MORE_ARRAY_TYPES_INVALID: [paramName: string, targetType: TargetParamType, receivedTypesArray: string];\n INVALID_TARGET: [targetType: TargetParamType, receivedType: string];\n INVALID_KEY: [paramName: string];\n INVALID_PARAMETER: [paramName: string, receivedType: string];\n DATABASE_CONNECTION_FAILED: [paramName: string]\n}\nexport const createTypesArray = <T>(...elements: any): string => `[${elements.map((element: any) => typeOf(element))}]`;\n/**\n * BlackCatError class.\n */\nexport class BlackCatError<TErrorCode extends keyof typeof errors> extends Error {\n /** \n * Creates a BlackCatError instance.\n * @param {string} errorCode Quick Mongo error code.\n * @param {any[]} params Additional parameters to replace the placeholders in the error message.\n */\n public constructor(errorCode: TErrorCode, ...params: ErrorParams[TErrorCode]) {\n const code = errors[errorCode] ? errorCode : \"UNKNOWN_ERROR\" as TErrorCode;\n let message = errors[code];\n for (let i = 0; i < params.length; i++) {\n message = message.replaceAll(`{${i + 1}}`, params[i]);\n };\n super(message);\n /**\n * The name of the error.\n */\n this.name = `BlackCatError [${code}]`;\n }\n}","import { ExtractObjectKeys, ExtractObjectValues, ExtractObjectEntries } from \"../types\";\n\n/**\n * Utility class for working with objects.\n *\n * Provides **static** methods for retrieving keys and values of an object with addition of types.\n *\n * This class enhances type safety by providing better typings for object keys and values.\n */\nexport class TypedObject {\n /**\n * Returns the names of the enumerable string properties and methods of an object.\n *\n * Type parameters:\n *\n * - `TObject` (`Record<string, any>`) - The object to get the object keys types from.\n *\n * @param {TObject} obj Object to get the keys from.\n *\n * @returns {Array<ExtractObjectKeys<TObject>>}\n * Array of names of the enumerable string properties and methods of the specified object.\n */\n public static keys<TObject extends Record<string, any>>(obj: TObject): ExtractObjectKeys<TObject>[] {\n return Object.keys(obj || {});\n }\n /**\n * Returns an array of values of the enumerable properties of an object.\n *\n * Type parameters:\n *\n * - `TObject` (`Record<string, any>`) - The object to get the object values types from.\n *\n * @param {TObject} obj Object to get the values from.\n *\n * @returns {Array<ExtractObjectValues<TObject>>}\n * Array of values of the enumerable properties of the specified object.\n */\n public static values<TObject extends Record<string, any>>(obj: TObject): ExtractObjectValues<TObject>[] {\n return Object.values(obj || {});\n }\n /**\n * Returns an array of entries (key-value pairs) of the enumerable properties of an object.\n *\n * Type parameters:\n *\n * - `TObject` (`Record<string, any>`) - The object to get the object entries types (key-value pairs types) from.\n *\n * @param {TObject} obj Object to get the entries from.\n *\n * @returns {ExtractObjectEntries<TObject>[]}\n * Array of entries (key-value pairs) of the enumerable properties of the specified object.\n */\n public static entries<TObject extends Record<string, any>>(obj: TObject): ExtractObjectEntries<TObject>[] {\n return Object.entries(obj || {})\n }\n}","import { EventEmitter } from \"node:events\";\n\nexport class Emitter<E extends Record<string, any>> {\n private _emitter = new EventEmitter();\n /**\n * Listens to the event.\n * @param {string} event Event name.\n * @param {Function} listener Listener function.\n */\n public on<K extends Exclude<keyof E, number>>(event: K, listener: (...args: E[K]) => any): Emitter<E> {\n this._emitter.on(event, listener);\n return this;\n }\n /**\n * Listens to the event only for once.\n * @param {string} event Event name.\n * @param {Function} listener Listener function.\n */\n public once<K extends Exclude<keyof E, number>>(event: K, listener: (...args: E[K]) => any): Emitter<E> {\n this._emitter.once(event, listener);\n return this;\n }\n /**\n * Emits the event.\n * @param {string} event Event name.\n * @param {any[]} args Listener arguments.\n * @returns {boolean} `true` if the event had listeners, `false` otherwise.\n */\n public emit<K extends Exclude<keyof E, number>>(event: K, ...args: E[K]): boolean {\n return this._emitter.emit(event, ...args as any[]);\n }\n}","import { DatabaseConfiguration, BaseDriver, AutocompletableString, FirstObjectKey, If, IsObject, ObjectPath, ObjectValue, Maybe, QueryFunction, RestOrArray, ExtractFromArray } from \"./types\";\nimport { BlackCatError, createTypesArray, isNumber, typeOf, TypedObject, isObject } from \"./utils\";\n\n/**\n * Database class.\n *\n * Type parameters:\n *\n * - `V` (`any`) - The type of the values in the database.\n *\n * @template V (`any`) - The type of the values in the database.\n *\n * @example\n * \n * // JSON\n * import { Database, JSONDriver } from \"blackcat-database\";\n *\n * const database = new Database({\n * driver: new JSONDriver({ filePath: \"./database.json\", minifyJSON: false }),\n * });\n * \n * \n */\nexport class Database<V = any> {\n /**\n * The low-level database driver handling basic operations.\n */\n public driver: BaseDriver;\n constructor(options: DatabaseConfiguration) {\n this.driver = options.driver;\n }\n /**\n * Gets all the database contents from the cache.\n *\n * Type parameters:\n *\n * - `T` (`object`, defaults to `Record<string, any>`) - The type of object of all the database object to be returned.\n *\n * @returns {T} Cached database contents.\n *\n * @template T (object, defaults to `Record<string, any>`) -\n * The type of object of all the database object to be returned.\n *\n * @example\n * const databaseContents = await database.all();\n * console.log(databaseContents); // -> { ... (the object of all the data stored in database) }\n */\n public async all<T extends Record<string, any> = Record<string, any>>(): Promise<T> {\n const allDatabase = await this.driver.all();\n return allDatabase as Promise<T>;\n }\n /**\n * Retrieves a value from database by a key.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @returns {Maybe<ObjectValue<V, P>>} The value of the target in database.\n *\n * @example\n * const simpleValue = await database.get(\"simpleValue\");\n * console.log(simpleValue); // -> 123\n *\n * const databaseObjectPropertyAccessed = await database.get(\"youCanAlso.accessDatabaseObjectProperties.likeThat\");\n * console.log(databaseObjectPropertyAccessed); // -> \"hello world!\"\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // simpleValue: 123,\n * // youCanAlso: {\n * // accessDatabaseObjectProperties: {\n * // likeThat: \"hello world!\"\n * // }\n * // }\n * // }\n */\n public async get<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>): Promise<Maybe<ObjectValue<V, P>> | V> {\n if (key !== undefined) {\n if (typeof key !== \"string\") {\n throw new BlackCatError(\"INVALID_TYPE\", \"key\", \"string\", typeOf(key));\n }\n return this.driver.get(key);\n } else {\n return this.all() as V;\n };\n }\n /**\n * Retrieves a value from database by a key.\n *\n * - This method is an alias for {@link Database.get()} method.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @returns {Maybe<ObjectValue<V, P>>} The value from database.\n *\n * @example\n * const simpleValue = await database.fetch(\"simpleValue\");\n * console.log(simpleValue); // -> 123\n *\n * // You can use the dot notation to access the database object properties:\n * const playerInventory = await database.fetch(\"player.inventory\");\n * console.log(playerInventory); // -> []\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // simpleValue: 123,\n * // player: {\n * // inventory: []\n * // }\n * // }\n */\n public async fetch<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>): Promise<Maybe<ObjectValue<V, P>> | V> {\n return this.get(key);\n }\n /**\n * Determines if the data is stored in database.\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @returns {boolean} Whether the data is stored in database.\n *\n * @example\n * const isSimpleValueInDatabase = await database.has(\"simpleValue\");\n * console.log(isSimpleValueInDatabase); // -> true\n *\n * const somethingElse = await database.has(\"somethingElse\");\n * console.log(somethingElse); // -> false\n *\n * // You can use the dot notation to check the database object properties:\n * const isObjectInDatabase = await database.has(\"youCanAlso.accessObjectProperties.likeThat\");\n * console.log(isObjectInDatabase); // -> true\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // simpleValue: 123,\n * // player: {\n * // inventory: []\n * // },\n * // youCanAlso: {\n * // accessObjectProperties: {\n * // likeThat: \"hello world!\"\n * // }\n * // }\n * // }\n */\n public async has<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>): Promise<boolean> {\n return this.get(key) !== null && this.get(key) !== undefined;\n }\n /**\n * Writes the specified value into database under the specified key.\n *\n * @param {AutocompletableString<P>} key The key to write in the target.\n * @param {ObjectValue<V, P>} value The value to write.\n *\n * @returns {Promise<If<IsObject<V>, FirstObjectKey<P>, V>>}\n * - If the `value` parameter's type is not an object (string, number, boolean, etc), then the specified\n * `value` parameter (type of `ObjectValue<V, P>`) will be returned.\n *\n * - If an object is specified in the `value` parameter, then the object of the first key will be returned.\n * (type of `FirstObjectKey<P>` - first object key (e.g. in key `member.user.id`, the first key will be `member`))\n *\n * @example\n * // Assuming that the initial database object for this example is empty.\n *\n * await database.set(\"something\", \"hello\");\n * const hello = await database.get(\"something\");\n *\n * console.log(hello); // -> \"hello\"\n *\n * // You can use the dot notation to write data in objects:\n * const dotNotationSetResult = await database.set(\"member.user.id\", 2000);\n * console.log(dotNotationSetResult); // -> 2000\n *\n * await database.set(\"member.inventory\", []);\n * const inventory = await database.get(\"member.inventory\");\n *\n * console.log(inventory); // -> []\n *\n * // Using objects as value will return the object of key `thats`:\n * await database.set(\"member.user\", { name: \"Jerry\" }); // -> { member: { user: { name: \"Jerry\" } } }\n *\n * // After these manipulations, the database object will look like this:\n * // {\n * // \"something\": \"hello\",\n * // \"member\": {\n * // \"inventory\": [],\n * // \"user\": { \n * // \"name\": \"Jerry\",\n * // \"id\": 2000 \n * // }\n * // }\n * // }\n */\n public async set<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, value: ObjectValue<V, P>): Promise<If<IsObject<V>, ObjectValue<V, FirstObjectKey<P>>, V>> {\n const allDatabase = await this.all();\n if (!key) {\n throw new BlackCatError(\"REQUIRED_PARAMETER_MISSING\", \"key\");\n }\n if (typeof key !== \"string\") {\n throw new BlackCatError(\"INVALID_TYPE\", \"key\", \"string\", typeOf(key));\n }\n const keys = key.split(\".\");\n let currentObj = allDatabase;\n\n for (let i = 0; i < keys.length; i++) {\n if (keys.length - 1 === i) {\n currentObj[keys[i]] = value\n } else {\n if (!isObject(currentObj[keys[i]])) {\n currentObj[keys[i]] = {};\n }\n currentObj = currentObj[keys[i]];\n };\n };\n await this.driver.set(keys[0], allDatabase);\n return typeof value == \"object\" && value !== null ? await this.get(keys[0]) as any : value as any;\n }\n /**\n * Update the specified value into database under the specified key.\n *\n * @param {AutocompletableString<P>} key The key to update the target.\n * @param {ObjectValue<V, P>} value The value to update.\n *\n * @returns {Promise<If<IsObject<V>, FirstObjectKey<P>, V>>}\n * - If the `value` parameter's type is not an object (string, number, boolean, etc), then the specified\n * `value` parameter (type of `ObjectValue<V, P>`) will be returned.\n *\n * - If an object is specified in the `value` parameter, then the object of the first key will be returned.\n * (type of `FirstObjectKey<P>` - first object key (e.g. in key `member.user.id`, the first key will be `member`))\n */\n public async update<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, value: ObjectValue<V, P>): Promise<If<IsObject<V>, ObjectValue<V, FirstObjectKey<P>>, V>> {\n const allDatabase = await this.all();\n const keys = key.split(\".\");\n let current: any = allDatabase;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const part = keys[i];\n if (!(part in current)) {\n current[part] = {};\n }\n current = current[part];\n }\n\n const lastKey = keys[keys.length - 1];\n current[lastKey] = value;\n\n await this.driver.set(keys[0], allDatabase);\n return current;\n }\n /**\n * Performs an arithmetical addition on a target number in database.\n *\n * [!!!] The type of target value must be a number.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @param {number} numberToAdd The number to add to the target number in database.\n * @returns {Promise<number>} Addition operation result.\n *\n * @example\n * const additionResult = await database.add(\"points\", 5);\n * console.log(additionResult); // -> 10 (5 + 5 = 10)\n *\n * // Notice that we don't need to assign a value to unexistent properties in database\n * // before performing an addition since the initial target value is 0 and will be used\n * // as the value of the unexistent property:\n * const unexistentAdditionResult = await database.add(\"somethingElse\", 3);\n *\n * console.log(unexistentAdditionResult); // -> 3 (0 + 3 = 3)\n * // the property didn't exist in database, that's why 0 is added to 3\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // points: 5\n * // }\n */\n public async add<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, numberToAdd: number): Promise<number> {\n const targetNumber = await this.get(key) as any ?? 0;\n\n if (!isNumber(targetNumber)) {\n throw new BlackCatError(\"INVALID_TARGET\", \"number\", typeOf(targetNumber));\n }\n if (numberToAdd === undefined) {\n throw new BlackCatError(\"REQUIRED_PARAMETER_MISSING\", \"numberToAdd\");\n }\n if (!isNumber(numberToAdd)) {\n throw new BlackCatError(\"INVALID_TYPE\", \"numberToAdd\", \"number\", typeOf(numberToAdd));\n }\n return await this.set(key, targetNumber + numberToAdd) as Promise<number>;\n }\n /**\n * Performs an arithmetical subtraction on a target number in database.\n *\n * [!!!] The type of target value must be a number.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @param {number} numberToSubtract The number to subtract from the target number in database.\n * @returns {Promise<number>} Subtraction operation result.\n *\n * @example\n * const subtractionResult = await database.subtract(\"points\", 5)\n * console.log(subtractionResult) // -> 5 (10 - 5 = 5)\n *\n * // Notice that we don't need to assign a value to unexistent properties in database\n * // before performing a subtraction since the initial target value is 0 and will be used\n * // as the value of the unexistent property:\n * const unexistentSubtractionitionResult = await database.subtract(\"somethingElse\", 3)\n *\n * console.log(unexistentSubtractionitionResult) // -> 3 (0 - 3 = -3)\n * // the property didn't exist in database, so 3 is subtracted from 0\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // points: 10\n * // }\n */\n public async subtract<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, numberToSubtract: number): Promise<number> {\n const targetNumber = await this.get(key) as any ?? 0;\n\n if (!isNumber(targetNumber)) {\n throw new BlackCatError(\"INVALID_TARGET\", \"number\", typeOf(targetNumber));\n }\n if (numberToSubtract === undefined) {\n throw new BlackCatError(\"REQUIRED_PARAMETER_MISSING\", \"numberToSubtract\");\n }\n if (!isNumber(numberToSubtract)) {\n throw new BlackCatError(\"INVALID_TYPE\", \"numberToSubtract\", \"number\", typeOf(numberToSubtract));\n }\n return await this.set(key, targetNumber - numberToSubtract as any) as Promise<number>;\n }\n /**\n * Pushes the specified value(s) into the target array in database.\n *\n * [!!!] The type of target value must be an array.\n * [!!!] get only values not stored in the database.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @param {RestOrArray<ExtractFromArray<ObjectValue<V, P>>>} values\n * The value(s) to be pushed into the target array in database.\n *\n * @returns {Promise<Array<ExtractFromArray<ObjectValue<V, P>>>>} Updated target array from database.\n *\n * @example\n * console.log(await database.push(\"members\", \"Jerry\")); // -> [\"Tom\", \"Jerry\"]\n * // You can also pass in multiple values to push into the target array:\n * console.log(await database.push(\"currencies\", \"VND\")); // -> [\"USD\", \"VND\"]\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // members: [\"Tom\"],\n * // currencies: [\"USD\"]\n * // }\n */\n public async push<P extends ObjectPath<V>>(key: AutocompletableString<P>, ...values: RestOrArray<ExtractFromArray<ObjectValue<V, P>>>): Promise<ExtractFromArray<ObjectValue<V, P>>[]> {\n if (!values.length) {\n throw new BlackCatError(\"REQUIRED_PARAMETER_MISSING\", \"values\");\n }\n const root = await this.all();\n const pathParts = key.split(\".\");\n let target = root;\n for (let i = 0; i < pathParts.length; i++) {\n const part = pathParts[i];\n if (!(part in target)) {\n throw new BlackCatError(\"INVALID_KEY\", key);\n }\n if (i === pathParts.length - 1) {\n if (!Array.isArray(target[part])) {\n throw new BlackCatError(\"INVALID_TARGET\", \"array\", typeOf(target[part]));\n }\n const uniqueValues = (values as any[]).filter(v => !target[part].includes(v));\n target[part].push(...uniqueValues);\n } else {\n target = target[part];\n }\n };\n const topKey = pathParts[0];\n await this.set(topKey, root[topKey]);\n return target[pathParts[pathParts.length - 1]];\n }\n /**\n * Replaces the specified element in target array with the specified value in the target array in database.\n *\n * [!!!] The type of target value must be an array.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @param {number} targetArrayElementIndex The index to find the element in target array by.\n * @param {V} value The value to be pushed into the target array in database.\n * @returns {Promise<Array<ExtractFromArray<ObjectValue<V, P>>>>} Updated target array from database.\n *\n * @example\n * console.log(await database.pull(\"members\", 1, \"James\")); // -> [\"Jerry\", \"James\", \"Tom\"]\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // members: [\"Jerry\", \"William\", \"Tom\"]\n * // }\n */\n public async pull<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, targetArrayElementIndex: number, value: ExtractFromArray<ObjectValue<V, P>>,): Promise<ExtractFromArray<ObjectValue<V, P>>[]> {\n if (!isNumber(targetArrayElementIndex)) {\n throw new BlackCatError(\"INVALID_TYPE\", \"targetArrayElementIndex\", \"number\", typeOf(targetArrayElementIndex));\n };\n if (value === undefined) {\n throw new BlackCatError(\"REQUIRED_PARAMETER_MISSING\", \"value\");\n };\n const root = await this.all();\n const pathParts = key.split(\".\");\n let target: any = root;\n for (let i = 0; i < pathParts.length; i++) {\n const part = pathParts[i];\n if (!(part in target)) {\n throw new BlackCatError(\"INVALID_KEY\", `Path \"${key}\" does not exist`);\n }\n if (i === pathParts.length - 1) {\n if (!Array.isArray(target[part])) {\n throw new BlackCatError(\"INVALID_TARGET\", \"array\", typeOf(target[part]));\n };\n const arr = target[part];\n const index = targetArrayElementIndex >= 0 ? targetArrayElementIndex : arr.length + targetArrayElementIndex;\n if (index < 0 || index >= arr.length) {\n console.error(`Index ${targetArrayElementIndex} is out of bounds`);\n };\n arr[index] = value;\n } else {\n target = target[part];\n };\n };\n await this.set(pathParts[0], root[pathParts[0]]);\n return target[pathParts[pathParts.length - 1]];\n }\n /**\n * Removes the specified element(s) from the target array in database.\n *\n * [!!!] The type of target value must be an array.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @param {RestOrArray<ExtractFromArray<number>>} targetArrayElementIndexes\n * The index(es) to find the element(s) in target array by.\n *\n * @returns {Promise<Array<ExtractFromArray<ObjectValue<V, P>>>>} Updated target array from database.\n *\n * @example\n * console.log(await database.pop(\"members\", 1)); // -> [\"Jerry\", \"Tom\"]\n *\n * console.log(await database.pop(\"currencies\", 1)); // -> [\"VND\", \"Euro\"]\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // members: [\"Jerry\", \"William\", \"Tom\"],\n * // currencies: [\"VND\", \"USD\", \"Euro\"]\n * // }\n */\n public async pop<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, ...targetArrayElementIndexes: RestOrArray<ExtractFromArray<number>>): Promise<ExtractFromArray<ObjectValue<V, P>>[]> {\n const targetArray = await this.get(key) ?? [];\n\n if (!Array.isArray(targetArray)) {\n throw new BlackCatError(\"INVALID_TARGET\", \"array\", typeOf(targetArray));\n };\n\n if (!targetArrayElementIndexes.length) {\n throw new BlackCatError(\"REQUIRED_PARAMETER_MISSING\", \"targetArrayElementIndex\");\n };\n const indexes = Array.isArray(targetArrayElementIndexes[0]) ? (targetArrayElementIndexes[0] as number[]) : (targetArrayElementIndexes as number[]);\n if (indexes.some(index => !isNumber(index))) {\n throw new BlackCatError(\"ONE_OR_MORE_ARRAY_TYPES_INVALID\", \"targetArrayElementIndexes\", \"number\", createTypesArray(indexes));\n };\n\n const sortedIndexes = [...indexes].sort((a, b) => b - a);\n const removedElements: any[] = [];\n\n for (const index of sortedIndexes) {\n const removed = targetArray.splice(index, 1);\n removedElements.push(...removed);\n };\n\n const parentPath = key.split(\".\").slice(0, -1).join(\".\") as AutocompletableString<any>;\n const fieldName = key.split(\".\").slice(-1)[0];\n\n if (parentPath) {\n const parentObject = await this.get(parentPath) as Record<string, any> ?? {};\n parentObject[fieldName] = targetArray;\n await this.set(parentPath, parentObject as NonNullable<Exclude<ObjectValue<V, P>, undefined>>);\n } else {\n await this.set(key, targetArray as NonNullable<Exclude<ObjectValue<V, P>, undefined>>);\n };\n return removedElements;\n }\n /**\n * Determines whether the specified target is an array.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @returns {Promise<boolean>} Whether the target is an array.\n *\n * @example\n * console.log(await databse.isTargetArray(\"array\")); // => true\n * console.log(await databse.isTargetArray(\"notArray\")); // => false\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // array: [],\n * // notArray: 123\n * // }\n */\n public async isTargetArray<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>): Promise<boolean> {\n const target = await this.get(key);\n return Array.isArray(target);\n }\n /**\n * Determines whether the specified target is a number.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @returns {Promise<boolean>} Whether the target is a number.\n *\n * @example\n * console.log(await database.isTargetNumber(\"number\")); // -> true\n * console.log(await database.isTargetNumber(\"notNumber\")); // -> false\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // number: 123,\n * // notNumber: []\n * // }\n */\n public async isTargetNumber<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>): Promise<boolean> {\n const target = await this.get(key);\n return isNumber(target);\n }\n /**\n * Returns an array of object keys by specified database key.\n *\n * If `key` parameter is omitted, then an array of object keys of database root object will be returned.\n *\n * Type parameters:\n *\n * - `TKeys` (`TupleOrArray<string>`, defaults to `K[]`) - The tuple or array of a type of keys to be returned.\n *\n * @param {P} [key] The key to access the target in database by.\n * @returns {Array<ObjectPath<P>>} Database object keys array.\n *\n * @example\n * const prop3Keys = await database.keys(\"prop3\");\n * console.log(prop3Keys) // -> [\"prop4\", \"prop5\"]\n *\n * const prop5Keys = await database.keys(\"prop3.prop5\");\n * console.log(prop5Keys) // -> [\"prop6\"]\n *\n * const prop6Keys = await database.keys(\"prop3.prop5.prop6\");\n * console.log(prop6Keys)\n * // -> [] (empty since the value in `prop6`, 111, is a primitive value and not an actual object)\n *\n * const databaseKeys = await database.keys();\n * // in this example, `key` parameter is omitted - object keys of database object are being returned\n *\n * console.log(databaseKeys) // -> [\"prop1\", \"prop2\", \"prop3\"]\n *\n * const unexistentKeys = await database.keys(\"somethingElse\");\n * console.log(unexistentKeys) // -> [] (empty since the key `somethingElse` does not exist in database)\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // prop1: 123,\n * // prop2: 456,\n * // prop3: { \n * // prop4: 789, \n * // prop5: { \n * // prop6: 111 \n * // } \n * // }\n * // }\n */\n public async keys<P extends AutocompletableString<ObjectPath<V>>>(key?: P): Promise<ObjectPath<P>[]> {\n if (!key) return TypedObject.keys(await this.all()) as ObjectPath<P>[];\n const data = await this.get(key) as Record<string, any>;\n return TypedObject.keys(data).filter((key) => data[key] !== undefined && data[key] !== null) as any\n }\n /**\n * Determines the number of keys in the root of the database.\n * @type {Promise<number>} amount of data.\n */\n public async size(): Promise<number> {\n const keys = await this.keys();\n return keys.length;\n }\n /**\n * Returns an array of object values by specified database key.\n *\n * If `key` parameter is omitted, then an array of object values of database root object will be returned.\n *\n * @param {P} [key] The key to access the target in database by.\n * @returns {Array<ObjectValue<V, P>>} Database object values array.\n *\n * @example\n * const prop3Values = await database.values(\"prop3\");\n * console.log(prop3Values); // -> [789, { prop6: 111 }]\n *\n * const prop5Values = await database.values(\"prop3.prop5\");\n * console.log(prop5Values); // -> []\n *\n * const prop6Values = await database.values(\"prop3.prop5.prop6\");\n * console.log(prop6Values);\n * // -> [] (empty since the value in `prop6`, 111, is a primitive value and not an actual object)\n *\n * const databaseValues = await database.values();\n * // in this example, `key` parameter is omitted - object values of database object are being returned\n *\n * console.log(databaseValues); // -> [123, 456, { prop4: 789, prop5: { prop6: 111 } }]\n *\n * const unexistentValues = await database.values(\"somethingElse\");\n * console.log(unexistentValues); // -> [] (empty since the key `somethingElse` does not exist in database)\n *\n * // Assuming that the initial database object for this example is:\n * // {\n * // prop1: 123,\n * // prop2: 456,\n * // prop3: { \n * // prop4: 789, \n * // prop5: { \n * // prop6: 111 \n * // } \n * // }\n * // }\n */\n public async values<P extends AutocompletableString<ObjectPath<V>>>(key?: P): Promise<ObjectValue<V, P>[]> {\n if (!key) return TypedObject.values(await this.all());\n const data = await this.get(key) as Record<string, any>;\n return TypedObject.values(data) as ObjectValue<V, P>[];\n }\n /**\n * This method works the same way as `Array.find()`.\n *\n * Iterates over root database values, finds the element in database values array\n * by specified condition in the callback function and returns the result.\n *\n * @param {QueryFunction<V>} queryFunction\n * A function that accepts up to three arguments.\n * The `find` method calls the `queryFunction` once for each element in database object values array.\n *\n * @returns {Promise<Maybe<V>>} The search\n */\n public async find(queryFunction: QueryFunction<V>): Promise<Maybe<V>> {\n const values = await this.values();\n return values.find(queryFunction as QueryFunction<ObjectValue<V, any>>) as Promise<Maybe<V>> ?? null;\n }\n /**\n * This method works the same way as `Array.map()`.\n *\n * Calls a defined callback function on each element of an array,\n * and returns an array that contains the results.\n *\n * @param {QueryFunction<V, TReturnType>} queryFunction\n * A function that accepts up to three arguments.\n * The `map` method calls the `queryFunction` once for each element in database object values array.\n *\n * @returns {Promise<TReturnType[]>}\n */\n public async map<TReturnType>(queryFunction: QueryFunction<V, TReturnType>): Promise<TReturnType[]> {\n const values = await this.values();\n return values.map(queryFunction as QueryFunction<ObjectValue<V, any>, TReturnType>);\n }\n /**\n * This method works the same way as `Array.findIndex()`.\n *\n * Iterates over root database values, finds the index of the element in database values array\n * by specified condition in the callback function and returns the result.\n *\n * @param {QueryFunction<V>} queryFunction\n * A function that accepts up to three arguments.\n * The `findIndex` method calls the `queryFunction` once for each element in database object values array.\n *\n * @returns {Promise<number>}\n */\n public async findIndex(queryFunction: QueryFunction<V>): Promise<number> {\n const values = await this.values();\n return values.findIndex(queryFunction as QueryFunction<ObjectValue<V, any>>);\n }\n /**\n * This method works the same way as `Array.filter()`.\n *\n * Iterates over root database values, finds all the element that match the\n * specified condition in the callback function and returns the result.\n *\n * @param {QueryFunction<V>} queryFunction\n * A function that accepts up to three arguments.\n * The `filter` method calls the `queryFunction` once for each element in database object values array.\n *\n * @returns {Promise<V[]>}\n */\n public async filter(queryFunction: QueryFunction<V>): Promise<V[]> {\n const values = await this.values();\n return values.filter(queryFunction as QueryFunction<ObjectValue<V, any>>) as any;\n }\n /**\n * This method works the same way as `Array.some()`.\n *\n * Iterates over root database values and checks if the\n * specified condition in the callback function returns `true`\n * for **any** of the elements of the database object values array.\n *\n * @param {QueryFunction<V>} queryFunction\n * A function that accepts up to three arguments.\n * The `some` method calls the `queryFunction` once for each element in database object values array.\n *\n * @returns {Promise<boolean>}\n */\n public async some(queryFunction: QueryFunction<V>): Promise<boolean> {\n const values = await this.values();\n return values.some(queryFunction as QueryFunction<ObjectValue<V, any>>);\n }\n /**\n * This method works the same way as `Array.every()`.\n *\n * Iterates over root database values and checks if the\n * specified condition in the callback function returns `true`\n * for **all** of the elements of the database object values array.\n *\n * @param {QueryFunction<V>} queryFunction\n * A function that accepts up to three arguments.\n * The `every` method calls the `queryFunction` once for each element in database object values array.\n *\n * @returns {Promise<boolean>}\n */\n public async every(queryFunction: QueryFunction<V>): Promise<boolean> {\n const values = await this.values();\n return values.every(queryFunction as QueryFunction<ObjectValue<V, any>>);\n }\n /**\n * Picks a random element of array in database and returns the picked array element.\n *\n * [!!!] The type of target value must be an array.\n *\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @returns {Promise<Maybe<ObjectValue<V, P>>>} The randomly picked element in the database array.\n *\n * @example\n * const array = await database.get(\"array\"); // assuming that the array is ['example1', 'example2', 'example3']\n * console.log(array); // -> ['example1', 'example2', 'example3']\n *\n * const randomArrayElement = await database.random(\"exampleArray\");\n * console.log(randomArrayElement); // -> randomly picked array element: either 'example1', 'example2', or 'example3'\n */\n public async random<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>): Promise<Maybe<ObjectValue<V, P>>> {\n const array = await this.get(key);\n if (!Array.isArray(array)) {\n throw new BlackCatError(\"INVALID_TARGET\", \"array\", typeOf(array));\n }\n return array[Math.floor(Math.random() * array.length)] ?? null;\n }\n /**\n * Deletes the data from database by key.\n * @param {AutocompletableString<P>} key The key to access the target in database by.\n * @returns {Promise<boolean>} Whether the deletion was successful.\n */\n public async delete<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>): Promise<boolean> {\n if (typeof key !== \"string\") {\n throw new BlackCatError(\"INVALID_TYPE\", \"key\", \"string\", typeof key);\n };\n const allDatabase = await this.all();\n const keys = key.split(\".\");\n const lastKey = keys.pop() as string;\n let currentObj: any = allDatabase;\n for (const k of keys) {\n if (!isObject(currentObj[k])) {\n return false;\n }\n currentObj = currentObj[k];\n }\n if (!(lastKey in currentObj)) return false;\n delete currentObj[lastKey];\n await this.driver.delete(allDatabase);\n return true;\n }\n /**\n * Deletes everything from the database.\n *\n * - This method is an alias for {@link QuickMongo.clear()} method.\n * @returns {Promise<boolean>} `true` if cleared successfully, `false` otherwise.\n */\n public async deleteAll(): Promise<boolean> {\n await this.driver.delete();\n return true;\n }\n}","import { promises as fs } from \"fs\";\nimport { BaseDriver } from \"../types\";\n\ninterface JSONDriverOptions {\n /**\n * JSON database file path.\n * @type {string}\n */\n filePath: string;\n /**\n * Minifies the JSON content in database file to save some space.\n * @type {boolean}\n */\n minifyJSON?: boolean;\n}\n/**\n * JSONDriver class.\n */\nexport class JSONDriver implements BaseDriver {\n /**\n * JSON database file path.\n * @type {string}\n */\n private filePath: string;\n /**\n * Minifies the JSON content in database file to save some space.\n * @type {boolean}\n */\n public minifyJSON: boolean;\n /**\n * JSONDriver class.\n * @param options.filePath Json database file path.\n * @param options.minifyJSON Minifies the JSON content in database file to save some space.\n */\n constructor(options: JSONDriverOptions) {\n this.filePath = options.filePath || \"database.json\";\n this.minifyJSON = options.minifyJSON || false;\n }\n /**\n * Returns all data from JSON database.\n * \n * @returns {Promise<any>} All data from JSON database.\n * \n * @template V The type of data being returned.\n */\n public async all<V>(): Promise<V> {\n return fs.readFile(this.filePath, \"utf-8\").then((content) => JSON.parse(content) as V).catch((error) => {\n console.error(`Failed to load database file: ${this.filePath}`, error);\n return {} as V;\n });\n }\n /**\n * Parses the key and fetches the value from JSON database.\n *\n * Type parameters:\n *\n * - `V` - The type of data being returned.\n *\n * @param {string} key The key in JSON database.\n * @returns {Promise<V>} The data from JSON database.\n *\n * @template V The type of data being returned.\n */\n public async get<V = any>(key: string): Promise<V | null> {\n const data = await this.all<any>();\n const keys = key.split(\".\");\n let result = data;\n for (const k of keys) {\n if (result === null || typeof result !== \"object\") return null;\n result = result[k];\n }\n return result as V;\n }\n /**\n * Parses the key and sets the value in JSON database.\n *\n * Type parameters:\n *\n * - `V` - The type of data being set.\n * - `R` - The type of data being returned.\n *\n * @param {string} key The key in JSON database.\n * @returns {Promise<R>} The data from JSON database.\n *\n * @template V The type of data being set.\n * @template R The type of data being returned.\n */\n public async set<V = any, R = any>(key: string, value: V): Promise<R> {\n const data = await this.all<R>();\n await fs.writeFile(this.filePath, JSON.stringify(value, null, this.minifyJSON ? undefined : \"\\t\"));\n return data;\n }\n /**\n * Parses the key and deletes it from JSON database. If no key is provided, clears the database.\n * @param {V} key The key in JSON database.\n * @returns {Promise<boolean>} `true` if deleted successfully.\n */\n public async delete<V = any>(key?: V): Promise<boolean> {\n if(key === undefined) {\n await fs.writeFile(this.filePath, \"{}\");\n return true;\n } else {\n await fs.writeFile(this.filePath, JSON.stringify(key, null, this.minifyJSON ? undefined : \"\\t\"));\n };\n return true;\n }\n}"],"mappings":"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","names":["key","fs"]}
|