@emulators/mongoatlas 0.5.0 → 0.6.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store.ts","../src/helpers.ts","../src/routes/data-api.ts","../src/routes/admin.ts","../src/index.ts"],"sourcesContent":["import { type Store, type Collection } from \"@emulators/core\";\nimport type {\n MongoAtlasCluster,\n MongoAtlasDatabase,\n MongoAtlasCollection,\n MongoAtlasDocument,\n MongoAtlasProject,\n MongoAtlasUser,\n} from \"./entities.js\";\n\nexport interface MongoAtlasStore {\n clusters: Collection<MongoAtlasCluster>;\n databases: Collection<MongoAtlasDatabase>;\n collections: Collection<MongoAtlasCollection>;\n documents: Collection<MongoAtlasDocument>;\n projects: Collection<MongoAtlasProject>;\n users: Collection<MongoAtlasUser>;\n}\n\nexport function getMongoAtlasStore(store: Store): MongoAtlasStore {\n return {\n clusters: store.collection<MongoAtlasCluster>(\"mongoatlas.clusters\", [\"cluster_id\", \"name\"]),\n databases: store.collection<MongoAtlasDatabase>(\"mongoatlas.databases\", [\"cluster_id\", \"name\"]),\n collections: store.collection<MongoAtlasCollection>(\"mongoatlas.collections\", [\"cluster_id\", \"database\", \"name\"]),\n documents: store.collection<MongoAtlasDocument>(\"mongoatlas.documents\", [\"cluster_id\", \"doc_id\"]),\n projects: store.collection<MongoAtlasProject>(\"mongoatlas.projects\", [\"group_id\"]),\n users: store.collection<MongoAtlasUser>(\"mongoatlas.users\", [\"user_id\", \"username\"]),\n };\n}\n","import { randomBytes } from \"crypto\";\nimport type { Context } from \"hono\";\n\nexport function generateObjectId(): string {\n const timestamp = Math.floor(Date.now() / 1000)\n .toString(16)\n .padStart(8, \"0\");\n const random = randomBytes(8).toString(\"hex\").slice(0, 16);\n return (timestamp + random).slice(0, 24);\n}\n\nexport function generateClusterId(): string {\n return randomBytes(12).toString(\"hex\");\n}\n\nexport function generateGroupId(): string {\n return randomBytes(12).toString(\"hex\");\n}\n\nexport function generateUserId(): string {\n return randomBytes(12).toString(\"hex\");\n}\n\nexport function mongoOk<T extends Record<string, unknown>>(c: Context, data: T, status = 200) {\n return c.json(data, status as 200);\n}\n\nexport function mongoError(c: Context, errorCode: string, detail: string, status = 400) {\n return c.json({ error: status, errorCode, detail }, status as 400);\n}\n","import type { RouteContext } from \"@emulators/core\";\nimport { getMongoAtlasStore } from \"../store.js\";\nimport { generateObjectId, mongoOk, mongoError } from \"../helpers.js\";\n\n/**\n * MongoDB Atlas Data API endpoints.\n * These emulate the Atlas Data API v1 for CRUD operations on documents.\n * See: https://www.mongodb.com/docs/atlas/api/data-api-resources/\n */\nexport function dataApiRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ms = () => getMongoAtlasStore(store);\n\n // Find a single document\n app.post(\"/app/data-api/v1/action/findOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n projection?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n const doc = matched[0] ?? null;\n const projected = doc ? applyProjection(doc.data, body.projection) : null;\n\n return mongoOk(c, { document: projected });\n });\n\n // Find multiple documents\n app.post(\"/app/data-api/v1/action/find\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n projection?: Record<string, unknown>;\n sort?: Record<string, number>;\n limit?: number;\n skip?: number;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n let docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n docs = matchFilter(docs, body.filter) ?? docs;\n\n if (body.sort) {\n docs = sortBySpec(docs, body.sort, (d) => d.data);\n }\n\n if (body.skip) {\n docs = docs.slice(body.skip);\n }\n\n if (body.limit) {\n docs = docs.slice(0, body.limit);\n }\n\n const documents = docs.map((d) => applyProjection(d.data, body.projection));\n return mongoOk(c, { documents });\n });\n\n // Insert a single document\n app.post(\"/app/data-api/v1/action/insertOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n document?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.document) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and document are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n\n const docId = (body.document._id as string) ?? generateObjectId();\n const data = { ...body.document, _id: docId };\n\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n\n return mongoOk(c, { insertedId: docId }, 201);\n });\n\n // Insert multiple documents\n app.post(\"/app/data-api/v1/action/insertMany\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n documents?: Array<Record<string, unknown>>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.documents) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and documents are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n\n const insertedIds: string[] = [];\n for (const doc of body.documents) {\n const docId = (doc._id as string) ?? generateObjectId();\n const data = { ...doc, _id: docId };\n\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n insertedIds.push(docId);\n }\n\n return mongoOk(c, { insertedIds }, 201);\n });\n\n // Update a single document\n app.post(\"/app/data-api/v1/action/updateOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n update?: Record<string, unknown>;\n upsert?: boolean;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.update) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and update are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n const doc = matched[0];\n\n if (doc) {\n const updatedData = applyUpdate(doc.data, body.update);\n ms().documents.update(doc.id, { data: updatedData });\n return mongoOk(c, { matchedCount: 1, modifiedCount: 1 });\n }\n\n if (body.upsert) {\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n const docId = generateObjectId();\n const baseDoc = extractEqualityFields(body.filter ?? {});\n const data = applyUpdate({ _id: docId, ...baseDoc }, body.update);\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n return mongoOk(c, { matchedCount: 0, modifiedCount: 0, upsertedId: docId });\n }\n\n return mongoOk(c, { matchedCount: 0, modifiedCount: 0 });\n });\n\n // Update multiple documents\n app.post(\"/app/data-api/v1/action/updateMany\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n update?: Record<string, unknown>;\n upsert?: boolean;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.update) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and update are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n let modifiedCount = 0;\n\n for (const doc of matched) {\n const updatedData = applyUpdate(doc.data, body.update);\n ms().documents.update(doc.id, { data: updatedData });\n modifiedCount++;\n }\n\n if (matched.length === 0 && body.upsert) {\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n const docId = generateObjectId();\n const baseDoc = extractEqualityFields(body.filter ?? {});\n const data = applyUpdate({ _id: docId, ...baseDoc }, body.update);\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n return mongoOk(c, { matchedCount: 0, modifiedCount: 0, upsertedId: docId });\n }\n\n return mongoOk(c, { matchedCount: matched.length, modifiedCount });\n });\n\n // Delete a single document\n app.post(\"/app/data-api/v1/action/deleteOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n const doc = matched[0];\n\n if (doc) {\n ms().documents.delete(doc.id);\n return mongoOk(c, { deletedCount: 1 });\n }\n\n return mongoOk(c, { deletedCount: 0 });\n });\n\n // Delete multiple documents\n app.post(\"/app/data-api/v1/action/deleteMany\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n let deletedCount = 0;\n\n for (const doc of matched) {\n ms().documents.delete(doc.id);\n deletedCount++;\n }\n\n return mongoOk(c, { deletedCount });\n });\n\n // Aggregate (simplified)\n app.post(\"/app/data-api/v1/action/aggregate\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n pipeline?: Array<Record<string, unknown>>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n // Process simplified pipeline stages\n const pipeline = body.pipeline ?? [];\n let results: Record<string, unknown>[] = docs.map((d) => d.data);\n\n for (const stage of pipeline) {\n if (\"$match\" in stage) {\n const filter = stage.$match as Record<string, unknown>;\n results = results.filter((d) => matchesFilter(d, filter));\n } else if (\"$limit\" in stage) {\n results = results.slice(0, stage.$limit as number);\n } else if (\"$skip\" in stage) {\n results = results.slice(stage.$skip as number);\n } else if (\"$sort\" in stage) {\n const sortSpec = stage.$sort as Record<string, number>;\n results = sortBySpec(results, sortSpec, (d) => d);\n } else if (\"$project\" in stage) {\n const projection = stage.$project as Record<string, unknown>;\n results = results.map((d) => applyProjection(d, projection));\n } else if (\"$count\" in stage) {\n const fieldName = stage.$count as string;\n results = [{ [fieldName]: results.length }];\n }\n }\n\n return mongoOk(c, { documents: results });\n });\n}\n\ntype MongoAtlasDocEntity = { data: Record<string, unknown>; id: number };\n\nfunction ensureCollectionExists(\n ms: () => ReturnType<typeof getMongoAtlasStore>,\n clusterId: string,\n database: string,\n collection: string,\n): void {\n const existing = ms()\n .collections.all()\n .find((col) => col.cluster_id === clusterId && col.database === database && col.name === collection);\n if (!existing) {\n // Auto-create database entry if needed\n const dbExists = ms()\n .databases.all()\n .find((db) => db.cluster_id === clusterId && db.name === database);\n if (!dbExists) {\n ms().databases.insert({ cluster_id: clusterId, name: database });\n }\n ms().collections.insert({ cluster_id: clusterId, database, name: collection });\n }\n}\n\nfunction matchesFilter(data: Record<string, unknown>, filter: Record<string, unknown>): boolean {\n for (const [key, value] of Object.entries(filter)) {\n if (key === \"$and\") {\n const conditions = value as Record<string, unknown>[];\n if (!conditions.every((cond) => matchesFilter(data, cond))) return false;\n continue;\n }\n if (key === \"$or\") {\n const conditions = value as Record<string, unknown>[];\n if (!conditions.some((cond) => matchesFilter(data, cond))) return false;\n continue;\n }\n if (key === \"$nor\") {\n const conditions = value as Record<string, unknown>[];\n if (conditions.some((cond) => matchesFilter(data, cond))) return false;\n continue;\n }\n\n const docValue = getNestedValue(data, key);\n\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n const ops = value as Record<string, unknown>;\n for (const [op, opVal] of Object.entries(ops)) {\n switch (op) {\n case \"$eq\":\n if (docValue !== opVal) return false;\n break;\n case \"$ne\":\n if (docValue === opVal) return false;\n break;\n case \"$gt\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue <= opVal) return false;\n break;\n case \"$gte\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue < opVal) return false;\n break;\n case \"$lt\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue >= opVal) return false;\n break;\n case \"$lte\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue > opVal) return false;\n break;\n case \"$in\":\n if (!Array.isArray(opVal) || !opVal.includes(docValue)) return false;\n break;\n case \"$nin\":\n if (!Array.isArray(opVal) || opVal.includes(docValue)) return false;\n break;\n case \"$exists\":\n if (opVal && docValue === undefined) return false;\n if (!opVal && docValue !== undefined) return false;\n break;\n case \"$regex\": {\n const pattern = opVal as string;\n const flags = (ops.$options as string) ?? \"\";\n try {\n if (pattern.length > 1000) return false;\n const re = new RegExp(pattern, flags);\n if (typeof docValue !== \"string\" || !re.test(docValue)) return false;\n } catch {\n return false;\n }\n break;\n }\n }\n }\n } else {\n if (docValue !== value) return false;\n }\n }\n return true;\n}\n\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split(\".\");\n if (hasDangerousKey(parts)) return undefined;\n let current: unknown = obj;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== \"object\") return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\nfunction matchFilter<T extends MongoAtlasDocEntity>(docs: T[], filter?: Record<string, unknown>): T[] | null {\n if (!filter || Object.keys(filter).length === 0) return null;\n return docs.filter((d) => matchesFilter(d.data, filter));\n}\n\nfunction applyProjection(data: Record<string, unknown>, projection?: Record<string, unknown>): Record<string, unknown> {\n if (!projection || Object.keys(projection).length === 0) return data;\n\n const hasInclusions = Object.values(projection).some((v) => v === 1 || v === true);\n\n if (hasInclusions) {\n const result: Record<string, unknown> = {};\n if (projection._id !== 0 && projection._id !== false) {\n result._id = data._id;\n }\n for (const [key, val] of Object.entries(projection)) {\n if (key === \"_id\") continue;\n if (val === 1 || val === true) {\n result[key] = data[key];\n }\n }\n return result;\n }\n\n const result = { ...data };\n for (const [key, val] of Object.entries(projection)) {\n if (val === 0 || val === false) {\n delete result[key];\n }\n }\n return result;\n}\n\nfunction applyUpdate(data: Record<string, unknown>, update: Record<string, unknown>): Record<string, unknown> {\n const result = { ...data };\n\n if (\"$set\" in update) {\n const setFields = update.$set as Record<string, unknown>;\n for (const [key, value] of Object.entries(setFields)) {\n setNestedValue(result, key, value);\n }\n }\n\n if (\"$unset\" in update) {\n const unsetFields = update.$unset as Record<string, unknown>;\n for (const key of Object.keys(unsetFields)) {\n const parts = key.split(\".\");\n if (hasDangerousKey(parts)) continue;\n if (parts.length === 1) {\n delete result[key];\n } else {\n let current: Record<string, unknown> = result;\n for (let i = 0; i < parts.length - 1; i++) {\n if (current[parts[i]] === null || current[parts[i]] === undefined || typeof current[parts[i]] !== \"object\")\n break;\n current = current[parts[i]] as Record<string, unknown>;\n }\n delete current[parts[parts.length - 1]];\n }\n }\n }\n\n if (\"$inc\" in update) {\n const incFields = update.$inc as Record<string, number>;\n for (const [key, value] of Object.entries(incFields)) {\n const current = (getNestedValue(result, key) as number) ?? 0;\n setNestedValue(result, key, current + value);\n }\n }\n\n if (\"$push\" in update) {\n const pushFields = update.$push as Record<string, unknown>;\n for (const [key, value] of Object.entries(pushFields)) {\n const current = getNestedValue(result, key);\n if (!Array.isArray(current)) {\n setNestedValue(result, key, [value]);\n } else {\n setNestedValue(result, key, [...current, value]);\n }\n }\n }\n\n if (\"$pull\" in update) {\n const pullFields = update.$pull as Record<string, unknown>;\n for (const [key, value] of Object.entries(pullFields)) {\n const current = getNestedValue(result, key);\n if (Array.isArray(current)) {\n setNestedValue(\n result,\n key,\n current.filter((item) => item !== value),\n );\n }\n }\n }\n\n if (\"$rename\" in update) {\n const renameFields = update.$rename as Record<string, string>;\n for (const [oldKey, newKey] of Object.entries(renameFields)) {\n const oldParts = oldKey.split(\".\");\n const newParts = newKey.split(\".\");\n if (hasDangerousKey(oldParts) || hasDangerousKey(newParts)) continue;\n const value = getNestedValue(result, oldKey);\n if (value !== undefined) {\n setNestedValue(result, newKey, value);\n if (oldParts.length === 1) {\n delete result[oldKey];\n } else {\n let current: Record<string, unknown> = result;\n for (let i = 0; i < oldParts.length - 1; i++) {\n if (typeof current[oldParts[i]] !== \"object\" || current[oldParts[i]] === null) break;\n current = current[oldParts[i]] as Record<string, unknown>;\n }\n delete current[oldParts[oldParts.length - 1]];\n }\n }\n }\n }\n\n // If no operators found, treat the entire update as a replacement (minus _id)\n const hasOperators = Object.keys(update).some((k) => k.startsWith(\"$\"));\n if (!hasOperators) {\n const id = result._id;\n for (const key of Object.keys(result)) {\n delete result[key];\n }\n result._id = id;\n Object.assign(result, update);\n }\n\n return result;\n}\n\nconst DANGEROUS_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nfunction hasDangerousKey(parts: string[]): boolean {\n return parts.some((p) => DANGEROUS_KEYS.has(p));\n}\n\nfunction setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split(\".\");\n if (hasDangerousKey(parts)) return;\n let current = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!(parts[i] in current) || typeof current[parts[i]] !== \"object\") {\n current[parts[i]] = {};\n }\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = value;\n}\n\nfunction sortBySpec<T>(\n docs: T[],\n sortSpec: Record<string, number>,\n accessor: (doc: T) => Record<string, unknown>,\n): T[] {\n return [...docs].sort((a, b) => {\n for (const [key, direction] of Object.entries(sortSpec)) {\n const aVal = getNestedValue(accessor(a), key);\n const bVal = getNestedValue(accessor(b), key);\n if (aVal === bVal) continue;\n if (aVal === undefined) return direction;\n if (bVal === undefined) return -direction;\n if ((aVal as number) < (bVal as number)) return -direction;\n if ((aVal as number) > (bVal as number)) return direction;\n }\n return 0;\n });\n}\n\n/**\n * Extract simple equality fields from a filter for use as a base document during upsert.\n * Strips out query operators (keys starting with $) and fields with operator-object values.\n */\nfunction extractEqualityFields(filter: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(filter)) {\n if (key.startsWith(\"$\")) continue;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n const ops = value as Record<string, unknown>;\n if (Object.keys(ops).some((k) => k.startsWith(\"$\"))) continue;\n }\n result[key] = value;\n }\n return result;\n}\n","import type { RouteContext } from \"@emulators/core\";\nimport { getMongoAtlasStore } from \"../store.js\";\nimport { generateClusterId, generateGroupId, generateUserId, mongoOk, mongoError } from \"../helpers.js\";\n\n/**\n * MongoDB Atlas Admin API endpoints.\n * These emulate the Atlas Administration API v2 for managing projects, clusters, and users.\n * See: https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/\n */\nexport function adminRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ms = () => getMongoAtlasStore(store);\n\n // --- Projects ---\n\n // List projects\n app.get(\"/api/atlas/v2/groups\", (c) => {\n const projects = ms().projects.all();\n return mongoOk(c, {\n results: projects.map(formatProject),\n totalCount: projects.length,\n });\n });\n\n // Get project by ID\n app.get(\"/api/atlas/v2/groups/:groupId\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n return mongoOk(c, formatProject(project));\n });\n\n // Create project\n app.post(\"/api/atlas/v2/groups\", async (c) => {\n const body = await c.req.json<{ name?: string; orgId?: string }>();\n if (!body.name?.trim()) {\n return mongoError(c, \"INVALID_PARAMETER\", \"name is required\");\n }\n\n const existing = ms()\n .projects.all()\n .find((p) => p.name === body.name);\n if (existing) {\n return mongoError(c, \"DUPLICATE_GROUP_NAME\", `Group name '${body.name}' already exists.`, 409);\n }\n\n const groupId = generateGroupId();\n const project = ms().projects.insert({\n group_id: groupId,\n name: body.name,\n org_id: body.orgId ?? \"default_org\",\n cluster_count: 0,\n });\n\n return mongoOk(c, formatProject(project), 201);\n });\n\n // Delete project\n app.delete(\"/api/atlas/v2/groups/:groupId\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n\n // Cascade delete clusters in this project\n const clusters = ms()\n .clusters.all()\n .filter((cl) => cl.group_id === groupId);\n for (const cluster of clusters) {\n deleteClusterData(ms, cluster.cluster_id);\n ms().clusters.delete(cluster.id);\n }\n\n ms().projects.delete(project.id);\n return c.body(null, 204);\n });\n\n // --- Clusters ---\n\n // List clusters\n app.get(\"/api/atlas/v2/groups/:groupId/clusters\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n\n const clusters = ms()\n .clusters.all()\n .filter((cl) => cl.group_id === groupId);\n return mongoOk(c, {\n results: clusters.map(formatCluster),\n totalCount: clusters.length,\n });\n });\n\n // Get cluster\n app.get(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n return mongoOk(c, formatCluster(cluster));\n });\n\n // Create cluster\n app.post(\"/api/atlas/v2/groups/:groupId/clusters\", async (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n\n const body = await c.req.json<{\n name?: string;\n clusterType?: \"REPLICASET\" | \"SHARDED\";\n providerSettings?: {\n providerName?: string;\n instanceSizeName?: string;\n regionName?: string;\n };\n diskSizeGB?: number;\n mongoDBMajorVersion?: string;\n }>();\n\n if (!body.name?.trim()) {\n return mongoError(c, \"INVALID_PARAMETER\", \"name is required\");\n }\n\n const existing = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === body.name);\n if (existing) {\n return mongoError(c, \"DUPLICATE_CLUSTER_NAME\", `Cluster '${body.name}' already exists.`, 409);\n }\n\n const clusterId = generateClusterId();\n const cluster = ms().clusters.insert({\n cluster_id: clusterId,\n name: body.name,\n group_id: groupId,\n state: \"IDLE\",\n mongo_uri: `mongodb+srv://${body.name}.emulate.mongodb.net`,\n connection_strings: {\n standard: `mongodb://${body.name}.emulate.mongodb.net:27017`,\n standard_srv: `mongodb+srv://${body.name}.emulate.mongodb.net`,\n },\n provider_settings: {\n provider_name: body.providerSettings?.providerName ?? \"AWS\",\n instance_size_name: body.providerSettings?.instanceSizeName ?? \"M10\",\n region_name: body.providerSettings?.regionName ?? \"US_EAST_1\",\n },\n cluster_type: body.clusterType ?? \"REPLICASET\",\n disk_size_gb: body.diskSizeGB ?? 10,\n mongodb_version: body.mongoDBMajorVersion ?? \"8.0\",\n });\n\n ms().projects.update(project.id, { cluster_count: project.cluster_count + 1 });\n\n return mongoOk(c, formatCluster(cluster), 201);\n });\n\n // Update cluster\n app.patch(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName\", async (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n const body = await c.req.json<{\n providerSettings?: {\n instanceSizeName?: string;\n regionName?: string;\n };\n diskSizeGB?: number;\n }>();\n\n const updates: Partial<typeof cluster> = {};\n if (body.providerSettings) {\n updates.provider_settings = {\n provider_name: cluster.provider_settings.provider_name,\n instance_size_name: body.providerSettings.instanceSizeName ?? cluster.provider_settings.instance_size_name,\n region_name: body.providerSettings.regionName ?? cluster.provider_settings.region_name,\n };\n }\n if (body.diskSizeGB !== undefined) {\n updates.disk_size_gb = body.diskSizeGB;\n }\n\n const updated = ms().clusters.update(cluster.id, updates);\n return mongoOk(c, formatCluster(updated!));\n });\n\n // Delete cluster\n app.delete(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n deleteClusterData(ms, cluster.cluster_id);\n ms().clusters.delete(cluster.id);\n\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (project) {\n ms().projects.update(project.id, { cluster_count: Math.max(0, project.cluster_count - 1) });\n }\n\n return c.body(null, 204);\n });\n\n // --- Database Users ---\n\n // List database users\n app.get(\"/api/atlas/v2/groups/:groupId/databaseUsers\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const users = ms()\n .users.all()\n .filter((u) => u.group_id === groupId);\n return mongoOk(c, {\n results: users.map(formatUser),\n totalCount: users.length,\n });\n });\n\n // Get database user\n app.get(\"/api/atlas/v2/groups/:groupId/databaseUsers/admin/:username\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const username = c.req.param(\"username\");\n const user = ms()\n .users.all()\n .find((u) => u.group_id === groupId && u.username === username);\n\n if (!user) {\n return mongoError(c, \"USER_NOT_FOUND\", `Database user '${username}' not found.`, 404);\n }\n\n return mongoOk(c, formatUser(user));\n });\n\n // Create database user\n app.post(\"/api/atlas/v2/groups/:groupId/databaseUsers\", async (c) => {\n const groupId = c.req.param(\"groupId\");\n const body = await c.req.json<{\n username?: string;\n password?: string;\n databaseName?: string;\n roles?: Array<{ databaseName: string; roleName: string }>;\n }>();\n\n if (!body.username?.trim()) {\n return mongoError(c, \"INVALID_PARAMETER\", \"username is required\");\n }\n\n const existing = ms()\n .users.all()\n .find((u) => u.group_id === groupId && u.username === body.username);\n if (existing) {\n return mongoError(c, \"DUPLICATE_USER\", `User '${body.username}' already exists.`, 409);\n }\n\n const userId = generateUserId();\n const user = ms().users.insert({\n user_id: userId,\n username: body.username,\n group_id: groupId,\n roles: (body.roles ?? []).map((r) => ({ database_name: r.databaseName, role_name: r.roleName })),\n });\n\n return mongoOk(c, formatUser(user), 201);\n });\n\n // Delete database user\n app.delete(\"/api/atlas/v2/groups/:groupId/databaseUsers/admin/:username\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const username = c.req.param(\"username\");\n const user = ms()\n .users.all()\n .find((u) => u.group_id === groupId && u.username === username);\n\n if (!user) {\n return mongoError(c, \"USER_NOT_FOUND\", `Database user '${username}' not found.`, 404);\n }\n\n ms().users.delete(user.id);\n return c.body(null, 204);\n });\n\n // --- Databases & Collections (Data Explorer) ---\n\n // List databases in a cluster\n app.get(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName/databases\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n const databases = ms()\n .databases.all()\n .filter((db) => db.cluster_id === cluster.cluster_id);\n return mongoOk(c, {\n results: databases.map((db) => ({ databaseName: db.name })),\n totalCount: databases.length,\n });\n });\n\n // List collections in a database\n app.get(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName/databases/:databaseName/collections\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const databaseName = c.req.param(\"databaseName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n const collections = ms()\n .collections.all()\n .filter((col) => col.cluster_id === cluster.cluster_id && col.database === databaseName);\n return mongoOk(c, {\n results: collections.map((col) => ({ collectionName: col.name, databaseName })),\n totalCount: collections.length,\n });\n });\n}\n\nfunction deleteClusterData(ms: () => ReturnType<typeof getMongoAtlasStore>, clusterId: string): void {\n const docs = ms()\n .documents.all()\n .filter((d) => d.cluster_id === clusterId);\n for (const doc of docs) ms().documents.delete(doc.id);\n\n const cols = ms()\n .collections.all()\n .filter((col) => col.cluster_id === clusterId);\n for (const col of cols) ms().collections.delete(col.id);\n\n const dbs = ms()\n .databases.all()\n .filter((db) => db.cluster_id === clusterId);\n for (const db of dbs) ms().databases.delete(db.id);\n}\n\nfunction formatProject(p: {\n group_id: string;\n name: string;\n org_id: string;\n cluster_count: number;\n created_at: string;\n}) {\n return {\n id: p.group_id,\n name: p.name,\n orgId: p.org_id,\n clusterCount: p.cluster_count,\n created: p.created_at,\n };\n}\n\nfunction formatCluster(cl: {\n cluster_id: string;\n name: string;\n group_id: string;\n state: string;\n mongo_uri: string;\n connection_strings: { standard: string; standard_srv: string };\n provider_settings: { provider_name: string; instance_size_name: string; region_name: string };\n cluster_type: string;\n disk_size_gb: number;\n mongodb_version: string;\n created_at: string;\n}) {\n return {\n id: cl.cluster_id,\n name: cl.name,\n groupId: cl.group_id,\n stateName: cl.state,\n mongoURI: cl.mongo_uri,\n connectionStrings: {\n standard: cl.connection_strings.standard,\n standardSrv: cl.connection_strings.standard_srv,\n },\n providerSettings: {\n providerName: cl.provider_settings.provider_name,\n instanceSizeName: cl.provider_settings.instance_size_name,\n regionName: cl.provider_settings.region_name,\n },\n clusterType: cl.cluster_type,\n diskSizeGB: cl.disk_size_gb,\n mongoDBVersion: cl.mongodb_version,\n created: cl.created_at,\n };\n}\n\nfunction formatUser(u: {\n user_id: string;\n username: string;\n group_id: string;\n roles: Array<{ database_name: string; role_name: string }>;\n}) {\n return {\n username: u.username,\n groupId: u.group_id,\n databaseName: \"admin\",\n roles: u.roles.map((r) => ({ databaseName: r.database_name, roleName: r.role_name })),\n };\n}\n","import type { Hono } from \"hono\";\nimport type { ServicePlugin, Store, WebhookDispatcher, TokenMap, AppEnv, RouteContext } from \"@emulators/core\";\nimport { getMongoAtlasStore } from \"./store.js\";\nimport { generateClusterId, generateGroupId, generateUserId } from \"./helpers.js\";\nimport { dataApiRoutes } from \"./routes/data-api.js\";\nimport { adminRoutes } from \"./routes/admin.js\";\n\nexport { getMongoAtlasStore, type MongoAtlasStore } from \"./store.js\";\nexport * from \"./entities.js\";\n\nexport interface MongoAtlasSeedConfig {\n port?: number;\n projects?: Array<{\n name: string;\n org_id?: string;\n }>;\n clusters?: Array<{\n name: string;\n project: string;\n provider?: string;\n instance_size?: string;\n region?: string;\n disk_size_gb?: number;\n mongodb_version?: string;\n }>;\n database_users?: Array<{\n username: string;\n project: string;\n roles?: Array<{ database_name: string; role_name: string }>;\n }>;\n databases?: Array<{\n cluster: string;\n name: string;\n collections?: string[];\n }>;\n}\n\nfunction seedDefaults(store: Store, _baseUrl: string): void {\n const ms = getMongoAtlasStore(store);\n\n const groupId = generateGroupId();\n ms.projects.insert({\n group_id: groupId,\n name: \"Project0\",\n org_id: \"default_org\",\n cluster_count: 1,\n });\n\n const clusterId = generateClusterId();\n ms.clusters.insert({\n cluster_id: clusterId,\n name: \"Cluster0\",\n group_id: groupId,\n state: \"IDLE\",\n mongo_uri: \"mongodb+srv://Cluster0.emulate.mongodb.net\",\n connection_strings: {\n standard: \"mongodb://Cluster0.emulate.mongodb.net:27017\",\n standard_srv: \"mongodb+srv://Cluster0.emulate.mongodb.net\",\n },\n provider_settings: {\n provider_name: \"AWS\",\n instance_size_name: \"M10\",\n region_name: \"US_EAST_1\",\n },\n cluster_type: \"REPLICASET\",\n disk_size_gb: 10,\n mongodb_version: \"8.0\",\n });\n\n ms.users.insert({\n user_id: generateUserId(),\n username: \"admin\",\n group_id: groupId,\n roles: [{ database_name: \"admin\", role_name: \"atlasAdmin\" }],\n });\n\n ms.databases.insert({ cluster_id: clusterId, name: \"test\" });\n ms.collections.insert({ cluster_id: clusterId, database: \"test\", name: \"items\" });\n}\n\nexport function seedFromConfig(store: Store, _baseUrl: string, config: MongoAtlasSeedConfig): void {\n const ms = getMongoAtlasStore(store);\n\n const projectIdMap = new Map<string, string>();\n\n if (config.projects) {\n for (const p of config.projects) {\n const existing = ms.projects.all().find((ep) => ep.name === p.name);\n if (existing) {\n projectIdMap.set(p.name, existing.group_id);\n continue;\n }\n\n const groupId = generateGroupId();\n ms.projects.insert({\n group_id: groupId,\n name: p.name,\n org_id: p.org_id ?? \"default_org\",\n cluster_count: 0,\n });\n projectIdMap.set(p.name, groupId);\n }\n }\n\n // Map default project\n const defaultProject = ms.projects.all()[0];\n if (defaultProject) {\n projectIdMap.set(defaultProject.name, defaultProject.group_id);\n }\n\n const clusterIdMap = new Map<string, string>();\n\n if (config.clusters) {\n for (const cl of config.clusters) {\n const groupId = projectIdMap.get(cl.project);\n if (!groupId) continue;\n\n const existing = ms.clusters.all().find((ec) => ec.group_id === groupId && ec.name === cl.name);\n if (existing) {\n clusterIdMap.set(cl.name, existing.cluster_id);\n continue;\n }\n\n const clusterId = generateClusterId();\n ms.clusters.insert({\n cluster_id: clusterId,\n name: cl.name,\n group_id: groupId,\n state: \"IDLE\",\n mongo_uri: `mongodb+srv://${cl.name}.emulate.mongodb.net`,\n connection_strings: {\n standard: `mongodb://${cl.name}.emulate.mongodb.net:27017`,\n standard_srv: `mongodb+srv://${cl.name}.emulate.mongodb.net`,\n },\n provider_settings: {\n provider_name: cl.provider ?? \"AWS\",\n instance_size_name: cl.instance_size ?? \"M10\",\n region_name: cl.region ?? \"US_EAST_1\",\n },\n cluster_type: \"REPLICASET\",\n disk_size_gb: cl.disk_size_gb ?? 10,\n mongodb_version: cl.mongodb_version ?? \"8.0\",\n });\n clusterIdMap.set(cl.name, clusterId);\n\n const project = ms.projects.findOneBy(\"group_id\", groupId);\n if (project) {\n ms.projects.update(project.id, { cluster_count: project.cluster_count + 1 });\n }\n }\n }\n\n // Map default cluster\n const defaultCluster = ms.clusters.all()[0];\n if (defaultCluster) {\n clusterIdMap.set(defaultCluster.name, defaultCluster.cluster_id);\n }\n\n if (config.database_users) {\n for (const u of config.database_users) {\n const groupId = projectIdMap.get(u.project);\n if (!groupId) continue;\n\n const existing = ms.users.all().find((eu) => eu.group_id === groupId && eu.username === u.username);\n if (existing) continue;\n\n ms.users.insert({\n user_id: generateUserId(),\n username: u.username,\n group_id: groupId,\n roles: u.roles ?? [{ database_name: \"admin\", role_name: \"readWriteAnyDatabase\" }],\n });\n }\n }\n\n if (config.databases) {\n for (const db of config.databases) {\n const clusterId = clusterIdMap.get(db.cluster);\n if (!clusterId) continue;\n\n const existingDb = ms.databases.all().find((edb) => edb.cluster_id === clusterId && edb.name === db.name);\n if (!existingDb) {\n ms.databases.insert({ cluster_id: clusterId, name: db.name });\n }\n\n if (db.collections) {\n for (const colName of db.collections) {\n const existingCol = ms.collections\n .all()\n .find((ec) => ec.cluster_id === clusterId && ec.database === db.name && ec.name === colName);\n if (!existingCol) {\n ms.collections.insert({ cluster_id: clusterId, database: db.name, name: colName });\n }\n }\n }\n }\n }\n}\n\nexport const mongoatlasPlugin: ServicePlugin = {\n name: \"mongoatlas\",\n register(app: Hono<AppEnv>, store: Store, webhooks: WebhookDispatcher, baseUrl: string, tokenMap?: TokenMap): void {\n const ctx: RouteContext = { app, store, webhooks, baseUrl, tokenMap };\n adminRoutes(ctx);\n dataApiRoutes(ctx);\n },\n seed(store: Store, baseUrl: string): void {\n seedDefaults(store, baseUrl);\n },\n};\n\nexport default mongoatlasPlugin;\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../src/store.ts","../src/helpers.ts","../src/routes/data-api.ts","../src/routes/admin.ts","../src/index.ts"],"sourcesContent":["import { type Store, type Collection } from \"@emulators/core\";\nimport type {\n MongoAtlasCluster,\n MongoAtlasDatabase,\n MongoAtlasCollection,\n MongoAtlasDocument,\n MongoAtlasProject,\n MongoAtlasUser,\n} from \"./entities.js\";\n\nexport interface MongoAtlasStore {\n clusters: Collection<MongoAtlasCluster>;\n databases: Collection<MongoAtlasDatabase>;\n collections: Collection<MongoAtlasCollection>;\n documents: Collection<MongoAtlasDocument>;\n projects: Collection<MongoAtlasProject>;\n users: Collection<MongoAtlasUser>;\n}\n\nexport function getMongoAtlasStore(store: Store): MongoAtlasStore {\n return {\n clusters: store.collection<MongoAtlasCluster>(\"mongoatlas.clusters\", [\"cluster_id\", \"name\"]),\n databases: store.collection<MongoAtlasDatabase>(\"mongoatlas.databases\", [\"cluster_id\", \"name\"]),\n collections: store.collection<MongoAtlasCollection>(\"mongoatlas.collections\", [\"cluster_id\", \"database\", \"name\"]),\n documents: store.collection<MongoAtlasDocument>(\"mongoatlas.documents\", [\"cluster_id\", \"doc_id\"]),\n projects: store.collection<MongoAtlasProject>(\"mongoatlas.projects\", [\"group_id\"]),\n users: store.collection<MongoAtlasUser>(\"mongoatlas.users\", [\"user_id\", \"username\"]),\n };\n}\n","import { randomBytes } from \"crypto\";\nimport type { Context } from \"@emulators/core\";\n\nexport function generateObjectId(): string {\n const timestamp = Math.floor(Date.now() / 1000)\n .toString(16)\n .padStart(8, \"0\");\n const random = randomBytes(8).toString(\"hex\").slice(0, 16);\n return (timestamp + random).slice(0, 24);\n}\n\nexport function generateClusterId(): string {\n return randomBytes(12).toString(\"hex\");\n}\n\nexport function generateGroupId(): string {\n return randomBytes(12).toString(\"hex\");\n}\n\nexport function generateUserId(): string {\n return randomBytes(12).toString(\"hex\");\n}\n\nexport function mongoOk<T extends Record<string, unknown>>(c: Context, data: T, status = 200) {\n return c.json(data, status as 200);\n}\n\nexport function mongoError(c: Context, errorCode: string, detail: string, status = 400) {\n return c.json({ error: status, errorCode, detail }, status as 400);\n}\n","import type { RouteContext } from \"@emulators/core\";\nimport { getMongoAtlasStore } from \"../store.js\";\nimport { generateObjectId, mongoOk, mongoError } from \"../helpers.js\";\n\n/**\n * MongoDB Atlas Data API endpoints.\n * These emulate the Atlas Data API v1 for CRUD operations on documents.\n * See: https://www.mongodb.com/docs/atlas/api/data-api-resources/\n */\nexport function dataApiRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ms = () => getMongoAtlasStore(store);\n\n // Find a single document\n app.post(\"/app/data-api/v1/action/findOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n projection?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n const doc = matched[0] ?? null;\n const projected = doc ? applyProjection(doc.data, body.projection) : null;\n\n return mongoOk(c, { document: projected });\n });\n\n // Find multiple documents\n app.post(\"/app/data-api/v1/action/find\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n projection?: Record<string, unknown>;\n sort?: Record<string, number>;\n limit?: number;\n skip?: number;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n let docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n docs = matchFilter(docs, body.filter) ?? docs;\n\n if (body.sort) {\n docs = sortBySpec(docs, body.sort, (d) => d.data);\n }\n\n if (body.skip) {\n docs = docs.slice(body.skip);\n }\n\n if (body.limit) {\n docs = docs.slice(0, body.limit);\n }\n\n const documents = docs.map((d) => applyProjection(d.data, body.projection));\n return mongoOk(c, { documents });\n });\n\n // Insert a single document\n app.post(\"/app/data-api/v1/action/insertOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n document?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.document) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and document are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n\n const docId = (body.document._id as string) ?? generateObjectId();\n const data = { ...body.document, _id: docId };\n\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n\n return mongoOk(c, { insertedId: docId }, 201);\n });\n\n // Insert multiple documents\n app.post(\"/app/data-api/v1/action/insertMany\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n documents?: Array<Record<string, unknown>>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.documents) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and documents are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n\n const insertedIds: string[] = [];\n for (const doc of body.documents) {\n const docId = (doc._id as string) ?? generateObjectId();\n const data = { ...doc, _id: docId };\n\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n insertedIds.push(docId);\n }\n\n return mongoOk(c, { insertedIds }, 201);\n });\n\n // Update a single document\n app.post(\"/app/data-api/v1/action/updateOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n update?: Record<string, unknown>;\n upsert?: boolean;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.update) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and update are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n const doc = matched[0];\n\n if (doc) {\n const updatedData = applyUpdate(doc.data, body.update);\n ms().documents.update(doc.id, { data: updatedData });\n return mongoOk(c, { matchedCount: 1, modifiedCount: 1 });\n }\n\n if (body.upsert) {\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n const docId = generateObjectId();\n const baseDoc = extractEqualityFields(body.filter ?? {});\n const data = applyUpdate({ _id: docId, ...baseDoc }, body.update);\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n return mongoOk(c, { matchedCount: 0, modifiedCount: 0, upsertedId: docId });\n }\n\n return mongoOk(c, { matchedCount: 0, modifiedCount: 0 });\n });\n\n // Update multiple documents\n app.post(\"/app/data-api/v1/action/updateMany\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n update?: Record<string, unknown>;\n upsert?: boolean;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection || !body.update) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, collection, and update are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n let modifiedCount = 0;\n\n for (const doc of matched) {\n const updatedData = applyUpdate(doc.data, body.update);\n ms().documents.update(doc.id, { data: updatedData });\n modifiedCount++;\n }\n\n if (matched.length === 0 && body.upsert) {\n ensureCollectionExists(ms, cluster.cluster_id, body.database, body.collection);\n const docId = generateObjectId();\n const baseDoc = extractEqualityFields(body.filter ?? {});\n const data = applyUpdate({ _id: docId, ...baseDoc }, body.update);\n ms().documents.insert({\n cluster_id: cluster.cluster_id,\n database: body.database,\n collection: body.collection,\n doc_id: docId,\n data,\n });\n return mongoOk(c, { matchedCount: 0, modifiedCount: 0, upsertedId: docId });\n }\n\n return mongoOk(c, { matchedCount: matched.length, modifiedCount });\n });\n\n // Delete a single document\n app.post(\"/app/data-api/v1/action/deleteOne\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n const doc = matched[0];\n\n if (doc) {\n ms().documents.delete(doc.id);\n return mongoOk(c, { deletedCount: 1 });\n }\n\n return mongoOk(c, { deletedCount: 0 });\n });\n\n // Delete multiple documents\n app.post(\"/app/data-api/v1/action/deleteMany\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n filter?: Record<string, unknown>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n const matched = matchFilter(docs, body.filter) ?? docs;\n let deletedCount = 0;\n\n for (const doc of matched) {\n ms().documents.delete(doc.id);\n deletedCount++;\n }\n\n return mongoOk(c, { deletedCount });\n });\n\n // Aggregate (simplified)\n app.post(\"/app/data-api/v1/action/aggregate\", async (c) => {\n const body = await c.req.json<{\n dataSource?: string;\n database?: string;\n collection?: string;\n pipeline?: Array<Record<string, unknown>>;\n }>();\n\n if (!body.dataSource || !body.database || !body.collection) {\n return mongoError(c, \"InvalidParameter\", \"dataSource, database, and collection are required\");\n }\n\n const cluster = ms().clusters.findOneBy(\"name\", body.dataSource);\n if (!cluster) {\n return mongoError(c, \"ClusterNotFound\", `Cluster '${body.dataSource}' not found`, 404);\n }\n\n const docs = ms()\n .documents.all()\n .filter(\n (d) => d.cluster_id === cluster.cluster_id && d.database === body.database && d.collection === body.collection,\n );\n\n // Process simplified pipeline stages\n const pipeline = body.pipeline ?? [];\n let results: Record<string, unknown>[] = docs.map((d) => d.data);\n\n for (const stage of pipeline) {\n if (\"$match\" in stage) {\n const filter = stage.$match as Record<string, unknown>;\n results = results.filter((d) => matchesFilter(d, filter));\n } else if (\"$limit\" in stage) {\n results = results.slice(0, stage.$limit as number);\n } else if (\"$skip\" in stage) {\n results = results.slice(stage.$skip as number);\n } else if (\"$sort\" in stage) {\n const sortSpec = stage.$sort as Record<string, number>;\n results = sortBySpec(results, sortSpec, (d) => d);\n } else if (\"$project\" in stage) {\n const projection = stage.$project as Record<string, unknown>;\n results = results.map((d) => applyProjection(d, projection));\n } else if (\"$count\" in stage) {\n const fieldName = stage.$count as string;\n results = [{ [fieldName]: results.length }];\n }\n }\n\n return mongoOk(c, { documents: results });\n });\n}\n\ntype MongoAtlasDocEntity = { data: Record<string, unknown>; id: number };\n\nfunction ensureCollectionExists(\n ms: () => ReturnType<typeof getMongoAtlasStore>,\n clusterId: string,\n database: string,\n collection: string,\n): void {\n const existing = ms()\n .collections.all()\n .find((col) => col.cluster_id === clusterId && col.database === database && col.name === collection);\n if (!existing) {\n // Auto-create database entry if needed\n const dbExists = ms()\n .databases.all()\n .find((db) => db.cluster_id === clusterId && db.name === database);\n if (!dbExists) {\n ms().databases.insert({ cluster_id: clusterId, name: database });\n }\n ms().collections.insert({ cluster_id: clusterId, database, name: collection });\n }\n}\n\nfunction matchesFilter(data: Record<string, unknown>, filter: Record<string, unknown>): boolean {\n for (const [key, value] of Object.entries(filter)) {\n if (key === \"$and\") {\n const conditions = value as Record<string, unknown>[];\n if (!conditions.every((cond) => matchesFilter(data, cond))) return false;\n continue;\n }\n if (key === \"$or\") {\n const conditions = value as Record<string, unknown>[];\n if (!conditions.some((cond) => matchesFilter(data, cond))) return false;\n continue;\n }\n if (key === \"$nor\") {\n const conditions = value as Record<string, unknown>[];\n if (conditions.some((cond) => matchesFilter(data, cond))) return false;\n continue;\n }\n\n const docValue = getNestedValue(data, key);\n\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n const ops = value as Record<string, unknown>;\n for (const [op, opVal] of Object.entries(ops)) {\n switch (op) {\n case \"$eq\":\n if (docValue !== opVal) return false;\n break;\n case \"$ne\":\n if (docValue === opVal) return false;\n break;\n case \"$gt\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue <= opVal) return false;\n break;\n case \"$gte\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue < opVal) return false;\n break;\n case \"$lt\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue >= opVal) return false;\n break;\n case \"$lte\":\n if (typeof docValue !== \"number\" || typeof opVal !== \"number\" || docValue > opVal) return false;\n break;\n case \"$in\":\n if (!Array.isArray(opVal) || !opVal.includes(docValue)) return false;\n break;\n case \"$nin\":\n if (!Array.isArray(opVal) || opVal.includes(docValue)) return false;\n break;\n case \"$exists\":\n if (opVal && docValue === undefined) return false;\n if (!opVal && docValue !== undefined) return false;\n break;\n case \"$regex\": {\n const pattern = opVal as string;\n const flags = (ops.$options as string) ?? \"\";\n try {\n if (pattern.length > 1000) return false;\n const re = new RegExp(pattern, flags);\n if (typeof docValue !== \"string\" || !re.test(docValue)) return false;\n } catch {\n return false;\n }\n break;\n }\n }\n }\n } else {\n if (docValue !== value) return false;\n }\n }\n return true;\n}\n\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split(\".\");\n if (hasDangerousKey(parts)) return undefined;\n let current: unknown = obj;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== \"object\") return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\nfunction matchFilter<T extends MongoAtlasDocEntity>(docs: T[], filter?: Record<string, unknown>): T[] | null {\n if (!filter || Object.keys(filter).length === 0) return null;\n return docs.filter((d) => matchesFilter(d.data, filter));\n}\n\nfunction applyProjection(data: Record<string, unknown>, projection?: Record<string, unknown>): Record<string, unknown> {\n if (!projection || Object.keys(projection).length === 0) return data;\n\n const hasInclusions = Object.values(projection).some((v) => v === 1 || v === true);\n\n if (hasInclusions) {\n const result: Record<string, unknown> = {};\n if (projection._id !== 0 && projection._id !== false) {\n result._id = data._id;\n }\n for (const [key, val] of Object.entries(projection)) {\n if (key === \"_id\") continue;\n if (val === 1 || val === true) {\n result[key] = data[key];\n }\n }\n return result;\n }\n\n const result = { ...data };\n for (const [key, val] of Object.entries(projection)) {\n if (val === 0 || val === false) {\n delete result[key];\n }\n }\n return result;\n}\n\nfunction applyUpdate(data: Record<string, unknown>, update: Record<string, unknown>): Record<string, unknown> {\n const result = { ...data };\n\n if (\"$set\" in update) {\n const setFields = update.$set as Record<string, unknown>;\n for (const [key, value] of Object.entries(setFields)) {\n setNestedValue(result, key, value);\n }\n }\n\n if (\"$unset\" in update) {\n const unsetFields = update.$unset as Record<string, unknown>;\n for (const key of Object.keys(unsetFields)) {\n const parts = key.split(\".\");\n if (hasDangerousKey(parts)) continue;\n if (parts.length === 1) {\n delete result[key];\n } else {\n let current: Record<string, unknown> = result;\n for (let i = 0; i < parts.length - 1; i++) {\n if (current[parts[i]] === null || current[parts[i]] === undefined || typeof current[parts[i]] !== \"object\")\n break;\n current = current[parts[i]] as Record<string, unknown>;\n }\n delete current[parts[parts.length - 1]];\n }\n }\n }\n\n if (\"$inc\" in update) {\n const incFields = update.$inc as Record<string, number>;\n for (const [key, value] of Object.entries(incFields)) {\n const current = (getNestedValue(result, key) as number) ?? 0;\n setNestedValue(result, key, current + value);\n }\n }\n\n if (\"$push\" in update) {\n const pushFields = update.$push as Record<string, unknown>;\n for (const [key, value] of Object.entries(pushFields)) {\n const current = getNestedValue(result, key);\n if (!Array.isArray(current)) {\n setNestedValue(result, key, [value]);\n } else {\n setNestedValue(result, key, [...current, value]);\n }\n }\n }\n\n if (\"$pull\" in update) {\n const pullFields = update.$pull as Record<string, unknown>;\n for (const [key, value] of Object.entries(pullFields)) {\n const current = getNestedValue(result, key);\n if (Array.isArray(current)) {\n setNestedValue(\n result,\n key,\n current.filter((item) => item !== value),\n );\n }\n }\n }\n\n if (\"$rename\" in update) {\n const renameFields = update.$rename as Record<string, string>;\n for (const [oldKey, newKey] of Object.entries(renameFields)) {\n const oldParts = oldKey.split(\".\");\n const newParts = newKey.split(\".\");\n if (hasDangerousKey(oldParts) || hasDangerousKey(newParts)) continue;\n const value = getNestedValue(result, oldKey);\n if (value !== undefined) {\n setNestedValue(result, newKey, value);\n if (oldParts.length === 1) {\n delete result[oldKey];\n } else {\n let current: Record<string, unknown> = result;\n for (let i = 0; i < oldParts.length - 1; i++) {\n if (typeof current[oldParts[i]] !== \"object\" || current[oldParts[i]] === null) break;\n current = current[oldParts[i]] as Record<string, unknown>;\n }\n delete current[oldParts[oldParts.length - 1]];\n }\n }\n }\n }\n\n // If no operators found, treat the entire update as a replacement (minus _id)\n const hasOperators = Object.keys(update).some((k) => k.startsWith(\"$\"));\n if (!hasOperators) {\n const id = result._id;\n for (const key of Object.keys(result)) {\n delete result[key];\n }\n result._id = id;\n Object.assign(result, update);\n }\n\n return result;\n}\n\nconst DANGEROUS_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nfunction hasDangerousKey(parts: string[]): boolean {\n return parts.some((p) => DANGEROUS_KEYS.has(p));\n}\n\nfunction setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split(\".\");\n if (hasDangerousKey(parts)) return;\n let current = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!(parts[i] in current) || typeof current[parts[i]] !== \"object\") {\n current[parts[i]] = {};\n }\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = value;\n}\n\nfunction sortBySpec<T>(\n docs: T[],\n sortSpec: Record<string, number>,\n accessor: (doc: T) => Record<string, unknown>,\n): T[] {\n return [...docs].sort((a, b) => {\n for (const [key, direction] of Object.entries(sortSpec)) {\n const aVal = getNestedValue(accessor(a), key);\n const bVal = getNestedValue(accessor(b), key);\n if (aVal === bVal) continue;\n if (aVal === undefined) return direction;\n if (bVal === undefined) return -direction;\n if ((aVal as number) < (bVal as number)) return -direction;\n if ((aVal as number) > (bVal as number)) return direction;\n }\n return 0;\n });\n}\n\n/**\n * Extract simple equality fields from a filter for use as a base document during upsert.\n * Strips out query operators (keys starting with $) and fields with operator-object values.\n */\nfunction extractEqualityFields(filter: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(filter)) {\n if (key.startsWith(\"$\")) continue;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n const ops = value as Record<string, unknown>;\n if (Object.keys(ops).some((k) => k.startsWith(\"$\"))) continue;\n }\n result[key] = value;\n }\n return result;\n}\n","import type { RouteContext } from \"@emulators/core\";\nimport { getMongoAtlasStore } from \"../store.js\";\nimport { generateClusterId, generateGroupId, generateUserId, mongoOk, mongoError } from \"../helpers.js\";\n\n/**\n * MongoDB Atlas Admin API endpoints.\n * These emulate the Atlas Administration API v2 for managing projects, clusters, and users.\n * See: https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/\n */\nexport function adminRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ms = () => getMongoAtlasStore(store);\n\n // --- Projects ---\n\n // List projects\n app.get(\"/api/atlas/v2/groups\", (c) => {\n const projects = ms().projects.all();\n return mongoOk(c, {\n results: projects.map(formatProject),\n totalCount: projects.length,\n });\n });\n\n // Get project by ID\n app.get(\"/api/atlas/v2/groups/:groupId\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n return mongoOk(c, formatProject(project));\n });\n\n // Create project\n app.post(\"/api/atlas/v2/groups\", async (c) => {\n const body = await c.req.json<{ name?: string; orgId?: string }>();\n if (!body.name?.trim()) {\n return mongoError(c, \"INVALID_PARAMETER\", \"name is required\");\n }\n\n const existing = ms()\n .projects.all()\n .find((p) => p.name === body.name);\n if (existing) {\n return mongoError(c, \"DUPLICATE_GROUP_NAME\", `Group name '${body.name}' already exists.`, 409);\n }\n\n const groupId = generateGroupId();\n const project = ms().projects.insert({\n group_id: groupId,\n name: body.name,\n org_id: body.orgId ?? \"default_org\",\n cluster_count: 0,\n });\n\n return mongoOk(c, formatProject(project), 201);\n });\n\n // Delete project\n app.delete(\"/api/atlas/v2/groups/:groupId\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n\n // Cascade delete clusters in this project\n const clusters = ms()\n .clusters.all()\n .filter((cl) => cl.group_id === groupId);\n for (const cluster of clusters) {\n deleteClusterData(ms, cluster.cluster_id);\n ms().clusters.delete(cluster.id);\n }\n\n ms().projects.delete(project.id);\n return c.body(null, 204);\n });\n\n // --- Clusters ---\n\n // List clusters\n app.get(\"/api/atlas/v2/groups/:groupId/clusters\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n\n const clusters = ms()\n .clusters.all()\n .filter((cl) => cl.group_id === groupId);\n return mongoOk(c, {\n results: clusters.map(formatCluster),\n totalCount: clusters.length,\n });\n });\n\n // Get cluster\n app.get(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n return mongoOk(c, formatCluster(cluster));\n });\n\n // Create cluster\n app.post(\"/api/atlas/v2/groups/:groupId/clusters\", async (c) => {\n const groupId = c.req.param(\"groupId\");\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (!project) {\n return mongoError(c, \"GROUP_NOT_FOUND\", `Group '${groupId}' not found.`, 404);\n }\n\n const body = await c.req.json<{\n name?: string;\n clusterType?: \"REPLICASET\" | \"SHARDED\";\n providerSettings?: {\n providerName?: string;\n instanceSizeName?: string;\n regionName?: string;\n };\n diskSizeGB?: number;\n mongoDBMajorVersion?: string;\n }>();\n\n if (!body.name?.trim()) {\n return mongoError(c, \"INVALID_PARAMETER\", \"name is required\");\n }\n\n const existing = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === body.name);\n if (existing) {\n return mongoError(c, \"DUPLICATE_CLUSTER_NAME\", `Cluster '${body.name}' already exists.`, 409);\n }\n\n const clusterId = generateClusterId();\n const cluster = ms().clusters.insert({\n cluster_id: clusterId,\n name: body.name,\n group_id: groupId,\n state: \"IDLE\",\n mongo_uri: `mongodb+srv://${body.name}.emulate.mongodb.net`,\n connection_strings: {\n standard: `mongodb://${body.name}.emulate.mongodb.net:27017`,\n standard_srv: `mongodb+srv://${body.name}.emulate.mongodb.net`,\n },\n provider_settings: {\n provider_name: body.providerSettings?.providerName ?? \"AWS\",\n instance_size_name: body.providerSettings?.instanceSizeName ?? \"M10\",\n region_name: body.providerSettings?.regionName ?? \"US_EAST_1\",\n },\n cluster_type: body.clusterType ?? \"REPLICASET\",\n disk_size_gb: body.diskSizeGB ?? 10,\n mongodb_version: body.mongoDBMajorVersion ?? \"8.0\",\n });\n\n ms().projects.update(project.id, { cluster_count: project.cluster_count + 1 });\n\n return mongoOk(c, formatCluster(cluster), 201);\n });\n\n // Update cluster\n app.patch(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName\", async (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n const body = await c.req.json<{\n providerSettings?: {\n instanceSizeName?: string;\n regionName?: string;\n };\n diskSizeGB?: number;\n }>();\n\n const updates: Partial<typeof cluster> = {};\n if (body.providerSettings) {\n updates.provider_settings = {\n provider_name: cluster.provider_settings.provider_name,\n instance_size_name: body.providerSettings.instanceSizeName ?? cluster.provider_settings.instance_size_name,\n region_name: body.providerSettings.regionName ?? cluster.provider_settings.region_name,\n };\n }\n if (body.diskSizeGB !== undefined) {\n updates.disk_size_gb = body.diskSizeGB;\n }\n\n const updated = ms().clusters.update(cluster.id, updates);\n return mongoOk(c, formatCluster(updated!));\n });\n\n // Delete cluster\n app.delete(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n deleteClusterData(ms, cluster.cluster_id);\n ms().clusters.delete(cluster.id);\n\n const project = ms().projects.findOneBy(\"group_id\", groupId);\n if (project) {\n ms().projects.update(project.id, { cluster_count: Math.max(0, project.cluster_count - 1) });\n }\n\n return c.body(null, 204);\n });\n\n // --- Database Users ---\n\n // List database users\n app.get(\"/api/atlas/v2/groups/:groupId/databaseUsers\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const users = ms()\n .users.all()\n .filter((u) => u.group_id === groupId);\n return mongoOk(c, {\n results: users.map(formatUser),\n totalCount: users.length,\n });\n });\n\n // Get database user\n app.get(\"/api/atlas/v2/groups/:groupId/databaseUsers/admin/:username\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const username = c.req.param(\"username\");\n const user = ms()\n .users.all()\n .find((u) => u.group_id === groupId && u.username === username);\n\n if (!user) {\n return mongoError(c, \"USER_NOT_FOUND\", `Database user '${username}' not found.`, 404);\n }\n\n return mongoOk(c, formatUser(user));\n });\n\n // Create database user\n app.post(\"/api/atlas/v2/groups/:groupId/databaseUsers\", async (c) => {\n const groupId = c.req.param(\"groupId\");\n const body = await c.req.json<{\n username?: string;\n password?: string;\n databaseName?: string;\n roles?: Array<{ databaseName: string; roleName: string }>;\n }>();\n\n if (!body.username?.trim()) {\n return mongoError(c, \"INVALID_PARAMETER\", \"username is required\");\n }\n\n const existing = ms()\n .users.all()\n .find((u) => u.group_id === groupId && u.username === body.username);\n if (existing) {\n return mongoError(c, \"DUPLICATE_USER\", `User '${body.username}' already exists.`, 409);\n }\n\n const userId = generateUserId();\n const user = ms().users.insert({\n user_id: userId,\n username: body.username,\n group_id: groupId,\n roles: (body.roles ?? []).map((r) => ({ database_name: r.databaseName, role_name: r.roleName })),\n });\n\n return mongoOk(c, formatUser(user), 201);\n });\n\n // Delete database user\n app.delete(\"/api/atlas/v2/groups/:groupId/databaseUsers/admin/:username\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const username = c.req.param(\"username\");\n const user = ms()\n .users.all()\n .find((u) => u.group_id === groupId && u.username === username);\n\n if (!user) {\n return mongoError(c, \"USER_NOT_FOUND\", `Database user '${username}' not found.`, 404);\n }\n\n ms().users.delete(user.id);\n return c.body(null, 204);\n });\n\n // --- Databases & Collections (Data Explorer) ---\n\n // List databases in a cluster\n app.get(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName/databases\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n const databases = ms()\n .databases.all()\n .filter((db) => db.cluster_id === cluster.cluster_id);\n return mongoOk(c, {\n results: databases.map((db) => ({ databaseName: db.name })),\n totalCount: databases.length,\n });\n });\n\n // List collections in a database\n app.get(\"/api/atlas/v2/groups/:groupId/clusters/:clusterName/databases/:databaseName/collections\", (c) => {\n const groupId = c.req.param(\"groupId\");\n const clusterName = c.req.param(\"clusterName\");\n const databaseName = c.req.param(\"databaseName\");\n const cluster = ms()\n .clusters.all()\n .find((cl) => cl.group_id === groupId && cl.name === clusterName);\n\n if (!cluster) {\n return mongoError(c, \"CLUSTER_NOT_FOUND\", `Cluster '${clusterName}' not found.`, 404);\n }\n\n const collections = ms()\n .collections.all()\n .filter((col) => col.cluster_id === cluster.cluster_id && col.database === databaseName);\n return mongoOk(c, {\n results: collections.map((col) => ({ collectionName: col.name, databaseName })),\n totalCount: collections.length,\n });\n });\n}\n\nfunction deleteClusterData(ms: () => ReturnType<typeof getMongoAtlasStore>, clusterId: string): void {\n const docs = ms()\n .documents.all()\n .filter((d) => d.cluster_id === clusterId);\n for (const doc of docs) ms().documents.delete(doc.id);\n\n const cols = ms()\n .collections.all()\n .filter((col) => col.cluster_id === clusterId);\n for (const col of cols) ms().collections.delete(col.id);\n\n const dbs = ms()\n .databases.all()\n .filter((db) => db.cluster_id === clusterId);\n for (const db of dbs) ms().databases.delete(db.id);\n}\n\nfunction formatProject(p: {\n group_id: string;\n name: string;\n org_id: string;\n cluster_count: number;\n created_at: string;\n}) {\n return {\n id: p.group_id,\n name: p.name,\n orgId: p.org_id,\n clusterCount: p.cluster_count,\n created: p.created_at,\n };\n}\n\nfunction formatCluster(cl: {\n cluster_id: string;\n name: string;\n group_id: string;\n state: string;\n mongo_uri: string;\n connection_strings: { standard: string; standard_srv: string };\n provider_settings: { provider_name: string; instance_size_name: string; region_name: string };\n cluster_type: string;\n disk_size_gb: number;\n mongodb_version: string;\n created_at: string;\n}) {\n return {\n id: cl.cluster_id,\n name: cl.name,\n groupId: cl.group_id,\n stateName: cl.state,\n mongoURI: cl.mongo_uri,\n connectionStrings: {\n standard: cl.connection_strings.standard,\n standardSrv: cl.connection_strings.standard_srv,\n },\n providerSettings: {\n providerName: cl.provider_settings.provider_name,\n instanceSizeName: cl.provider_settings.instance_size_name,\n regionName: cl.provider_settings.region_name,\n },\n clusterType: cl.cluster_type,\n diskSizeGB: cl.disk_size_gb,\n mongoDBVersion: cl.mongodb_version,\n created: cl.created_at,\n };\n}\n\nfunction formatUser(u: {\n user_id: string;\n username: string;\n group_id: string;\n roles: Array<{ database_name: string; role_name: string }>;\n}) {\n return {\n username: u.username,\n groupId: u.group_id,\n databaseName: \"admin\",\n roles: u.roles.map((r) => ({ databaseName: r.database_name, roleName: r.role_name })),\n };\n}\n","import type { Hono } from \"@emulators/core\";\nimport type { ServicePlugin, Store, WebhookDispatcher, TokenMap, AppEnv, RouteContext } from \"@emulators/core\";\nimport { getMongoAtlasStore } from \"./store.js\";\nimport { generateClusterId, generateGroupId, generateUserId } from \"./helpers.js\";\nimport { dataApiRoutes } from \"./routes/data-api.js\";\nimport { adminRoutes } from \"./routes/admin.js\";\n\nexport { getMongoAtlasStore, type MongoAtlasStore } from \"./store.js\";\nexport * from \"./entities.js\";\n\nexport interface MongoAtlasSeedConfig {\n port?: number;\n projects?: Array<{\n name: string;\n org_id?: string;\n }>;\n clusters?: Array<{\n name: string;\n project: string;\n provider?: string;\n instance_size?: string;\n region?: string;\n disk_size_gb?: number;\n mongodb_version?: string;\n }>;\n database_users?: Array<{\n username: string;\n project: string;\n roles?: Array<{ database_name: string; role_name: string }>;\n }>;\n databases?: Array<{\n cluster: string;\n name: string;\n collections?: string[];\n }>;\n}\n\nfunction seedDefaults(store: Store, _baseUrl: string): void {\n const ms = getMongoAtlasStore(store);\n\n const groupId = generateGroupId();\n ms.projects.insert({\n group_id: groupId,\n name: \"Project0\",\n org_id: \"default_org\",\n cluster_count: 1,\n });\n\n const clusterId = generateClusterId();\n ms.clusters.insert({\n cluster_id: clusterId,\n name: \"Cluster0\",\n group_id: groupId,\n state: \"IDLE\",\n mongo_uri: \"mongodb+srv://Cluster0.emulate.mongodb.net\",\n connection_strings: {\n standard: \"mongodb://Cluster0.emulate.mongodb.net:27017\",\n standard_srv: \"mongodb+srv://Cluster0.emulate.mongodb.net\",\n },\n provider_settings: {\n provider_name: \"AWS\",\n instance_size_name: \"M10\",\n region_name: \"US_EAST_1\",\n },\n cluster_type: \"REPLICASET\",\n disk_size_gb: 10,\n mongodb_version: \"8.0\",\n });\n\n ms.users.insert({\n user_id: generateUserId(),\n username: \"admin\",\n group_id: groupId,\n roles: [{ database_name: \"admin\", role_name: \"atlasAdmin\" }],\n });\n\n ms.databases.insert({ cluster_id: clusterId, name: \"test\" });\n ms.collections.insert({ cluster_id: clusterId, database: \"test\", name: \"items\" });\n}\n\nexport function seedFromConfig(store: Store, _baseUrl: string, config: MongoAtlasSeedConfig): void {\n const ms = getMongoAtlasStore(store);\n\n const projectIdMap = new Map<string, string>();\n\n if (config.projects) {\n for (const p of config.projects) {\n const existing = ms.projects.all().find((ep) => ep.name === p.name);\n if (existing) {\n projectIdMap.set(p.name, existing.group_id);\n continue;\n }\n\n const groupId = generateGroupId();\n ms.projects.insert({\n group_id: groupId,\n name: p.name,\n org_id: p.org_id ?? \"default_org\",\n cluster_count: 0,\n });\n projectIdMap.set(p.name, groupId);\n }\n }\n\n // Map default project\n const defaultProject = ms.projects.all()[0];\n if (defaultProject) {\n projectIdMap.set(defaultProject.name, defaultProject.group_id);\n }\n\n const clusterIdMap = new Map<string, string>();\n\n if (config.clusters) {\n for (const cl of config.clusters) {\n const groupId = projectIdMap.get(cl.project);\n if (!groupId) continue;\n\n const existing = ms.clusters.all().find((ec) => ec.group_id === groupId && ec.name === cl.name);\n if (existing) {\n clusterIdMap.set(cl.name, existing.cluster_id);\n continue;\n }\n\n const clusterId = generateClusterId();\n ms.clusters.insert({\n cluster_id: clusterId,\n name: cl.name,\n group_id: groupId,\n state: \"IDLE\",\n mongo_uri: `mongodb+srv://${cl.name}.emulate.mongodb.net`,\n connection_strings: {\n standard: `mongodb://${cl.name}.emulate.mongodb.net:27017`,\n standard_srv: `mongodb+srv://${cl.name}.emulate.mongodb.net`,\n },\n provider_settings: {\n provider_name: cl.provider ?? \"AWS\",\n instance_size_name: cl.instance_size ?? \"M10\",\n region_name: cl.region ?? \"US_EAST_1\",\n },\n cluster_type: \"REPLICASET\",\n disk_size_gb: cl.disk_size_gb ?? 10,\n mongodb_version: cl.mongodb_version ?? \"8.0\",\n });\n clusterIdMap.set(cl.name, clusterId);\n\n const project = ms.projects.findOneBy(\"group_id\", groupId);\n if (project) {\n ms.projects.update(project.id, { cluster_count: project.cluster_count + 1 });\n }\n }\n }\n\n // Map default cluster\n const defaultCluster = ms.clusters.all()[0];\n if (defaultCluster) {\n clusterIdMap.set(defaultCluster.name, defaultCluster.cluster_id);\n }\n\n if (config.database_users) {\n for (const u of config.database_users) {\n const groupId = projectIdMap.get(u.project);\n if (!groupId) continue;\n\n const existing = ms.users.all().find((eu) => eu.group_id === groupId && eu.username === u.username);\n if (existing) continue;\n\n ms.users.insert({\n user_id: generateUserId(),\n username: u.username,\n group_id: groupId,\n roles: u.roles ?? [{ database_name: \"admin\", role_name: \"readWriteAnyDatabase\" }],\n });\n }\n }\n\n if (config.databases) {\n for (const db of config.databases) {\n const clusterId = clusterIdMap.get(db.cluster);\n if (!clusterId) continue;\n\n const existingDb = ms.databases.all().find((edb) => edb.cluster_id === clusterId && edb.name === db.name);\n if (!existingDb) {\n ms.databases.insert({ cluster_id: clusterId, name: db.name });\n }\n\n if (db.collections) {\n for (const colName of db.collections) {\n const existingCol = ms.collections\n .all()\n .find((ec) => ec.cluster_id === clusterId && ec.database === db.name && ec.name === colName);\n if (!existingCol) {\n ms.collections.insert({ cluster_id: clusterId, database: db.name, name: colName });\n }\n }\n }\n }\n }\n}\n\nexport const mongoatlasPlugin: ServicePlugin = {\n name: \"mongoatlas\",\n register(app: Hono<AppEnv>, store: Store, webhooks: WebhookDispatcher, baseUrl: string, tokenMap?: TokenMap): void {\n const ctx: RouteContext = { app, store, webhooks, baseUrl, tokenMap };\n adminRoutes(ctx);\n dataApiRoutes(ctx);\n },\n seed(store: Store, baseUrl: string): void {\n seedDefaults(store, baseUrl);\n },\n};\n\nexport default mongoatlasPlugin;\n"],"mappings":"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","names":["result"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emulators/mongoatlas",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,8 +27,7 @@
27
27
  "dist"
28
28
  ],
29
29
  "dependencies": {
30
- "hono": "^4",
31
- "@emulators/core": "0.5.0"
30
+ "@emulators/core": "0.6.0"
32
31
  },
33
32
  "devDependencies": {
34
33
  "tsup": "^8",