unjs / nitro

Next Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.
https://nitro.unjs.io
MIT License
5.81k stars 489 forks source link

Allow conigure local custom storage drivers #530

Open mcremer-able opened 1 year ago

mcremer-able commented 1 year ago

Environment

nitropack@0.4.24 $ node --version v16.17.0

Reproduction

Follow the example of unstorage https://github.com/unjs/unstorage#making-custom-drivers I used the original memory driver as "custom driver"

import { defineDriver } from './utils'
import type { StorageValue } from '../types'

export default defineDriver(() => {
  const data = new Map<string, StorageValue>()

  return {
    hasItem (key) {
      return data.has(key)
    },
    getItem (key) {
      return data.get(key) || null
    },
    setItem(key, value) {
      data.set(key, value)
    },
    removeItem (key) {
      data.delete(key)
    },
    getKeys() {
      return Array.from(data.keys())
    },
    clear() {
      data.clear()
    },
    dispose() {
      data.clear()
    }
  }
})

Describe the bug

The current interface for storage options is:

interface StorageMounts {
    [path: string]: {
        driver: BuiltinDriverName | CustomDriverName;
        [option: string]: any;
    };
}

but unstorage allows the use of custom drivers and we are not using them.

Additional context

I found https://github.com/unjs/nitro/blob/main/src/rollup/plugins/storage.ts on line 47

${driverImports.map(i => genImport(i, genSafeVariableName(i))).join('\n')} I am not quite sure if that means we should do the following

storage:{
  db: {
    driver: "../../../../CosmoDriver.js",
    options: {
     // my driver options 
    },
  },
}

This kind of complex and error prone We should allow the user to pass in the driver directly and just driver:new Driver({})

Logs

No response

Minecraftschurli commented 1 year ago

I'm having the same problem but bigger because I wrote my driver in typescript and can't even use the workaround because it only gets bundled into the server and is not importable

Minecraftschurli commented 1 year ago

I had a look in the code and it is definitely more complicated than just adding the pure driver factory to the type definition because they use the string to generate the variable name and use dynamic imports

maoosi commented 1 year ago

I am facing the same problem trying to use a Custom Driver. Any updates on that issue?

yuusheng commented 1 year ago

I have the same problem. Does nitro support Custom Driver?

Hebilicious commented 1 year ago

You should use an absolute path for your custom driver location :

import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

export default defineNitroConfig({
  storage: {
    "custom-db": {
      driver: resolve(
        dirname(fileURLToPath(import.meta.url)),
        "unstorage/custom-driver.ts"
      ),
    },
  },
});
yuusheng commented 1 year ago

You should use an absolute path for your custom driver location :

import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

export default defineNitroConfig({
  storage: {
    "custom-db": {
      driver: resolve(
        dirname(fileURLToPath(import.meta.url)),
        "unstorage/custom-driver.ts"
      ),
    },
  },
});

It worked for me. But I think we should support using Driver/Storage imported from other ts/js files directly. Since this didn't support TypeScript files and is not very elegant.

I would like to help if we have a plan to support this.

Hebilicious commented 1 year ago

It supports typescript files. You can replace dirname(fileURLToPath(import.meta.url)) with __dirname if you want something less verbose.