@appweaver/core 1.0.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/LICENSE +1 -0
- package/README.md +7 -0
- package/app/application.d.ts +43 -0
- package/app/application.js +112 -0
- package/app/create-app.d.ts +32 -0
- package/app/create-app.js +38 -0
- package/app/index.d.ts +2 -0
- package/app/index.js +18 -0
- package/app/lifecycle-manager.d.ts +20 -0
- package/app/lifecycle-manager.js +42 -0
- package/app/load-modules.d.ts +10 -0
- package/app/load-modules.js +50 -0
- package/app/load-providers.d.ts +8 -0
- package/app/load-providers.js +33 -0
- package/cache/cache-service.d.ts +72 -0
- package/cache/cache-service.js +202 -0
- package/cache/cache.d.ts +12 -0
- package/cache/cache.js +184 -0
- package/cache/caching.d.ts +8 -0
- package/cache/caching.js +72 -0
- package/cache/eviction/eviction-index.d.ts +35 -0
- package/cache/eviction/eviction-index.js +2 -0
- package/cache/eviction/fifo-eviction-index.d.ts +7 -0
- package/cache/eviction/fifo-eviction-index.js +28 -0
- package/cache/eviction/index.d.ts +4 -0
- package/cache/eviction/index.js +20 -0
- package/cache/eviction/lfu-eviction-index.d.ts +8 -0
- package/cache/eviction/lfu-eviction-index.js +82 -0
- package/cache/eviction/lru-eviction-index.d.ts +8 -0
- package/cache/eviction/lru-eviction-index.js +81 -0
- package/cache/index.d.ts +2 -0
- package/cache/index.js +18 -0
- package/cache/memory-cache.d.ts +4 -0
- package/cache/memory-cache.js +12 -0
- package/cache/redis-cache.d.ts +4 -0
- package/cache/redis-cache.js +12 -0
- package/context/context.d.ts +2 -0
- package/context/context.js +13 -0
- package/context/dependency-injection.d.ts +98 -0
- package/context/dependency-injection.js +276 -0
- package/context/index.d.ts +2 -0
- package/context/index.js +18 -0
- package/database/create-client.d.ts +11 -0
- package/database/create-client.js +142 -0
- package/database/index.d.ts +1 -0
- package/database/index.js +17 -0
- package/database/prisma-database.d.ts +15 -0
- package/database/prisma-database.js +53 -0
- package/errors/error-handler.d.ts +3 -0
- package/errors/error-handler.js +24 -0
- package/errors/error-schema.d.ts +32 -0
- package/errors/error-schema.js +31 -0
- package/errors/http-error.d.ts +21 -0
- package/errors/http-error.js +33 -0
- package/errors/index.d.ts +3 -0
- package/errors/index.js +19 -0
- package/events/node-events.d.ts +7 -0
- package/events/node-events.js +39 -0
- package/export/export-service.d.ts +19 -0
- package/export/export-service.js +154 -0
- package/export/index.d.ts +1 -0
- package/export/index.js +17 -0
- package/factory/create-model.d.ts +2 -0
- package/factory/create-model.js +366 -0
- package/factory/create-policy.d.ts +2 -0
- package/factory/create-policy.js +16 -0
- package/factory/create-routes.d.ts +2 -0
- package/factory/create-routes.js +21 -0
- package/factory/create-service.d.ts +3 -0
- package/factory/create-service.js +97 -0
- package/factory/index.d.ts +4 -0
- package/factory/index.js +20 -0
- package/health/health-routes.d.ts +2 -0
- package/health/health-routes.js +36 -0
- package/health/health-schema.d.ts +45 -0
- package/health/health-schema.js +52 -0
- package/health/health-service.d.ts +38 -0
- package/health/health-service.js +82 -0
- package/health/index.d.ts +2 -0
- package/health/index.js +18 -0
- package/index.d.ts +15 -0
- package/index.js +31 -0
- package/mailer/email-service.d.ts +36 -0
- package/mailer/email-service.js +89 -0
- package/mailer/index.d.ts +1 -0
- package/mailer/index.js +17 -0
- package/mailer/json-mailer.d.ts +7 -0
- package/mailer/json-mailer.js +32 -0
- package/mailer/smtp-mailer.d.ts +7 -0
- package/mailer/smtp-mailer.js +43 -0
- package/memory/in-memory.d.ts +24 -0
- package/memory/in-memory.js +164 -0
- package/memory/redis.d.ts +26 -0
- package/memory/redis.js +158 -0
- package/package.json +68 -0
- package/prisma/client/browser.d.ts +34 -0
- package/prisma/client/browser.js +56 -0
- package/prisma/client/client.d.ts +53 -0
- package/prisma/client/client.js +70 -0
- package/prisma/client/commonInputTypes.d.ts +395 -0
- package/prisma/client/commonInputTypes.js +11 -0
- package/prisma/client/enums.d.ts +1 -0
- package/prisma/client/enums.js +11 -0
- package/prisma/client/internal/class.d.ts +187 -0
- package/prisma/client/internal/class.js +85 -0
- package/prisma/client/internal/prismaNamespace.d.ts +987 -0
- package/prisma/client/internal/prismaNamespace.js +193 -0
- package/prisma/client/internal/prismaNamespaceBrowser.d.ts +125 -0
- package/prisma/client/internal/prismaNamespaceBrowser.js +164 -0
- package/prisma/client/models/ApiKey.d.ts +1167 -0
- package/prisma/client/models/ApiKey.js +2 -0
- package/prisma/client/models/File.d.ts +1248 -0
- package/prisma/client/models/File.js +2 -0
- package/prisma/client/models/OneTimeToken.d.ts +1083 -0
- package/prisma/client/models/OneTimeToken.js +2 -0
- package/prisma/client/models/Permission.d.ts +1209 -0
- package/prisma/client/models/Permission.js +2 -0
- package/prisma/client/models/Role.d.ts +1209 -0
- package/prisma/client/models/Role.js +2 -0
- package/prisma/client/models/Seeder.d.ts +1023 -0
- package/prisma/client/models/Seeder.js +2 -0
- package/prisma/client/models.d.ts +7 -0
- package/prisma/client/models.js +2 -0
- package/queue/bull-queue.d.ts +37 -0
- package/queue/bull-queue.js +207 -0
- package/queue/memory-queue.d.ts +54 -0
- package/queue/memory-queue.js +283 -0
- package/resource/index.d.ts +4 -0
- package/resource/index.js +20 -0
- package/resource/resource-loader.d.ts +26 -0
- package/resource/resource-loader.js +161 -0
- package/resource/resource-routes.d.ts +3 -0
- package/resource/resource-routes.js +174 -0
- package/resource/resource-schema.d.ts +33 -0
- package/resource/resource-schema.js +186 -0
- package/resource/resource-service.d.ts +89 -0
- package/resource/resource-service.js +772 -0
- package/resources.d.ts +9 -0
- package/resources.js +24 -0
- package/scheduler/cron-scheduler.d.ts +12 -0
- package/scheduler/cron-scheduler.js +73 -0
- package/security/account/account-routes.d.ts +2 -0
- package/security/account/account-routes.js +104 -0
- package/security/account/account-schema.d.ts +290 -0
- package/security/account/account-schema.js +166 -0
- package/security/account/account-service.d.ts +88 -0
- package/security/account/account-service.js +218 -0
- package/security/account/index.d.ts +3 -0
- package/security/account/index.js +19 -0
- package/security/api-key/api-key-auth.d.ts +4 -0
- package/security/api-key/api-key-auth.js +66 -0
- package/security/api-key/index.d.ts +1 -0
- package/security/api-key/index.js +17 -0
- package/security/auth-routes.d.ts +2 -0
- package/security/auth-routes.js +80 -0
- package/security/auth-schema.d.ts +215 -0
- package/security/auth-schema.js +129 -0
- package/security/auth-service.d.ts +117 -0
- package/security/auth-service.js +272 -0
- package/security/auth.d.ts +3 -0
- package/security/auth.js +127 -0
- package/security/basic/basic-auth.d.ts +4 -0
- package/security/basic/basic-auth.js +32 -0
- package/security/basic/index.d.ts +1 -0
- package/security/basic/index.js +17 -0
- package/security/create-auth-resources.d.ts +6 -0
- package/security/create-auth-resources.js +129 -0
- package/security/helper.d.ts +127 -0
- package/security/helper.js +329 -0
- package/security/index.d.ts +4 -0
- package/security/index.js +20 -0
- package/security/jwt/index.d.ts +2 -0
- package/security/jwt/index.js +18 -0
- package/security/jwt/jwt-auth.d.ts +4 -0
- package/security/jwt/jwt-auth.js +57 -0
- package/security/jwt/jwt-keys.d.ts +7 -0
- package/security/jwt/jwt-keys.js +43 -0
- package/security/oauth2/create-oauth2-plugin.d.ts +17 -0
- package/security/oauth2/create-oauth2-plugin.js +85 -0
- package/security/oauth2/index.d.ts +3 -0
- package/security/oauth2/index.js +19 -0
- package/security/oauth2/oauth2-custom.d.ts +7 -0
- package/security/oauth2/oauth2-custom.js +40 -0
- package/security/oauth2/oauth2-facebook.d.ts +1 -0
- package/security/oauth2/oauth2-facebook.js +30 -0
- package/security/oauth2/oauth2-google.d.ts +1 -0
- package/security/oauth2/oauth2-google.js +28 -0
- package/security/oauth2/oauth2-schema.d.ts +10 -0
- package/security/oauth2/oauth2-schema.js +53 -0
- package/security/recaptcha/index.d.ts +2 -0
- package/security/recaptcha/index.js +18 -0
- package/security/recaptcha/recaptcha-verify.d.ts +1 -0
- package/security/recaptcha/recaptcha-verify.js +33 -0
- package/security/recaptcha/recaptcha.d.ts +2 -0
- package/security/recaptcha/recaptcha.js +22 -0
- package/security/resources/api-key/model.d.ts +2 -0
- package/security/resources/api-key/model.js +63 -0
- package/security/resources/api-key/policy.d.ts +2 -0
- package/security/resources/api-key/policy.js +26 -0
- package/security/resources/api-key/routes.d.ts +2 -0
- package/security/resources/api-key/routes.js +15 -0
- package/security/resources/api-key/service.d.ts +3 -0
- package/security/resources/api-key/service.js +33 -0
- package/security/resources/one-time-token/model.d.ts +2 -0
- package/security/resources/one-time-token/model.js +32 -0
- package/security/resources/permission/model.d.ts +2 -0
- package/security/resources/permission/model.js +16 -0
- package/security/resources/role/model.d.ts +2 -0
- package/security/resources/role/model.js +22 -0
- package/security/store/database-security-store.d.ts +5 -0
- package/security/store/database-security-store.js +51 -0
- package/security/store/redis-security-store.d.ts +5 -0
- package/security/store/redis-security-store.js +32 -0
- package/seeder/create-seeder.d.ts +21 -0
- package/seeder/create-seeder.js +17 -0
- package/seeder/index.d.ts +2 -0
- package/seeder/index.js +18 -0
- package/seeder/resources/seeder/model.d.ts +2 -0
- package/seeder/resources/seeder/model.js +38 -0
- package/seeder/seeder.d.ts +20 -0
- package/seeder/seeder.js +175 -0
- package/server/create-server.d.ts +20 -0
- package/server/create-server.js +160 -0
- package/server/index.d.ts +4 -0
- package/server/index.js +20 -0
- package/server/info-route.d.ts +2 -0
- package/server/info-route.js +18 -0
- package/server/info-schema.d.ts +37 -0
- package/server/info-schema.js +19 -0
- package/server/register-model.d.ts +2 -0
- package/server/register-model.js +12 -0
- package/server/register-plugin.d.ts +2 -0
- package/server/register-plugin.js +13 -0
- package/server/register-route.d.ts +3 -0
- package/server/register-route.js +74 -0
- package/server/schemas.d.ts +3 -0
- package/server/schemas.js +30 -0
- package/server/swagger.d.ts +3 -0
- package/server/swagger.js +122 -0
- package/storage/file-route.d.ts +2 -0
- package/storage/file-route.js +39 -0
- package/storage/file-schema.d.ts +9 -0
- package/storage/file-schema.js +42 -0
- package/storage/file-service.d.ts +81 -0
- package/storage/file-service.js +384 -0
- package/storage/filesystem-storage.d.ts +10 -0
- package/storage/filesystem-storage.js +128 -0
- package/storage/index.d.ts +2 -0
- package/storage/index.js +18 -0
- package/storage/resources/file/model.d.ts +2 -0
- package/storage/resources/file/model.js +75 -0
- package/types/application-context.d.ts +20 -0
- package/types/application-context.js +2 -0
- package/types/auth.d.ts +31 -0
- package/types/auth.js +2 -0
- package/types/fastify-extensions.d.ts +24 -0
- package/types/fastify-extensions.js +4 -0
- package/types/generated.d.ts +193 -0
- package/types/generated.js +3 -0
- package/types/index.d.ts +4 -0
- package/types/index.js +20 -0
- package/types/server.d.ts +4 -0
- package/types/server.js +2 -0
- package/utils/export-util.d.ts +8 -0
- package/utils/export-util.js +25 -0
- package/utils/file-util.d.ts +64 -0
- package/utils/file-util.js +141 -0
- package/utils/index.d.ts +3 -0
- package/utils/index.js +19 -0
- package/utils/schema-util.d.ts +20 -0
- package/utils/schema-util.js +37 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type * from './models/ApiKey';
|
|
2
|
+
export type * from './models/OneTimeToken';
|
|
3
|
+
export type * from './models/Permission';
|
|
4
|
+
export type * from './models/Role';
|
|
5
|
+
export type * from './models/Seeder';
|
|
6
|
+
export type * from './models/File';
|
|
7
|
+
export type * from './commonInputTypes';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Job, JobProgress, Worker, WorkerOptions } from 'bullmq';
|
|
2
|
+
import { JobsOptions } from 'bullmq/dist/esm/types';
|
|
3
|
+
import { HealthCheckResult, Queue as CommonQueue, QueueHandlerResponse, QueueProcessor } from '@appweaver/common';
|
|
4
|
+
export declare class BullQueue extends CommonQueue {
|
|
5
|
+
onDestroy(): Promise<void>;
|
|
6
|
+
get<Data = any, Response = any>(name: string): BullQueueProcessor<Data, Response>;
|
|
7
|
+
close(name: string): Promise<boolean>;
|
|
8
|
+
closeAll(): Promise<void>;
|
|
9
|
+
checkHealth(): Promise<HealthCheckResult>;
|
|
10
|
+
}
|
|
11
|
+
declare class BullQueueProcessor<Data = any, Response = any> extends QueueProcessor<Data, Response, Job<Data, Response>, JobsOptions, Worker<Data, Response>, WorkerOptions> {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
constructor(name: string);
|
|
14
|
+
sendJob(data: Data, name?: string, options?: JobsOptions): Promise<Job<Data, Response>>;
|
|
15
|
+
sendBulkJobs(jobs: Array<{
|
|
16
|
+
data: Data;
|
|
17
|
+
name?: string;
|
|
18
|
+
options?: Omit<JobsOptions, 'repeat'>;
|
|
19
|
+
}>): Promise<Array<Job<Data, Response>>>;
|
|
20
|
+
addWorker(processor: (job: Job<Data, Response>) => Promise<Response>, options?: Omit<WorkerOptions, 'connection'>): Worker<Data, Response>;
|
|
21
|
+
removeWorker(id: string): Promise<boolean>;
|
|
22
|
+
onCompleted(handler: (job: Job<Data, Response>, result: Response, prev: string) => QueueHandlerResponse): string;
|
|
23
|
+
onFailed(handler: (job: Job<Data, Response> | undefined, error: Error, prev: string) => QueueHandlerResponse): string;
|
|
24
|
+
onError(handler: (error: Error) => QueueHandlerResponse): string;
|
|
25
|
+
onProgress(handler: (job: Job<Data, Response>, progress: JobProgress) => QueueHandlerResponse): string;
|
|
26
|
+
onActive(handler: (job: Job<Data, Response>, prev: string) => QueueHandlerResponse): string;
|
|
27
|
+
onStalled(handler: (jobId: string, prev: string) => QueueHandlerResponse): string;
|
|
28
|
+
onDrained(handler: () => QueueHandlerResponse): string;
|
|
29
|
+
onReady(handler: () => QueueHandlerResponse): string;
|
|
30
|
+
onPaused(handler: () => QueueHandlerResponse): string;
|
|
31
|
+
onResumed(handler: () => QueueHandlerResponse): string;
|
|
32
|
+
onClosing(handler: (msg: string) => QueueHandlerResponse): string;
|
|
33
|
+
onClosed(handler: () => QueueHandlerResponse): string;
|
|
34
|
+
removeListener(id: string): boolean;
|
|
35
|
+
close(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BullQueue = void 0;
|
|
4
|
+
const bullmq_1 = require("bullmq");
|
|
5
|
+
const common_1 = require("@appweaver/common");
|
|
6
|
+
const context_1 = require("../context");
|
|
7
|
+
class BullQueue extends common_1.Queue {
|
|
8
|
+
/** @internal */
|
|
9
|
+
_queues = new Map();
|
|
10
|
+
async onDestroy() {
|
|
11
|
+
await this.closeAll();
|
|
12
|
+
}
|
|
13
|
+
get(name) {
|
|
14
|
+
let processor = this._queues.get(name);
|
|
15
|
+
if (!processor) {
|
|
16
|
+
processor = new BullQueueProcessor(name);
|
|
17
|
+
this._queues.set(name, processor);
|
|
18
|
+
}
|
|
19
|
+
return processor;
|
|
20
|
+
}
|
|
21
|
+
async close(name) {
|
|
22
|
+
const processor = this._queues.get(name);
|
|
23
|
+
if (!processor) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
await processor.close();
|
|
27
|
+
this._queues.delete(name);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
async closeAll() {
|
|
31
|
+
for (const queueName of this._queues.keys()) {
|
|
32
|
+
await this.close(queueName);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async checkHealth() {
|
|
36
|
+
try {
|
|
37
|
+
const queue = new BullQueueProcessor('health-check');
|
|
38
|
+
await queue.close();
|
|
39
|
+
return { success: true };
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
return { success: false, message: e.message };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.BullQueue = BullQueue;
|
|
47
|
+
class BullQueueProcessor extends common_1.QueueProcessor {
|
|
48
|
+
name;
|
|
49
|
+
/** @internal */
|
|
50
|
+
_connection = (0, context_1.inject)(common_1.Redis).createClient({
|
|
51
|
+
maxRetriesPerRequest: null
|
|
52
|
+
});
|
|
53
|
+
/** @internal */
|
|
54
|
+
_queue;
|
|
55
|
+
/** @internal */
|
|
56
|
+
_workers = [];
|
|
57
|
+
/** @internal */
|
|
58
|
+
_listeners = {};
|
|
59
|
+
constructor(name) {
|
|
60
|
+
super();
|
|
61
|
+
this.name = name;
|
|
62
|
+
this._queue = new bullmq_1.Queue(name, {
|
|
63
|
+
connection: this._connection,
|
|
64
|
+
skipVersionCheck: true,
|
|
65
|
+
defaultJobOptions: {
|
|
66
|
+
removeOnComplete: {
|
|
67
|
+
count: common_1.config.QUEUE_KEEP_COMPLETED_COUNT,
|
|
68
|
+
age: common_1.config.QUEUE_KEEP_COMPLETED_SECONDS
|
|
69
|
+
},
|
|
70
|
+
removeOnFail: {
|
|
71
|
+
count: common_1.config.QUEUE_KEEP_FAILED_COUNT,
|
|
72
|
+
age: common_1.config.QUEUE_KEEP_FAILED_SECONDS
|
|
73
|
+
},
|
|
74
|
+
attempts: common_1.config.QUEUE_RETRY_ATTEMPTS,
|
|
75
|
+
backoff: {
|
|
76
|
+
delay: common_1.config.QUEUE_RETRY_BACKOFF,
|
|
77
|
+
type: common_1.config.QUEUE_RETRY_BACKOFF_TYPE
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async sendJob(data, name, options = {}) {
|
|
83
|
+
return await this._queue.add(name ?? 'defaultJob', data, options);
|
|
84
|
+
}
|
|
85
|
+
async sendBulkJobs(jobs) {
|
|
86
|
+
return await this._queue.addBulk(jobs.map(({ data, name, options }) => ({
|
|
87
|
+
data,
|
|
88
|
+
name: name ?? 'defaultJob',
|
|
89
|
+
...(options ?? {})
|
|
90
|
+
})));
|
|
91
|
+
}
|
|
92
|
+
addWorker(processor, options = {}) {
|
|
93
|
+
const worker = new bullmq_1.Worker(this.name, processor, {
|
|
94
|
+
...options,
|
|
95
|
+
connection: this._connection,
|
|
96
|
+
skipVersionCheck: true,
|
|
97
|
+
name: `${this.name}_${(0, common_1.uuid)()}`
|
|
98
|
+
});
|
|
99
|
+
for (const event of [
|
|
100
|
+
'completed',
|
|
101
|
+
'failed',
|
|
102
|
+
'error',
|
|
103
|
+
'progress',
|
|
104
|
+
'active',
|
|
105
|
+
'stalled',
|
|
106
|
+
'drained',
|
|
107
|
+
'ready',
|
|
108
|
+
'paused',
|
|
109
|
+
'resumed',
|
|
110
|
+
'closing',
|
|
111
|
+
'closed'
|
|
112
|
+
]) {
|
|
113
|
+
worker.on(event, async (...args) => {
|
|
114
|
+
try {
|
|
115
|
+
await this.handleEvent(event, ...args);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
common_1.logger.error(error, `Error occurred while handling event '${event}' for queue '${this.name}'`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
this._workers.push(worker);
|
|
123
|
+
return worker;
|
|
124
|
+
}
|
|
125
|
+
async removeWorker(id) {
|
|
126
|
+
const index = this._workers.findIndex((w) => w.id === id);
|
|
127
|
+
if (index === -1) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
await this._workers[index].close();
|
|
132
|
+
this._workers.splice(index, 1);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
common_1.logger.error(error, `Error occurred while removing worker with ID '${id}' from queue '${this.name}'`);
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
onCompleted(handler) {
|
|
141
|
+
return this.addListener('completed', handler);
|
|
142
|
+
}
|
|
143
|
+
onFailed(handler) {
|
|
144
|
+
return this.addListener('failed', handler);
|
|
145
|
+
}
|
|
146
|
+
onError(handler) {
|
|
147
|
+
return this.addListener('error', handler);
|
|
148
|
+
}
|
|
149
|
+
onProgress(handler) {
|
|
150
|
+
return this.addListener('progress', handler);
|
|
151
|
+
}
|
|
152
|
+
onActive(handler) {
|
|
153
|
+
return this.addListener('active', handler);
|
|
154
|
+
}
|
|
155
|
+
onStalled(handler) {
|
|
156
|
+
return this.addListener('stalled', handler);
|
|
157
|
+
}
|
|
158
|
+
onDrained(handler) {
|
|
159
|
+
return this.addListener('drained', handler);
|
|
160
|
+
}
|
|
161
|
+
onReady(handler) {
|
|
162
|
+
return this.addListener('ready', handler);
|
|
163
|
+
}
|
|
164
|
+
onPaused(handler) {
|
|
165
|
+
return this.addListener('paused', handler);
|
|
166
|
+
}
|
|
167
|
+
onResumed(handler) {
|
|
168
|
+
return this.addListener('resumed', handler);
|
|
169
|
+
}
|
|
170
|
+
onClosing(handler) {
|
|
171
|
+
return this.addListener('closing', handler);
|
|
172
|
+
}
|
|
173
|
+
onClosed(handler) {
|
|
174
|
+
return this.addListener('closed', handler);
|
|
175
|
+
}
|
|
176
|
+
removeListener(id) {
|
|
177
|
+
const listener = this._listeners[id];
|
|
178
|
+
if (!listener) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
delete this._listeners[id];
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
async close() {
|
|
185
|
+
await this._queue.close();
|
|
186
|
+
for (const worker of this._workers) {
|
|
187
|
+
await worker.close();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** @internal */
|
|
191
|
+
addListener(event, listener) {
|
|
192
|
+
const listenerId = (0, common_1.uuid)();
|
|
193
|
+
this._listeners[listenerId] = { event, listener };
|
|
194
|
+
return listenerId;
|
|
195
|
+
}
|
|
196
|
+
/** @internal */
|
|
197
|
+
async handleEvent(event, ...args) {
|
|
198
|
+
const handlerActions = [];
|
|
199
|
+
for (const value of Object.values(this._listeners)) {
|
|
200
|
+
if (value.event !== event) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
handlerActions.push(value.listener(...args));
|
|
204
|
+
}
|
|
205
|
+
await Promise.allSettled(handlerActions);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { HealthCheckResult, Queue as CommonQueue, QueueHandlerResponse, QueueJob, QueueProcessor } from '@appweaver/common';
|
|
2
|
+
type MemoryQueueJob<Data = any, Response = any> = QueueJob<Data, Response> & {
|
|
3
|
+
status: 'waiting' | 'active' | 'completed' | 'failed';
|
|
4
|
+
error?: Error;
|
|
5
|
+
attempts: number;
|
|
6
|
+
maxAttempts: number;
|
|
7
|
+
createdAt: number;
|
|
8
|
+
processedAt?: number;
|
|
9
|
+
finishedAt?: number;
|
|
10
|
+
};
|
|
11
|
+
type MemoryJobOptions = {
|
|
12
|
+
attempts?: number;
|
|
13
|
+
delay?: number;
|
|
14
|
+
priority?: number;
|
|
15
|
+
};
|
|
16
|
+
type MemoryWorker<Data = any, Response = any> = {
|
|
17
|
+
id: string;
|
|
18
|
+
processor: (job: MemoryQueueJob<Data, Response>) => Promise<Response>;
|
|
19
|
+
active: boolean;
|
|
20
|
+
};
|
|
21
|
+
export declare class MemoryQueue extends CommonQueue {
|
|
22
|
+
onDestroy(): Promise<void>;
|
|
23
|
+
get<Data = any, Response = any>(name: string): MemoryQueueProcessor<Data, Response>;
|
|
24
|
+
close(name: string): Promise<boolean>;
|
|
25
|
+
closeAll(): Promise<void>;
|
|
26
|
+
checkHealth(): Promise<HealthCheckResult>;
|
|
27
|
+
}
|
|
28
|
+
declare class MemoryQueueProcessor<Data = any, Response = any> extends QueueProcessor<Data, Response, MemoryQueueJob<Data, Response>, MemoryJobOptions, MemoryWorker<Data, Response>, undefined> {
|
|
29
|
+
readonly name: string;
|
|
30
|
+
constructor(name: string);
|
|
31
|
+
sendJob(data: Data, name?: string, options?: MemoryJobOptions): Promise<MemoryQueueJob<Data, Response>>;
|
|
32
|
+
sendBulkJobs(jobs: Array<{
|
|
33
|
+
data: Data;
|
|
34
|
+
name?: string;
|
|
35
|
+
options?: MemoryJobOptions;
|
|
36
|
+
}>): Promise<Array<MemoryQueueJob<Data, Response>>>;
|
|
37
|
+
addWorker(processor: (job: MemoryQueueJob<Data, Response>) => Promise<Response>, _options?: undefined): MemoryWorker<Data, Response>;
|
|
38
|
+
removeWorker(id: string): Promise<boolean>;
|
|
39
|
+
onCompleted(handler: (job: MemoryQueueJob<Data, Response>, result: Response, prev: string) => QueueHandlerResponse): string;
|
|
40
|
+
onFailed(handler: (job: MemoryQueueJob<Data, Response> | undefined, error: Error, prev: string) => QueueHandlerResponse): string;
|
|
41
|
+
onError(handler: (error: Error) => QueueHandlerResponse): string;
|
|
42
|
+
onProgress(handler: (job: MemoryQueueJob<Data, Response>, progress: string | boolean | number | object) => QueueHandlerResponse): string;
|
|
43
|
+
onActive(handler: (job: MemoryQueueJob<Data, Response>, prev: string) => QueueHandlerResponse): string;
|
|
44
|
+
onStalled(handler: (jobId: string, prev: string) => QueueHandlerResponse): string;
|
|
45
|
+
onDrained(handler: () => QueueHandlerResponse): string;
|
|
46
|
+
onReady(handler: () => QueueHandlerResponse): string;
|
|
47
|
+
onPaused(handler: () => QueueHandlerResponse): string;
|
|
48
|
+
onResumed(handler: () => QueueHandlerResponse): string;
|
|
49
|
+
onClosing(handler: (msg: string) => QueueHandlerResponse): string;
|
|
50
|
+
onClosed(handler: () => QueueHandlerResponse): string;
|
|
51
|
+
removeListener(id: string): boolean;
|
|
52
|
+
close(): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemoryQueue = void 0;
|
|
4
|
+
const common_1 = require("@appweaver/common");
|
|
5
|
+
class MemoryQueue extends common_1.Queue {
|
|
6
|
+
/** @internal */
|
|
7
|
+
_queues = new Map();
|
|
8
|
+
async onDestroy() {
|
|
9
|
+
await this.closeAll();
|
|
10
|
+
}
|
|
11
|
+
get(name) {
|
|
12
|
+
let processor = this._queues.get(name);
|
|
13
|
+
if (!processor) {
|
|
14
|
+
processor = new MemoryQueueProcessor(name);
|
|
15
|
+
this._queues.set(name, processor);
|
|
16
|
+
}
|
|
17
|
+
return processor;
|
|
18
|
+
}
|
|
19
|
+
async close(name) {
|
|
20
|
+
const processor = this._queues.get(name);
|
|
21
|
+
if (!processor) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
await processor.close();
|
|
25
|
+
this._queues.delete(name);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
async closeAll() {
|
|
29
|
+
for (const queueName of this._queues.keys()) {
|
|
30
|
+
await this.close(queueName);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async checkHealth() {
|
|
34
|
+
try {
|
|
35
|
+
const queue = new MemoryQueueProcessor('health-check');
|
|
36
|
+
await queue.close();
|
|
37
|
+
return { success: true };
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
return { success: false, message: e.message };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.MemoryQueue = MemoryQueue;
|
|
45
|
+
class MemoryQueueProcessor extends common_1.QueueProcessor {
|
|
46
|
+
name;
|
|
47
|
+
/** @internal */
|
|
48
|
+
_jobs = new Map();
|
|
49
|
+
/** @internal */
|
|
50
|
+
_workers = [];
|
|
51
|
+
/** @internal */
|
|
52
|
+
_listeners = {};
|
|
53
|
+
/** @internal */
|
|
54
|
+
_processing = false;
|
|
55
|
+
/** @internal */
|
|
56
|
+
_paused = false;
|
|
57
|
+
/** @internal */
|
|
58
|
+
_closed = false;
|
|
59
|
+
/** @internal */
|
|
60
|
+
_processingTimeout;
|
|
61
|
+
constructor(name) {
|
|
62
|
+
super();
|
|
63
|
+
this.name = name;
|
|
64
|
+
this.emitEvent('ready').catch((error) => {
|
|
65
|
+
common_1.logger.error(error, `Memory queue processing error`);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async sendJob(data, name, options = {}) {
|
|
69
|
+
if (this._closed) {
|
|
70
|
+
throw new Error(`Queue ${this.name} is closed`);
|
|
71
|
+
}
|
|
72
|
+
const jobId = (0, common_1.uuid)();
|
|
73
|
+
const job = {
|
|
74
|
+
id: jobId,
|
|
75
|
+
name: name ?? 'defaultJob',
|
|
76
|
+
data,
|
|
77
|
+
returnvalue: undefined,
|
|
78
|
+
status: 'waiting',
|
|
79
|
+
attempts: 0,
|
|
80
|
+
maxAttempts: options.attempts ?? 3,
|
|
81
|
+
createdAt: Date.now()
|
|
82
|
+
};
|
|
83
|
+
if (options.delay) {
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
this._jobs.set(jobId, job);
|
|
86
|
+
this.processJobs();
|
|
87
|
+
}, options.delay);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this._jobs.set(jobId, job);
|
|
91
|
+
this.processJobs();
|
|
92
|
+
}
|
|
93
|
+
return job;
|
|
94
|
+
}
|
|
95
|
+
async sendBulkJobs(jobs) {
|
|
96
|
+
const createdJobs = [];
|
|
97
|
+
for (const jobSpec of jobs) {
|
|
98
|
+
const job = await this.sendJob(jobSpec.data, jobSpec.name, jobSpec.options);
|
|
99
|
+
createdJobs.push(job);
|
|
100
|
+
}
|
|
101
|
+
return createdJobs;
|
|
102
|
+
}
|
|
103
|
+
addWorker(processor, _options) {
|
|
104
|
+
const worker = {
|
|
105
|
+
id: (0, common_1.uuid)(),
|
|
106
|
+
processor,
|
|
107
|
+
active: true
|
|
108
|
+
};
|
|
109
|
+
this._workers.push(worker);
|
|
110
|
+
this.processJobs();
|
|
111
|
+
return worker;
|
|
112
|
+
}
|
|
113
|
+
async removeWorker(id) {
|
|
114
|
+
const index = this._workers.findIndex((w) => w.id === id);
|
|
115
|
+
if (index === -1) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
this._workers[index].active = false;
|
|
119
|
+
this._workers.splice(index, 1);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
onCompleted(handler) {
|
|
123
|
+
return this.addListener('completed', handler);
|
|
124
|
+
}
|
|
125
|
+
onFailed(handler) {
|
|
126
|
+
return this.addListener('failed', handler);
|
|
127
|
+
}
|
|
128
|
+
onError(handler) {
|
|
129
|
+
return this.addListener('error', handler);
|
|
130
|
+
}
|
|
131
|
+
onProgress(handler) {
|
|
132
|
+
return this.addListener('progress', handler);
|
|
133
|
+
}
|
|
134
|
+
onActive(handler) {
|
|
135
|
+
return this.addListener('active', handler);
|
|
136
|
+
}
|
|
137
|
+
onStalled(handler) {
|
|
138
|
+
return this.addListener('stalled', handler);
|
|
139
|
+
}
|
|
140
|
+
onDrained(handler) {
|
|
141
|
+
return this.addListener('drained', handler);
|
|
142
|
+
}
|
|
143
|
+
onReady(handler) {
|
|
144
|
+
return this.addListener('ready', handler);
|
|
145
|
+
}
|
|
146
|
+
onPaused(handler) {
|
|
147
|
+
return this.addListener('paused', handler);
|
|
148
|
+
}
|
|
149
|
+
onResumed(handler) {
|
|
150
|
+
return this.addListener('resumed', handler);
|
|
151
|
+
}
|
|
152
|
+
onClosing(handler) {
|
|
153
|
+
return this.addListener('closing', handler);
|
|
154
|
+
}
|
|
155
|
+
onClosed(handler) {
|
|
156
|
+
return this.addListener('closed', handler);
|
|
157
|
+
}
|
|
158
|
+
removeListener(id) {
|
|
159
|
+
const listener = this._listeners[id];
|
|
160
|
+
if (!listener) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
delete this._listeners[id];
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
async close() {
|
|
167
|
+
this._closed = true;
|
|
168
|
+
await this.emitEvent('closing', 'Queue is closing');
|
|
169
|
+
if (this._processingTimeout) {
|
|
170
|
+
clearTimeout(this._processingTimeout);
|
|
171
|
+
}
|
|
172
|
+
// Wait for active jobs to complete
|
|
173
|
+
const activeJobs = Array.from(this._jobs.values()).filter((job) => job.status === 'active');
|
|
174
|
+
if (activeJobs.length > 0) {
|
|
175
|
+
await new Promise((resolve) => {
|
|
176
|
+
const checkInterval = setInterval(() => {
|
|
177
|
+
const stillActive = Array.from(this._jobs.values()).some((job) => job.status === 'active');
|
|
178
|
+
if (!stillActive) {
|
|
179
|
+
clearInterval(checkInterval);
|
|
180
|
+
resolve();
|
|
181
|
+
}
|
|
182
|
+
}, 100);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
await this.emitEvent('closed');
|
|
186
|
+
}
|
|
187
|
+
/** @internal */
|
|
188
|
+
addListener(event, listener) {
|
|
189
|
+
const listenerId = (0, common_1.uuid)();
|
|
190
|
+
this._listeners[listenerId] = { event, listener };
|
|
191
|
+
return listenerId;
|
|
192
|
+
}
|
|
193
|
+
/** @internal */
|
|
194
|
+
async emitEvent(event, ...args) {
|
|
195
|
+
const handlerActions = [];
|
|
196
|
+
for (const value of Object.values(this._listeners)) {
|
|
197
|
+
if (value.event !== event) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
handlerActions.push(value.listener(...args));
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
common_1.logger.error(error, `Error occurred while handling event '${event}' for queue '${this.name}'`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
await Promise.allSettled(handlerActions);
|
|
208
|
+
}
|
|
209
|
+
/** @internal */
|
|
210
|
+
processJobs() {
|
|
211
|
+
if (this._processing || this._paused || this._closed) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
this._processing = true;
|
|
215
|
+
this._processingTimeout = setTimeout(async () => {
|
|
216
|
+
try {
|
|
217
|
+
const waitingJobs = Array.from(this._jobs.values())
|
|
218
|
+
.filter((job) => job.status === 'waiting')
|
|
219
|
+
.sort((a, b) => a.createdAt - b.createdAt);
|
|
220
|
+
const availableWorkers = this._workers.filter((w) => w.active);
|
|
221
|
+
if (waitingJobs.length === 0 || availableWorkers.length === 0) {
|
|
222
|
+
this._processing = false;
|
|
223
|
+
if (waitingJobs.length === 0 && this._jobs.size > 0) {
|
|
224
|
+
const hasActiveJobs = Array.from(this._jobs.values()).some((job) => job.status === 'active');
|
|
225
|
+
if (!hasActiveJobs) {
|
|
226
|
+
await this.emitEvent('drained');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// Process jobs with available workers
|
|
232
|
+
const jobsToProcess = waitingJobs.slice(0, availableWorkers.length);
|
|
233
|
+
for (let i = 0; i < jobsToProcess.length; i++) {
|
|
234
|
+
const job = jobsToProcess[i];
|
|
235
|
+
const worker = availableWorkers[i];
|
|
236
|
+
await this.processJob(job, worker);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
finally {
|
|
240
|
+
this._processing = false;
|
|
241
|
+
// Continue processing if there are more jobs
|
|
242
|
+
if (!this._paused && !this._closed) {
|
|
243
|
+
this.processJobs();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}, 0);
|
|
247
|
+
}
|
|
248
|
+
/** @internal */
|
|
249
|
+
async processJob(job, worker) {
|
|
250
|
+
job.status = 'active';
|
|
251
|
+
job.processedAt = Date.now();
|
|
252
|
+
job.attempts++;
|
|
253
|
+
await this.emitEvent('active', job, job.status);
|
|
254
|
+
try {
|
|
255
|
+
const result = await worker.processor(job);
|
|
256
|
+
job.returnvalue = result;
|
|
257
|
+
job.status = 'completed';
|
|
258
|
+
job.finishedAt = Date.now();
|
|
259
|
+
await this.emitEvent('completed', job, result, 'active');
|
|
260
|
+
// Clean up completed job after a short delay
|
|
261
|
+
setTimeout(() => {
|
|
262
|
+
this._jobs.delete(job.id);
|
|
263
|
+
}, 1000);
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
job.error = error;
|
|
267
|
+
if (job.attempts >= job.maxAttempts) {
|
|
268
|
+
job.status = 'failed';
|
|
269
|
+
job.finishedAt = Date.now();
|
|
270
|
+
await this.emitEvent('failed', job, error, 'active');
|
|
271
|
+
// Clean up failed job after a short delay
|
|
272
|
+
setTimeout(() => {
|
|
273
|
+
this._jobs.delete(job.id);
|
|
274
|
+
}, 1000);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
// Retry the job
|
|
278
|
+
job.status = 'waiting';
|
|
279
|
+
await this.emitEvent('error', error);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./resource-loader"), exports);
|
|
18
|
+
__exportStar(require("./resource-routes"), exports);
|
|
19
|
+
__exportStar(require("./resource-schema"), exports);
|
|
20
|
+
__exportStar(require("./resource-service"), exports);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ResourceContext } from '../types';
|
|
2
|
+
export type LoadResourcePaths = {
|
|
3
|
+
/** Path pattern used for finding files that export resource models (default: `./src/resources/"*"/*model.ts`) */
|
|
4
|
+
modelPattern?: string;
|
|
5
|
+
/** Path pattern used for finding files that export resource models (default: `./src/resources/"*"/*service.ts`) */
|
|
6
|
+
servicePattern?: string;
|
|
7
|
+
/** Path pattern used for finding files that export resource models (default: `./src/resources/"*"/*policy.ts`) */
|
|
8
|
+
policyPattern?: string;
|
|
9
|
+
/** Path pattern used for finding files that export resource models (default: `./src/resources/"*"/*route.ts)` */
|
|
10
|
+
routePattern?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Loads application resources including models, services, policies, and routes.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} [baseDir] - Optional base directory path from which to load the resources.
|
|
16
|
+
* If not provided, defaults to the application's root directory.
|
|
17
|
+
* @param {LoadResourcePaths} [paths={}] Path patterns for loading resources: models, services, policies, and routes.
|
|
18
|
+
* @return {Promise<ResourceContext>} A promise that resolves to an object containing
|
|
19
|
+
* the loaded resources:
|
|
20
|
+
*
|
|
21
|
+
* - `models`: The application models.
|
|
22
|
+
* - `services`: The application services.
|
|
23
|
+
* - `policies`: The access policies.
|
|
24
|
+
* - `routes`: The application routes.
|
|
25
|
+
*/
|
|
26
|
+
export declare function loadResources(baseDir?: string, paths?: LoadResourcePaths): Promise<ResourceContext>;
|