Skip to content

Commit

Permalink
feat: support spinning up in-memory mongo server for local development
Browse files Browse the repository at this point in the history
  • Loading branch information
TillaTheHun0 committed Dec 1, 2023
1 parent 4cdde19 commit de15b62
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 215 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__hyper__
445 changes: 236 additions & 209 deletions deno.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export * as R from 'npm:[email protected]'
export { EJSON } from 'npm:[email protected]'
export { type Collection, MongoClient } from 'npm:[email protected]'
export { default as cuid } from 'npm:[email protected]'
export { MongoMemoryServer } from 'npm:[email protected]'

export { join } from 'https://deno.land/[email protected]/path/mod.ts'

import {
HyperErr,
Expand Down
28 changes: 25 additions & 3 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { MongoMemoryServer, join } from './deps.ts'
import type { AdapterConfig } from './types.ts'
import PORT_NAME from './port_name.ts'

import { AtlasDataClient } from './clients/atlas-data.ts'
import { NativeClient } from './clients/native.ts'
import type { MongoInstanceClient } from './clients/types.ts'

import { mkdir } from './utils.ts'
import { adapter } from './adapter.ts'
import { MetaDb } from './meta.ts'

Expand All @@ -15,11 +17,31 @@ export default (config: AdapterConfig) => ({
id: 'mongodb',
port: PORT_NAME,
load: async () => {
const url = new URL(config.url)
let url: URL
/**
* Dynamically create an in memory database
*/
if (config.dir) {
const mongoMsDir = join(config.dir, 'mongoms')
await mkdir(join(mongoMsDir, 'data'))
/**
* See https://github.com/nodkz/mongodb-memory-server#available-options-for-mongomemoryserver
* for available options.
*
* Other options may
*/
url = await MongoMemoryServer.create({
instance: { dbPath: join(mongoMsDir, 'data'), storageEngine: 'wiredTiger' },
binary: { downloadDir: mongoMsDir, version: config.dirVersion }
}).then(mongod => new URL(mongod.getUri()))
console.log(`In-Memory MongoDB: ${url.toString()}`)
} else {
url = new URL(config.url as string)
}
let client: NativeClient | AtlasDataClient

if (isNative(url)) {
client = new NativeClient({ url: config.url })
client = new NativeClient({ url: url.toString() })
await client.connect()
} else if (isAtlas(url)) {
if (!config.options?.atlas) {
Expand All @@ -29,7 +51,7 @@ export default (config: AdapterConfig) => ({
}
client = new AtlasDataClient({
...config.options.atlas,
endpoint: config.url,
endpoint: url.toString(),
fetch,
})
} else {
Expand Down
2 changes: 1 addition & 1 deletion test/hyper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Harness deps
import { default as hyper } from 'https://raw.githubusercontent.com/hyper63/hyper/hyper%40v4.3.1/packages/core/mod.ts'
import { default as hyper } from 'https://raw.githubusercontent.com/hyper63/hyper/hyper%40v4.3.2/packages/core/mod.ts'
import { default as app } from 'https://raw.githubusercontent.com/hyper63/hyper/hyper-app-express%40v1.2.1/packages/app-express/mod.ts'

import mongo from '../mod.ts'
Expand Down
9 changes: 7 additions & 2 deletions types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
export type AdapterConfig = {
url: string
url?: string
options?: {
atlas?: {
dataSource: string
auth: EmailPasswordAuthOptions | ApiKeyAuthOptions | CustomJwtAuthOptions
}
}
},
/**
* config when wanting to use an in-memory Mongo instance
*/
dir?: string,
dirVersion?: string
}

// deno-lint-ignore no-explicit-any
Expand Down
14 changes: 14 additions & 0 deletions utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@ import { crocks, HyperErr, isHyperErr, R } from './deps.ts'
const { map, omit, ifElse, evolve, applyTo, propOr, always } = R
const { Async } = crocks

export async function mkdir(dir: string) {
try {
return await Deno.mkdir(dir, { recursive: true })
} catch (err) {
if (err instanceof Deno.errors.AlreadyExists) {
// already exists so return
return true
} else {
// unexpected error, maybe permissions, pass it along
throw err
}
}
}

export const handleHyperErr = ifElse(
isHyperErr,
Async.Resolved,
Expand Down

0 comments on commit de15b62

Please sign in to comment.