jcc-express-mvc 1.8.7 → 1.8.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/Core/index.d.ts +4 -0
- package/Core/index.d.ts.map +1 -1
- package/Core/index.js +5 -0
- package/__tests__/Job.test.d.ts +2 -0
- package/__tests__/Job.test.d.ts.map +1 -0
- package/__tests__/Job.test.js +205 -0
- package/__tests__/MySqlSchemaBlueprint.test.d.ts +2 -0
- package/__tests__/MySqlSchemaBlueprint.test.d.ts.map +1 -0
- package/__tests__/MySqlSchemaBlueprint.test.js +55 -0
- package/__tests__/PostgresTranslator.test.d.ts +2 -0
- package/__tests__/PostgresTranslator.test.d.ts.map +1 -0
- package/__tests__/PostgresTranslator.test.js +82 -0
- package/__tests__/SQLiteTranslator.test.d.ts +2 -0
- package/__tests__/SQLiteTranslator.test.d.ts.map +1 -0
- package/__tests__/SQLiteTranslator.test.js +125 -0
- package/__tests__/SchemaAlterBlueprint.test.d.ts +2 -0
- package/__tests__/SchemaAlterBlueprint.test.d.ts.map +1 -0
- package/__tests__/SchemaAlterBlueprint.test.js +35 -0
- package/global.d.ts +3 -1
- package/index.d.ts +28 -3
- package/index.d.ts.map +1 -1
- package/index.js +33 -75
- package/lib/Application/Application.d.ts.map +1 -1
- package/lib/Application/Application.js +2 -2
- package/lib/Application/ApplicationBuilder.d.ts.map +1 -1
- package/lib/Application/ApplicationBuilder.js +22 -11
- package/lib/Auth/AuthMiddleware.d.ts.map +1 -1
- package/lib/Auth/AuthMiddleware.js +29 -12
- package/lib/Auth/index.d.ts +17 -3
- package/lib/Auth/index.d.ts.map +1 -1
- package/lib/Auth/index.js +128 -26
- package/lib/Auth/loginRateLimit.d.ts +6 -0
- package/lib/Auth/loginRateLimit.d.ts.map +1 -0
- package/lib/Auth/loginRateLimit.js +25 -0
- package/lib/Auth/refreshTokenStore.d.ts +24 -0
- package/lib/Auth/refreshTokenStore.d.ts.map +1 -0
- package/lib/Auth/refreshTokenStore.js +46 -0
- package/lib/Command-Line/DBCommand.d.ts.map +1 -1
- package/lib/Command-Line/DBCommand.js +9 -3
- package/lib/Command-Line/KeyGenerateCommand.d.ts +6 -0
- package/lib/Command-Line/KeyGenerateCommand.d.ts.map +1 -0
- package/lib/Command-Line/KeyGenerateCommand.js +47 -0
- package/lib/Command-Line/MakeCommand.d.ts +1 -0
- package/lib/Command-Line/MakeCommand.d.ts.map +1 -1
- package/lib/Command-Line/MakeCommand.js +36 -32
- package/lib/Command-Line/NodeArtisanCommand.d.ts +2 -0
- package/lib/Command-Line/NodeArtisanCommand.d.ts.map +1 -1
- package/lib/Command-Line/NodeArtisanCommand.js +24 -6
- package/lib/Command-Line/NodeTinker/Tinker.d.ts +5 -2
- package/lib/Command-Line/NodeTinker/Tinker.d.ts.map +1 -1
- package/lib/Command-Line/NodeTinker/Tinker.js +13 -3
- package/lib/Command-Line/WatchCommand.d.ts +29 -0
- package/lib/Command-Line/WatchCommand.d.ts.map +1 -0
- package/lib/Command-Line/WatchCommand.js +234 -0
- package/lib/Command-Line/files/Models.d.ts.map +1 -1
- package/lib/Command-Line/files/Models.js +67 -0
- package/lib/Console/Command.d.ts +18 -0
- package/lib/Console/Command.d.ts.map +1 -1
- package/lib/Console/Command.js +29 -0
- package/lib/Container/index.d.ts.map +1 -1
- package/lib/Container/index.js +22 -8
- package/lib/Database/Database.d.ts +21 -0
- package/lib/Database/Database.d.ts.map +1 -0
- package/lib/Database/Database.js +55 -0
- package/lib/Database/DatabaseServiceProvider.d.ts +22 -0
- package/lib/Database/DatabaseServiceProvider.d.ts.map +1 -0
- package/lib/Database/DatabaseServiceProvider.js +50 -0
- package/lib/Database/Drivers/KnexDriver.d.ts +13 -0
- package/lib/Database/Drivers/KnexDriver.d.ts.map +1 -0
- package/lib/Database/Drivers/KnexDriver.js +29 -0
- package/lib/Database/Drivers/MongooseDriver.d.ts +20 -0
- package/lib/Database/Drivers/MongooseDriver.d.ts.map +1 -0
- package/lib/Database/Drivers/MongooseDriver.js +57 -0
- package/lib/Database/Drivers/SequelizeDriver.d.ts +24 -0
- package/lib/Database/Drivers/SequelizeDriver.d.ts.map +1 -0
- package/lib/Database/Drivers/SequelizeDriver.js +82 -0
- package/lib/Database/index.d.ts +7 -0
- package/lib/Database/index.d.ts.map +1 -0
- package/lib/Database/index.js +11 -0
- package/lib/Database/interface.d.ts +14 -0
- package/lib/Database/interface.d.ts.map +1 -0
- package/lib/Database/interface.js +2 -0
- package/lib/Database/type.d.ts +18 -0
- package/lib/Database/type.d.ts.map +1 -0
- package/lib/Database/type.js +2 -0
- package/lib/Error/DisplayErrorCode.d.ts.map +1 -1
- package/lib/Error/DisplayErrorCode.js +27 -17
- package/lib/Error/MissMatchTokenException/index.d.ts +4 -0
- package/lib/Error/MissMatchTokenException/index.d.ts.map +1 -0
- package/lib/Error/MissMatchTokenException/index.js +9 -0
- package/lib/Error/SocialiteAuthError/SocialiteAuthError.d.ts +9 -0
- package/lib/Error/SocialiteAuthError/SocialiteAuthError.d.ts.map +1 -0
- package/lib/Error/SocialiteAuthError/SocialiteAuthError.js +17 -0
- package/lib/Global/helpers.d.ts.map +1 -1
- package/lib/Global/helpers.js +7 -6
- package/lib/Http/index.d.ts +3 -1
- package/lib/Http/index.d.ts.map +1 -1
- package/lib/Http/index.js +26 -5
- package/lib/Interface/index.d.ts +17 -3
- package/lib/Interface/index.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Builder.d.ts +12 -1
- package/lib/Jcc-eloquent/lib/Builder.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Builder.js +119 -5
- package/lib/Jcc-eloquent/lib/Database/index.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Database/index.js +2 -1
- package/lib/Jcc-eloquent/lib/Interfaces/index.d.ts +37 -2
- package/lib/Jcc-eloquent/lib/Interfaces/index.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Migration.d.ts +6 -0
- package/lib/Jcc-eloquent/lib/Migration.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Migration.js +24 -2
- package/lib/Jcc-eloquent/lib/Model.d.ts +24 -7
- package/lib/Jcc-eloquent/lib/Model.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Model.js +35 -2
- package/lib/Jcc-eloquent/lib/QueryBuilder.d.ts +2 -1
- package/lib/Jcc-eloquent/lib/QueryBuilder.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/QueryBuilder.js +10 -1
- package/lib/Jcc-eloquent/lib/Rollback.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Rollback.js +9 -2
- package/lib/Jcc-eloquent/lib/Schema/BaseSchemaEntity/index.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Schema/BaseSchemaEntity/index.js +3 -3
- package/lib/Jcc-eloquent/lib/Schema/BluePrint/index.d.ts +6 -2
- package/lib/Jcc-eloquent/lib/Schema/BluePrint/index.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Schema/BluePrint/index.js +41 -12
- package/lib/Jcc-eloquent/lib/Schema/Translator/Sqlite.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Schema/Translator/Sqlite.js +21 -3
- package/lib/Jcc-eloquent/lib/Schema/Translator/postgres.d.ts +1 -0
- package/lib/Jcc-eloquent/lib/Schema/Translator/postgres.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Schema/Translator/postgres.js +70 -14
- package/lib/Jcc-eloquent/lib/Schema/index.d.ts +12 -0
- package/lib/Jcc-eloquent/lib/Schema/index.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/Schema/index.js +27 -6
- package/lib/Jcc-eloquent/lib/utils/index.d.ts +13 -0
- package/lib/Jcc-eloquent/lib/utils/index.d.ts.map +1 -1
- package/lib/Jcc-eloquent/lib/utils/index.js +62 -0
- package/lib/Middleware/index.d.ts +1 -0
- package/lib/Middleware/index.d.ts.map +1 -1
- package/lib/Middleware/index.js +20 -8
- package/lib/Model/Sequelize.d.ts +3 -0
- package/lib/Model/Sequelize.d.ts.map +1 -0
- package/lib/Model/Sequelize.js +6 -0
- package/lib/Providers/RouteServiceProvider.d.ts.map +1 -1
- package/lib/Providers/RouteServiceProvider.js +3 -0
- package/lib/Providers/SessionServiceProvider.d.ts +12 -0
- package/lib/Providers/SessionServiceProvider.d.ts.map +1 -0
- package/lib/Providers/SessionServiceProvider.js +47 -0
- package/lib/Queue/Controllers/QueueControllers.d.ts +31 -0
- package/lib/Queue/Controllers/QueueControllers.d.ts.map +1 -0
- package/lib/Queue/Controllers/QueueControllers.js +126 -0
- package/lib/Queue/Drivers/DatabaseDriver.d.ts +6 -1
- package/lib/Queue/Drivers/DatabaseDriver.d.ts.map +1 -1
- package/lib/Queue/Drivers/DatabaseDriver.js +76 -21
- package/lib/Queue/Drivers/MemoryDriver.d.ts +17 -6
- package/lib/Queue/Drivers/MemoryDriver.d.ts.map +1 -1
- package/lib/Queue/Drivers/MemoryDriver.js +323 -14
- package/lib/Queue/Drivers/RedisDriver.d.ts +48 -0
- package/lib/Queue/Drivers/RedisDriver.d.ts.map +1 -0
- package/lib/Queue/Drivers/RedisDriver.js +533 -0
- package/lib/Queue/Job.d.ts +8 -0
- package/lib/Queue/Job.d.ts.map +1 -1
- package/lib/Queue/Job.js +25 -1
- package/lib/Queue/JobsLogger.d.ts.map +1 -1
- package/lib/Queue/JobsLogger.js +6 -3
- package/lib/Queue/Queue.d.ts +17 -0
- package/lib/Queue/Queue.d.ts.map +1 -1
- package/lib/Queue/Queue.js +146 -11
- package/lib/Queue/QueueServiceProvider.d.ts +6 -0
- package/lib/Queue/QueueServiceProvider.d.ts.map +1 -0
- package/lib/Queue/QueueServiceProvider.js +18 -0
- package/lib/Queue/Route/web.d.ts +2 -0
- package/lib/Queue/Route/web.d.ts.map +1 -0
- package/lib/Queue/Route/web.js +16 -0
- package/lib/Queue/index.d.ts +1 -0
- package/lib/Queue/index.d.ts.map +1 -1
- package/lib/Queue/index.js +3 -0
- package/lib/Queue/interface.d.ts +25 -0
- package/lib/Queue/interface.d.ts.map +1 -1
- package/lib/Queue/middleware/queueDashboardGuard.d.ts +7 -0
- package/lib/Queue/middleware/queueDashboardGuard.d.ts.map +1 -0
- package/lib/Queue/middleware/queueDashboardGuard.js +43 -0
- package/lib/Queue/type.d.ts +12 -1
- package/lib/Queue/type.d.ts.map +1 -1
- package/lib/Response/index.d.ts.map +1 -1
- package/lib/Response/index.js +6 -1
- package/lib/Routes/Route.d.ts +2 -2
- package/lib/Routes/Route.d.ts.map +1 -1
- package/lib/Routes/RouteBuilder.d.ts +2 -2
- package/lib/Routes/RouteBuilder.d.ts.map +1 -1
- package/lib/Security/CsrfMiddleware.d.ts +37 -0
- package/lib/Security/CsrfMiddleware.d.ts.map +1 -0
- package/lib/Security/CsrfMiddleware.js +85 -0
- package/lib/Security/MethodSpoofingMiddleware.d.ts +36 -0
- package/lib/Security/MethodSpoofingMiddleware.d.ts.map +1 -0
- package/lib/Security/MethodSpoofingMiddleware.js +51 -0
- package/lib/Security/index.d.ts +5 -0
- package/lib/Security/index.d.ts.map +1 -0
- package/lib/Security/index.js +7 -0
- package/lib/Session/DatabaseSession.d.ts +9 -3
- package/lib/Session/DatabaseSession.d.ts.map +1 -1
- package/lib/Session/DatabaseSession.js +38 -36
- package/lib/Session/ExpressJccSession.d.ts +23 -0
- package/lib/Session/ExpressJccSession.d.ts.map +1 -0
- package/lib/Session/ExpressJccSession.js +110 -0
- package/lib/Session/RedisSession.d.ts +2 -2
- package/lib/Session/RedisSession.d.ts.map +1 -1
- package/lib/Session/RedisSession.js +19 -5
- package/lib/Session/SessionManager.d.ts +18 -4
- package/lib/Session/SessionManager.d.ts.map +1 -1
- package/lib/Session/SessionManager.js +53 -17
- package/lib/Socialite/AbstractProvider.d.ts +60 -0
- package/lib/Socialite/AbstractProvider.d.ts.map +1 -0
- package/lib/Socialite/AbstractProvider.js +136 -0
- package/lib/Socialite/Drivers/facebook/FacebookDriver.d.ts +9 -0
- package/lib/Socialite/Drivers/facebook/FacebookDriver.d.ts.map +1 -0
- package/lib/Socialite/Drivers/facebook/FacebookDriver.js +40 -0
- package/lib/Socialite/Drivers/facebook/FacebookProvider.d.ts +15 -0
- package/lib/Socialite/Drivers/facebook/FacebookProvider.d.ts.map +1 -0
- package/lib/Socialite/Drivers/facebook/FacebookProvider.js +28 -0
- package/lib/Socialite/Drivers/github/GitHubDriver.d.ts +9 -0
- package/lib/Socialite/Drivers/github/GitHubDriver.d.ts.map +1 -0
- package/lib/Socialite/Drivers/github/GitHubDriver.js +54 -0
- package/lib/Socialite/Drivers/github/GitHubProvider.d.ts +15 -0
- package/lib/Socialite/Drivers/github/GitHubProvider.d.ts.map +1 -0
- package/lib/Socialite/Drivers/github/GitHubProvider.js +28 -0
- package/lib/Socialite/Drivers/gitlab/GitLabDriver.d.ts +10 -0
- package/lib/Socialite/Drivers/gitlab/GitLabDriver.d.ts.map +1 -0
- package/lib/Socialite/Drivers/gitlab/GitLabDriver.js +37 -0
- package/lib/Socialite/Drivers/gitlab/GitLabProvider.d.ts +15 -0
- package/lib/Socialite/Drivers/gitlab/GitLabProvider.d.ts.map +1 -0
- package/lib/Socialite/Drivers/gitlab/GitLabProvider.js +28 -0
- package/lib/Socialite/Drivers/google/GoogleDriver.d.ts +9 -0
- package/lib/Socialite/Drivers/google/GoogleDriver.d.ts.map +1 -0
- package/lib/Socialite/Drivers/google/GoogleDriver.js +39 -0
- package/lib/Socialite/Drivers/google/GoogleProvider.d.ts +15 -0
- package/lib/Socialite/Drivers/google/GoogleProvider.d.ts.map +1 -0
- package/lib/Socialite/Drivers/google/GoogleProvider.js +28 -0
- package/lib/Socialite/Drivers/slack/SlackDriver.d.ts +9 -0
- package/lib/Socialite/Drivers/slack/SlackDriver.d.ts.map +1 -0
- package/lib/Socialite/Drivers/slack/SlackDriver.js +41 -0
- package/lib/Socialite/Drivers/slack/SlackProvider.d.ts +16 -0
- package/lib/Socialite/Drivers/slack/SlackProvider.d.ts.map +1 -0
- package/lib/Socialite/Drivers/slack/SlackProvider.js +37 -0
- package/lib/Socialite/Drivers/twitter/TwitterDriver.d.ts +9 -0
- package/lib/Socialite/Drivers/twitter/TwitterDriver.d.ts.map +1 -0
- package/lib/Socialite/Drivers/twitter/TwitterDriver.js +57 -0
- package/lib/Socialite/Drivers/twitter/TwitterProvider.d.ts +16 -0
- package/lib/Socialite/Drivers/twitter/TwitterProvider.d.ts.map +1 -0
- package/lib/Socialite/Drivers/twitter/TwitterProvider.js +38 -0
- package/lib/Socialite/SocialUser.d.ts +42 -0
- package/lib/Socialite/SocialUser.d.ts.map +1 -0
- package/lib/Socialite/SocialUser.js +116 -0
- package/lib/Socialite/Socialite.d.ts +13 -0
- package/lib/Socialite/Socialite.d.ts.map +1 -0
- package/lib/Socialite/Socialite.js +41 -0
- package/lib/Socialite/SocialiteProvider.d.ts +9 -0
- package/lib/Socialite/SocialiteProvider.d.ts.map +1 -0
- package/lib/Socialite/SocialiteProvider.js +15 -0
- package/lib/Socialite/config.d.ts +7 -0
- package/lib/Socialite/config.d.ts.map +1 -0
- package/lib/Socialite/config.js +44 -0
- package/lib/Socialite/constant.d.ts +18 -0
- package/lib/Socialite/constant.d.ts.map +1 -0
- package/lib/Socialite/constant.js +20 -0
- package/lib/Socialite/index.d.ts +13 -0
- package/lib/Socialite/index.d.ts.map +1 -0
- package/lib/Socialite/index.js +25 -0
- package/lib/Socialite/types.d.ts +13 -0
- package/lib/Socialite/types.d.ts.map +1 -0
- package/lib/Socialite/types.js +2 -0
- package/lib/Templating-engine/benchmark.d.ts +7 -0
- package/lib/Templating-engine/benchmark.d.ts.map +1 -0
- package/lib/Templating-engine/benchmark.js +44 -0
- package/lib/Templating-engine/engineHelper.d.ts +37 -8
- package/lib/Templating-engine/engineHelper.d.ts.map +1 -1
- package/lib/Templating-engine/engineHelper.js +203 -26
- package/lib/Templating-engine/errors.d.ts +15 -0
- package/lib/Templating-engine/errors.d.ts.map +1 -0
- package/lib/Templating-engine/errors.js +35 -0
- package/lib/Templating-engine/expressions.d.ts +24 -0
- package/lib/Templating-engine/expressions.d.ts.map +1 -1
- package/lib/Templating-engine/expressions.js +27 -5
- package/lib/Templating-engine/index.d.ts +87 -17
- package/lib/Templating-engine/index.d.ts.map +1 -1
- package/lib/Templating-engine/index.js +701 -96
- package/lib/Templating-engine/plugins.d.ts +30 -0
- package/lib/Templating-engine/plugins.d.ts.map +1 -0
- package/lib/Templating-engine/plugins.js +47 -0
- package/lib/Type/index.d.ts +1 -0
- package/lib/Type/index.d.ts.map +1 -1
- package/lib/Validation/Validator/CustomValidation.d.ts.map +1 -1
- package/lib/Validation/Validator/CustomValidation.js +2 -2
- package/lib/Validation/Validator/helper.d.ts.map +1 -1
- package/lib/Validation/Validator/helper.js +8 -1
- package/lib/util/index.d.ts +42 -1
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +154 -17
- package/package.json +1 -1
package/lib/Queue/Queue.js
CHANGED
|
@@ -15,14 +15,27 @@ class Queue {
|
|
|
15
15
|
this.events = new events_1.default();
|
|
16
16
|
this.jobClasses = {};
|
|
17
17
|
this.driver = this.resolveDriver(config);
|
|
18
|
+
this.processSync = config.processSync ?? false;
|
|
19
|
+
if (config.queue) {
|
|
20
|
+
this.defaultQueue = config.queue;
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
23
|
resolveDriver(config) {
|
|
20
24
|
switch (config.driver) {
|
|
21
25
|
case "database":
|
|
22
26
|
return new DatabaseDriver_1.DatabaseDriver();
|
|
27
|
+
case "redis": {
|
|
28
|
+
const { RedisDriver } = require("./Drivers/RedisDriver");
|
|
29
|
+
return new RedisDriver(config);
|
|
30
|
+
}
|
|
23
31
|
case "memory":
|
|
24
|
-
default:
|
|
25
|
-
|
|
32
|
+
default: {
|
|
33
|
+
const memoryConfig = config.memory ?? { queue: "default" };
|
|
34
|
+
return new MemoryDriver_1.MemoryDriver({
|
|
35
|
+
defaultQueue: memoryConfig.queue ?? config.queue ?? "default",
|
|
36
|
+
file: memoryConfig.file,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
26
39
|
}
|
|
27
40
|
}
|
|
28
41
|
/**
|
|
@@ -41,6 +54,7 @@ class Queue {
|
|
|
41
54
|
queue,
|
|
42
55
|
payload: {
|
|
43
56
|
job: job.constructor.name,
|
|
57
|
+
path: job.jobPath,
|
|
44
58
|
data: job.data,
|
|
45
59
|
maxAttempts: job.maxAttempts,
|
|
46
60
|
timeout: job.timeout,
|
|
@@ -51,8 +65,11 @@ class Queue {
|
|
|
51
65
|
availableAt: new Date(),
|
|
52
66
|
createdAt: new Date(),
|
|
53
67
|
};
|
|
54
|
-
this.jobClasses[job.constructor.name] = job;
|
|
68
|
+
this.jobClasses[job.constructor.name] = job.constructor;
|
|
55
69
|
await this.driver.push(queuedJob, queue);
|
|
70
|
+
if (this.processSync) {
|
|
71
|
+
await this.processNext(queue);
|
|
72
|
+
}
|
|
56
73
|
return queuedJob.id;
|
|
57
74
|
}
|
|
58
75
|
/**
|
|
@@ -65,6 +82,7 @@ class Queue {
|
|
|
65
82
|
queue,
|
|
66
83
|
payload: {
|
|
67
84
|
job: job.constructor.name,
|
|
85
|
+
path: job.jobPath,
|
|
68
86
|
data: job.data,
|
|
69
87
|
maxAttempts: job.maxAttempts,
|
|
70
88
|
timeout: job.timeout,
|
|
@@ -75,7 +93,11 @@ class Queue {
|
|
|
75
93
|
availableAt: new Date(Date.now() + delay * 1000),
|
|
76
94
|
createdAt: new Date(),
|
|
77
95
|
};
|
|
96
|
+
this.jobClasses[job.constructor.name] = job.constructor;
|
|
78
97
|
await this.driver.later(queuedJob, delay, queue);
|
|
98
|
+
if (this.processSync && delay <= 0) {
|
|
99
|
+
await this.processNext(queue);
|
|
100
|
+
}
|
|
79
101
|
return queuedJob.id;
|
|
80
102
|
}
|
|
81
103
|
/**
|
|
@@ -88,10 +110,10 @@ class Queue {
|
|
|
88
110
|
// console.log(`[Queue] No jobs found in queue: ${queue}`);
|
|
89
111
|
return false;
|
|
90
112
|
}
|
|
91
|
-
console.log(`[Queue] Processing job: ${queuedJob.id}`);
|
|
92
113
|
const payload = JSON.parse(queuedJob.payload);
|
|
93
114
|
try {
|
|
94
|
-
const
|
|
115
|
+
const jobPath = payload.path || payload.job;
|
|
116
|
+
const JobClass = this.jobClasses[payload.job] || (0, util_1.getJobClass)(jobPath);
|
|
95
117
|
if (!JobClass) {
|
|
96
118
|
throw new Error(`Unknown job class: ${payload.job}`);
|
|
97
119
|
}
|
|
@@ -109,14 +131,17 @@ class Queue {
|
|
|
109
131
|
queuedJob.maxAttempts = job.maxAttempts;
|
|
110
132
|
queuedJob.timeout = job.timeout;
|
|
111
133
|
await job.handle();
|
|
112
|
-
await this.driver.
|
|
134
|
+
await this.driver.updateStatus(queuedJob.id, {
|
|
135
|
+
status: "completed",
|
|
136
|
+
finishedAt: new Date(),
|
|
137
|
+
});
|
|
113
138
|
logger.success();
|
|
114
139
|
return true;
|
|
115
140
|
}
|
|
116
141
|
catch (error) {
|
|
117
|
-
console.error(`[Queue] Error processing job ${queuedJob.id}:`, error);
|
|
118
142
|
// Handle failure
|
|
119
|
-
const
|
|
143
|
+
const jobPath = payload.path || payload.job;
|
|
144
|
+
const JobClass = this.jobClasses[payload.job] || (0, util_1.getJobClass)(jobPath);
|
|
120
145
|
const job = app.make(JobClass, [payload.data]);
|
|
121
146
|
const logger = new JobsLogger_1.JobLogger(job);
|
|
122
147
|
if (job) {
|
|
@@ -141,10 +166,12 @@ class Queue {
|
|
|
141
166
|
await this.driver.release(queuedJob, delay);
|
|
142
167
|
}
|
|
143
168
|
else {
|
|
144
|
-
//
|
|
169
|
+
// Mark as failed in jobs table
|
|
170
|
+
await this.driver.updateStatus(queuedJob.id, {
|
|
171
|
+
status: "failed",
|
|
172
|
+
failedAt: new Date(),
|
|
173
|
+
});
|
|
145
174
|
await this.driver.failed(queuedJob, error);
|
|
146
|
-
// Remove from the main jobs table since it has officially failed
|
|
147
|
-
await this.driver.delete(queuedJob.id);
|
|
148
175
|
}
|
|
149
176
|
}
|
|
150
177
|
/**
|
|
@@ -169,5 +196,113 @@ class Queue {
|
|
|
169
196
|
}
|
|
170
197
|
}
|
|
171
198
|
}
|
|
199
|
+
async getQueues() {
|
|
200
|
+
return await this.driver.getQueues();
|
|
201
|
+
}
|
|
202
|
+
async findQueueById(id) {
|
|
203
|
+
return await this.driver.findQueueById(id);
|
|
204
|
+
}
|
|
205
|
+
async findQueueBy(key, value) {
|
|
206
|
+
return await this.driver.findQueueBy(key, value);
|
|
207
|
+
}
|
|
208
|
+
/** Delete a job by ID (for dashboard manual delete). */
|
|
209
|
+
async deleteJob(jobId) {
|
|
210
|
+
await this.driver.delete(jobId);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Retry a failed job — removes it from failed state, re-queues, and runs it immediately.
|
|
214
|
+
* Returns the new job ID on success, or null if the job was not found.
|
|
215
|
+
*/
|
|
216
|
+
async retry(jobId) {
|
|
217
|
+
const record = await this.driver.findQueueById(jobId);
|
|
218
|
+
if (!record)
|
|
219
|
+
return null;
|
|
220
|
+
const payload = typeof record.payload === "string"
|
|
221
|
+
? JSON.parse(record.payload)
|
|
222
|
+
: record.payload;
|
|
223
|
+
await this.driver.delete(jobId);
|
|
224
|
+
const newId = crypto.randomUUID();
|
|
225
|
+
const queuedJob = {
|
|
226
|
+
id: newId,
|
|
227
|
+
queue: record.queue || this.defaultQueue,
|
|
228
|
+
status: "pending",
|
|
229
|
+
payload,
|
|
230
|
+
attempts: 0,
|
|
231
|
+
maxAttempts: payload.maxAttempts || 3,
|
|
232
|
+
timeout: payload.timeout || 60,
|
|
233
|
+
availableAt: new Date(),
|
|
234
|
+
createdAt: new Date(),
|
|
235
|
+
};
|
|
236
|
+
await this.driver.push(queuedJob, queuedJob.queue);
|
|
237
|
+
await this.runJob(newId);
|
|
238
|
+
return newId;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Run a specific job by ID immediately.
|
|
242
|
+
* Works for pending, failed, and processing jobs.
|
|
243
|
+
* Deletes the old record, executes handle(), then writes the final status.
|
|
244
|
+
*/
|
|
245
|
+
async runJob(jobId) {
|
|
246
|
+
const record = await this.driver.findQueueById(jobId);
|
|
247
|
+
if (!record)
|
|
248
|
+
return false;
|
|
249
|
+
const payload = typeof record.payload === "string"
|
|
250
|
+
? JSON.parse(record.payload)
|
|
251
|
+
: record.payload;
|
|
252
|
+
const queuedJob = {
|
|
253
|
+
id: jobId,
|
|
254
|
+
queue: record.queue || this.defaultQueue,
|
|
255
|
+
payload,
|
|
256
|
+
attempts: record.attempts || 0,
|
|
257
|
+
maxAttempts: payload.maxAttempts || 3,
|
|
258
|
+
timeout: payload.timeout || 60,
|
|
259
|
+
availableAt: new Date(),
|
|
260
|
+
createdAt: record.created_at ? new Date(record.created_at) : new Date(),
|
|
261
|
+
};
|
|
262
|
+
await this.driver.delete(jobId);
|
|
263
|
+
try {
|
|
264
|
+
const jobPath = payload.path || payload.job;
|
|
265
|
+
const JobClass = this.jobClasses[payload.job] || (0, util_1.getJobClass)(jobPath);
|
|
266
|
+
if (!JobClass) {
|
|
267
|
+
throw new Error(`Unknown job class: ${payload.job}`);
|
|
268
|
+
}
|
|
269
|
+
const job = app.make(JobClass, [payload.data]);
|
|
270
|
+
if (!job) {
|
|
271
|
+
throw new Error(`Failed to instantiate job: ${payload.job}`);
|
|
272
|
+
}
|
|
273
|
+
const logger = new JobsLogger_1.JobLogger(job);
|
|
274
|
+
logger.processing();
|
|
275
|
+
job.id = jobId;
|
|
276
|
+
job.attempts = queuedJob.attempts;
|
|
277
|
+
job.maxAttempts = queuedJob.maxAttempts;
|
|
278
|
+
job.timeout = queuedJob.timeout;
|
|
279
|
+
queuedJob.maxAttempts = job.maxAttempts;
|
|
280
|
+
queuedJob.timeout = job.timeout;
|
|
281
|
+
await job.handle();
|
|
282
|
+
// Re-push so updateStatus has something to update
|
|
283
|
+
await this.driver.push(queuedJob, queuedJob.queue);
|
|
284
|
+
await this.driver.updateStatus(jobId, {
|
|
285
|
+
status: "completed",
|
|
286
|
+
finishedAt: new Date(),
|
|
287
|
+
});
|
|
288
|
+
logger.success();
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
const jobPath = payload.path || payload.job;
|
|
293
|
+
const JobClass = this.jobClasses[payload.job] || (0, util_1.getJobClass)(jobPath);
|
|
294
|
+
const job = app.make(JobClass, [payload.data]);
|
|
295
|
+
const logger = new JobsLogger_1.JobLogger(job);
|
|
296
|
+
if (job) {
|
|
297
|
+
job.id = jobId;
|
|
298
|
+
job.attempts = queuedJob.attempts;
|
|
299
|
+
}
|
|
300
|
+
// Re-push so handleFailedJob can update/release it
|
|
301
|
+
await this.driver.push(queuedJob, queuedJob.queue);
|
|
302
|
+
await this.handleFailedJob(queuedJob, error, job);
|
|
303
|
+
logger.failed(error);
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
172
307
|
}
|
|
173
308
|
exports.Queue = Queue;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueueServiceProvider.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Queue/QueueServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,qBAAa,oBAAqB,SAAQ,eAAe;IAChD,QAAQ,IAAI,IAAI;IAQhB,IAAI,IAAI,IAAI;CAGpB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueueServiceProvider = void 0;
|
|
4
|
+
const ServiceProvider_1 = require("../Providers/ServiceProvider");
|
|
5
|
+
const Queue_1 = require("./Queue");
|
|
6
|
+
class QueueServiceProvider extends ServiceProvider_1.ServiceProvider {
|
|
7
|
+
register() {
|
|
8
|
+
this.app.singleton("Queue", () => {
|
|
9
|
+
const queueConfig = this.app.config.queue;
|
|
10
|
+
const config = queueConfig.connections;
|
|
11
|
+
return new Queue_1.Queue({ ...config, driver: queueConfig?.driver });
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
boot() {
|
|
15
|
+
//
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.QueueServiceProvider = QueueServiceProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../../jcc-express-mvc/lib/Queue/Route/web.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Route_1 = require("../../Routes/Route");
|
|
4
|
+
const QueueControllers_1 = require("../Controllers/QueueControllers");
|
|
5
|
+
const queueDashboardGuard_1 = require("../middleware/queueDashboardGuard");
|
|
6
|
+
Route_1.Route.middleware([queueDashboardGuard_1.queueDashboardGuard])
|
|
7
|
+
.controller(QueueControllers_1.QueueControllers)
|
|
8
|
+
.group((Route) => {
|
|
9
|
+
Route.get("/dashboard", "dashboard");
|
|
10
|
+
Route.get("/jobs", "index");
|
|
11
|
+
Route.get("/jobs/{status}", "show");
|
|
12
|
+
Route.post("/jobs", "runJob");
|
|
13
|
+
Route.put("/jobs/{id}/{status}", "update");
|
|
14
|
+
Route.patch("/jobs/{id}/{status}", "update");
|
|
15
|
+
Route.delete("/jobs/{id}", "destroy");
|
|
16
|
+
});
|
package/lib/Queue/index.d.ts
CHANGED
package/lib/Queue/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Queue/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Queue/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC"}
|
package/lib/Queue/index.js
CHANGED
|
@@ -14,7 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.queueDashboardGuard = void 0;
|
|
17
18
|
__exportStar(require("./Queue"), exports);
|
|
18
19
|
__exportStar(require("./Job"), exports);
|
|
19
20
|
__exportStar(require("./type"), exports);
|
|
20
21
|
__exportStar(require("./interface"), exports);
|
|
22
|
+
var queueDashboardGuard_1 = require("./middleware/queueDashboardGuard");
|
|
23
|
+
Object.defineProperty(exports, "queueDashboardGuard", { enumerable: true, get: function () { return queueDashboardGuard_1.queueDashboardGuard; } });
|
package/lib/Queue/interface.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
export type JobStatus = "pending" | "processing" | "completed" | "failed";
|
|
1
2
|
export interface QueuedJob {
|
|
2
3
|
id: string;
|
|
3
4
|
queue: string;
|
|
4
5
|
payload: {
|
|
5
6
|
job: string;
|
|
7
|
+
path?: string;
|
|
6
8
|
data: any;
|
|
7
9
|
maxAttempts?: number;
|
|
8
10
|
timeout?: number;
|
|
@@ -12,8 +14,21 @@ export interface QueuedJob {
|
|
|
12
14
|
timeout: number;
|
|
13
15
|
availableAt: Date;
|
|
14
16
|
createdAt: Date;
|
|
17
|
+
status?: JobStatus;
|
|
18
|
+
startedAt?: Date;
|
|
19
|
+
finishedAt?: Date;
|
|
20
|
+
failedAt?: Date;
|
|
21
|
+
}
|
|
22
|
+
export interface JobStatusUpdate {
|
|
23
|
+
status: JobStatus;
|
|
24
|
+
startedAt?: Date;
|
|
25
|
+
finishedAt?: Date;
|
|
26
|
+
failedAt?: Date;
|
|
15
27
|
}
|
|
16
28
|
export interface QueueDriver {
|
|
29
|
+
getQueues(): Promise<any[]>;
|
|
30
|
+
findQueueById(id: string): Promise<any>;
|
|
31
|
+
findQueueBy(key: string, value: any): Promise<any[]>;
|
|
17
32
|
/**
|
|
18
33
|
* Push a job onto the queue
|
|
19
34
|
*/
|
|
@@ -38,11 +53,20 @@ export interface QueueDriver {
|
|
|
38
53
|
* Mark a job as failed
|
|
39
54
|
*/
|
|
40
55
|
failed(job: QueuedJob, error: any): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Update job status (processing, completed, failed) with started_at, finished_at, failed_at.
|
|
58
|
+
*/
|
|
59
|
+
updateStatus(jobId: string, update: JobStatusUpdate): Promise<void>;
|
|
41
60
|
}
|
|
42
61
|
export interface QueueItem {
|
|
43
62
|
id: string;
|
|
44
63
|
job: QueuedJob;
|
|
45
64
|
availableAt: number;
|
|
65
|
+
status?: JobStatus;
|
|
66
|
+
startedAt?: number;
|
|
67
|
+
finishedAt?: number;
|
|
68
|
+
failedAt?: number;
|
|
69
|
+
exception?: string;
|
|
46
70
|
}
|
|
47
71
|
export interface FailedItem {
|
|
48
72
|
id: string;
|
|
@@ -52,5 +76,6 @@ export interface FailedItem {
|
|
|
52
76
|
stack?: string;
|
|
53
77
|
};
|
|
54
78
|
failedAt: number;
|
|
79
|
+
exception?: string;
|
|
55
80
|
}
|
|
56
81
|
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Queue/interface.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,GAAG,CAAC;QACV,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,IAAI,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;OAEG;IACH,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Queue/interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AppNext, AppRequest, AppResponse } from "../../Interface";
|
|
2
|
+
/**
|
|
3
|
+
* Protects all `/queue/*` routes: in non-local env runs session auth then `viewJobs` gate.
|
|
4
|
+
* In `APP_ENV=local`, skips checks (development convenience).
|
|
5
|
+
*/
|
|
6
|
+
export declare function queueDashboardGuard(req: AppRequest, res: AppResponse, next: AppNext): void;
|
|
7
|
+
//# sourceMappingURL=queueDashboardGuard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queueDashboardGuard.d.ts","sourceRoot":"","sources":["../../../../jcc-express-mvc/lib/Queue/middleware/queueDashboardGuard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAQxE;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,OAAO,GACZ,IAAI,CA4BN"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.queueDashboardGuard = queueDashboardGuard;
|
|
4
|
+
const Config_1 = require("../../Config/Config");
|
|
5
|
+
const Authorization_1 = require("../../Authorization");
|
|
6
|
+
const AuthMiddleware_1 = require("../../Auth/AuthMiddleware");
|
|
7
|
+
const VIEW_JOBS_ABILITY = "viewJobs";
|
|
8
|
+
function isLocalEnv() {
|
|
9
|
+
return String(Config_1.config.get("APP_ENV", "") ?? "").toLowerCase() === "local";
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Protects all `/queue/*` routes: in non-local env runs session auth then `viewJobs` gate.
|
|
13
|
+
* In `APP_ENV=local`, skips checks (development convenience).
|
|
14
|
+
*/
|
|
15
|
+
function queueDashboardGuard(req, res, next) {
|
|
16
|
+
if (isLocalEnv()) {
|
|
17
|
+
next();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
void AuthMiddleware_1.authMiddleware.auth(req, res, () => {
|
|
21
|
+
void (async () => {
|
|
22
|
+
try {
|
|
23
|
+
const user = req.user;
|
|
24
|
+
if (!user) {
|
|
25
|
+
req.jccSession?.put("redirect", req.originalUrl || req.url || "/");
|
|
26
|
+
return res.redirect(303, `/login?redirect=${encodeURIComponent(req.originalUrl || req.url || "/")}`);
|
|
27
|
+
}
|
|
28
|
+
if (!(await Authorization_1.GateFacade.can(user, VIEW_JOBS_ABILITY))) {
|
|
29
|
+
if (req.expectsJson() && !req.isInertia()) {
|
|
30
|
+
return res
|
|
31
|
+
.status(403)
|
|
32
|
+
.json({ message: "This action is unauthorized." });
|
|
33
|
+
}
|
|
34
|
+
return res.status(403).send("Forbidden");
|
|
35
|
+
}
|
|
36
|
+
next();
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
next(e);
|
|
40
|
+
}
|
|
41
|
+
})();
|
|
42
|
+
});
|
|
43
|
+
}
|
package/lib/Queue/type.d.ts
CHANGED
|
@@ -10,14 +10,25 @@ export type JobType = {
|
|
|
10
10
|
};
|
|
11
11
|
export type QueueConfig = {
|
|
12
12
|
driver: "memory" | "redis" | "database";
|
|
13
|
-
connection?:
|
|
13
|
+
connection?: string | {
|
|
14
|
+
host?: string;
|
|
15
|
+
port?: number;
|
|
16
|
+
password?: string;
|
|
17
|
+
};
|
|
14
18
|
table?: string;
|
|
15
19
|
queue?: string;
|
|
20
|
+
prefix?: string;
|
|
16
21
|
retryAfter?: number;
|
|
22
|
+
/** Redis: seconds to block when waiting for jobs (BLPOP). Default 5. */
|
|
17
23
|
blockFor?: number;
|
|
24
|
+
/** When true (memory driver only), process jobs immediately on push. Use when not running a separate worker. */
|
|
25
|
+
processSync?: boolean;
|
|
26
|
+
/** Memory driver: file path to persist queue (enables queue:work across processes). e.g. "storage/queue.json" */
|
|
27
|
+
file?: string;
|
|
18
28
|
};
|
|
19
29
|
export interface JobData {
|
|
20
30
|
id?: string;
|
|
31
|
+
path?: string;
|
|
21
32
|
displayName?: string;
|
|
22
33
|
maxAttempts?: number;
|
|
23
34
|
timeout?: number;
|
package/lib/Queue/type.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Queue/type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IACxC,UAAU,CAAC,EAAE,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Queue/type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gHAAgH;IAChH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iHAAiH;IACjH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,IAAI,EAAE,GAAG,CAAC;CACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Response/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGvD;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAc;gBAClB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW;IAYtD;;;OAGG;IACH,SAAS,CAAC,WAAW;IAerB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,IAAI;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Response/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGvD;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAc;gBAClB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW;IAYtD;;;OAGG;IACH,SAAS,CAAC,WAAW;IAerB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,IAAI;CAQb"}
|
package/lib/Response/index.js
CHANGED
|
@@ -47,7 +47,12 @@ class HttpResponse {
|
|
|
47
47
|
// : this.response.redirect(303, reqUrls[0]);
|
|
48
48
|
}
|
|
49
49
|
with(message, type) {
|
|
50
|
-
this.request.
|
|
50
|
+
if (this.request.jccSession) {
|
|
51
|
+
this.request.jccSession.flash(type, message);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.request.flash(type, message);
|
|
55
|
+
}
|
|
51
56
|
return this;
|
|
52
57
|
}
|
|
53
58
|
}
|
package/lib/Routes/Route.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RequestHandler } from "express";
|
|
2
2
|
import { ResourceOption } from "../Interface/index";
|
|
3
|
-
import { Constructor,
|
|
3
|
+
import { Constructor, MiddlewareInput, RouteHandler } from "../Type";
|
|
4
4
|
export declare class Route<T extends Record<string, RequestHandler>> {
|
|
5
5
|
private static routeBuilder;
|
|
6
6
|
/**
|
|
@@ -20,7 +20,7 @@ export declare class Route<T extends Record<string, RequestHandler>> {
|
|
|
20
20
|
* @param {Array | function} middleware - Array of middleware functions.
|
|
21
21
|
* @returns {Route} - Returns the route instance.
|
|
22
22
|
*/
|
|
23
|
-
static middleware(middleware:
|
|
23
|
+
static middleware(middleware: MiddlewareInput): typeof Route;
|
|
24
24
|
/**
|
|
25
25
|
* Groups routes using a callback function.
|
|
26
26
|
* @param {Function} callback - Callback function for defining grouped routes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Route.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Routes/Route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,
|
|
1
|
+
{"version":3,"file":"Route.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Routes/Route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EACL,WAAW,EAGX,eAAe,EACf,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,qBAAa,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IACzD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAqC;IAEhE;;;;OAIG;WACW,UAAU,CAAC,UAAU,EAAE,GAAG,GAAG,OAAO,KAAK;IAOvD;;;;OAIG;WACW,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,KAAK;IAK/C;;;;OAIG;WACW,UAAU,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,KAAK;IAKnE;;;;OAIG;WACW,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,KAAK,IAAI,GAAG,OAAO,KAAK;IAQ3E;;;;;OAKG;WACW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAS5D;;;;;OAKG;WACW,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI7D;;;;;OAKG;WACW,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI9D;;;;;OAKG;WACW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI5D;;;;;OAKG;WACW,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;WAIjD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;WAM7C,QAAQ,CACpB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,WAAW,CAAC,GAAG,CAAC,EAC5B,MAAM,GAAE,cAAyC;WAarC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAMnC,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAOnC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Application as ExpressApplication, RequestHandler } from "express";
|
|
2
2
|
import { BaseController, ExpressCallback, MethodsInterface, ResourceOption } from "../Interface";
|
|
3
|
-
import { HttpMethodType, HttpRoutes,
|
|
3
|
+
import { HttpMethodType, HttpRoutes, MiddlewareInput, ObjectType, RouteHandler } from "../Type";
|
|
4
4
|
import type { Application } from "../Application/Application";
|
|
5
5
|
export declare class RouteBuilder {
|
|
6
6
|
private static middlewareStack;
|
|
@@ -18,7 +18,7 @@ export declare class RouteBuilder {
|
|
|
18
18
|
static validateResourceOption(option: ResourceOption, methods: ObjectType): boolean | ObjectType;
|
|
19
19
|
static setPrefix(prefix: string): void;
|
|
20
20
|
private static replaceRouteParameters;
|
|
21
|
-
static setMiddle(middleware:
|
|
21
|
+
static setMiddle(middleware: MiddlewareInput): number | RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>[] | undefined;
|
|
22
22
|
static setController(Controller: new (...args: any[]) => any): void;
|
|
23
23
|
static buildRoute(httpMethod: HttpMethodType, url: string, callback: RouteHandler): void;
|
|
24
24
|
static setServiceContainer(container: Application): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteBuilder.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Routes/RouteBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAIL,cAAc,EACd,eAAe,EAEf,gBAAgB,EAChB,cAAc,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,UAAU,
|
|
1
|
+
{"version":3,"file":"RouteBuilder.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Routes/RouteBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAIL,cAAc,EACd,eAAe,EAEf,gBAAgB,EAChB,cAAc,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,UAAU,EAEV,eAAe,EACf,UAAU,EACV,YAAY,EACb,MAAM,SAAS,CAAC;AAMjB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAG9D,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,eAAe,CAA0B;IACxD,OAAO,CAAC,MAAM,CAAC,UAAU,CAAwB;IACjD,OAAO,CAAC,MAAM,CAAC,MAAM,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAS;IACjC,SAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC;IAC/C,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,cAAc,CAAC;IAC5C,OAAO,CAAC,MAAM,CAAC,MAAM,CAAkB;WAEzB,UAAU;WAKV,QAAQ;IAItB,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAOpC,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB;WAahD,YAAY,CAAC,GAAG,EAAE,MAAM;WAIxB,sBAAsB,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,UAAU,GAClB,OAAO,GAAG,UAAU;WAmBT,SAAS,CAAC,MAAM,EAAE,MAAM;IAItC,OAAO,CAAC,MAAM,CAAC,sBAAsB;WAKvB,SAAS,CAAC,UAAU,EAAE,eAAe;WA4BrC,aAAa,CAAC,UAAU,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;WAIrD,UAAU,CACtB,UAAU,EAAE,cAAc,EAC1B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,YAAY;WA0BV,mBAAmB,CAAC,SAAS,EAAE,WAAW;IAIxD,SAAS,CAAC,MAAM,CAAC,QAAQ,CACvB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,cAAc,GAAG,cAAc,EAAE,GAC5C,GAAG;IASN,SAAS,CAAC,MAAM,CAAC,gBAAgB,CAC/B,QAAQ,EAAE,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,GACpC,eAAe;IAwBlB,OAAO,CAAC,MAAM,CAAC,cAAc;WAgCf,aAAa,CAAC,GAAG,EAAE,kBAAkB;IAoCnD,WAAkB,SAAS,IAAI,UAAU,CAExC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { AppNext, AppRequest, AppResponse } from "../Interface";
|
|
2
|
+
export interface CsrfOptions {
|
|
3
|
+
/** Routes to exclude from CSRF verification (supports string and regex). */
|
|
4
|
+
except?: (string | RegExp)[];
|
|
5
|
+
/** Session key used to store the token. Default: "_csrf_token" */
|
|
6
|
+
sessionKey?: string;
|
|
7
|
+
/** Name of the hidden form field. Default: "_token" */
|
|
8
|
+
fieldName?: string;
|
|
9
|
+
/** Name of the HTTP header to check. Default: "x-csrf-token" */
|
|
10
|
+
headerName?: string;
|
|
11
|
+
/** Token byte length (hex-encoded = 2x). Default: 32 */
|
|
12
|
+
tokenLength?: number;
|
|
13
|
+
/** Skip CSRF for API routes (paths starting with /api). Default: true */
|
|
14
|
+
skipApi?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* CSRF protection middleware.
|
|
18
|
+
*
|
|
19
|
+
* Generates a per-session token and validates it on unsafe HTTP methods.
|
|
20
|
+
* The token is available via:
|
|
21
|
+
* - `req.csrfToken()` (programmatic)
|
|
22
|
+
* - `res.locals._token` (for templates / @csrf directive)
|
|
23
|
+
*
|
|
24
|
+
* Usage in Kernel:
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { csrf } from "../../jcc-express-mvc";
|
|
27
|
+
* export class Kernel {
|
|
28
|
+
* public middlewares = [
|
|
29
|
+
* // ...session, cookieParser, etc.
|
|
30
|
+
* csrf(), // default options
|
|
31
|
+
* csrf({ except: ["/webhooks"] }), // with exclusions
|
|
32
|
+
* ];
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function csrf(options?: CsrfOptions): (req: AppRequest, res: AppResponse, next: AppNext) => void;
|
|
37
|
+
//# sourceMappingURL=CsrfMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CsrfMiddleware.d.ts","sourceRoot":"","sources":["../../../jcc-express-mvc/lib/Security/CsrfMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhE,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC7B,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,IAUpC,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,UAkDzD"}
|