@elysiumjs/core 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/env.ts +6 -2
- package/src/middleware.ts +20 -1
- package/src/model.ts +34 -10
- package/src/utils.ts +12 -10
package/package.json
CHANGED
package/src/env.ts
CHANGED
|
@@ -32,10 +32,14 @@ export namespace Env {
|
|
|
32
32
|
* Gets the value of an environment variable.
|
|
33
33
|
* @author Axel Nana <axel.nana@workbud.com>
|
|
34
34
|
* @param name The name of the environment variable.
|
|
35
|
+
* @param defaultValue The default value to return if the environment variable is not set.
|
|
35
36
|
* @returns The value of the environment variable.
|
|
36
37
|
*/
|
|
37
|
-
export const get = <TKey extends keyof AppEnv>(
|
|
38
|
-
|
|
38
|
+
export const get = <TKey extends keyof AppEnv>(
|
|
39
|
+
name: TKey,
|
|
40
|
+
defaultValue?: AppEnv[TKey]
|
|
41
|
+
): AppEnv[TKey] => {
|
|
42
|
+
return (env.get(name) ?? defaultValue) as AppEnv[TKey];
|
|
39
43
|
};
|
|
40
44
|
|
|
41
45
|
/**
|
package/src/middleware.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { Symbols } from './utils';
|
|
|
30
30
|
export const executeMiddlewareChain = (
|
|
31
31
|
middlewares: Middleware[],
|
|
32
32
|
context: any,
|
|
33
|
-
method: keyof Middleware
|
|
33
|
+
method: Exclude<keyof Middleware, 'guards'>
|
|
34
34
|
): Promise<any> => {
|
|
35
35
|
return Application.context.run(
|
|
36
36
|
new Map([
|
|
@@ -102,6 +102,25 @@ export abstract class Middleware {
|
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Creates a guarded version of the middleware.
|
|
107
|
+
* @author Axel Nana <axel.nana@workbud.com>
|
|
108
|
+
* @param guards The list of guards for the middleware.
|
|
109
|
+
* @returns A middleware class decorated with guards.
|
|
110
|
+
*/
|
|
111
|
+
public static guards(guards: string[]): Class<Middleware> {
|
|
112
|
+
class GuardedMiddleware extends this {}
|
|
113
|
+
Reflect.defineMetadata(Symbols.middlewareGuards, guards, GuardedMiddleware);
|
|
114
|
+
return GuardedMiddleware;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Gets the list of guards for the middleware.
|
|
119
|
+
*/
|
|
120
|
+
public get guards(): string[] {
|
|
121
|
+
return Reflect.getMetadata(Symbols.middlewareGuards, this.constructor) ?? [];
|
|
122
|
+
}
|
|
123
|
+
|
|
105
124
|
/**
|
|
106
125
|
* Called after the request has been handled, but before the response is sent.
|
|
107
126
|
* @param ctx The request context.
|
package/src/model.ts
CHANGED
|
@@ -101,6 +101,7 @@ const parseTypes = (element: PgColumn) => {
|
|
|
101
101
|
* @template TTable The drizzle's table schema wrapped by the repository.
|
|
102
102
|
*/
|
|
103
103
|
export type ModelClass<
|
|
104
|
+
TTableName extends string,
|
|
104
105
|
TColumnsMap extends Record<string, PgColumnBuilderBase>,
|
|
105
106
|
TTable extends PgTable = ReturnType<typeof pgTable<string, TColumnsMap>>
|
|
106
107
|
> = {
|
|
@@ -128,7 +129,7 @@ export type ModelClass<
|
|
|
128
129
|
/**
|
|
129
130
|
* The name of the table wrapped by the model.
|
|
130
131
|
*/
|
|
131
|
-
readonly tableName:
|
|
132
|
+
readonly tableName: TTableName;
|
|
132
133
|
|
|
133
134
|
/**
|
|
134
135
|
* The table columns configuration.
|
|
@@ -173,8 +174,11 @@ export type ModelClass<
|
|
|
173
174
|
* @param tableName The name of the table.
|
|
174
175
|
* @param columns The table columns configuration.
|
|
175
176
|
*/
|
|
176
|
-
export const Model = <
|
|
177
|
-
|
|
177
|
+
export const Model = <
|
|
178
|
+
TTableName extends string,
|
|
179
|
+
TColumnsMap extends Record<string, PgColumnBuilderBase>
|
|
180
|
+
>(
|
|
181
|
+
tableName: TTableName,
|
|
178
182
|
columns: TColumnsMap
|
|
179
183
|
) => {
|
|
180
184
|
const table = pgTable(tableName, columns);
|
|
@@ -198,7 +202,7 @@ export const Model = <TColumnsMap extends Record<string, PgColumnBuilderBase>>(
|
|
|
198
202
|
/**
|
|
199
203
|
* The drizzle's table schema wrapped by this model.
|
|
200
204
|
*/
|
|
201
|
-
public static get table(): ReturnType<typeof pgTable<
|
|
205
|
+
public static get table(): ReturnType<typeof pgTable<TTableName, TColumnsMap>> {
|
|
202
206
|
// If we are not inside an Application context, we can't use the tenancy system
|
|
203
207
|
if (!Application.instance || !Application.context.getStore) {
|
|
204
208
|
return table;
|
|
@@ -207,7 +211,7 @@ export const Model = <TColumnsMap extends Record<string, PgColumnBuilderBase>>(
|
|
|
207
211
|
if (this.supportTenancy) {
|
|
208
212
|
const tenant = Tenancy.getCurrentTenant() ?? 'public';
|
|
209
213
|
// @ts-expect-error typeof this strangely doesn't match the ModelClass type
|
|
210
|
-
return Tenancy.
|
|
214
|
+
return Tenancy.wrapTenant(tenant, this);
|
|
211
215
|
}
|
|
212
216
|
|
|
213
217
|
return table;
|
|
@@ -292,9 +296,13 @@ export namespace Tenancy {
|
|
|
292
296
|
* @param model The model class that wraps the `PgTable`.
|
|
293
297
|
* @returns The drizzle's table schema wrapped by the tenant.
|
|
294
298
|
*/
|
|
295
|
-
export const
|
|
296
|
-
T extends ModelClass<TColumnsMap>,
|
|
299
|
+
export const wrapTenant = <
|
|
300
|
+
T extends ModelClass<TTableName, TColumnsMap>,
|
|
301
|
+
TTableName extends string = T extends ModelClass<infer TTableName, infer TColumnsMap>
|
|
302
|
+
? TTableName
|
|
303
|
+
: string,
|
|
297
304
|
TColumnsMap extends Record<string, PgColumnBuilderBase> = T extends ModelClass<
|
|
305
|
+
TTableName,
|
|
298
306
|
infer TColumnsMap
|
|
299
307
|
>
|
|
300
308
|
? TColumnsMap
|
|
@@ -302,21 +310,21 @@ export namespace Tenancy {
|
|
|
302
310
|
>(
|
|
303
311
|
tenant: string,
|
|
304
312
|
model: T
|
|
305
|
-
): ReturnType<typeof pgTable<
|
|
313
|
+
): ReturnType<typeof pgTable<TTableName, TColumnsMap>> => {
|
|
306
314
|
if (tenant === 'public') {
|
|
307
315
|
return pgTable(model.tableName, model.columns);
|
|
308
316
|
}
|
|
309
317
|
|
|
310
318
|
const tableName = `${tenant}.${model.tableName}`;
|
|
311
319
|
if (tenantSchemas.has(tableName)) {
|
|
312
|
-
return tenantSchemas.get(tableName)! as ReturnType<typeof pgTable<
|
|
320
|
+
return tenantSchemas.get(tableName)! as ReturnType<typeof pgTable<TTableName, TColumnsMap>>;
|
|
313
321
|
}
|
|
314
322
|
|
|
315
323
|
const tenantSchema = getTenantSchema(tenant);
|
|
316
324
|
const schemaTable = tenantSchema.table(model.tableName, model.columns);
|
|
317
325
|
tenantSchemas.set(tableName, schemaTable);
|
|
318
326
|
|
|
319
|
-
return schemaTable as unknown as ReturnType<typeof pgTable<
|
|
327
|
+
return schemaTable as unknown as ReturnType<typeof pgTable<TTableName, TColumnsMap>>;
|
|
320
328
|
};
|
|
321
329
|
|
|
322
330
|
/**
|
|
@@ -333,4 +341,20 @@ export namespace Tenancy {
|
|
|
333
341
|
|
|
334
342
|
return tenantSchema;
|
|
335
343
|
};
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Runs the given callback in a context with the given tenant.
|
|
347
|
+
* @author Axel Nana <axel.nana@workbud.com>
|
|
348
|
+
* @param tenant The name of the tenant.
|
|
349
|
+
* @param callback The callback to run.
|
|
350
|
+
* @returns The result of the callback.
|
|
351
|
+
*/
|
|
352
|
+
export const withTenant = <TReturn>(tenant: string, callback: () => TReturn): TReturn => {
|
|
353
|
+
const currentStore = Application.context.getStore();
|
|
354
|
+
|
|
355
|
+
const newStore = new Map(currentStore);
|
|
356
|
+
newStore.set('tenant', tenant);
|
|
357
|
+
|
|
358
|
+
return Application.context.run(newStore, callback);
|
|
359
|
+
};
|
|
336
360
|
}
|
package/src/utils.ts
CHANGED
|
@@ -17,25 +17,27 @@ import type { Elysia } from 'elysia';
|
|
|
17
17
|
import { isObject, isPrimitive } from 'radash';
|
|
18
18
|
|
|
19
19
|
export namespace Symbols {
|
|
20
|
-
export const app = Symbol('
|
|
20
|
+
export const app = Symbol('elysium:Application');
|
|
21
21
|
|
|
22
|
-
export const controller = Symbol('
|
|
22
|
+
export const controller = Symbol('elysium:Controller');
|
|
23
23
|
|
|
24
|
-
export const middlewares = Symbol('
|
|
24
|
+
export const middlewares = Symbol('elysium:MiddlewaresList');
|
|
25
25
|
|
|
26
|
-
export const services = Symbol('
|
|
26
|
+
export const services = Symbol('elysium:ServicesList');
|
|
27
27
|
|
|
28
|
-
export const websocket = Symbol('
|
|
28
|
+
export const websocket = Symbol('elysium:WebSocket');
|
|
29
29
|
|
|
30
|
-
export const wamp = Symbol('
|
|
30
|
+
export const wamp = Symbol('elysium:Wamp');
|
|
31
31
|
|
|
32
|
-
export const http = Symbol('
|
|
32
|
+
export const http = Symbol('elysium:Http');
|
|
33
33
|
|
|
34
|
-
export const job = Symbol('
|
|
34
|
+
export const job = Symbol('elysium:Job');
|
|
35
35
|
|
|
36
|
-
export const arg = Symbol('
|
|
36
|
+
export const arg = Symbol('elysium:CommandArguments');
|
|
37
37
|
|
|
38
|
-
export const elysiaPlugin = Symbol('
|
|
38
|
+
export const elysiaPlugin = Symbol('elysium:ElysiaPlugin');
|
|
39
|
+
|
|
40
|
+
export const middlewareGuards = Symbol('elysium:MiddlewareGuards');
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
export const nextTick = () => new Promise((resolve) => process.nextTick(resolve));
|