nmtjs 0.15.0-beta.2 → 0.15.0-beta.21
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/dist/cli.d.ts +2 -0
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -0
- package/dist/entrypoints/cli.d.ts +1 -0
- package/dist/entrypoints/cli.js +1 -0
- package/dist/entrypoints/cli.js.map +1 -0
- package/dist/entrypoints/main.d.ts +5 -0
- package/dist/entrypoints/main.js +83 -15
- package/dist/entrypoints/main.js.map +1 -0
- package/dist/entrypoints/thread.d.ts +14 -0
- package/dist/entrypoints/thread.js +130 -24
- package/dist/entrypoints/thread.js.map +1 -0
- package/dist/entrypoints/worker.d.ts +3 -0
- package/dist/entrypoints/worker.js +4 -3
- package/dist/entrypoints/worker.js.map +1 -0
- package/dist/index.d.ts +69 -0
- package/dist/{_exports/index.js → index.js} +9 -5
- package/dist/index.js.map +1 -0
- package/dist/resolver.d.ts +2 -0
- package/dist/resolver.js +1 -0
- package/dist/resolver.js.map +1 -0
- package/dist/runtime/application/api/api.d.ts +49 -0
- package/dist/runtime/application/api/api.js +193 -0
- package/dist/runtime/application/api/api.js.map +1 -0
- package/dist/runtime/application/api/constants.d.ts +14 -0
- package/dist/runtime/application/api/constants.js +8 -0
- package/dist/runtime/application/api/constants.js.map +1 -0
- package/dist/runtime/application/api/filters.d.ts +14 -0
- package/dist/runtime/application/api/filters.js +11 -0
- package/dist/runtime/application/api/filters.js.map +1 -0
- package/dist/runtime/application/api/guards.d.ts +13 -0
- package/dist/runtime/application/api/guards.js +8 -0
- package/dist/runtime/application/api/guards.js.map +1 -0
- package/dist/runtime/application/api/index.d.ts +8 -0
- package/dist/runtime/application/api/index.js +9 -0
- package/dist/runtime/application/api/index.js.map +1 -0
- package/dist/runtime/application/api/middlewares.d.ts +14 -0
- package/dist/runtime/application/api/middlewares.js +12 -0
- package/dist/runtime/application/api/middlewares.js.map +1 -0
- package/dist/runtime/application/api/procedure.d.ts +67 -0
- package/dist/runtime/application/api/procedure.js +50 -0
- package/dist/runtime/application/api/procedure.js.map +1 -0
- package/dist/runtime/application/api/router.d.ts +71 -0
- package/dist/runtime/application/api/router.js +51 -0
- package/dist/runtime/application/api/router.js.map +1 -0
- package/dist/runtime/application/api/types.d.ts +32 -0
- package/dist/runtime/application/api/types.js +2 -0
- package/dist/runtime/application/api/types.js.map +1 -0
- package/dist/runtime/application/config.d.ts +26 -0
- package/dist/runtime/application/config.js +21 -0
- package/dist/runtime/application/config.js.map +1 -0
- package/dist/runtime/application/constants.d.ts +2 -0
- package/dist/runtime/application/constants.js +2 -0
- package/dist/runtime/application/constants.js.map +1 -0
- package/dist/runtime/application/hook.d.ts +19 -0
- package/dist/runtime/application/hook.js +11 -0
- package/dist/runtime/application/hook.js.map +1 -0
- package/dist/runtime/application/hooks.d.ts +3 -0
- package/dist/runtime/application/hooks.js +4 -0
- package/dist/runtime/application/hooks.js.map +1 -0
- package/dist/runtime/application/index.d.ts +5 -0
- package/dist/runtime/application/index.js +6 -0
- package/dist/runtime/application/index.js.map +1 -0
- package/dist/runtime/constants.d.ts +8 -0
- package/dist/runtime/constants.js +5 -0
- package/dist/runtime/constants.js.map +1 -0
- package/dist/runtime/core/hooks.d.ts +4 -0
- package/dist/runtime/core/hooks.js +4 -0
- package/dist/runtime/core/hooks.js.map +1 -0
- package/dist/runtime/core/plugin.d.ts +8 -0
- package/dist/runtime/core/plugin.js +4 -0
- package/dist/runtime/core/plugin.js.map +1 -0
- package/dist/runtime/core/runtime.d.ts +27 -0
- package/dist/runtime/core/runtime.js +81 -0
- package/dist/runtime/core/runtime.js.map +1 -0
- package/dist/runtime/enums.d.ts +21 -0
- package/dist/runtime/enums.js +26 -0
- package/dist/runtime/enums.js.map +1 -0
- package/dist/runtime/index.d.ts +21 -0
- package/dist/runtime/index.js +22 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/injectables.d.ts +23 -0
- package/dist/runtime/injectables.js +20 -0
- package/dist/runtime/injectables.js.map +1 -0
- package/dist/runtime/jobs/job.d.ts +132 -0
- package/dist/runtime/jobs/job.js +68 -0
- package/dist/runtime/jobs/job.js.map +1 -0
- package/dist/runtime/jobs/manager.d.ts +113 -0
- package/dist/runtime/jobs/manager.js +210 -0
- package/dist/runtime/jobs/manager.js.map +1 -0
- package/dist/runtime/jobs/router.d.ts +266 -0
- package/dist/runtime/jobs/router.js +432 -0
- package/dist/runtime/jobs/router.js.map +1 -0
- package/dist/runtime/jobs/runner.d.ts +64 -0
- package/dist/runtime/jobs/runner.js +256 -0
- package/dist/runtime/jobs/runner.js.map +1 -0
- package/dist/runtime/jobs/step.d.ts +23 -0
- package/dist/runtime/jobs/step.js +18 -0
- package/dist/runtime/jobs/step.js.map +1 -0
- package/dist/runtime/jobs/ui.d.ts +3 -0
- package/dist/runtime/jobs/ui.js +17 -0
- package/dist/runtime/jobs/ui.js.map +1 -0
- package/dist/runtime/pubsub/manager.d.ts +48 -0
- package/dist/runtime/pubsub/manager.js +119 -0
- package/dist/runtime/pubsub/manager.js.map +1 -0
- package/dist/runtime/pubsub/redis.d.ts +16 -0
- package/dist/runtime/pubsub/redis.js +98 -0
- package/dist/runtime/pubsub/redis.js.map +1 -0
- package/dist/runtime/scheduler/index.d.ts +22 -0
- package/dist/runtime/scheduler/index.js +20 -0
- package/dist/runtime/scheduler/index.js.map +1 -0
- package/dist/runtime/server/applications.d.ts +52 -0
- package/dist/runtime/server/applications.js +133 -0
- package/dist/runtime/server/applications.js.map +1 -0
- package/dist/runtime/server/config.d.ts +121 -0
- package/dist/runtime/server/config.js +33 -0
- package/dist/runtime/server/config.js.map +1 -0
- package/dist/runtime/server/jobs.d.ts +41 -0
- package/dist/runtime/server/jobs.js +181 -0
- package/dist/runtime/server/jobs.js.map +1 -0
- package/dist/runtime/server/pool.d.ts +54 -0
- package/dist/runtime/server/pool.js +194 -0
- package/dist/runtime/server/pool.js.map +1 -0
- package/dist/runtime/server/proxy.d.ts +21 -0
- package/dist/runtime/server/proxy.js +79 -0
- package/dist/runtime/server/proxy.js.map +1 -0
- package/dist/runtime/server/server.d.ts +53 -0
- package/dist/runtime/server/server.js +90 -0
- package/dist/runtime/server/server.js.map +1 -0
- package/dist/runtime/store/index.d.ts +3 -0
- package/dist/runtime/store/index.js +23 -0
- package/dist/runtime/store/index.js.map +1 -0
- package/dist/runtime/types.d.ts +103 -0
- package/dist/runtime/types.js +2 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/runtime/workers/application.d.ts +47 -0
- package/dist/runtime/workers/application.js +162 -0
- package/dist/runtime/workers/application.js.map +1 -0
- package/dist/runtime/workers/base.d.ts +16 -0
- package/dist/runtime/workers/base.js +46 -0
- package/dist/runtime/workers/base.js.map +1 -0
- package/dist/runtime/workers/cli.d.ts +1 -0
- package/dist/runtime/workers/cli.js +2 -0
- package/dist/runtime/workers/cli.js.map +1 -0
- package/dist/runtime/workers/job.d.ts +20 -0
- package/dist/runtime/workers/job.js +172 -0
- package/dist/runtime/workers/job.js.map +1 -0
- package/dist/typings.d.ts +5 -0
- package/dist/typings.js +4 -3
- package/dist/typings.js.map +1 -0
- package/dist/vite/builder.d.ts +5 -0
- package/dist/vite/builder.js +5 -1
- package/dist/vite/builder.js.map +1 -0
- package/dist/vite/config.d.ts +28 -0
- package/dist/vite/config.js +1 -0
- package/dist/vite/config.js.map +1 -0
- package/dist/vite/plugins.d.ts +2 -0
- package/dist/vite/plugins.js +1 -0
- package/dist/vite/plugins.js.map +1 -0
- package/dist/vite/runners/worker.d.ts +4 -0
- package/dist/vite/runners/worker.js +1 -0
- package/dist/vite/runners/worker.js.map +1 -0
- package/dist/vite/server.d.ts +3 -0
- package/dist/vite/server.js +6 -1
- package/dist/vite/server.js.map +1 -0
- package/dist/vite/servers/main.d.ts +8 -0
- package/dist/vite/servers/main.js +1 -0
- package/dist/vite/servers/main.js.map +1 -0
- package/dist/vite/servers/worker.d.ts +11 -0
- package/dist/vite/servers/worker.js +28 -0
- package/dist/vite/servers/worker.js.map +1 -0
- package/package.json +31 -18
- package/src/cli.ts +144 -0
- package/src/config.ts +64 -0
- package/src/entrypoints/cli.ts +13 -0
- package/src/entrypoints/main.ts +200 -0
- package/src/entrypoints/thread.ts +184 -0
- package/src/entrypoints/worker.ts +48 -0
- package/src/index.ts +82 -0
- package/src/resolver.ts +16 -0
- package/src/runtime/application/api/api.ts +265 -0
- package/src/runtime/application/api/constants.ts +22 -0
- package/src/runtime/application/api/filters.ts +39 -0
- package/src/runtime/application/api/guards.ts +29 -0
- package/src/runtime/application/api/index.ts +8 -0
- package/src/runtime/application/api/middlewares.ts +37 -0
- package/src/runtime/application/api/procedure.ts +229 -0
- package/src/runtime/application/api/router.ts +193 -0
- package/src/runtime/application/api/types.ts +124 -0
- package/src/runtime/application/config.ts +69 -0
- package/src/runtime/application/constants.ts +4 -0
- package/src/runtime/application/hook.ts +51 -0
- package/src/runtime/application/hooks.ts +3 -0
- package/src/runtime/application/index.ts +5 -0
- package/src/runtime/constants.ts +13 -0
- package/src/runtime/core/hooks.ts +5 -0
- package/src/runtime/core/plugin.ts +13 -0
- package/src/runtime/core/runtime.ts +109 -0
- package/src/runtime/enums.ts +24 -0
- package/src/runtime/index.ts +21 -0
- package/src/runtime/injectables.ts +61 -0
- package/src/runtime/jobs/job.ts +370 -0
- package/src/runtime/jobs/manager.ts +348 -0
- package/src/runtime/jobs/router.ts +896 -0
- package/src/runtime/jobs/runner.ts +320 -0
- package/src/runtime/jobs/step.ts +66 -0
- package/src/runtime/jobs/ui.ts +21 -0
- package/src/runtime/pubsub/manager.ts +211 -0
- package/src/runtime/pubsub/redis.ts +108 -0
- package/src/runtime/scheduler/index.ts +39 -0
- package/src/runtime/server/applications.ts +210 -0
- package/src/runtime/server/config.ts +158 -0
- package/src/runtime/server/jobs.ts +250 -0
- package/src/runtime/server/pool.ts +260 -0
- package/src/runtime/server/proxy.ts +118 -0
- package/src/runtime/server/server.ts +155 -0
- package/src/runtime/store/index.ts +30 -0
- package/src/runtime/types.ts +93 -0
- package/src/runtime/workers/application.ts +209 -0
- package/src/runtime/workers/base.ts +68 -0
- package/src/runtime/workers/cli.ts +0 -0
- package/src/runtime/workers/job.ts +153 -0
- package/src/typings.ts +30 -0
- package/src/vite/builder.ts +122 -0
- package/src/vite/config.ts +45 -0
- package/src/vite/plugins.ts +26 -0
- package/src/vite/runners/worker.ts +57 -0
- package/src/vite/server.ts +39 -0
- package/src/vite/servers/main.ts +34 -0
- package/src/vite/servers/worker.ts +143 -0
- package/dist/_exports/application.js +0 -1
- package/dist/_exports/common.js +0 -1
- package/dist/_exports/contract.js +0 -2
- package/dist/_exports/core.js +0 -1
- package/dist/_exports/gateway.js +0 -1
- package/dist/_exports/http-transport/bun.js +0 -1
- package/dist/_exports/http-transport/deno.js +0 -1
- package/dist/_exports/http-transport/node.js +0 -1
- package/dist/_exports/http-transport.js +0 -1
- package/dist/_exports/json-format.js +0 -1
- package/dist/_exports/protocol/client.js +0 -1
- package/dist/_exports/protocol/server.js +0 -1
- package/dist/_exports/protocol.js +0 -1
- package/dist/_exports/runtime/types.js +0 -1
- package/dist/_exports/runtime.js +0 -1
- package/dist/_exports/type.js +0 -2
- package/dist/_exports/ws-transport/bun.js +0 -1
- package/dist/_exports/ws-transport/deno.js +0 -1
- package/dist/_exports/ws-transport/node.js +0 -1
- package/dist/_exports/ws-transport.js +0 -1
- package/dist/command.js +0 -30
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import type { MaybePromise } from '@nmtjs/common';
|
|
2
|
+
import type { TProcedureContract, TRouterContract } from '@nmtjs/contract';
|
|
3
|
+
import type { Dependencies, DependencyContext, Metadata } from '@nmtjs/core';
|
|
4
|
+
import type { NullableType, OptionalType } from '@nmtjs/type';
|
|
5
|
+
import type { NeverType } from '@nmtjs/type/never';
|
|
6
|
+
import { t } from '@nmtjs/type';
|
|
7
|
+
import type { AnyGuard } from '../application/api/guards.ts';
|
|
8
|
+
import type { AnyMiddleware } from '../application/api/middlewares.ts';
|
|
9
|
+
import type { Router } from '../application/api/router.ts';
|
|
10
|
+
import type { AnyJob } from './job.ts';
|
|
11
|
+
/** Base operation config shared by all operations */
|
|
12
|
+
export type BaseOperationConfig<Deps extends Dependencies = {}> = {
|
|
13
|
+
dependencies?: Deps;
|
|
14
|
+
guards?: AnyGuard[];
|
|
15
|
+
middlewares?: AnyMiddleware[];
|
|
16
|
+
metadata?: Metadata[];
|
|
17
|
+
timeout?: number;
|
|
18
|
+
};
|
|
19
|
+
/** List operation config (read-only, no hooks) */
|
|
20
|
+
export type ListOperationConfig<Deps extends Dependencies = {}> = BaseOperationConfig<Deps>;
|
|
21
|
+
/** Get operation config (read-only, no hooks) */
|
|
22
|
+
export type GetOperationConfig<Deps extends Dependencies = {}> = BaseOperationConfig<Deps>;
|
|
23
|
+
/** Info operation config (read-only, no hooks) */
|
|
24
|
+
export type InfoOperationConfig<Deps extends Dependencies = {}> = BaseOperationConfig<Deps>;
|
|
25
|
+
/** Add queue options */
|
|
26
|
+
export type AddQueueOptions = {
|
|
27
|
+
priority?: number;
|
|
28
|
+
attempts?: number;
|
|
29
|
+
delay?: number;
|
|
30
|
+
};
|
|
31
|
+
/** Add operation config with before/after hooks */
|
|
32
|
+
export type AddOperationConfig<T extends AnyJob = AnyJob, Deps extends Dependencies = {}> = BaseOperationConfig<Deps> & {
|
|
33
|
+
beforeAdd?: (ctx: DependencyContext<Deps>, input: T['_']['input']) => MaybePromise<T['_']['input']>;
|
|
34
|
+
afterAdd?: (ctx: DependencyContext<Deps>, result: {
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
}, input: T['_']['input']) => MaybePromise<void>;
|
|
38
|
+
options?: AddQueueOptions;
|
|
39
|
+
};
|
|
40
|
+
/** Remove operation config with before/after hooks */
|
|
41
|
+
export type RemoveOperationConfig<Deps extends Dependencies = {}> = BaseOperationConfig<Deps> & {
|
|
42
|
+
beforeRemove?: (ctx: DependencyContext<Deps>, params: {
|
|
43
|
+
id: string;
|
|
44
|
+
}) => MaybePromise<void>;
|
|
45
|
+
afterRemove?: (ctx: DependencyContext<Deps>, params: {
|
|
46
|
+
id: string;
|
|
47
|
+
}) => MaybePromise<void>;
|
|
48
|
+
};
|
|
49
|
+
/** Retry operation config with before/after hooks */
|
|
50
|
+
export type RetryOperationConfig<Deps extends Dependencies = {}> = BaseOperationConfig<Deps> & {
|
|
51
|
+
clearState?: boolean;
|
|
52
|
+
beforeRetry?: (ctx: DependencyContext<Deps>, params: {
|
|
53
|
+
id: string;
|
|
54
|
+
clearState?: boolean;
|
|
55
|
+
}) => MaybePromise<void>;
|
|
56
|
+
afterRetry?: (ctx: DependencyContext<Deps>, params: {
|
|
57
|
+
id: string;
|
|
58
|
+
clearState?: boolean;
|
|
59
|
+
}) => MaybePromise<void>;
|
|
60
|
+
};
|
|
61
|
+
/** Cancel operation config with before/after hooks */
|
|
62
|
+
export type CancelOperationConfig<Deps extends Dependencies = {}> = BaseOperationConfig<Deps> & {
|
|
63
|
+
beforeCancel?: (ctx: DependencyContext<Deps>, params: {
|
|
64
|
+
id: string;
|
|
65
|
+
}) => MaybePromise<void>;
|
|
66
|
+
afterCancel?: (ctx: DependencyContext<Deps>, params: {
|
|
67
|
+
id: string;
|
|
68
|
+
}) => MaybePromise<void>;
|
|
69
|
+
};
|
|
70
|
+
/** All operations for a job (false = disabled) */
|
|
71
|
+
export type JobOperations<T extends AnyJob = AnyJob> = {
|
|
72
|
+
info?: InfoOperationConfig<any> | false;
|
|
73
|
+
list?: ListOperationConfig<any> | false;
|
|
74
|
+
get?: GetOperationConfig<any> | false;
|
|
75
|
+
add?: AddOperationConfig<T, any> | false;
|
|
76
|
+
retry?: RetryOperationConfig<any> | false;
|
|
77
|
+
cancel?: CancelOperationConfig<any> | false;
|
|
78
|
+
remove?: RemoveOperationConfig<any> | false;
|
|
79
|
+
};
|
|
80
|
+
/** Default operations config */
|
|
81
|
+
export type DefaultOperations = {
|
|
82
|
+
info?: InfoOperationConfig<any> | false;
|
|
83
|
+
list?: ListOperationConfig<any> | false;
|
|
84
|
+
get?: GetOperationConfig<any> | false;
|
|
85
|
+
add?: AddOperationConfig<AnyJob, any> | false;
|
|
86
|
+
retry?: RetryOperationConfig<any> | false;
|
|
87
|
+
cancel?: CancelOperationConfig<any> | false;
|
|
88
|
+
remove?: RemoveOperationConfig<any> | false;
|
|
89
|
+
};
|
|
90
|
+
/** Options for createJobsRouter */
|
|
91
|
+
export type CreateJobsRouterOptions<Jobs extends Record<string, AnyJob>> = {
|
|
92
|
+
jobs: Jobs;
|
|
93
|
+
guards?: AnyGuard[];
|
|
94
|
+
middlewares?: AnyMiddleware[];
|
|
95
|
+
defaults?: DefaultOperations;
|
|
96
|
+
overrides?: {
|
|
97
|
+
[K in keyof Jobs]?: JobOperations<Jobs[K]>;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
/** Type-level representation of createJobItemSchema output */
|
|
101
|
+
type JobItemSchemaType<T extends AnyJob> = t.ObjectType<{
|
|
102
|
+
id: t.StringType;
|
|
103
|
+
queueName: t.StringType;
|
|
104
|
+
priority: OptionalType<t.NumberType>;
|
|
105
|
+
progress: t.AnyType;
|
|
106
|
+
name: t.StringType;
|
|
107
|
+
data: T['input'];
|
|
108
|
+
returnvalue: OptionalType<NullableType<T['output']>>;
|
|
109
|
+
attemptsMade: t.NumberType;
|
|
110
|
+
processedOn: OptionalType<t.NumberType>;
|
|
111
|
+
finishedOn: OptionalType<t.NumberType>;
|
|
112
|
+
failedReason: OptionalType<t.StringType>;
|
|
113
|
+
stacktrace: OptionalType<t.ArrayType<t.StringType>>;
|
|
114
|
+
status: t.StringType;
|
|
115
|
+
}>;
|
|
116
|
+
/** Type-level representation of createListOutputSchema output */
|
|
117
|
+
type ListOutputSchemaType<T extends AnyJob> = t.ObjectType<{
|
|
118
|
+
items: t.ArrayType<JobItemSchemaType<T>>;
|
|
119
|
+
page: t.NumberType;
|
|
120
|
+
limit: t.NumberType;
|
|
121
|
+
pages: t.NumberType;
|
|
122
|
+
total: t.NumberType;
|
|
123
|
+
}>;
|
|
124
|
+
/** Type-level representation of createGetOutputSchema output */
|
|
125
|
+
type GetOutputSchemaType<T extends AnyJob> = NullableType<JobItemSchemaType<T>>;
|
|
126
|
+
/** Type-level representation of infoOutputSchema */
|
|
127
|
+
type InfoOutputSchemaType = typeof infoOutputSchema;
|
|
128
|
+
/** Type-level representation of createAddInputSchema output */
|
|
129
|
+
type AddInputSchemaType<T extends AnyJob> = t.ObjectType<{
|
|
130
|
+
data: T['input'];
|
|
131
|
+
jobId: OptionalType<t.StringType>;
|
|
132
|
+
priority: OptionalType<t.NumberType>;
|
|
133
|
+
delay: OptionalType<t.NumberType>;
|
|
134
|
+
}>;
|
|
135
|
+
/** Operations contract for a single job - now properly typed per job */
|
|
136
|
+
type JobOperationsProcedures<T extends AnyJob> = {
|
|
137
|
+
info: TProcedureContract<NeverType, InfoOutputSchemaType>;
|
|
138
|
+
list: TProcedureContract<typeof listInputSchema, ListOutputSchemaType<T>>;
|
|
139
|
+
get: TProcedureContract<typeof getInputSchema, GetOutputSchemaType<T>>;
|
|
140
|
+
add: TProcedureContract<AddInputSchemaType<T>, typeof addOutputSchema>;
|
|
141
|
+
retry: TProcedureContract<typeof retryInputSchema, NeverType>;
|
|
142
|
+
cancel: TProcedureContract<typeof idInputSchema, NeverType>;
|
|
143
|
+
remove: TProcedureContract<typeof idInputSchema, NeverType>;
|
|
144
|
+
};
|
|
145
|
+
/** Router contract for a single job's operations */
|
|
146
|
+
type JobRouterContract<T extends AnyJob> = TRouterContract<JobOperationsProcedures<T>>;
|
|
147
|
+
/** Full jobs router contract mapping job names to their operation routers */
|
|
148
|
+
type JobsRouterContract<Jobs extends Record<string, AnyJob>> = TRouterContract<{
|
|
149
|
+
[K in keyof Jobs]: JobRouterContract<Jobs[K]>;
|
|
150
|
+
}>;
|
|
151
|
+
/** Return type for createJobsRouter */
|
|
152
|
+
export type JobsRouter<Jobs extends Record<string, AnyJob>> = Router<JobsRouterContract<Jobs>>;
|
|
153
|
+
/** Input schema for list operation */
|
|
154
|
+
declare const listInputSchema: t.ObjectType<{
|
|
155
|
+
page: OptionalType<t.NumberType>;
|
|
156
|
+
limit: OptionalType<t.NumberType>;
|
|
157
|
+
state: OptionalType<t.ArrayType<t.StringType>>;
|
|
158
|
+
}>;
|
|
159
|
+
/** Input schema for get operation */
|
|
160
|
+
declare const getInputSchema: t.ObjectType<{
|
|
161
|
+
id: t.StringType;
|
|
162
|
+
}>;
|
|
163
|
+
/** Output schema for add operation */
|
|
164
|
+
declare const addOutputSchema: t.ObjectType<{
|
|
165
|
+
id: t.StringType;
|
|
166
|
+
name: t.StringType;
|
|
167
|
+
}>;
|
|
168
|
+
/** Input schema for retry operation */
|
|
169
|
+
declare const retryInputSchema: t.ObjectType<{
|
|
170
|
+
id: t.StringType;
|
|
171
|
+
clearState: OptionalType<t.BooleanType>;
|
|
172
|
+
}>;
|
|
173
|
+
/** Input schema for cancel/remove operations */
|
|
174
|
+
declare const idInputSchema: t.ObjectType<{
|
|
175
|
+
id: t.StringType;
|
|
176
|
+
}>;
|
|
177
|
+
/** Output schema for info operation */
|
|
178
|
+
declare const infoOutputSchema: t.ObjectType<{
|
|
179
|
+
name: t.StringType;
|
|
180
|
+
steps: t.ArrayType<t.ObjectType<{
|
|
181
|
+
label: OptionalType<t.StringType>;
|
|
182
|
+
conditional: t.BooleanType;
|
|
183
|
+
}>>;
|
|
184
|
+
}>;
|
|
185
|
+
/**
|
|
186
|
+
* Helper function to create a type-safe operation config with dependencies.
|
|
187
|
+
* Use this when you need custom dependencies for hooks.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* add: jobOperation({
|
|
192
|
+
* dependencies: { userService, auditLog },
|
|
193
|
+
* beforeAdd: async (ctx, input) => {
|
|
194
|
+
* return { ...input, createdBy: ctx.userService.getCurrentId() }
|
|
195
|
+
* },
|
|
196
|
+
* })
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
export declare function jobOperation<Deps extends Dependencies, T extends AnyJob = AnyJob>(config: BaseOperationConfig<Deps> & {
|
|
200
|
+
beforeAdd?: (ctx: DependencyContext<Deps>, input: T['_']['input']) => MaybePromise<T['_']['input']>;
|
|
201
|
+
afterAdd?: (ctx: DependencyContext<Deps>, result: {
|
|
202
|
+
id: string;
|
|
203
|
+
name: string;
|
|
204
|
+
}, input: T['_']['input']) => MaybePromise<void>;
|
|
205
|
+
options?: AddQueueOptions;
|
|
206
|
+
beforeRemove?: (ctx: DependencyContext<Deps>, params: {
|
|
207
|
+
id: string;
|
|
208
|
+
}) => MaybePromise<void>;
|
|
209
|
+
afterRemove?: (ctx: DependencyContext<Deps>, params: {
|
|
210
|
+
id: string;
|
|
211
|
+
}) => MaybePromise<void>;
|
|
212
|
+
clearState?: boolean;
|
|
213
|
+
beforeRetry?: (ctx: DependencyContext<Deps>, params: {
|
|
214
|
+
id: string;
|
|
215
|
+
clearState?: boolean;
|
|
216
|
+
}) => MaybePromise<void>;
|
|
217
|
+
afterRetry?: (ctx: DependencyContext<Deps>, params: {
|
|
218
|
+
id: string;
|
|
219
|
+
clearState?: boolean;
|
|
220
|
+
}) => MaybePromise<void>;
|
|
221
|
+
beforeCancel?: (ctx: DependencyContext<Deps>, params: {
|
|
222
|
+
id: string;
|
|
223
|
+
}) => MaybePromise<void>;
|
|
224
|
+
afterCancel?: (ctx: DependencyContext<Deps>, params: {
|
|
225
|
+
id: string;
|
|
226
|
+
}) => MaybePromise<void>;
|
|
227
|
+
}): typeof config;
|
|
228
|
+
/**
|
|
229
|
+
* Creates a router with CRUD-like operations for multiple jobs.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* const jobsRouter = createJobsRouter({
|
|
234
|
+
* jobs: [userJob, emailJob] as const,
|
|
235
|
+
* guards: [authGuard],
|
|
236
|
+
* defaults: {
|
|
237
|
+
* list: {},
|
|
238
|
+
* get: {},
|
|
239
|
+
* add: {},
|
|
240
|
+
* retry: { guards: [adminGuard] },
|
|
241
|
+
* cancel: { guards: [adminGuard] },
|
|
242
|
+
* remove: false,
|
|
243
|
+
* },
|
|
244
|
+
* overrides: {
|
|
245
|
+
* userProcessing: {
|
|
246
|
+
* add: jobOperation({
|
|
247
|
+
* dependencies: { userService },
|
|
248
|
+
* beforeAdd: async (ctx, input) => ({
|
|
249
|
+
* ...input,
|
|
250
|
+
* userId: ctx.userService.getCurrentId(),
|
|
251
|
+
* }),
|
|
252
|
+
* }),
|
|
253
|
+
* },
|
|
254
|
+
* },
|
|
255
|
+
* })
|
|
256
|
+
*
|
|
257
|
+
* // Use in your router
|
|
258
|
+
* createRouter({
|
|
259
|
+
* routes: {
|
|
260
|
+
* jobs: jobsRouter,
|
|
261
|
+
* }
|
|
262
|
+
* })
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
export declare function createJobsRouter<const Jobs extends Record<string, AnyJob>>(options: CreateJobsRouterOptions<Jobs>): JobsRouter<Jobs>;
|
|
266
|
+
export {};
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import { CoreInjectables } from '@nmtjs/core';
|
|
2
|
+
import { t } from '@nmtjs/type';
|
|
3
|
+
import { createProcedure } from "../application/api/procedure.js";
|
|
4
|
+
import { createRouter } from "../application/api/router.js";
|
|
5
|
+
import { jobManager } from "../injectables.js";
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Schemas
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/** Input schema for list operation */
|
|
10
|
+
const listInputSchema = t.object({
|
|
11
|
+
page: t.number().optional(),
|
|
12
|
+
limit: t.number().optional(),
|
|
13
|
+
state: t.array(t.string()).optional(),
|
|
14
|
+
});
|
|
15
|
+
/** Input schema for get operation */
|
|
16
|
+
const getInputSchema = t.object({ id: t.string() });
|
|
17
|
+
/** Output schema for add operation */
|
|
18
|
+
const addOutputSchema = t.object({ id: t.string(), name: t.string() });
|
|
19
|
+
/** Input schema for retry operation */
|
|
20
|
+
const retryInputSchema = t.object({
|
|
21
|
+
id: t.string(),
|
|
22
|
+
clearState: t.boolean().optional(),
|
|
23
|
+
});
|
|
24
|
+
/** Input schema for cancel/remove operations */
|
|
25
|
+
const idInputSchema = t.object({ id: t.string() });
|
|
26
|
+
/** Output schema for info operation */
|
|
27
|
+
const infoOutputSchema = t.object({
|
|
28
|
+
name: t.string(),
|
|
29
|
+
steps: t.array(t.object({ label: t.string().optional(), conditional: t.boolean() })),
|
|
30
|
+
});
|
|
31
|
+
/** JobItem schema for list/get responses - typed per job */
|
|
32
|
+
function createJobItemSchema(job) {
|
|
33
|
+
return t.object({
|
|
34
|
+
id: t.string(),
|
|
35
|
+
queueName: t.string(),
|
|
36
|
+
priority: t.number().optional(),
|
|
37
|
+
progress: t.any(),
|
|
38
|
+
name: t.string(),
|
|
39
|
+
data: job.input,
|
|
40
|
+
returnvalue: job.output.nullish(),
|
|
41
|
+
attemptsMade: t.number(),
|
|
42
|
+
processedOn: t.number().optional(),
|
|
43
|
+
finishedOn: t.number().optional(),
|
|
44
|
+
failedReason: t.string().optional(),
|
|
45
|
+
stacktrace: t.array(t.string()).optional(),
|
|
46
|
+
status: t.string(),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Creates list output schema for a specific job */
|
|
50
|
+
function createListOutputSchema(job) {
|
|
51
|
+
return t.object({
|
|
52
|
+
items: t.array(createJobItemSchema(job)),
|
|
53
|
+
page: t.number(),
|
|
54
|
+
limit: t.number(),
|
|
55
|
+
pages: t.number(),
|
|
56
|
+
total: t.number(),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Creates get output schema for a specific job */
|
|
60
|
+
function createGetOutputSchema(job) {
|
|
61
|
+
return createJobItemSchema(job).nullable();
|
|
62
|
+
}
|
|
63
|
+
/** Creates add input schema for a specific job */
|
|
64
|
+
function createAddInputSchema(job) {
|
|
65
|
+
return t.object({
|
|
66
|
+
data: job.input,
|
|
67
|
+
jobId: t.string().optional(),
|
|
68
|
+
priority: t.number().optional(),
|
|
69
|
+
delay: t.number().optional(),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Helpers
|
|
74
|
+
// ============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Helper function to create a type-safe operation config with dependencies.
|
|
77
|
+
* Use this when you need custom dependencies for hooks.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* add: jobOperation({
|
|
82
|
+
* dependencies: { userService, auditLog },
|
|
83
|
+
* beforeAdd: async (ctx, input) => {
|
|
84
|
+
* return { ...input, createdBy: ctx.userService.getCurrentId() }
|
|
85
|
+
* },
|
|
86
|
+
* })
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export function jobOperation(config) {
|
|
90
|
+
return config;
|
|
91
|
+
}
|
|
92
|
+
function createInfoProcedure(job, config = {}, shared) {
|
|
93
|
+
const allGuards = [...(shared.guards ?? []), ...(config.guards ?? [])];
|
|
94
|
+
const allMiddlewares = [
|
|
95
|
+
...(shared.middlewares ?? []),
|
|
96
|
+
...(config.middlewares ?? []),
|
|
97
|
+
];
|
|
98
|
+
const deps = { jobManager, logger: CoreInjectables.logger };
|
|
99
|
+
return createProcedure({
|
|
100
|
+
output: infoOutputSchema,
|
|
101
|
+
dependencies: { ...deps, ...(config.dependencies ?? {}) },
|
|
102
|
+
guards: allGuards,
|
|
103
|
+
middlewares: allMiddlewares,
|
|
104
|
+
metadata: config.metadata,
|
|
105
|
+
timeout: config.timeout,
|
|
106
|
+
handler: (ctx) => {
|
|
107
|
+
ctx.logger.trace({ jobName: job.options.name }, 'Getting job info');
|
|
108
|
+
return ctx.jobManager.getInfo(job);
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function createListProcedure(job, config = {}, shared) {
|
|
113
|
+
const allGuards = [...(shared.guards ?? []), ...(config.guards ?? [])];
|
|
114
|
+
const allMiddlewares = [
|
|
115
|
+
...(shared.middlewares ?? []),
|
|
116
|
+
...(config.middlewares ?? []),
|
|
117
|
+
];
|
|
118
|
+
const deps = { jobManager, logger: CoreInjectables.logger };
|
|
119
|
+
return createProcedure({
|
|
120
|
+
input: listInputSchema,
|
|
121
|
+
output: createListOutputSchema(job),
|
|
122
|
+
dependencies: { ...deps, ...(config.dependencies ?? {}) },
|
|
123
|
+
guards: allGuards,
|
|
124
|
+
middlewares: allMiddlewares,
|
|
125
|
+
metadata: config.metadata,
|
|
126
|
+
timeout: config.timeout,
|
|
127
|
+
handler: async (ctx, input) => {
|
|
128
|
+
ctx.logger.debug({
|
|
129
|
+
jobName: job.options.name,
|
|
130
|
+
page: input.page,
|
|
131
|
+
limit: input.limit,
|
|
132
|
+
state: input.state,
|
|
133
|
+
}, 'Listing jobs');
|
|
134
|
+
const result = await ctx.jobManager.list(job, {
|
|
135
|
+
page: input.page,
|
|
136
|
+
limit: input.limit,
|
|
137
|
+
state: input.state,
|
|
138
|
+
});
|
|
139
|
+
ctx.logger.debug({ jobName: job.options.name, total: result.total, pages: result.pages }, 'Jobs listed');
|
|
140
|
+
return result;
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function createGetProcedure(job, config = {}, shared) {
|
|
145
|
+
const allGuards = [...(shared.guards ?? []), ...(config.guards ?? [])];
|
|
146
|
+
const allMiddlewares = [
|
|
147
|
+
...(shared.middlewares ?? []),
|
|
148
|
+
...(config.middlewares ?? []),
|
|
149
|
+
];
|
|
150
|
+
const deps = { jobManager, logger: CoreInjectables.logger };
|
|
151
|
+
return createProcedure({
|
|
152
|
+
input: getInputSchema,
|
|
153
|
+
output: createGetOutputSchema(job),
|
|
154
|
+
dependencies: { ...deps, ...(config.dependencies ?? {}) },
|
|
155
|
+
guards: allGuards,
|
|
156
|
+
middlewares: allMiddlewares,
|
|
157
|
+
metadata: config.metadata,
|
|
158
|
+
timeout: config.timeout,
|
|
159
|
+
handler: async (ctx, input) => {
|
|
160
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id }, 'Getting job');
|
|
161
|
+
const result = await ctx.jobManager.get(job, input.id);
|
|
162
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id, found: result !== null }, 'Job retrieved');
|
|
163
|
+
return result;
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function createAddProcedure(job, config = {}, shared) {
|
|
168
|
+
const allGuards = [...(shared.guards ?? []), ...(config.guards ?? [])];
|
|
169
|
+
const allMiddlewares = [
|
|
170
|
+
...(shared.middlewares ?? []),
|
|
171
|
+
...(config.middlewares ?? []),
|
|
172
|
+
];
|
|
173
|
+
const deps = { jobManager, logger: CoreInjectables.logger };
|
|
174
|
+
return createProcedure({
|
|
175
|
+
input: createAddInputSchema(job),
|
|
176
|
+
output: addOutputSchema,
|
|
177
|
+
dependencies: { ...deps, ...(config.dependencies ?? {}) },
|
|
178
|
+
guards: allGuards,
|
|
179
|
+
middlewares: allMiddlewares,
|
|
180
|
+
metadata: config.metadata,
|
|
181
|
+
timeout: config.timeout,
|
|
182
|
+
handler: async (ctx, input) => {
|
|
183
|
+
let jobData = input.data;
|
|
184
|
+
ctx.logger.debug({
|
|
185
|
+
jobName: job.options.name,
|
|
186
|
+
jobId: input.jobId,
|
|
187
|
+
priority: input.priority,
|
|
188
|
+
}, 'Adding job');
|
|
189
|
+
// Call beforeAdd hook if provided
|
|
190
|
+
if (config.beforeAdd) {
|
|
191
|
+
ctx.logger.debug({ jobName: job.options.name }, 'Running beforeAdd hook');
|
|
192
|
+
jobData = await config.beforeAdd(ctx, jobData);
|
|
193
|
+
}
|
|
194
|
+
const queueResult = await ctx.jobManager.add(job, jobData, {
|
|
195
|
+
jobId: input.jobId,
|
|
196
|
+
priority: input.priority ?? config.options?.priority,
|
|
197
|
+
delay: input.delay ?? config.options?.delay,
|
|
198
|
+
attempts: config.options?.attempts,
|
|
199
|
+
});
|
|
200
|
+
const result = { id: queueResult.id, name: queueResult.name };
|
|
201
|
+
ctx.logger.info({ jobName: job.options.name, id: result.id }, 'Job added');
|
|
202
|
+
// Call afterAdd hook if provided
|
|
203
|
+
if (config.afterAdd) {
|
|
204
|
+
ctx.logger.trace({ jobName: job.options.name, id: result.id }, 'Running afterAdd hook');
|
|
205
|
+
await config.afterAdd(ctx, result, jobData);
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
function createRetryProcedure(job, config = {}, shared) {
|
|
212
|
+
const allGuards = [...(shared.guards ?? []), ...(config.guards ?? [])];
|
|
213
|
+
const allMiddlewares = [
|
|
214
|
+
...(shared.middlewares ?? []),
|
|
215
|
+
...(config.middlewares ?? []),
|
|
216
|
+
];
|
|
217
|
+
const deps = { jobManager, logger: CoreInjectables.logger };
|
|
218
|
+
return createProcedure({
|
|
219
|
+
input: retryInputSchema,
|
|
220
|
+
dependencies: { ...deps, ...(config.dependencies ?? {}) },
|
|
221
|
+
guards: allGuards,
|
|
222
|
+
middlewares: allMiddlewares,
|
|
223
|
+
metadata: config.metadata,
|
|
224
|
+
timeout: config.timeout,
|
|
225
|
+
handler: async (ctx, input) => {
|
|
226
|
+
const clearState = input.clearState ?? config.clearState;
|
|
227
|
+
ctx.logger.debug({ jobName: job.options.name, id: input.id, clearState }, 'Retrying job');
|
|
228
|
+
// Call beforeRetry hook if provided
|
|
229
|
+
if (config.beforeRetry) {
|
|
230
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id }, 'Running beforeRetry hook');
|
|
231
|
+
await config.beforeRetry(ctx, { id: input.id, clearState });
|
|
232
|
+
}
|
|
233
|
+
await ctx.jobManager.retry(job, input.id, { clearState });
|
|
234
|
+
ctx.logger.info({ jobName: job.options.name, id: input.id }, 'Job retried');
|
|
235
|
+
// Call afterRetry hook if provided
|
|
236
|
+
if (config.afterRetry) {
|
|
237
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id }, 'Running afterRetry hook');
|
|
238
|
+
await config.afterRetry(ctx, { id: input.id, clearState });
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
function createCancelProcedure(job, config = {}, shared) {
|
|
244
|
+
const allGuards = [...(shared.guards ?? []), ...(config.guards ?? [])];
|
|
245
|
+
const allMiddlewares = [
|
|
246
|
+
...(shared.middlewares ?? []),
|
|
247
|
+
...(config.middlewares ?? []),
|
|
248
|
+
];
|
|
249
|
+
const deps = { jobManager, logger: CoreInjectables.logger };
|
|
250
|
+
return createProcedure({
|
|
251
|
+
input: idInputSchema,
|
|
252
|
+
dependencies: { ...deps, ...(config.dependencies ?? {}) },
|
|
253
|
+
guards: allGuards,
|
|
254
|
+
middlewares: allMiddlewares,
|
|
255
|
+
metadata: config.metadata,
|
|
256
|
+
timeout: config.timeout,
|
|
257
|
+
handler: async (ctx, input) => {
|
|
258
|
+
ctx.logger.debug({ jobName: job.options.name, id: input.id }, 'Canceling job');
|
|
259
|
+
// Call beforeCancel hook if provided
|
|
260
|
+
if (config.beforeCancel) {
|
|
261
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id }, 'Running beforeCancel hook');
|
|
262
|
+
await config.beforeCancel(ctx, { id: input.id });
|
|
263
|
+
}
|
|
264
|
+
await ctx.jobManager.cancel(job, input.id);
|
|
265
|
+
ctx.logger.info({ jobName: job.options.name, id: input.id }, 'Job canceled');
|
|
266
|
+
// Call afterCancel hook if provided
|
|
267
|
+
if (config.afterCancel) {
|
|
268
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id }, 'Running afterCancel hook');
|
|
269
|
+
await config.afterCancel(ctx, { id: input.id });
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function createRemoveProcedure(job, config = {}, shared) {
|
|
275
|
+
const allGuards = [...(shared.guards ?? []), ...(config.guards ?? [])];
|
|
276
|
+
const allMiddlewares = [
|
|
277
|
+
...(shared.middlewares ?? []),
|
|
278
|
+
...(config.middlewares ?? []),
|
|
279
|
+
];
|
|
280
|
+
const deps = { jobManager, logger: CoreInjectables.logger };
|
|
281
|
+
return createProcedure({
|
|
282
|
+
input: idInputSchema,
|
|
283
|
+
dependencies: { ...deps, ...(config.dependencies ?? {}) },
|
|
284
|
+
guards: allGuards,
|
|
285
|
+
middlewares: allMiddlewares,
|
|
286
|
+
metadata: config.metadata,
|
|
287
|
+
timeout: config.timeout,
|
|
288
|
+
handler: async (ctx, input) => {
|
|
289
|
+
ctx.logger.debug({ jobName: job.options.name, id: input.id }, 'Removing job');
|
|
290
|
+
// Call beforeRemove hook if provided
|
|
291
|
+
if (config.beforeRemove) {
|
|
292
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id }, 'Running beforeRemove hook');
|
|
293
|
+
await config.beforeRemove(ctx, { id: input.id });
|
|
294
|
+
}
|
|
295
|
+
await ctx.jobManager.remove(job, input.id);
|
|
296
|
+
ctx.logger.info({ jobName: job.options.name, id: input.id }, 'Job removed');
|
|
297
|
+
// Call afterRemove hook if provided
|
|
298
|
+
if (config.afterRemove) {
|
|
299
|
+
ctx.logger.trace({ jobName: job.options.name, id: input.id }, 'Running afterRemove hook');
|
|
300
|
+
await config.afterRemove(ctx, { id: input.id });
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
// ============================================================================
|
|
306
|
+
// Main router factory
|
|
307
|
+
// ============================================================================
|
|
308
|
+
/**
|
|
309
|
+
* Merge default operations with job-specific overrides
|
|
310
|
+
*/
|
|
311
|
+
function mergeOperations(defaults = {}, overrides = {}) {
|
|
312
|
+
const result = {};
|
|
313
|
+
const ops = [
|
|
314
|
+
'info',
|
|
315
|
+
'list',
|
|
316
|
+
'get',
|
|
317
|
+
'add',
|
|
318
|
+
'retry',
|
|
319
|
+
'cancel',
|
|
320
|
+
'remove',
|
|
321
|
+
];
|
|
322
|
+
for (const op of ops) {
|
|
323
|
+
const override = overrides[op];
|
|
324
|
+
const defaultOp = defaults[op];
|
|
325
|
+
if (override === false) {
|
|
326
|
+
result[op] = false;
|
|
327
|
+
}
|
|
328
|
+
else if (override !== undefined) {
|
|
329
|
+
// Override provided - use it (merged with default base config if both are objects)
|
|
330
|
+
if (defaultOp &&
|
|
331
|
+
defaultOp !== false &&
|
|
332
|
+
typeof override === 'object') {
|
|
333
|
+
result[op] = {
|
|
334
|
+
...defaultOp,
|
|
335
|
+
...override,
|
|
336
|
+
guards: [
|
|
337
|
+
...(defaultOp.guards ?? []),
|
|
338
|
+
...(override.guards ?? []),
|
|
339
|
+
],
|
|
340
|
+
middlewares: [
|
|
341
|
+
...(defaultOp.middlewares ?? []),
|
|
342
|
+
...(override.middlewares ?? []),
|
|
343
|
+
],
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
result[op] = override;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else if (defaultOp !== undefined) {
|
|
351
|
+
result[op] = defaultOp;
|
|
352
|
+
}
|
|
353
|
+
// else: undefined = use default behavior (enabled with empty config)
|
|
354
|
+
}
|
|
355
|
+
return result;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Creates a router with CRUD-like operations for multiple jobs.
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```ts
|
|
362
|
+
* const jobsRouter = createJobsRouter({
|
|
363
|
+
* jobs: [userJob, emailJob] as const,
|
|
364
|
+
* guards: [authGuard],
|
|
365
|
+
* defaults: {
|
|
366
|
+
* list: {},
|
|
367
|
+
* get: {},
|
|
368
|
+
* add: {},
|
|
369
|
+
* retry: { guards: [adminGuard] },
|
|
370
|
+
* cancel: { guards: [adminGuard] },
|
|
371
|
+
* remove: false,
|
|
372
|
+
* },
|
|
373
|
+
* overrides: {
|
|
374
|
+
* userProcessing: {
|
|
375
|
+
* add: jobOperation({
|
|
376
|
+
* dependencies: { userService },
|
|
377
|
+
* beforeAdd: async (ctx, input) => ({
|
|
378
|
+
* ...input,
|
|
379
|
+
* userId: ctx.userService.getCurrentId(),
|
|
380
|
+
* }),
|
|
381
|
+
* }),
|
|
382
|
+
* },
|
|
383
|
+
* },
|
|
384
|
+
* })
|
|
385
|
+
*
|
|
386
|
+
* // Use in your router
|
|
387
|
+
* createRouter({
|
|
388
|
+
* routes: {
|
|
389
|
+
* jobs: jobsRouter,
|
|
390
|
+
* }
|
|
391
|
+
* })
|
|
392
|
+
* ```
|
|
393
|
+
*/
|
|
394
|
+
export function createJobsRouter(options) {
|
|
395
|
+
const { jobs, guards: sharedGuards = [], middlewares: sharedMiddlewares = [], defaults = {}, overrides = {}, } = options;
|
|
396
|
+
const routes = {};
|
|
397
|
+
const shared = { guards: sharedGuards, middlewares: sharedMiddlewares };
|
|
398
|
+
for (const jobName in jobs) {
|
|
399
|
+
const job = jobs[jobName];
|
|
400
|
+
const jobOverrides = overrides[jobName] ?? {};
|
|
401
|
+
// Merge defaults with job-specific overrides
|
|
402
|
+
const operations = mergeOperations(defaults, jobOverrides);
|
|
403
|
+
const jobRoutes = {};
|
|
404
|
+
// Generate each enabled operation
|
|
405
|
+
if (operations.info !== false) {
|
|
406
|
+
jobRoutes.info = createInfoProcedure(job, operations.info, shared);
|
|
407
|
+
}
|
|
408
|
+
if (operations.list !== false) {
|
|
409
|
+
jobRoutes.list = createListProcedure(job, operations.list, shared);
|
|
410
|
+
}
|
|
411
|
+
if (operations.get !== false) {
|
|
412
|
+
jobRoutes.get = createGetProcedure(job, operations.get, shared);
|
|
413
|
+
}
|
|
414
|
+
if (operations.add !== false) {
|
|
415
|
+
jobRoutes.add = createAddProcedure(job, operations.add, shared);
|
|
416
|
+
}
|
|
417
|
+
if (operations.retry !== false) {
|
|
418
|
+
jobRoutes.retry = createRetryProcedure(job, operations.retry, shared);
|
|
419
|
+
}
|
|
420
|
+
if (operations.cancel !== false) {
|
|
421
|
+
jobRoutes.cancel = createCancelProcedure(job, operations.cancel, shared);
|
|
422
|
+
}
|
|
423
|
+
if (operations.remove !== false) {
|
|
424
|
+
jobRoutes.remove = createRemoveProcedure(job, operations.remove, shared);
|
|
425
|
+
}
|
|
426
|
+
// Create router for this job (named by job name)
|
|
427
|
+
routes[jobName] = createRouter({ routes: jobRoutes });
|
|
428
|
+
}
|
|
429
|
+
// Return router containing all job routers
|
|
430
|
+
return createRouter({ routes });
|
|
431
|
+
}
|
|
432
|
+
//# sourceMappingURL=router.js.map
|