|
1 | | -import { NodeProvider } from '@stenodb/node' |
| 1 | +import { AsyncAdapter, NodeProvider, SyncAdapter } from '@stenodb/node' |
2 | 2 | import { targetConstructorToSchema } from 'class-validator-jsonschema' |
3 | 3 | import type { Steno } from '@stenodb/node' |
4 | 4 | import type { IOptions } from 'class-validator-jsonschema/build/options' |
5 | 5 | import type { FastifyInstance } from 'fastify' |
6 | 6 |
|
7 | 7 | export interface StenoOptions extends Steno.NodeProviderOptions { |
8 | | - entities: Steno.Entity<any>[] |
| 8 | + adapters: Steno.NodeAdapter<any>[] |
| 9 | + entities?: Steno.Entity<any>[] |
| 10 | + entityOptions?: IOptions |
9 | 11 | } |
10 | 12 |
|
11 | 13 | export class StenoPlugin { |
12 | 14 | #fastify: FastifyInstance |
13 | 15 | #options: StenoOptions |
14 | 16 | #provider: NodeProvider |
| 17 | + #databases: Map<string, Steno.NodeProvider<any>> |
15 | 18 |
|
16 | | - constructor(fastify: FastifyInstance, options: StenoOptions, done: () => void) { |
| 19 | + constructor(fastify: FastifyInstance, options: StenoOptions) { |
17 | 20 | this.#fastify = fastify |
18 | 21 | this.#options = options |
19 | 22 | this.#provider = new NodeProvider(options) |
20 | | - |
21 | | - this.#fastify.decorate('steno', {}) |
22 | | - this.registerSchemas() |
23 | | - |
24 | | - done() |
| 23 | + this.#databases = new Map<string, Steno.NodeProvider<any>>() |
| 24 | + this.#fastify.decorate('steno', { get: this.getDatabase.bind(this) }) |
25 | 25 | } |
26 | 26 |
|
27 | 27 | static async createInstance( |
28 | 28 | fastify: FastifyInstance, |
29 | 29 | options: StenoOptions, |
30 | 30 | done: () => void |
31 | 31 | ): Promise<StenoPlugin> { |
32 | | - return new StenoPlugin(fastify, options, done) |
| 32 | + const db = new StenoPlugin(fastify, options) |
| 33 | + await db.registerDatabases() |
| 34 | + done() |
| 35 | + return db |
| 36 | + } |
| 37 | + |
| 38 | + async registerDatabases(): Promise<void> { |
| 39 | + this.registerEntities() |
| 40 | + |
| 41 | + for (const adapter of this.#options.adapters) { |
| 42 | + const db = await this.#provider.create(adapter) |
| 43 | + |
| 44 | + if (adapter instanceof SyncAdapter) { |
| 45 | + db.read() |
| 46 | + } else if (adapter instanceof AsyncAdapter) { |
| 47 | + await db.read() |
| 48 | + } else { |
| 49 | + throw new TypeError('Invalid adapter') |
| 50 | + } |
| 51 | + |
| 52 | + this.addSchema(adapter.entity) |
| 53 | + this.#databases.set(adapter.fileName, db) |
| 54 | + } |
33 | 55 | } |
34 | 56 |
|
35 | | - private registerSchemas(options?: IOptions): void { |
| 57 | + private registerEntities() { |
| 58 | + if (!this.#options.entities) return |
36 | 59 | for (const entity of this.#options.entities) { |
37 | | - const schema = targetConstructorToSchema(entity, options) |
38 | | - this.#fastify.addSchema({ ...schema, $id: entity.name }) |
| 60 | + this.addSchema(entity) |
39 | 61 | } |
40 | 62 | } |
| 63 | + |
| 64 | + private addSchema(entity: Steno.Entity<any>): void { |
| 65 | + if (this.#fastify.getSchema(entity.name)) return |
| 66 | + const schema = targetConstructorToSchema( |
| 67 | + entity, |
| 68 | + this.#options.entityOptions |
| 69 | + ) |
| 70 | + this.#fastify.addSchema({ ...schema, $id: entity.name }) |
| 71 | + } |
| 72 | + |
| 73 | + private getDatabase<T>(name: string): Steno.NodeProvider<T> | undefined { |
| 74 | + return this.#databases.get(name) |
| 75 | + } |
41 | 76 | } |
0 commit comments