-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathplugin.ts
116 lines (99 loc) · 2.87 KB
/
plugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import type { StarbaseApp, StarbaseDBConfiguration } from './handler'
import { DataSource } from './types'
class UnimplementedError extends Error {
constructor(public method: string) {
super(`Method ${method} is not implemented`)
}
}
export abstract class StarbasePlugin {
constructor(
public name: string,
public opts: { requiresAuth: boolean } = { requiresAuth: true },
public pathPrefix?: string
) {}
public async register(app: StarbaseApp): Promise<void> {
throw new UnimplementedError('register')
}
public async beforeQuery(opts: {
sql: string
params?: unknown[]
dataSource?: DataSource
config?: StarbaseDBConfiguration
}): Promise<{ sql: string; params?: unknown[] }> {
return {
sql: opts.sql,
params: opts.params,
}
}
public async afterQuery(opts: {
sql: string
result: any
isRaw: boolean
dataSource?: DataSource
config?: StarbaseDBConfiguration
}): Promise<any> {
return opts.result
}
}
export class StarbasePluginRegistry {
private app: StarbaseApp
private plugins: StarbasePlugin[] = []
constructor(opts: { app: StarbaseApp; plugins: StarbasePlugin[] }) {
this.app = opts.app
this.plugins = opts.plugins
}
async init() {
for (const plugin of this.plugins) {
await this.registerPlugin(plugin)
}
}
private async registerPlugin(plugin: StarbasePlugin) {
try {
await plugin.register(this.app)
console.log(`Plugin ${plugin.name} registered`)
} catch (e) {
if (e instanceof UnimplementedError) {
return
}
console.error(`Error registering plugin ${plugin.name}: ${e}`)
throw e
}
}
public currentPlugins(): string[] {
return this.plugins.map((plugin) => plugin.name)
}
public async beforeQuery(opts: {
sql: string
params?: unknown[]
dataSource?: DataSource
config?: StarbaseDBConfiguration
}): Promise<{ sql: string; params?: unknown[] }> {
let { sql, params } = opts
for (const plugin of this.plugins) {
const { sql: _sql, params: _params } =
await plugin.beforeQuery(opts)
sql = _sql
params = _params
}
return {
sql,
params,
}
}
public async afterQuery(opts: {
sql: string
result: any
isRaw: boolean
dataSource?: DataSource
config?: StarbaseDBConfiguration
}): Promise<any> {
let { result } = opts
for (const plugin of this.plugins) {
result = await plugin.afterQuery({
...opts,
result,
})
}
return result
}
}