Skip to content

Commit 8444212

Browse files
committed
feat: fastify plugin
1 parent 3f06ac9 commit 8444212

File tree

4 files changed

+61
-26
lines changed

4 files changed

+61
-26
lines changed

examples/with-fastify/src/index.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
import 'reflect-metadata'
22
import { dirname, resolve } from 'node:path'
33
import { fileURLToPath } from 'node:url'
4-
import { FastifySteno } from '@stenodb/fastify'
4+
import { AsyncAdapter, FastifySteno } from '@stenodb/fastify'
55
import Fastify from 'fastify'
66
import { Post, User, Users } from './entities.js'
77

88
const fastify = Fastify()
99

1010
fastify.register(FastifySteno, {
1111
path: resolve(dirname(fileURLToPath(import.meta.url)), '..', 'db'),
12-
entities: [User, Post]
12+
entities: [User, Post],
13+
adapters: [new AsyncAdapter('users', Users, new Users(new User('John', 18)))]
14+
})
15+
16+
fastify.get('/', () => {
17+
const users = fastify.steno.get<Users>('users')
18+
return users?.data
1319
})
1420

1521
fastify.post('/', { schema: { body: { $ref: 'User' } } }, (req) => {
16-
return {
17-
body: req.body,
18-
schema: req.routeSchema
19-
}
22+
return req.body
2023
})
2124

22-
fastify.listen({ host: '0.0.0.0', port: 3000 }, async (err, address) => {
25+
fastify.listen({ host: '0.0.0.0', port: 3000 }, (err, address) => {
2326
if (err) throw err
2427
console.log(address)
2528
})

packages/fastify/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { AsyncAdapter, SyncAdapter } from '@stenodb/node'
12
import fp from 'fastify-plugin'
23
import { StenoPlugin } from './plugin.js'
4+
import './types.js'
35

46
const FastifySteno = fp(StenoPlugin.createInstance, {
57
name: '@stenodb/fastify',
68
fastify: '4.x'
79
})
810

9-
export { FastifySteno }
11+
export { FastifySteno, AsyncAdapter, SyncAdapter }
1012
export default StenoPlugin.createInstance

packages/fastify/src/plugin.ts

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,76 @@
1-
import { NodeProvider } from '@stenodb/node'
1+
import { AsyncAdapter, NodeProvider, SyncAdapter } from '@stenodb/node'
22
import { targetConstructorToSchema } from 'class-validator-jsonschema'
33
import type { Steno } from '@stenodb/node'
44
import type { IOptions } from 'class-validator-jsonschema/build/options'
55
import type { FastifyInstance } from 'fastify'
66

77
export interface StenoOptions extends Steno.NodeProviderOptions {
8-
entities: Steno.Entity<any>[]
8+
adapters: Steno.NodeAdapter<any>[]
9+
entities?: Steno.Entity<any>[]
10+
entityOptions?: IOptions
911
}
1012

1113
export class StenoPlugin {
1214
#fastify: FastifyInstance
1315
#options: StenoOptions
1416
#provider: NodeProvider
17+
#databases: Map<string, Steno.NodeProvider<any>>
1518

16-
constructor(fastify: FastifyInstance, options: StenoOptions, done: () => void) {
19+
constructor(fastify: FastifyInstance, options: StenoOptions) {
1720
this.#fastify = fastify
1821
this.#options = options
1922
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) })
2525
}
2626

2727
static async createInstance(
2828
fastify: FastifyInstance,
2929
options: StenoOptions,
3030
done: () => void
3131
): 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+
}
3355
}
3456

35-
private registerSchemas(options?: IOptions): void {
57+
private registerEntities() {
58+
if (!this.#options.entities) return
3659
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)
3961
}
4062
}
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+
}
4176
}

packages/fastify/src/types.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
import type { NodeProvider, Steno } from '@stenodb/node'
1+
import type { Steno } from '@stenodb/node'
22

33
declare module 'fastify' {
44
export interface FastifyInstance {
55
steno: {
6-
create: <T>(
7-
name: string,
8-
entity: Steno.Entity<T>,
9-
initialData?: T
10-
) => Promise<void>
116
get: <T>(name: string) => Steno.NodeProvider<T> | undefined
127
}
138
}

0 commit comments

Comments
 (0)