diff --git a/adapter.ts b/adapter.ts index 44fe813..e54387b 100644 --- a/adapter.ts +++ b/adapter.ts @@ -85,29 +85,32 @@ export function adapter({ // DB DNE, so create it () => /** - * Add a document, then immediately remove it - * so that the empty database and collection is implcitly created + * Create metadata doc for db */ - Async.of($database(name)).chain(($db) => - $db - .insertOne({ - _id: 'info', - type: '_ADMIN', - created: new Date().toISOString(), - }) - .chain(() => $db.removeOne({ _id: 'info' })) - /** - * Make sure to persist metadata on the db - */ - .chain(() => meta.create(name)) - .bimap( - mongoErrToHyperErr({ - subject: `database ${name}`, - db: `database ${name}`, - }), - always({ ok: true }), - ) - ), + meta.create(name).chain((metaDoc) => { + /** + * Add a document, then immediately remove it + * so that the empty database and collection are implcitly created + */ + return Async.of( + $database((metaDoc as { name: string }).name), + ).chain(($db) => + $db + .insertOne({ + _id: 'info', + type: '_ADMIN', + created: new Date().toISOString(), + }) + .chain(() => $db.removeOne({ _id: 'info' })) + .bimap( + mongoErrToHyperErr({ + subject: `database ${name}`, + db: `database ${name}`, + }), + always({ ok: true }), + ) + ) + }), // Already exists, so return a HyperErr(409) () => Async.Rejected( @@ -124,7 +127,7 @@ export function adapter({ function removeDatabase(name: string) { return meta .get(name) - .chain(() => $database(name).dropDatabase()) + .chain(({ name: actualName }) => $database(actualName).dropDatabase()) .chain(() => meta.remove(name)) .bimap( mongoErrToHyperErr({ @@ -151,11 +154,11 @@ export function adapter({ }) { return meta .get(db) - .chain(() => + .chain(({ name: actualName }) => isEmpty(doc) ? Async.Rejected(HyperErr({ status: 400, msg: 'document empty' })) : Async.of({ ...doc, _id: id }).chain((docWithId) => - $database(db) + $database(actualName) .insertOne(docWithId) .bimap( mongoErrToHyperErr({ @@ -176,7 +179,7 @@ export function adapter({ function retrieveDocument({ db, id }: { db: string; id: string }) { return meta .get(db) - .chain(() => $database(db).findOne({ _id: id })) + .chain(({ name: actualName }) => $database(actualName).findOne({ _id: id })) .chain((doc) => doc ? Async.Resolved(doc) : Async.Rejected( HyperErr({ @@ -211,8 +214,8 @@ export function adapter({ }) { return meta .get(db) - .chain(() => - $database(db) + .chain(({ name: actualName }) => + $database(actualName) .replaceOne({ _id: id }, doc, { upsert: true }) .chain(({ matchedCount, modifiedCount }) => matchedCount + modifiedCount === 2 ? Async.Resolved({ ok: true, id }) : Async.Rejected( @@ -240,8 +243,8 @@ export function adapter({ function removeDocument({ db, id }: { db: string; id: string }) { return meta .get(db) - .chain(() => - $database(db) + .chain(({ name: actualName }) => + $database(actualName) .removeOne({ _id: id }) .chain(({ deletedCount }) => deletedCount === 1 ? Async.Resolved({ ok: true, id }) : Async.Rejected( @@ -270,8 +273,8 @@ export function adapter({ function queryDocuments({ db, query }: { db: string; query: any }) { return meta .get(db) - .chain(() => - $database(db) + .chain(({ name: actualName }) => + $database(actualName) .find(query.selector, { ...queryOptions(query), }) @@ -295,8 +298,8 @@ export function adapter({ }) { return meta .get(db) - .chain(() => - $database(db) + .chain(({ name: actualName }) => + $database(actualName) .createIndex({ name, spec: mapSort(fields) }) .bimap( mongoErrToHyperErr({ @@ -346,8 +349,8 @@ export function adapter({ return meta .get(db) - .chain(() => - $database(db) + .chain(({ name: actualName }) => + $database(actualName) .find(q, { ...options }) .bimap( mongoErrToHyperErr({ @@ -373,8 +376,8 @@ export function adapter({ }) { return meta .get(db) - .chain(() => - $database(db) + .chain(({ name: actualName }) => + $database(actualName) .bulk(toBulkOperations(docs)) .bimap( mongoErrToHyperErr({ diff --git a/deno.lock b/deno.lock index 5fc200f..e6df966 100644 --- a/deno.lock +++ b/deno.lock @@ -697,12 +697,13 @@ }, "npm": { "specifiers": { - "bson": "bson@5.3.0", - "mongodb": "mongodb@5.6.0" + "bson@5.3.0": "bson@5.3.0", + "cuid@3.0.0": "cuid@3.0.0", + "mongodb@5.6.0": "mongodb@5.6.0" }, "packages": { - "@types/node@20.2.5": { - "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", + "@types/node@20.3.2": { + "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==", "dependencies": {} }, "@types/webidl-conversions@7.0.0": { @@ -712,7 +713,7 @@ "@types/whatwg-url@8.2.2": { "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", "dependencies": { - "@types/node": "@types/node@20.2.5", + "@types/node": "@types/node@20.3.2", "@types/webidl-conversions": "@types/webidl-conversions@7.0.0" } }, @@ -720,6 +721,10 @@ "integrity": "sha512-ukmCZMneMlaC5ebPHXIkP8YJzNl5DC41N5MAIvKDqLggdao342t4McltoJBQfQya/nHBWAcSsYRqlXPoQkTJag==", "dependencies": {} }, + "cuid@3.0.0": { + "integrity": "sha512-WZYYkHdIDnaxdeP8Misq3Lah5vFjJwGuItJuV+tvMafosMzw0nF297T7mrm8IOWiPJkV6gc7sa8pzx27+w25Zg==", + "dependencies": {} + }, "ip@2.0.0": { "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", "dependencies": {} diff --git a/deps.ts b/deps.ts index 4c890e3..488bd21 100644 --- a/deps.ts +++ b/deps.ts @@ -5,8 +5,9 @@ export { default as crocks } from 'https://cdn.skypack.dev/crocks@0.12.4' export * as R from 'https://cdn.skypack.dev/ramda@^0.29.0?dts' -export { EJSON } from 'npm:bson' -export { type Collection, MongoClient } from 'npm:mongodb' +export { EJSON } from 'npm:bson@5.3.0' +export { type Collection, MongoClient } from 'npm:mongodb@5.6.0' +export { default as cuid } from 'npm:cuid@3.0.0' export { HyperErr, diff --git a/meta.ts b/meta.ts index 8b7f0b8..75ac124 100644 --- a/meta.ts +++ b/meta.ts @@ -1,4 +1,4 @@ -import { crocks, HyperErr } from './deps.ts' +import { crocks, cuid, HyperErr } from './deps.ts' import type { MongoInstanceClient } from './clients/types.ts' @@ -58,7 +58,9 @@ export class MetaDb { .chain( Async.fromPromise((collection) => collection.findOne({ _id: name }, {})), ) - .chain((doc) => + .chain, DatabaseMeta>((doc) => + // deno-lint-ignore ban-ts-comment + // @ts-ignore doc ? Async.Resolved(doc) : Async.Rejected( HyperErr({ status: 404, msg: `database does not exist` }), ) @@ -84,12 +86,13 @@ export class MetaDb { Async.fromPromise((collection) => { const doc = { _id: name, - name, + // Use a cuid for the actual name of the database + name: cuid(), type: 'database' as const, createdAt: new Date().toISOString(), } - return collection.insertOne(doc) + return collection.insertOne(doc).then(() => doc) }), ), // DB was found, so produce a conflict