opinionated-machine 2.1.0 → 2.3.0
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 +17 -8
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/AbstractModule.d.ts +4 -0
- package/dist/lib/AbstractModule.js.map +1 -1
- package/dist/lib/AbstractTestContextFactory.d.ts +23 -0
- package/dist/lib/AbstractTestContextFactory.js +39 -0
- package/dist/lib/AbstractTestContextFactory.js.map +1 -0
- package/dist/lib/DIContext.d.ts +6 -4
- package/dist/lib/DIContext.js +21 -9
- package/dist/lib/DIContext.js.map +1 -1
- package/dist/lib/resolverFunctions.d.ts +10 -0
- package/dist/lib/resolverFunctions.js +35 -2
- package/dist/lib/resolverFunctions.js.map +1 -1
- package/package.json +10 -2
- package/dist/lib/typeUtils.d.ts +0 -19
- package/dist/lib/typeUtils.js +0 -2
- package/dist/lib/typeUtils.js.map +0 -1
package/README.md
CHANGED
|
@@ -86,18 +86,27 @@ const contract = buildDeleteRoute({
|
|
|
86
86
|
|
|
87
87
|
export class MyController extends AbstractController<typeof MyController.contracts> {
|
|
88
88
|
public static contracts = { deleteItem: contract } as const
|
|
89
|
+
private readonly service: Service
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
constructor({ service }: ModuleDependencies) {
|
|
92
|
+
super()
|
|
93
|
+
this.service = testService
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private deleteItem = buildFastifyNoPayloadRoute(
|
|
97
|
+
TestController.contracts.deleteItem,
|
|
94
98
|
async (req, reply) => {
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
req.log.info(req.params.userId)
|
|
100
|
+
this.service.execute()
|
|
101
|
+
await reply.status(204).send()
|
|
97
102
|
},
|
|
98
|
-
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
public buildRoutes() {
|
|
106
|
+
return {
|
|
107
|
+
deleteItem: this.deleteItem,
|
|
108
|
+
}
|
|
99
109
|
}
|
|
100
|
-
}
|
|
101
110
|
}
|
|
102
111
|
```
|
|
103
112
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { DIContext, type DependencyInjectionOptions, type
|
|
2
|
-
export { AbstractModule, type MandatoryNameAndRegistrationPair } from './lib/AbstractModule.js';
|
|
1
|
+
export { DIContext, type DependencyInjectionOptions, type RegisterDependenciesParams, } from './lib/DIContext.js';
|
|
2
|
+
export { AbstractModule, type MandatoryNameAndRegistrationPair, type UnionToIntersection, } from './lib/AbstractModule.js';
|
|
3
3
|
export { ENABLE_ALL, resolveJobQueuesEnabled, isJobQueueEnabled, isMessageQueueConsumerEnabled, isJobWorkersEnabled, isPeriodicJobEnabled, } from './lib/diConfigUtils.js';
|
|
4
4
|
export { AbstractController } from './lib/AbstractController.js';
|
|
5
|
-
export { asJobQueueClass, asJobWorkerClass, asMessageQueueHandlerClass, asControllerClass, asSingletonClass, asPeriodicJobClass, } from './lib/resolverFunctions.js';
|
|
5
|
+
export { asJobQueueClass, asJobWorkerClass, asMessageQueueHandlerClass, asControllerClass, asSingletonClass, asPeriodicJobClass, asSingletonFunction, asServiceClass, asRepositoryClass, asUseCaseClass, } from './lib/resolverFunctions.js';
|
|
6
6
|
export type { PeriodicJobOptions, JobQueueModuleOptions, MessageQueueConsumerModuleOptions, JobWorkerModuleOptions, } from './lib/resolverFunctions.js';
|
|
7
|
-
export type
|
|
7
|
+
export { AbstractTestContextFactory, type CreateTestContextParams, type ConfigOverrides, } from './lib/AbstractTestContextFactory.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { DIContext, } from './lib/DIContext.js';
|
|
2
|
-
export { AbstractModule } from './lib/AbstractModule.js';
|
|
2
|
+
export { AbstractModule, } from './lib/AbstractModule.js';
|
|
3
3
|
export { ENABLE_ALL, resolveJobQueuesEnabled, isJobQueueEnabled, isMessageQueueConsumerEnabled, isJobWorkersEnabled, isPeriodicJobEnabled, } from './lib/diConfigUtils.js';
|
|
4
4
|
export { AbstractController } from './lib/AbstractController.js';
|
|
5
|
-
export { asJobQueueClass, asJobWorkerClass, asMessageQueueHandlerClass, asControllerClass, asSingletonClass, asPeriodicJobClass, } from './lib/resolverFunctions.js';
|
|
5
|
+
export { asJobQueueClass, asJobWorkerClass, asMessageQueueHandlerClass, asControllerClass, asSingletonClass, asPeriodicJobClass, asSingletonFunction, asServiceClass, asRepositoryClass, asUseCaseClass, } from './lib/resolverFunctions.js';
|
|
6
|
+
export { AbstractTestContextFactory, } from './lib/AbstractTestContextFactory.js';
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,GAGV,MAAM,oBAAoB,CAAA;AAC3B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,GAGV,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,cAAc,GAGf,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,6BAA6B,EAC7B,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,0BAA0B,EAC1B,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,cAAc,GACf,MAAM,4BAA4B,CAAA;AASnC,OAAO,EACL,0BAA0B,GAG3B,MAAM,qCAAqC,CAAA"}
|
|
@@ -3,6 +3,10 @@ import type { DependencyInjectionOptions } from './DIContext.js';
|
|
|
3
3
|
export type MandatoryNameAndRegistrationPair<T> = {
|
|
4
4
|
[U in keyof T]: Resolver<T[U]>;
|
|
5
5
|
};
|
|
6
|
+
/**
|
|
7
|
+
* Use this utility type to combine dependencies from multiple modules into full context list of dependencies
|
|
8
|
+
*/
|
|
9
|
+
export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
6
10
|
export declare abstract class AbstractModule<ModuleDependencies, ExternalDependencies = never> {
|
|
7
11
|
abstract resolveDependencies(diOptions: DependencyInjectionOptions, externalDependencies: ExternalDependencies): MandatoryNameAndRegistrationPair<ModuleDependencies>;
|
|
8
12
|
abstract resolveControllers(): MandatoryNameAndRegistrationPair<unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractModule.js","sourceRoot":"","sources":["../../lib/AbstractModule.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AbstractModule.js","sourceRoot":"","sources":["../../lib/AbstractModule.ts"],"names":[],"mappings":"AAcA,MAAM,OAAgB,cAAc;CAOnC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type NameAndRegistrationPair } from 'awilix';
|
|
2
|
+
import type { AbstractModule } from './AbstractModule.js';
|
|
3
|
+
import { DIContext, type DependencyInjectionOptions } from './DIContext.js';
|
|
4
|
+
type NestedPartial<T> = {
|
|
5
|
+
[P in keyof T]?: NestedPartial<T[P]>;
|
|
6
|
+
};
|
|
7
|
+
export type ConfigOverrides<Config> = NestedPartial<Config>;
|
|
8
|
+
export type CreateTestContextParams<Dependencies, Config extends object> = {
|
|
9
|
+
modules?: readonly AbstractModule<unknown>[];
|
|
10
|
+
diOptions?: DependencyInjectionOptions;
|
|
11
|
+
dependencyOverrides?: NameAndRegistrationPair<Dependencies>;
|
|
12
|
+
configOverrides?: ConfigOverrides<Config>;
|
|
13
|
+
};
|
|
14
|
+
export declare abstract class AbstractTestContextFactory<Dependencies extends object, ExternalDependencies, Config extends object> {
|
|
15
|
+
private readonly externalDependencies;
|
|
16
|
+
protected configDependencyId: string;
|
|
17
|
+
private readonly allModules;
|
|
18
|
+
constructor(externalDependencies: ExternalDependencies, allModules: readonly AbstractModule<unknown>[]);
|
|
19
|
+
resetExternalDependencies(): void;
|
|
20
|
+
abstract resolveBaseAppConfig(): Config;
|
|
21
|
+
createTestContext(params?: CreateTestContextParams<Dependencies, Config>): Promise<DIContext<Dependencies, ExternalDependencies>>;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createContainer } from 'awilix';
|
|
2
|
+
import { merge } from 'ts-deepmerge';
|
|
3
|
+
import { DIContext } from './DIContext.js';
|
|
4
|
+
import { asSingletonFunction } from './resolverFunctions.js';
|
|
5
|
+
export class AbstractTestContextFactory {
|
|
6
|
+
externalDependencies;
|
|
7
|
+
configDependencyId = 'config'; // override in subclass if different
|
|
8
|
+
allModules;
|
|
9
|
+
constructor(externalDependencies, allModules) {
|
|
10
|
+
this.externalDependencies = externalDependencies;
|
|
11
|
+
this.allModules = allModules;
|
|
12
|
+
}
|
|
13
|
+
resetExternalDependencies() {
|
|
14
|
+
// Override if necessary
|
|
15
|
+
}
|
|
16
|
+
async createTestContext(params = {}) {
|
|
17
|
+
const diContainer = createContainer({
|
|
18
|
+
injectionMode: 'PROXY',
|
|
19
|
+
});
|
|
20
|
+
const context = new DIContext(diContainer, params.diOptions ?? {});
|
|
21
|
+
const dependencyOverrides = params.configOverrides
|
|
22
|
+
? {
|
|
23
|
+
...params.dependencyOverrides,
|
|
24
|
+
[this.configDependencyId]: asSingletonFunction(() => {
|
|
25
|
+
// biome-ignore lint/style/noNonNullAssertion: there is a ternary condition above
|
|
26
|
+
return merge(this.resolveBaseAppConfig(), params.configOverrides);
|
|
27
|
+
}),
|
|
28
|
+
}
|
|
29
|
+
: params.dependencyOverrides;
|
|
30
|
+
const modules = params.modules ?? this.allModules;
|
|
31
|
+
context.registerDependencies({
|
|
32
|
+
dependencyOverrides,
|
|
33
|
+
modules,
|
|
34
|
+
}, this.externalDependencies, false);
|
|
35
|
+
await context.init();
|
|
36
|
+
return context;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=AbstractTestContextFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractTestContextFactory.js","sourceRoot":"","sources":["../../lib/AbstractTestContextFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,eAAe,EAAE,MAAM,QAAQ,CAAA;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AAEpC,OAAO,EAAE,SAAS,EAAmC,MAAM,gBAAgB,CAAA;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAe5D,MAAM,OAAgB,0BAA0B;IAK7B,oBAAoB,CAAsB;IACjD,kBAAkB,GAAG,QAAQ,CAAA,CAAC,oCAAoC;IAC3D,UAAU,CAAoC;IAE/D,YACE,oBAA0C,EAC1C,UAA8C;QAE9C,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAA;QAChD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;IAED,yBAAyB;QACvB,wBAAwB;IAC1B,CAAC;IAID,KAAK,CAAC,iBAAiB,CACrB,SAAwD,EAAE;QAE1D,MAAM,WAAW,GAAG,eAAe,CAAC;YAClC,aAAa,EAAE,OAAO;SACvB,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,IAAI,SAAS,CAC3B,WAAW,EACX,MAAM,CAAC,SAAS,IAAI,EAAE,CACvB,CAAA;QAED,MAAM,mBAAmB,GAAG,MAAM,CAAC,eAAe;YAChD,CAAC,CAAE;gBACC,GAAG,MAAM,CAAC,mBAAmB;gBAC7B,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,GAAG,EAAE;oBAClD,iFAAiF;oBACjF,OAAO,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,MAAM,CAAC,eAAgB,CAAC,CAAA;gBACpE,CAAC,CAAC;aACuC;YAC7C,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAA;QAE9B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,CAAA;QACjD,OAAO,CAAC,oBAAoB,CAC1B;YACE,mBAAmB;YACnB,OAAO;SACR,EACD,IAAI,CAAC,oBAAoB,EACzB,KAAK,CACN,CAAA;QAED,MAAM,OAAO,CAAC,IAAI,EAAE,CAAA;QAEpB,OAAO,OAAO,CAAA;IAChB,CAAC;CACF"}
|
package/dist/lib/DIContext.d.ts
CHANGED
|
@@ -3,23 +3,25 @@ import { AwilixManager } from 'awilix-manager';
|
|
|
3
3
|
import type { FastifyInstance } from 'fastify';
|
|
4
4
|
import type { AbstractModule } from './AbstractModule.js';
|
|
5
5
|
import type { ENABLE_ALL } from './diConfigUtils.js';
|
|
6
|
-
export type
|
|
6
|
+
export type RegisterDependenciesParams<Dependencies, ExternalDependencies> = {
|
|
7
7
|
modules: readonly AbstractModule<unknown, ExternalDependencies>[];
|
|
8
|
+
secondaryModules?: readonly AbstractModule<unknown, ExternalDependencies>[];
|
|
8
9
|
dependencyOverrides?: NameAndRegistrationPair<Dependencies>;
|
|
9
10
|
};
|
|
10
11
|
export type DependencyInjectionOptions = {
|
|
11
12
|
jobQueuesEnabled?: false | typeof ENABLE_ALL | string[];
|
|
12
13
|
jobWorkersEnabled?: false | typeof ENABLE_ALL | string[];
|
|
13
14
|
messageQueueConsumersEnabled?: false | typeof ENABLE_ALL | string[];
|
|
14
|
-
periodicJobsEnabled?: false | typeof ENABLE_ALL;
|
|
15
|
+
periodicJobsEnabled?: false | typeof ENABLE_ALL | string[];
|
|
15
16
|
};
|
|
16
|
-
export declare class DIContext<Dependencies extends object, ExternalDependencies =
|
|
17
|
+
export declare class DIContext<Dependencies extends object, ExternalDependencies = undefined> {
|
|
17
18
|
private readonly options;
|
|
18
19
|
readonly awilixManager: AwilixManager;
|
|
19
20
|
readonly diContainer: AwilixContainer<Dependencies>;
|
|
20
21
|
private readonly controllerResolvers;
|
|
21
22
|
constructor(diContainer: AwilixContainer, options: DependencyInjectionOptions);
|
|
22
|
-
|
|
23
|
+
private registerModule;
|
|
24
|
+
registerDependencies(params: RegisterDependenciesParams<Dependencies, ExternalDependencies>, externalDependencies: ExternalDependencies, resolveControllers?: boolean): void;
|
|
23
25
|
registerRoutes(app: FastifyInstance): void;
|
|
24
26
|
destroy(): Promise<void>;
|
|
25
27
|
init(): Promise<void>;
|
package/dist/lib/DIContext.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AwilixManager } from 'awilix-manager';
|
|
2
|
-
// biome-ignore lint/complexity/noBannedTypes: default is empty object
|
|
3
2
|
export class DIContext {
|
|
4
3
|
options;
|
|
5
4
|
awilixManager;
|
|
@@ -18,18 +17,31 @@ export class DIContext {
|
|
|
18
17
|
});
|
|
19
18
|
this.controllerResolvers = [];
|
|
20
19
|
}
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
for (const key in resolvedDIConfig) {
|
|
20
|
+
registerModule(module, targetDiConfig, externalDependencies, resolveControllers, isPrimaryModule) {
|
|
21
|
+
const resolvedDIConfig = module.resolveDependencies(this.options, externalDependencies);
|
|
22
|
+
for (const key in resolvedDIConfig) {
|
|
23
|
+
// @ts-expect-error we can't really ensure type-safety here
|
|
24
|
+
if (isPrimaryModule || resolvedDIConfig[key].public) {
|
|
27
25
|
// @ts-expect-error we can't really ensure type-safety here
|
|
28
|
-
|
|
26
|
+
targetDiConfig[key] = resolvedDIConfig[key];
|
|
29
27
|
}
|
|
28
|
+
}
|
|
29
|
+
if (isPrimaryModule && resolveControllers) {
|
|
30
30
|
this.controllerResolvers.push(...Object.values(module.resolveControllers()));
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
}
|
|
33
|
+
registerDependencies(params, externalDependencies, resolveControllers = true) {
|
|
34
|
+
const _dependencyOverrides = params.dependencyOverrides ?? {};
|
|
35
|
+
const targetDiConfig = {};
|
|
36
|
+
for (const primaryModule of params.modules) {
|
|
37
|
+
this.registerModule(primaryModule, targetDiConfig, externalDependencies, resolveControllers, true);
|
|
38
|
+
}
|
|
39
|
+
if (params.secondaryModules) {
|
|
40
|
+
for (const secondaryModule of params.secondaryModules) {
|
|
41
|
+
this.registerModule(secondaryModule, targetDiConfig, externalDependencies, resolveControllers, false);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
this.diContainer.register(targetDiConfig);
|
|
33
45
|
for (const [dependencyKey, _dependencyValue] of Object.entries(_dependencyOverrides)) {
|
|
34
46
|
const dependencyValue = { ..._dependencyValue };
|
|
35
47
|
// preserve lifetime from original resolver
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DIContext.js","sourceRoot":"","sources":["../../lib/DIContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"DIContext.js","sourceRoot":"","sources":["../../lib/DIContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { BuildResolver, BuildResolverOptions, Constructor, DisposableResolver } from 'awilix';
|
|
2
|
+
import type { FunctionReturning } from 'awilix/lib/container';
|
|
2
3
|
import type { DependencyInjectionOptions } from './DIContext.js';
|
|
4
|
+
declare module 'awilix' {
|
|
5
|
+
interface ResolverOptions<T> {
|
|
6
|
+
public?: boolean;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
3
9
|
export declare function asSingletonClass<T = object>(Type: Constructor<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
|
|
10
|
+
export declare function asSingletonFunction<T>(fn: FunctionReturning<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
|
|
11
|
+
export declare function asServiceClass<T = object>(Type: Constructor<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
|
|
12
|
+
export declare function asUseCaseClass<T = object>(Type: Constructor<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
|
|
13
|
+
export declare function asRepositoryClass<T = object>(Type: Constructor<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
|
|
4
14
|
export declare function asControllerClass<T = object>(Type: Constructor<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
|
|
5
15
|
export type MessageQueueConsumerModuleOptions = {
|
|
6
16
|
queueName: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { asClass } from 'awilix';
|
|
1
|
+
import { asClass, asFunction } from 'awilix';
|
|
2
2
|
import { isJobQueueEnabled, isJobWorkersEnabled, isMessageQueueConsumerEnabled, isPeriodicJobEnabled, } from './diConfigUtils.js';
|
|
3
3
|
export function asSingletonClass(Type, opts) {
|
|
4
4
|
return asClass(Type, {
|
|
@@ -6,8 +6,36 @@ export function asSingletonClass(Type, opts) {
|
|
|
6
6
|
lifetime: 'SINGLETON',
|
|
7
7
|
});
|
|
8
8
|
}
|
|
9
|
+
export function asSingletonFunction(fn, opts) {
|
|
10
|
+
return asFunction(fn, {
|
|
11
|
+
...opts,
|
|
12
|
+
lifetime: 'SINGLETON',
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export function asServiceClass(Type, opts) {
|
|
16
|
+
return asClass(Type, {
|
|
17
|
+
public: true,
|
|
18
|
+
...opts,
|
|
19
|
+
lifetime: 'SINGLETON',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function asUseCaseClass(Type, opts) {
|
|
23
|
+
return asClass(Type, {
|
|
24
|
+
public: true,
|
|
25
|
+
...opts,
|
|
26
|
+
lifetime: 'SINGLETON',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export function asRepositoryClass(Type, opts) {
|
|
30
|
+
return asClass(Type, {
|
|
31
|
+
public: false,
|
|
32
|
+
...opts,
|
|
33
|
+
lifetime: 'SINGLETON',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
9
36
|
export function asControllerClass(Type, opts) {
|
|
10
37
|
return asClass(Type, {
|
|
38
|
+
public: false,
|
|
11
39
|
...opts,
|
|
12
40
|
lifetime: 'SINGLETON',
|
|
13
41
|
});
|
|
@@ -20,6 +48,7 @@ export function asMessageQueueHandlerClass(Type, mqOptions, opts) {
|
|
|
20
48
|
asyncDisposePriority: 10,
|
|
21
49
|
enabled: isMessageQueueConsumerEnabled(mqOptions.diOptions.messageQueueConsumersEnabled, mqOptions.queueName),
|
|
22
50
|
lifetime: 'SINGLETON',
|
|
51
|
+
public: false,
|
|
23
52
|
...opts,
|
|
24
53
|
});
|
|
25
54
|
}
|
|
@@ -28,7 +57,8 @@ export function asJobWorkerClass(Type, workerOptions, opts) {
|
|
|
28
57
|
// these follow background-jobs-common conventions
|
|
29
58
|
asyncInit: 'start',
|
|
30
59
|
asyncDispose: 'dispose',
|
|
31
|
-
asyncDisposePriority:
|
|
60
|
+
asyncDisposePriority: 15,
|
|
61
|
+
public: false,
|
|
32
62
|
enabled: isJobWorkersEnabled(workerOptions.diOptions.jobWorkersEnabled, workerOptions.queueName),
|
|
33
63
|
lifetime: 'SINGLETON',
|
|
34
64
|
...opts,
|
|
@@ -38,6 +68,8 @@ export function asPeriodicJobClass(Type, workerOptions, opts) {
|
|
|
38
68
|
return asClass(Type, {
|
|
39
69
|
// this follows background-jobs-common conventions
|
|
40
70
|
eagerInject: 'register',
|
|
71
|
+
asyncDispose: 'dispose',
|
|
72
|
+
public: false,
|
|
41
73
|
enabled: isPeriodicJobEnabled(workerOptions.diOptions.periodicJobsEnabled, workerOptions.jobName),
|
|
42
74
|
lifetime: 'SINGLETON',
|
|
43
75
|
...opts,
|
|
@@ -49,6 +81,7 @@ export function asJobQueueClass(Type, queueOptions, opts) {
|
|
|
49
81
|
asyncInit: 'start',
|
|
50
82
|
asyncDispose: 'dispose',
|
|
51
83
|
asyncDisposePriority: 20,
|
|
84
|
+
public: true,
|
|
52
85
|
enabled: isJobQueueEnabled(queueOptions.diOptions.jobQueuesEnabled, queueOptions.queueName),
|
|
53
86
|
lifetime: 'SINGLETON',
|
|
54
87
|
...opts,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolverFunctions.js","sourceRoot":"","sources":["../../lib/resolverFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"resolverFunctions.js","sourceRoot":"","sources":["../../lib/resolverFunctions.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opinionated-machine",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Very opinionated DI framework for fastify, built on top of awilix ",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
8
12
|
"maintainers": [
|
|
9
13
|
{
|
|
10
14
|
"name": "Igor Savin",
|
|
@@ -12,7 +16,7 @@
|
|
|
12
16
|
}
|
|
13
17
|
],
|
|
14
18
|
"scripts": {
|
|
15
|
-
"build": "tsc -p tsconfig.build.json",
|
|
19
|
+
"build": "rimraf dist && tsc -p tsconfig.build.json",
|
|
16
20
|
"lint": "biome check . && tsc",
|
|
17
21
|
"lint:fix": "biome check --write .",
|
|
18
22
|
"test": "vitest --coverage",
|
|
@@ -22,6 +26,9 @@
|
|
|
22
26
|
"type": "git",
|
|
23
27
|
"url": "git+https://github.com/kibertoad/opinionated-machine.git"
|
|
24
28
|
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"ts-deepmerge": "^7.0.2"
|
|
31
|
+
},
|
|
25
32
|
"peerDependencies": {
|
|
26
33
|
"@lokalise/fastify-api-contracts": ">=1.4.4",
|
|
27
34
|
"@lokalise/universal-ts-utils": ">=4.2.0",
|
|
@@ -44,6 +51,7 @@
|
|
|
44
51
|
"fastify": "^5.2.2",
|
|
45
52
|
"fastify-type-provider-zod": "^4.0.2",
|
|
46
53
|
"vitest": "^3.0.9",
|
|
54
|
+
"rimraf": "^6.0.1",
|
|
47
55
|
"typescript": "^5.8.2",
|
|
48
56
|
"zod": "^3.24.2"
|
|
49
57
|
},
|
package/dist/lib/typeUtils.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { FastifyRequest } from 'fastify';
|
|
2
|
-
import type { z } from 'zod';
|
|
3
|
-
type InferredOptionalSchema<Schema> = Schema extends z.Schema ? z.infer<Schema> : never;
|
|
4
|
-
/**
|
|
5
|
-
* Infer fastify request type from a contract
|
|
6
|
-
*/
|
|
7
|
-
export type InferRequestFromContract<Contract extends {
|
|
8
|
-
requestHeaderSchema?: z.Schema;
|
|
9
|
-
requestPathParamsSchema?: z.Schema;
|
|
10
|
-
requestQuerySchema?: z.Schema;
|
|
11
|
-
successResponseBodySchema: z.Schema;
|
|
12
|
-
}> = FastifyRequest<{
|
|
13
|
-
Body: never;
|
|
14
|
-
Headers: InferredOptionalSchema<Contract['requestHeaderSchema']>;
|
|
15
|
-
Params: InferredOptionalSchema<Contract['requestPathParamsSchema']>;
|
|
16
|
-
Querystring: InferredOptionalSchema<Contract['requestQuerySchema']>;
|
|
17
|
-
Reply: InferredOptionalSchema<Contract['successResponseBodySchema']>;
|
|
18
|
-
}>;
|
|
19
|
-
export {};
|
package/dist/lib/typeUtils.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"typeUtils.js","sourceRoot":"","sources":["../../lib/typeUtils.ts"],"names":[],"mappings":""}
|