{"version":3,"sources":["../src/utils.ts","../src/bumpy.ts"],"names":["generateCuid","alphabet","timestamp","randomPart","num","baseFieldSchema","z","Bumpy","options","parsedPath","path","rootPath","existsSync","mkdir","fileContent","readFile","parsedContent","parse","hasDiff","collection","initialData","acc","writeFile","stringify","items","sort","sortChain","key","order","sortFn","firstBy","data","validated","now","newDoc","dataArray","results","query","sift","item","updated","validatedData","matchingItems","updatedItems","collectionName","operations","createBumpy","createCollection"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from \"zod\";\r\n\r\nexport function generateCuid(): string {\r\n\tconst alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\r\n\t// Generate timestamp part\r\n\tconst timestamp = Date.now().toString(36);\r\n\t// Generate a random string part\r\n\tconst randomPart = Array.from(crypto.getRandomValues(new Uint8Array(12)))\r\n\t\t.map((num) => alphabet[num % alphabet.length])\r\n\t\t.join(\"\");\r\n\t// Combine the parts into a final cuid-like identifier\r\n\treturn `c${timestamp}${randomPart}`;\r\n}\r\n\r\nexport const baseFieldSchema = z.object({\r\n\tid: z.string().cuid(),\r\n\tcreatedAt: z.coerce.date(),\r\n\tupdatedAt: z.coerce.date(),\r\n});\r\n","import { existsSync } from \"fs\";\r\nimport path from \"path\";\r\nimport { parse, stringify } from \"flatted\";\r\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\r\nimport sift from \"sift\";\r\nimport { firstBy } from \"thenby\";\r\nimport type { z } from \"zod\";\r\nimport type {\r\n\tBumpyOptions,\r\n\tCollection,\r\n\tCollectionOperations,\r\n\tData,\r\n\tFindOptions,\r\n\tInferSchema,\r\n\tOperations,\r\n\tSnakeCase,\r\n\tSortOptions,\r\n\tWithBaseField,\r\n} from \"./types\";\r\nimport { baseFieldSchema, generateCuid } from \"./utils\";\r\n\r\n/**\r\n * @template {string} TName\r\n * @template {z.ZodSchema} TSchema\r\n * @template {Collection<TName, TSchema>} TCollection\r\n * @class Bumpy\r\n * @description A lightweight document database that stores data in JSON files with schema validation\r\n */\r\nclass Bumpy<\r\n\tTName extends string,\r\n\tTSchema extends z.ZodSchema,\r\n\tTCollection extends Collection<TName, TSchema> = Collection<TName, TSchema>,\r\n> {\r\n\tprivate filePath = \"\";\r\n\tprivate data: Partial<Data<TCollection>> = {};\r\n\tprivate operations: Partial<CollectionOperations<TCollection>> = {};\r\n\r\n\t/**\r\n\t * Creates an instance of Bumpy database\r\n\t * @param {BumpyOptions<TCollection>} options - Configuration options for the database\r\n\t */\r\n\tconstructor(private options: BumpyOptions<TCollection>) { }\r\n\r\n\t/**\r\n\t * Initializes the database by creating necessary directories and files\r\n\t * @async\r\n\t * @returns {Promise<void>}\r\n\t * @throws {Error} If base path is not a valid JSON file\r\n\t */\r\n\tpublic async initialize() {\r\n\t\tconst parsedPath = path.parse(this.options.basePath);\r\n\r\n\t\tif (!parsedPath.ext || parsedPath.ext !== \".json\") {\r\n\t\t\tthrow new Error(\"Base path must be a valid JSON file\");\r\n\t\t}\r\n\r\n\t\tconst rootPath = path.join(process.cwd(), parsedPath.dir);\r\n\t\tthis.filePath = path.join(rootPath, parsedPath.base);\r\n\r\n\t\tif (!existsSync(rootPath)) {\r\n\t\t\tawait mkdir(rootPath, { recursive: true });\r\n\t\t}\r\n\r\n\t\tif (!existsSync(this.filePath)) {\r\n\t\t\tconst initialData = this.options.collections.reduce(\r\n\t\t\t\t(acc, collection) => {\r\n\t\t\t\t\tacc[collection.name as TCollection[\"name\"]] = {};\r\n\t\t\t\t\treturn acc;\r\n\t\t\t\t},\r\n\t\t\t\t{} as Record<TCollection[\"name\"], {}>,\r\n\t\t\t);\r\n\r\n\t\t\tawait writeFile(this.filePath, stringify(initialData));\r\n\t\t\tthis.data = initialData;\r\n\t\t} else {\r\n\t\t\tconst fileContent = await readFile(this.filePath, \"utf-8\");\r\n\t\t\tconst parsedContent = parse(fileContent) as Data<TCollection>;\r\n\r\n\t\t\tlet hasDiff = false;\r\n\t\t\tfor (const collection of this.options.collections) {\r\n\t\t\t\tif (collection.name in parsedContent) continue;\r\n\t\t\t\tthis.data[collection.name] = {};\r\n\t\t\t\tif (!hasDiff) {\r\n\t\t\t\t\thasDiff = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tthis.data = { ...this.data, ...parsedContent } as Data<TCollection>;\r\n\r\n\t\t\tif (hasDiff) {\r\n\t\t\t\tawait this.saveToFile();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfor (const collection of this.options.collections) {\r\n\t\t\t(this.operations[collection.name] as any) =\r\n\t\t\t\tthis.createOperations(collection);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Saves current database state to file\r\n\t * @private\r\n\t * @async\r\n\t * @returns {Promise<void>}\r\n\t */\r\n\tprivate async saveToFile(): Promise<void> {\r\n\t\tawait writeFile(this.filePath, stringify(this.data));\r\n\t}\r\n\r\n\t/**\r\n\t * Applies sorting to an array of items\r\n\t * @private\r\n\t * @template T\r\n\t * @param {T[]} items - Array of items to sort\r\n\t * @param {SortOptions} sort - Sort configuration\r\n\t * @returns {T[]} Sorted array\r\n\t */\r\n\tprivate applySorting<T>(items: T[], sort: SortOptions): T[] {\r\n\t\tlet sortChain = null;\r\n\r\n\t\tfor (const [key, order] of Object.entries(sort)) {\r\n\t\t\tconst sortFn = firstBy(key, { direction: order === \"desc\" ? -1 : 1 });\r\n\t\t\tsortChain = sortChain\r\n\t\t\t\t? sortChain.thenBy(key, { direction: order === \"desc\" ? -1 : 1 })\r\n\t\t\t\t: sortFn;\r\n\t\t}\r\n\r\n\t\treturn sortChain ? [...items].sort(sortChain as any) : items;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates operations for a collection\r\n\t * @private\r\n\t * @template {z.ZodSchema} S\r\n\t * @param {TCollection} collection - Collection configuration\r\n\t * @returns {Operations<S>} Collection operations\r\n\t */\r\n\tprivate createOperations<S extends z.ZodSchema>(\r\n\t\tcollection: TCollection,\r\n\t): Operations<S> {\r\n\t\treturn {\r\n\t\t\tcreate: async (data: InferSchema<S>) => {\r\n\t\t\t\tconst validated = collection.schema.parse(data) as InferSchema<S>;\r\n\t\t\t\tconst now = new Date().toISOString();\r\n\t\t\t\tconst newDoc: WithBaseField<InferSchema<S>> = {\r\n\t\t\t\t\t...validated,\r\n\t\t\t\t\tid: generateCuid(),\r\n\t\t\t\t\tcreatedAt: now,\r\n\t\t\t\t\tupdatedAt: now,\r\n\t\t\t\t} satisfies WithBaseField<InferSchema<S>>;\r\n\r\n\t\t\t\tif (!this.data[collection.name]) {\r\n\t\t\t\t\tthis.data[collection.name] = {};\r\n\t\t\t\t}\r\n\r\n\t\t\t\t(this.data[collection.name] as any)[newDoc.id] = newDoc;\r\n\t\t\t\tawait this.saveToFile();\r\n\t\t\t\treturn newDoc;\r\n\t\t\t},\r\n\r\n\t\t\tcreateMany: async (dataArray: InferSchema<S>[]) => {\r\n\t\t\t\tconst results: WithBaseField<InferSchema<S>>[] = [];\r\n\r\n\t\t\t\tfor (const data of dataArray) {\r\n\t\t\t\t\tconst newDoc = await this.operations[collection.name]?.create(data);\r\n\t\t\t\t\tif (newDoc) {\r\n\t\t\t\t\t\tresults.push(newDoc);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn results;\r\n\t\t\t},\r\n\r\n\t\t\tfindOne: async (query) => {\r\n\t\t\t\tconst items = Object.values(this.data[collection.name] || {});\r\n\t\t\t\treturn items.find(sift(query)) || null;\r\n\t\t\t},\r\n\r\n\t\t\tfindMany: async (query, options: FindOptions = {}) => {\r\n\t\t\t\tconst { sort } = options;\r\n\t\t\t\tlet items = Object.values(this.data[collection.name] || {}).filter(\r\n\t\t\t\t\tsift(query),\r\n\t\t\t\t);\r\n\r\n\t\t\t\tif (sort) {\r\n\t\t\t\t\titems = this.applySorting(items, sort);\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn items;\r\n\t\t\t},\r\n\r\n\t\t\tupdate: async (query, data: Partial<InferSchema<S>>) => {\r\n\t\t\t\tconst items = this.data[collection.name] || {};\r\n\t\t\t\tconst item = Object.values(items).find(sift(query));\r\n\r\n\t\t\t\tif (!item) return null;\r\n\r\n\t\t\t\tconst updated = {\r\n\t\t\t\t\t...item,\r\n\t\t\t\t\t...data,\r\n\t\t\t\t\tupdatedAt: new Date().toISOString(),\r\n\t\t\t\t};\r\n\r\n\t\t\t\tconst validatedData = (await baseFieldSchema\r\n\t\t\t\t\t.merge(collection.schema as any)\r\n\t\t\t\t\t.parseAsync(updated)) as WithBaseField<InferSchema<S>>;\r\n\r\n\t\t\t\titems[item.id as string] = validatedData;\r\n\r\n\t\t\t\tthis.data[collection.name] = items;\r\n\r\n\t\t\t\tawait this.saveToFile();\r\n\r\n\t\t\t\treturn updated;\r\n\t\t\t},\r\n\r\n\t\t\tupdateMany: async (query, data) => {\r\n\t\t\t\tconst items = this.data[collection.name] || {};\r\n\t\t\t\tconst matchingItems = Object.values(items).filter(sift(query));\r\n\t\t\t\tconst updatedItems: WithBaseField<InferSchema<S>>[] = [];\r\n\r\n\t\t\t\tfor (const item of matchingItems) {\r\n\t\t\t\t\tconst updated = await this.operations[collection.name]?.update(\r\n\t\t\t\t\t\t{ id: item.id } as any,\r\n\t\t\t\t\t\tdata,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (updated) {\r\n\t\t\t\t\t\tupdatedItems.push(updated);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn updatedItems;\r\n\t\t\t},\r\n\r\n\t\t\tdelete: async (query) => {\r\n\t\t\t\tconst items = this.data[collection.name] || {};\r\n\t\t\t\tconst item = Object.values(items).find(sift(query));\r\n\r\n\t\t\t\tif (!item) return false;\r\n\r\n\t\t\t\tdelete items[item.id as string];\r\n\t\t\t\tthis.data[collection.name] = items;\r\n\t\t\t\tawait this.saveToFile();\r\n\r\n\t\t\t\treturn true;\r\n\t\t\t},\r\n\r\n\t\t\tdeleteMany: async (query) => {\r\n\t\t\t\tconst items = this.data[collection.name] || {};\r\n\t\t\t\tconst matchingItems = Object.values(items).filter(sift(query));\r\n\r\n\t\t\t\tfor (const item of matchingItems) {\r\n\t\t\t\t\tdelete items[item.id as string];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.data[collection.name] = items;\r\n\t\t\t\tawait this.saveToFile();\r\n\r\n\t\t\t\treturn matchingItems.length;\r\n\t\t\t},\r\n\r\n\t\t\tcount: async (query) => {\r\n\t\t\t\tconst items = Object.values(this.data[collection.name] || {});\r\n\t\t\t\treturn items.filter(sift(query || {})).length;\r\n\t\t\t},\r\n\t\t};\r\n\t}\r\n\r\n\t/**\r\n\t * Gets a collection by name with its associated operations\r\n\t * @template {TCollection['name']} T\r\n\t * @param {T} collectionName - Name of the collection to retrieve\r\n\t * @returns {Operations<TSchema>} Collection operations\r\n\t * @throws {Error} If collection is not found\r\n\t */\r\n\tpublic getCollection<T extends TCollection[\"name\"]>(collectionName: T) {\r\n\t\tconst operations = this.operations[collectionName];\r\n\t\tif (!operations) {\r\n\t\t\tthrow new Error(`Collection ${collectionName} not found`);\r\n\t\t}\r\n\t\treturn operations;\r\n\t}\r\n}\r\n\r\n/**\r\n * Creates a new Bumpy database instance\r\n * @template {string} N Collection name type\r\n * @template {z.ZodSchema} S Schema type\r\n * @template {Collection<N, S>} C Collection type\r\n * @param {BumpyOptions<C>} options - Database configuration options\r\n * @returns {Bumpy<N, S, C>} New Bumpy instance\r\n * @example\r\n * const db = await createBumpy({\r\n *   basePath: './data/db.json',\r\n *   collections: [Users]\r\n * });\r\n */\r\nexport function createBumpy<\r\n\tN extends string,\r\n\tS extends z.ZodSchema,\r\n\tC extends Collection<N, S>,\r\n>(options: BumpyOptions<C>) {\r\n\treturn new Bumpy(options);\r\n}\r\n\r\n/**\r\n * Creates a new collection configuration\r\n * @template {string} N Collection name type\r\n * @template {z.ZodSchema} S Schema type\r\n * @param {Collection<N, S>} options - Collection configuration\r\n * @returns {Collection<N, S>} Frozen collection configuration\r\n * @example\r\n * const Users = createCollection({\r\n *   name: 'users',\r\n *   schema: UserSchema\r\n * });\r\n */\r\nexport function createCollection<N extends string, S extends z.ZodSchema>(\r\n\toptions: Collection<SnakeCase<N>, S>,\r\n): Collection<SnakeCase<N>, S> {\r\n\treturn Object.freeze(options);\r\n}\r\n"]}