@elysiumjs/core 0.4.3 → 0.5.1
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/README.md +26 -17
- package/dist/app.d.ts +180 -0
- package/dist/cache.d.ts +113 -0
- package/dist/command.d.ts +272 -0
- package/dist/console.d.ts +166 -0
- package/dist/database.d.ts +112 -0
- package/dist/env.d.ts +33 -0
- package/dist/event.d.ts +93 -0
- package/dist/http.d.ts +246 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +19 -0
- package/dist/job.d.ts +105 -0
- package/dist/macros.d.ts +8 -0
- package/dist/middleware.d.ts +69 -0
- package/dist/model.d.ts +4802 -0
- package/dist/module.d.ts +44 -0
- package/dist/redis.d.ts +133 -0
- package/dist/repository.d.ts +163 -0
- package/dist/service.d.ts +131 -0
- package/dist/utils.d.ts +25 -0
- package/dist/wamp.d.ts +272 -0
- package/dist/websocket.d.ts +91 -0
- package/dist/worker.d.ts +219 -0
- package/package.json +16 -9
- package/tsconfig.json +34 -33
- package/index.ts +0 -54
- package/macros.ts +0 -16
- package/src/app.ts +0 -647
- package/src/cache.ts +0 -218
- package/src/command.ts +0 -908
- package/src/console.ts +0 -493
- package/src/database.ts +0 -257
- package/src/env.ts +0 -62
- package/src/event.ts +0 -227
- package/src/http.ts +0 -736
- package/src/job.ts +0 -196
- package/src/middleware.ts +0 -164
- package/src/model.ts +0 -386
- package/src/module.ts +0 -108
- package/src/redis.ts +0 -408
- package/src/repository.ts +0 -295
- package/src/service.ts +0 -351
- package/src/utils.ts +0 -95
- package/src/wamp.ts +0 -569
- package/src/websocket.ts +0 -191
- package/src/worker.ts +0 -849
- package/types.d.ts +0 -35
package/src/service.ts
DELETED
|
@@ -1,351 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import type { Class } from 'type-fest';
|
|
16
|
-
|
|
17
|
-
import { isString } from 'radash';
|
|
18
|
-
|
|
19
|
-
import { Symbols } from './utils';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* The scope of a service.
|
|
23
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
24
|
-
*/
|
|
25
|
-
export enum ServiceScope {
|
|
26
|
-
/**
|
|
27
|
-
* A single instance of the service is created and shared everywhere it is injected or retrieved.
|
|
28
|
-
*/
|
|
29
|
-
SINGLETON,
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* A new instance of the service is created every time it is injected or retrieved.
|
|
33
|
-
*/
|
|
34
|
-
FACTORY
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* A generic service class.
|
|
39
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
40
|
-
*/
|
|
41
|
-
type ServiceClass = Class<any>;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* A typed service class.
|
|
45
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
46
|
-
*/
|
|
47
|
-
type TypedServiceClass<T> = Class<T>;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Describes metadata for each registered service.
|
|
51
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
52
|
-
*/
|
|
53
|
-
type ServiceRegistration = {
|
|
54
|
-
/**
|
|
55
|
-
* The service's scope.
|
|
56
|
-
*/
|
|
57
|
-
scope: ServiceScope;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* A factory function that create the service.
|
|
61
|
-
*
|
|
62
|
-
* When `scope` is set to `Scope.SINGLETON`, this function always return the
|
|
63
|
-
* same instance.
|
|
64
|
-
*
|
|
65
|
-
* @returns An instance to the service.
|
|
66
|
-
*/
|
|
67
|
-
factory: () => any;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Describes the metadata stored for each injected services.
|
|
72
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
73
|
-
*/
|
|
74
|
-
type InjectedService = {
|
|
75
|
-
/**
|
|
76
|
-
* The name of the injected service. It should match the one used when
|
|
77
|
-
* registering the service.
|
|
78
|
-
*/
|
|
79
|
-
name: string;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* The index in the constructor where the service is injected.
|
|
83
|
-
*/
|
|
84
|
-
index: number;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Type for a factory function.
|
|
89
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
90
|
-
*/
|
|
91
|
-
type FactoryFn<T> = () => T extends void ? never : T;
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Utility function to check if a value is a class.
|
|
95
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
96
|
-
* @param value The value to check.
|
|
97
|
-
* @returns `true` if the value is a class, `false` otherwise.
|
|
98
|
-
*/
|
|
99
|
-
const isClass = <T, V>(value: Class<T> | V): value is Class<T> => {
|
|
100
|
-
return typeof value === 'function' && value.prototype && value.prototype.constructor === value;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Storage for registered services.
|
|
105
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
106
|
-
*/
|
|
107
|
-
const servicesRegistry = new Map<string, ServiceRegistration>();
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Properties required when declaring a service using the `@service()` decorator.
|
|
111
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
112
|
-
*/
|
|
113
|
-
export type ServiceProps = Partial<{
|
|
114
|
-
/**
|
|
115
|
-
* The name of the service. If not set, it will default to the service class name.
|
|
116
|
-
*/
|
|
117
|
-
name: string;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* The service's scope.
|
|
121
|
-
*
|
|
122
|
-
* Set it to `Scope.SINGLETON` to ensure that only one instance of this service is
|
|
123
|
-
* used everywhere it is injected or retrieved.
|
|
124
|
-
*
|
|
125
|
-
* Set it to `Scope.FACTORY` to ensure that every time you inject or retrieve this
|
|
126
|
-
* service, you have a new instance created.
|
|
127
|
-
*
|
|
128
|
-
* @see ServiceScope
|
|
129
|
-
*/
|
|
130
|
-
scope: ServiceScope;
|
|
131
|
-
}>;
|
|
132
|
-
|
|
133
|
-
export namespace Service {
|
|
134
|
-
/**
|
|
135
|
-
* Marks a class as a service
|
|
136
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
137
|
-
* @param options The decorator options.
|
|
138
|
-
*/
|
|
139
|
-
export const register = (options?: ServiceProps) => {
|
|
140
|
-
return function (target: ServiceClass) {
|
|
141
|
-
const name = options?.name ?? target.name;
|
|
142
|
-
const scope = options?.scope ?? ServiceScope.SINGLETON;
|
|
143
|
-
|
|
144
|
-
if (Service.exists(name)) {
|
|
145
|
-
// TODO: Use the logger service here
|
|
146
|
-
console.error(`A service with the name ${name} has already been registered.`);
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const factory = () => Service.make(target);
|
|
151
|
-
|
|
152
|
-
if (scope === ServiceScope.SINGLETON) {
|
|
153
|
-
const service = factory();
|
|
154
|
-
servicesRegistry.set(name, {
|
|
155
|
-
scope,
|
|
156
|
-
factory() {
|
|
157
|
-
return service;
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
} else {
|
|
161
|
-
servicesRegistry.set(name, {
|
|
162
|
-
scope,
|
|
163
|
-
factory
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Resolves a registered service and set it as a parameter value.
|
|
171
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
172
|
-
* @param service An optional name for the service. If not set, the name of the parameter's type is used instead.
|
|
173
|
-
*/
|
|
174
|
-
export const inject = (service?: string | ServiceClass): ParameterDecorator => {
|
|
175
|
-
return function (target, propertyKey, parameterIndex) {
|
|
176
|
-
const services = Reflect.getMetadata(Symbols.services, target, propertyKey!) ?? [];
|
|
177
|
-
const types: Function[] =
|
|
178
|
-
Reflect.getMetadata('design:paramtypes', target, propertyKey!) ?? [];
|
|
179
|
-
const name = isString(service) ? service : (service?.name ?? types[parameterIndex].name);
|
|
180
|
-
|
|
181
|
-
services.push({
|
|
182
|
-
name,
|
|
183
|
-
index: parameterIndex
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
Reflect.defineMetadata(Symbols.services, services, target, propertyKey!);
|
|
187
|
-
};
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Retrieves a registered service's instance from the container.
|
|
192
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
193
|
-
* @param service The name of the service, or its class.
|
|
194
|
-
* @returns An instance of the registered service, or `null` if no service with that name/type was registered.
|
|
195
|
-
*/
|
|
196
|
-
export const get = <T>(service: string | TypedServiceClass<T>): T | null => {
|
|
197
|
-
const name = isString(service) ? service : service.name;
|
|
198
|
-
|
|
199
|
-
if (exists(name)) {
|
|
200
|
-
const service = servicesRegistry.get(name)!;
|
|
201
|
-
return service.factory() as T;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return null;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Instantiates a service with its dependencies.
|
|
209
|
-
*
|
|
210
|
-
* This function always create a new instance of the service, even if the service's scope is `ServiceScope.SINGLETON`
|
|
211
|
-
* and it has already been registered in the container.
|
|
212
|
-
*
|
|
213
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
214
|
-
*
|
|
215
|
-
* @param service The service class to instantiate.
|
|
216
|
-
*/
|
|
217
|
-
export const make = <T>(service: TypedServiceClass<T>): T => {
|
|
218
|
-
const dependencies: Array<InjectedService> =
|
|
219
|
-
Reflect.getMetadata(Symbols.services, service) ?? [];
|
|
220
|
-
|
|
221
|
-
const params: any[] = [];
|
|
222
|
-
dependencies.forEach((dependency) => {
|
|
223
|
-
const s = get(dependency.name);
|
|
224
|
-
|
|
225
|
-
if (s === null) {
|
|
226
|
-
// TODO: Use the logger service here
|
|
227
|
-
console.error(
|
|
228
|
-
`Cannot inject service ${dependency.name}. No service was registered with the name: ${dependency.name}`
|
|
229
|
-
);
|
|
230
|
-
process.exit(1);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
params[dependency.index] = s;
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
return new service(...params);
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Binds a service to the container and sets it as a singleton.
|
|
241
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
242
|
-
* @param service The service class to bind.
|
|
243
|
-
* @param name An optional name for the service. If not set, the name of the service class is used instead.
|
|
244
|
-
*/
|
|
245
|
-
export const bind = <T>(service: TypedServiceClass<T>, name?: string): T => {
|
|
246
|
-
const s = make(service);
|
|
247
|
-
return instance(name ?? service.name, s);
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Binds a service to the container and sets it as a factory.
|
|
252
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
253
|
-
* @param name A name for the service.
|
|
254
|
-
* @param factory The factory function used to instantiate the service.
|
|
255
|
-
*/
|
|
256
|
-
export function factory<T>(name: string, factory: FactoryFn<T>): T;
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Binds a service to the container and sets it as a factory.
|
|
260
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
261
|
-
* @param service The service class to bind.
|
|
262
|
-
* @param name An optional name for the service. If not set, the name of the service class is used instead.
|
|
263
|
-
*/
|
|
264
|
-
export function factory<T>(service: TypedServiceClass<T>, name?: string): T;
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Binds a service to the container and sets it as a factory.
|
|
268
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
269
|
-
* @param serviceOrName The service class to bind or its name.
|
|
270
|
-
* @param nameOrFactory The service name or a factory function.
|
|
271
|
-
*/
|
|
272
|
-
export function factory<T>(
|
|
273
|
-
serviceOrName: TypedServiceClass<T> | string,
|
|
274
|
-
nameOrFactory?: FactoryFn<T> | string
|
|
275
|
-
): T {
|
|
276
|
-
const serviceName = isString(serviceOrName)
|
|
277
|
-
? serviceOrName
|
|
278
|
-
: ((nameOrFactory as string | undefined) ?? serviceOrName.name);
|
|
279
|
-
|
|
280
|
-
if (exists(serviceName)) {
|
|
281
|
-
// TODO: Use the logger service here
|
|
282
|
-
console.error(`A service with the name ${serviceName} has already been registered.`);
|
|
283
|
-
process.exit(1);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const factory = () => {
|
|
287
|
-
return isClass(serviceOrName) ? make(serviceOrName) : (nameOrFactory as FactoryFn<T>)();
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
servicesRegistry.set(serviceName, {
|
|
291
|
-
scope: ServiceScope.FACTORY,
|
|
292
|
-
factory
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
return factory();
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Binds a service's instance to the container.
|
|
300
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
301
|
-
* @param service The service class or name to bind.
|
|
302
|
-
* @param instance The instance to bind.
|
|
303
|
-
*/
|
|
304
|
-
export const instance = <T>(service: string | TypedServiceClass<T>, instance: T): T => {
|
|
305
|
-
const serviceName = isString(service) ? service : service.name;
|
|
306
|
-
|
|
307
|
-
if (exists(serviceName)) {
|
|
308
|
-
// TODO: Use the logger service here
|
|
309
|
-
console.error(`A service with the name ${serviceName} has already been registered.`);
|
|
310
|
-
process.exit(1);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
servicesRegistry.set(serviceName, {
|
|
314
|
-
scope: ServiceScope.SINGLETON,
|
|
315
|
-
factory() {
|
|
316
|
-
return instance;
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
return instance;
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Removes a service from the container.
|
|
325
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
326
|
-
* @param service The service class or name to remove.
|
|
327
|
-
*/
|
|
328
|
-
export const remove = (service: string | TypedServiceClass<any>): void => {
|
|
329
|
-
const serviceName = isString(service) ? service : service.name;
|
|
330
|
-
servicesRegistry.delete(serviceName);
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Checks if a service exists in the container.
|
|
335
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
336
|
-
* @param service The service class or name to check.
|
|
337
|
-
* @returns `true` if the service exists, `false` otherwise.
|
|
338
|
-
*/
|
|
339
|
-
export const exists = (service: string | TypedServiceClass<any>): boolean => {
|
|
340
|
-
const serviceName = isString(service) ? service : service.name;
|
|
341
|
-
return servicesRegistry.has(serviceName);
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Clears the container.
|
|
346
|
-
* @author Axel Nana <axel.nana@workbud.com>
|
|
347
|
-
*/
|
|
348
|
-
export const clear = () => {
|
|
349
|
-
servicesRegistry.clear();
|
|
350
|
-
};
|
|
351
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import type { Elysia } from 'elysia';
|
|
16
|
-
|
|
17
|
-
import { isObject, isPrimitive } from 'radash';
|
|
18
|
-
|
|
19
|
-
export namespace Symbols {
|
|
20
|
-
export const app = Symbol('elysium:Application');
|
|
21
|
-
|
|
22
|
-
export const controller = Symbol('elysium:Controller');
|
|
23
|
-
|
|
24
|
-
export const middlewares = Symbol('elysium:MiddlewaresList');
|
|
25
|
-
|
|
26
|
-
export const services = Symbol('elysium:ServicesList');
|
|
27
|
-
|
|
28
|
-
export const websocket = Symbol('elysium:WebSocket');
|
|
29
|
-
|
|
30
|
-
export const wamp = Symbol('elysium:Wamp');
|
|
31
|
-
|
|
32
|
-
export const http = Symbol('elysium:Http');
|
|
33
|
-
|
|
34
|
-
export const job = Symbol('elysium:Job');
|
|
35
|
-
|
|
36
|
-
export const arg = Symbol('elysium:CommandArguments');
|
|
37
|
-
|
|
38
|
-
export const elysiaPlugin = Symbol('elysium:ElysiaPlugin');
|
|
39
|
-
|
|
40
|
-
export const middlewareGuards = Symbol('elysium:MiddlewareGuards');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const nextTick = () => new Promise((resolve) => process.nextTick(resolve));
|
|
44
|
-
|
|
45
|
-
export type ElysiaPlugin = () => Promise<Elysia>;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Deeply merges objects from right to left
|
|
49
|
-
* Arrays are also merged if they are found in child objects
|
|
50
|
-
*
|
|
51
|
-
* @param target The target object to merge into
|
|
52
|
-
* @param sources One or more source objects to merge from
|
|
53
|
-
* @returns The merged object (same reference as target)
|
|
54
|
-
*/
|
|
55
|
-
export function deepMerge<T extends Record<string, any | any[]>>(target: T, ...sources: T[]): T {
|
|
56
|
-
if (!sources.length) return target;
|
|
57
|
-
|
|
58
|
-
const source = sources.shift();
|
|
59
|
-
if (source === undefined) return target;
|
|
60
|
-
|
|
61
|
-
if (isObject(target) && isObject(source)) {
|
|
62
|
-
for (const key in source) {
|
|
63
|
-
if (isObject(source[key])) {
|
|
64
|
-
if (!target[key]) {
|
|
65
|
-
Object.assign(target, { [key]: source[key] });
|
|
66
|
-
}
|
|
67
|
-
} else if (Array.isArray(source[key])) {
|
|
68
|
-
if (!Array.isArray(target[key])) {
|
|
69
|
-
target[key] = [] as any;
|
|
70
|
-
}
|
|
71
|
-
// Merge arrays by concatenating and removing duplicates for primitive values
|
|
72
|
-
if (source[key].length > 0 && !isObject(source[key][0])) {
|
|
73
|
-
target[key] = [...new Set([...target[key], ...source[key]])] as any;
|
|
74
|
-
} else {
|
|
75
|
-
// For arrays of objects, merge each item
|
|
76
|
-
source[key].forEach((item: any, index: number) => {
|
|
77
|
-
if (isObject(item) && target[key][index]) {
|
|
78
|
-
target[key][index] = deepMerge(target[key][index], item);
|
|
79
|
-
} else {
|
|
80
|
-
if (!target[key].includes(item)) {
|
|
81
|
-
target[key].push(item);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
} else if (isPrimitive(source[key])) {
|
|
87
|
-
target[key] ??= source[key];
|
|
88
|
-
} else {
|
|
89
|
-
deepMerge(target[key], source[key]);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return deepMerge(target, ...sources);
|
|
95
|
-
}
|