@appconda/nextjs 1.0.131 → 1.0.132
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/modules/hooks/index.d.ts +3 -0
- package/dist/modules/hooks/index.js +4 -0
- package/dist/modules/hooks/lib/Hooks.d.ts +32 -0
- package/dist/modules/hooks/lib/Hooks.js +64 -0
- package/dist/modules/hooks/lib/handler.d.ts +12 -0
- package/dist/modules/hooks/lib/handler.js +23 -0
- package/dist/modules/hooks/lib/jobs/index.d.ts +2 -0
- package/dist/modules/hooks/lib/jobs/index.js +3 -0
- package/dist/modules/hooks/lib/jobs/job1.d.ts +1 -0
- package/dist/modules/hooks/lib/jobs/job1.js +16 -0
- package/dist/modules/hooks/lib/jobs/log-job.d.ts +1 -0
- package/dist/modules/hooks/lib/jobs/log-job.js +9 -0
- package/dist/modules/hooks/lib/wait.d.ts +8 -0
- package/dist/modules/hooks/lib/wait.js +13 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +2 -1
- package/dist/modules/scheduled-job/action.d.ts +40 -1
- package/dist/modules/scheduled-job/action.js +26 -2
- package/dist/modules/scheduled-job/index.d.ts +3 -0
- package/dist/modules/scheduled-job/index.js +4 -1
- package/dist/modules/scheduled-job/lib/Schedules.d.ts +32 -0
- package/dist/modules/scheduled-job/lib/Schedules.js +64 -0
- package/dist/modules/scheduled-job/lib/handler.d.ts +12 -0
- package/dist/modules/scheduled-job/lib/handler.js +23 -0
- package/dist/modules/scheduled-job/lib/jobs/index.d.ts +2 -0
- package/dist/modules/scheduled-job/lib/jobs/index.js +3 -0
- package/dist/modules/scheduled-job/lib/jobs/job1.d.ts +1 -0
- package/dist/modules/scheduled-job/lib/jobs/job1.js +30 -0
- package/dist/modules/scheduled-job/lib/jobs/log-job.d.ts +1 -0
- package/dist/modules/scheduled-job/lib/jobs/log-job.js +9 -0
- package/dist/modules/scheduled-job/lib/wait.d.ts +8 -0
- package/dist/modules/scheduled-job/lib/wait.js +13 -0
- package/dist/modules/scheduled-job/schema.d.ts +20 -0
- package/dist/modules/scheduled-job/schema.js +10 -2
- package/dist/modules/scheduled-job/service.d.ts +4 -2
- package/dist/modules/scheduled-job/service.js +7 -1
- package/dist/modules/scheduled-job/types.d.ts +6 -0
- package/dist/modules/scheduled-job/types.js +1 -1
- package/package.json +1 -1
- package/src/modules/hooks/index.ts +5 -0
- package/src/modules/hooks/lib/Hooks.ts +103 -0
- package/src/modules/hooks/lib/handler.ts +27 -0
- package/src/modules/hooks/lib/jobs/index.ts +2 -0
- package/src/modules/hooks/lib/jobs/job1.ts +20 -0
- package/src/modules/hooks/lib/jobs/log-job.ts +10 -0
- package/src/modules/hooks/lib/wait.ts +17 -0
- package/src/modules/index.ts +2 -1
- package/src/modules/scheduled-job/action.ts +30 -2
- package/src/modules/scheduled-job/index.ts +5 -1
- package/src/modules/scheduled-job/lib/Schedules.ts +103 -0
- package/src/modules/scheduled-job/lib/handler.ts +27 -0
- package/src/modules/scheduled-job/lib/jobs/index.ts +2 -0
- package/src/modules/scheduled-job/lib/jobs/job1.ts +34 -0
- package/src/modules/scheduled-job/lib/jobs/log-job.ts +9 -0
- package/src/modules/scheduled-job/lib/wait.ts +17 -0
- package/src/modules/scheduled-job/schema.ts +13 -1
- package/src/modules/scheduled-job/service.ts +10 -2
- package/src/modules/scheduled-job/types.ts +10 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
import { schedules } from "../Schedules";
|
2
|
+
schedules.task({
|
3
|
+
id: "test",
|
4
|
+
cron: "*/50 * * * * *",
|
5
|
+
run: async () => {
|
6
|
+
console.log("test");
|
7
|
+
},
|
8
|
+
});
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLWpvYi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3NjaGVkdWxlZC1qb2IvbGliL2pvYnMvbG9nLWpvYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXpDLFNBQVMsQ0FBQyxJQUFJLENBQUM7SUFDWCxFQUFFLEVBQUUsTUFBTTtJQUNWLElBQUksRUFBRSxnQkFBZ0I7SUFDdEIsR0FBRyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ1osT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4QixDQUFDO0NBQ0osQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc2NoZWR1bGVzIH0gZnJvbSBcIi4uL1NjaGVkdWxlc1wiO1xuXG5zY2hlZHVsZXMudGFzayh7XG4gICAgaWQ6IFwidGVzdFwiLFxuICAgIGNyb246IFwiKi81MCAqICogKiAqICpcIixcbiAgICBydW46IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coXCJ0ZXN0XCIpO1xuICAgIH0sXG59KTsiXX0=
|
@@ -0,0 +1,13 @@
|
|
1
|
+
export const wait = {
|
2
|
+
for: ({ seconds }) => new Promise((resolve) => setTimeout(resolve, seconds * 1000)),
|
3
|
+
until: ({ date }) => {
|
4
|
+
const now = new Date();
|
5
|
+
const diff = date.getTime() - now.getTime();
|
6
|
+
if (diff <= 0) {
|
7
|
+
// Hedef tarih zaten geçmişse hiç bekleme
|
8
|
+
return Promise.resolve();
|
9
|
+
}
|
10
|
+
return new Promise((resolve) => setTimeout(resolve, diff));
|
11
|
+
},
|
12
|
+
};
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FpdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3NjaGVkdWxlZC1qb2IvbGliL3dhaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHO0lBQ2hCLEdBQUcsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUF1QixFQUFFLEVBQUUsQ0FDeEMsSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBRS9ELEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFrQixFQUFFLEVBQUU7UUFDbEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRTVDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2QseUNBQXlDO1lBQ3pDLE9BQU8sT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzNCLENBQUM7UUFFRCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztDQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3Qgd2FpdCA9IHtcbiAgICBmb3I6ICh7IHNlY29uZHMgfTogeyBzZWNvbmRzOiBudW1iZXIgfSkgPT5cbiAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHNlY29uZHMgKiAxMDAwKSksXG4gIFxuICAgIHVudGlsOiAoeyBkYXRlIH06IHsgZGF0ZTogRGF0ZSB9KSA9PiB7XG4gICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgICAgY29uc3QgZGlmZiA9IGRhdGUuZ2V0VGltZSgpIC0gbm93LmdldFRpbWUoKTtcbiAgXG4gICAgICBpZiAoZGlmZiA8PSAwKSB7XG4gICAgICAgIC8vIEhlZGVmIHRhcmloIHphdGVuIGdlw6dtacWfc2UgaGnDpyBiZWtsZW1lXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH1cbiAgXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgZGlmZikpO1xuICAgIH0sXG4gIH07XG4gICJdfQ==
|
@@ -25,10 +25,30 @@ export declare const GetScheduledJobSchema: z.ZodObject<{
|
|
25
25
|
}>;
|
26
26
|
export declare const ListExecutionsSchema: z.ZodObject<{
|
27
27
|
scheduledJobId: z.ZodString;
|
28
|
+
status: z.ZodOptional<z.ZodString>;
|
28
29
|
}, "strip", z.ZodTypeAny, {
|
29
30
|
scheduledJobId: string;
|
31
|
+
status?: string | undefined;
|
30
32
|
}, {
|
31
33
|
scheduledJobId: string;
|
34
|
+
status?: string | undefined;
|
35
|
+
}>;
|
36
|
+
export declare const ListAvgExecutionsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
37
|
+
export declare const UpdateJobSchema: z.ZodObject<{
|
38
|
+
id: z.ZodString;
|
39
|
+
name: z.ZodOptional<z.ZodString>;
|
40
|
+
cron: z.ZodOptional<z.ZodString>;
|
41
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
42
|
+
}, "strip", z.ZodTypeAny, {
|
43
|
+
id: string;
|
44
|
+
name?: string | undefined;
|
45
|
+
enabled?: boolean | undefined;
|
46
|
+
cron?: string | undefined;
|
47
|
+
}, {
|
48
|
+
id: string;
|
49
|
+
name?: string | undefined;
|
50
|
+
enabled?: boolean | undefined;
|
51
|
+
cron?: string | undefined;
|
32
52
|
}>;
|
33
53
|
export declare const GetDailyExecutionTrendSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
34
54
|
export declare const GetTopFailedJobsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
@@ -10,9 +10,17 @@ export const GetScheduledJobSchema = z.object({
|
|
10
10
|
id: z.string()
|
11
11
|
});
|
12
12
|
export const ListExecutionsSchema = z.object({
|
13
|
-
scheduledJobId: z.string()
|
13
|
+
scheduledJobId: z.string(),
|
14
|
+
status: z.string().optional()
|
15
|
+
});
|
16
|
+
export const ListAvgExecutionsSchema = z.object({});
|
17
|
+
export const UpdateJobSchema = z.object({
|
18
|
+
id: z.string(),
|
19
|
+
name: z.string().optional(),
|
20
|
+
cron: z.string().optional(),
|
21
|
+
enabled: z.boolean().optional(),
|
14
22
|
});
|
15
23
|
export const GetDailyExecutionTrendSchema = z.object({});
|
16
24
|
export const GetTopFailedJobsSchema = z.object({});
|
17
25
|
export const GetJobStatsSchema = z.object({});
|
18
|
-
//# sourceMappingURL=data:application/json;base64,
|
26
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZHVsZXMvc2NoZWR1bGVkLWpvYi9zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUV4QixNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzdDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3pCLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0lBQ2hCLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0lBQ2hCLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztDQUNoRCxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBRS9DLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDMUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7Q0FDakIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUN6QyxjQUFjLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtJQUMxQixNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUNoQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQy9DLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3BDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0lBQ2QsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDbEMsQ0FBQyxDQUFDO0FBR0gsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUVwRCxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBRTlDLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFFekMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuZXhwb3J0IGNvbnN0IENyZWF0ZVNjaGVkdWxlZEpvYlNjaGVtYSA9IHoub2JqZWN0KHtcbiAgICBpZDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIG5hbWU6IHouc3RyaW5nKCksXG4gICAgY3Jvbjogei5zdHJpbmcoKSxcbiAgICBlbmFibGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLmRlZmF1bHQodHJ1ZSksXG59KTtcblxuZXhwb3J0IGNvbnN0IExpc3RTY2hlZHVsZWRKb2JzU2NoZW1hID0gei5vYmplY3Qoe1xuICAgXG59KTtcblxuZXhwb3J0IGNvbnN0IEdldFNjaGVkdWxlZEpvYlNjaGVtYSA9IHoub2JqZWN0KHtcbiAgICBpZDogei5zdHJpbmcoKVxufSk7XG5cbmV4cG9ydCBjb25zdCBMaXN0RXhlY3V0aW9uc1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgICBzY2hlZHVsZWRKb2JJZDogei5zdHJpbmcoKSxcbiAgICBzdGF0dXM6IHouc3RyaW5nKCkub3B0aW9uYWwoKVxufSk7XG4gICAgXG5leHBvcnQgY29uc3QgTGlzdEF2Z0V4ZWN1dGlvbnNTY2hlbWEgPSB6Lm9iamVjdCh7XG59KTtcblxuZXhwb3J0IGNvbnN0IFVwZGF0ZUpvYlNjaGVtYSA9IHoub2JqZWN0KHtcbiAgICBpZDogei5zdHJpbmcoKSxcbiAgICBuYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgY3Jvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGVuYWJsZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG59KTtcblxuICAgIFxuZXhwb3J0IGNvbnN0IEdldERhaWx5RXhlY3V0aW9uVHJlbmRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gICBcbn0pO1xuXG5leHBvcnQgY29uc3QgR2V0VG9wRmFpbGVkSm9ic1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgIFxufSk7XG5cbmV4cG9ydCBjb25zdCBHZXRKb2JTdGF0c1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgIFxufSk7XG5cbiJdfQ==
|
@@ -1,13 +1,15 @@
|
|
1
1
|
import z from "zod";
|
2
2
|
import { ServiceClient } from "../../service-client";
|
3
|
-
import { CreateScheduledJobSchema, ListScheduledJobsSchema, GetScheduledJobSchema, ListExecutionsSchema, GetDailyExecutionTrendSchema, GetTopFailedJobsSchema, GetJobStatsSchema } from "./schema";
|
4
|
-
import { Execution, ExecutionTrend, FailedJob, JobStats, ScheduledJob } from "./types";
|
3
|
+
import { CreateScheduledJobSchema, ListScheduledJobsSchema, GetScheduledJobSchema, ListExecutionsSchema, GetDailyExecutionTrendSchema, GetTopFailedJobsSchema, GetJobStatsSchema, ListAvgExecutionsSchema, UpdateJobSchema } from "./schema";
|
4
|
+
import { AvgExecution, Execution, ExecutionTrend, FailedJob, JobStats, ScheduledJob } from "./types";
|
5
5
|
export declare class ScheduledJobService extends ServiceClient {
|
6
6
|
protected getServiceName(): string;
|
7
7
|
CreateScheduledJob(payload: z.infer<typeof CreateScheduledJobSchema>): Promise<ScheduledJob>;
|
8
8
|
ListScheduledJobs(payload: z.infer<typeof ListScheduledJobsSchema>): Promise<ScheduledJob[]>;
|
9
9
|
GetScheduledJob(payload: z.infer<typeof GetScheduledJobSchema>): Promise<ScheduledJob>;
|
10
10
|
ListExecutions(payload: z.infer<typeof ListExecutionsSchema>): Promise<Execution[]>;
|
11
|
+
ListAvgExecutions(payload: z.infer<typeof ListAvgExecutionsSchema>): Promise<AvgExecution[]>;
|
12
|
+
UpdateJob(payload: z.infer<typeof UpdateJobSchema>): Promise<ScheduledJob>;
|
11
13
|
GetDailyExecutionTrend(payload: z.infer<typeof GetDailyExecutionTrendSchema>): Promise<ExecutionTrend[]>;
|
12
14
|
GetTopFailedJobs(payload: z.infer<typeof GetTopFailedJobsSchema>): Promise<FailedJob>;
|
13
15
|
GetJobStats(payload: z.infer<typeof GetJobStatsSchema>): Promise<JobStats>;
|
@@ -15,6 +15,12 @@ export class ScheduledJobService extends ServiceClient {
|
|
15
15
|
async ListExecutions(payload) {
|
16
16
|
return await this.actionCall('ListExecutions', payload);
|
17
17
|
}
|
18
|
+
async ListAvgExecutions(payload) {
|
19
|
+
return await this.actionCall('ListAvgExecutions', payload);
|
20
|
+
}
|
21
|
+
async UpdateJob(payload) {
|
22
|
+
return await this.actionCall('UpdateJob', payload);
|
23
|
+
}
|
18
24
|
async GetDailyExecutionTrend(payload) {
|
19
25
|
return await this.actionCall('GetDailyExecutionTrend', payload);
|
20
26
|
}
|
@@ -25,4 +31,4 @@ export class ScheduledJobService extends ServiceClient {
|
|
25
31
|
return await this.actionCall('GetJobStats', payload);
|
26
32
|
}
|
27
33
|
}
|
28
|
-
//# sourceMappingURL=data:application/json;base64,
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tb2R1bGVzL3NjaGVkdWxlZC1qb2Ivc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFJckQsTUFBTSxPQUFPLG1CQUFvQixTQUFRLGFBQWE7SUFDeEMsY0FBYztRQUNwQixPQUFPLHFDQUFxQyxDQUFDO0lBQ2pELENBQUM7SUFFTSxLQUFLLENBQUMsa0JBQWtCLENBQUMsT0FBaUQ7UUFDN0UsT0FBTyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsb0JBQW9CLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVNLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUFnRDtRQUMzRSxPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRU0sS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUE4QztRQUN2RSxPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRU0sS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUE2QztRQUNyRSxPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRU0sS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQWdEO1FBQzNFLE9BQU8sTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLG1CQUFtQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFTSxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQXdDO1FBQzNELE9BQU8sTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRU0sS0FBSyxDQUFDLHNCQUFzQixDQUFDLE9BQXFEO1FBQ3JGLE9BQU8sTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLHdCQUF3QixFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFTSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBK0M7UUFDekUsT0FBTyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVNLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBMEM7UUFDL0QsT0FBTyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3pELENBQUM7Q0FFSiIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0IHogZnJvbSBcInpvZFwiO1xuaW1wb3J0IHsgU2VydmljZUNsaWVudCB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlLWNsaWVudFwiO1xuaW1wb3J0IHsgQ3JlYXRlU2NoZWR1bGVkSm9iU2NoZW1hLCBMaXN0U2NoZWR1bGVkSm9ic1NjaGVtYSwgR2V0U2NoZWR1bGVkSm9iU2NoZW1hLCBMaXN0RXhlY3V0aW9uc1NjaGVtYSwgR2V0RGFpbHlFeGVjdXRpb25UcmVuZFNjaGVtYSwgR2V0VG9wRmFpbGVkSm9ic1NjaGVtYSwgR2V0Sm9iU3RhdHNTY2hlbWEsIExpc3RBdmdFeGVjdXRpb25zU2NoZW1hLCBVcGRhdGVKb2JTY2hlbWEgfSBmcm9tIFwiLi9zY2hlbWFcIjtcbmltcG9ydCB7IEF2Z0V4ZWN1dGlvbiwgRXhlY3V0aW9uLCBFeGVjdXRpb25UcmVuZCwgRmFpbGVkSm9iLCBKb2JTdGF0cywgU2NoZWR1bGVkSm9iIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIFNjaGVkdWxlZEpvYlNlcnZpY2UgZXh0ZW5kcyBTZXJ2aWNlQ2xpZW50IHtcbiAgICBwcm90ZWN0ZWQgZ2V0U2VydmljZU5hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuICdjb20uYXBwY29uZGEuc2VydmljZS5zY2hlZHVsZWQtam9icyc7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIENyZWF0ZVNjaGVkdWxlZEpvYihwYXlsb2FkOiB6LmluZmVyPHR5cGVvZiBDcmVhdGVTY2hlZHVsZWRKb2JTY2hlbWE+KTogUHJvbWlzZTxTY2hlZHVsZWRKb2I+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aW9uQ2FsbCgnQ3JlYXRlU2NoZWR1bGVkSm9iJywgcGF5bG9hZCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIExpc3RTY2hlZHVsZWRKb2JzKHBheWxvYWQ6IHouaW5mZXI8dHlwZW9mIExpc3RTY2hlZHVsZWRKb2JzU2NoZW1hPik6IFByb21pc2U8U2NoZWR1bGVkSm9iW10+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aW9uQ2FsbCgnTGlzdFNjaGVkdWxlZEpvYnMnLCBwYXlsb2FkKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgR2V0U2NoZWR1bGVkSm9iKHBheWxvYWQ6IHouaW5mZXI8dHlwZW9mIEdldFNjaGVkdWxlZEpvYlNjaGVtYT4pOiBQcm9taXNlPFNjaGVkdWxlZEpvYj4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5hY3Rpb25DYWxsKCdHZXRTY2hlZHVsZWRKb2InLCBwYXlsb2FkKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgTGlzdEV4ZWN1dGlvbnMocGF5bG9hZDogei5pbmZlcjx0eXBlb2YgTGlzdEV4ZWN1dGlvbnNTY2hlbWE+KTogUHJvbWlzZTxFeGVjdXRpb25bXT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5hY3Rpb25DYWxsKCdMaXN0RXhlY3V0aW9ucycsIHBheWxvYWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBMaXN0QXZnRXhlY3V0aW9ucyhwYXlsb2FkOiB6LmluZmVyPHR5cGVvZiBMaXN0QXZnRXhlY3V0aW9uc1NjaGVtYT4pOiBQcm9taXNlPEF2Z0V4ZWN1dGlvbltdPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFjdGlvbkNhbGwoJ0xpc3RBdmdFeGVjdXRpb25zJywgcGF5bG9hZCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIFVwZGF0ZUpvYihwYXlsb2FkOiB6LmluZmVyPHR5cGVvZiBVcGRhdGVKb2JTY2hlbWE+KTogUHJvbWlzZTxTY2hlZHVsZWRKb2I+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aW9uQ2FsbCgnVXBkYXRlSm9iJywgcGF5bG9hZCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIEdldERhaWx5RXhlY3V0aW9uVHJlbmQocGF5bG9hZDogei5pbmZlcjx0eXBlb2YgR2V0RGFpbHlFeGVjdXRpb25UcmVuZFNjaGVtYT4pOiBQcm9taXNlPEV4ZWN1dGlvblRyZW5kW10+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aW9uQ2FsbCgnR2V0RGFpbHlFeGVjdXRpb25UcmVuZCcsIHBheWxvYWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBHZXRUb3BGYWlsZWRKb2JzKHBheWxvYWQ6IHouaW5mZXI8dHlwZW9mIEdldFRvcEZhaWxlZEpvYnNTY2hlbWE+KTogUHJvbWlzZTxGYWlsZWRKb2I+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aW9uQ2FsbCgnR2V0VG9wRmFpbGVkSm9icycsIHBheWxvYWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBHZXRKb2JTdGF0cyhwYXlsb2FkOiB6LmluZmVyPHR5cGVvZiBHZXRKb2JTdGF0c1NjaGVtYT4pOiBQcm9taXNlPEpvYlN0YXRzPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFjdGlvbkNhbGwoJ0dldEpvYlN0YXRzJywgcGF5bG9hZCk7XG4gICAgfVxuICAgIFxufVxuIl19
|
@@ -21,6 +21,12 @@ export type Execution = {
|
|
21
21
|
updatedAt: Date;
|
22
22
|
status: string;
|
23
23
|
};
|
24
|
+
export type AvgExecution = {
|
25
|
+
scheduledJobId: string;
|
26
|
+
totalExecutions: number;
|
27
|
+
activeDays: number;
|
28
|
+
avgExecutionsPerDay: number;
|
29
|
+
};
|
24
30
|
export type ExecutionTrend = {
|
25
31
|
labels: string[];
|
26
32
|
datasets: {
|
@@ -1,2 +1,2 @@
|
|
1
1
|
export {};
|
2
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbW9kdWxlcy9zY2hlZHVsZWQtam9iL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJcblxuZXhwb3J0IHR5cGUgU2NoZWR1bGVkSm9iID0ge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGNyb246IHN0cmluZztcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgbGFzdFJ1bj86IERhdGU7XG4gIG5leHRSdW4/
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbW9kdWxlcy9zY2hlZHVsZWQtam9iL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJcblxuZXhwb3J0IHR5cGUgU2NoZWR1bGVkSm9iID0ge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGNyb246IHN0cmluZztcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgbGFzdFJ1bj86IERhdGU7XG4gIG5leHRSdW4/OiBEYXRlO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIHVwZGF0ZWRBdDogRGF0ZTtcbn1cblxuZXhwb3J0IHR5cGUgSm9iUnVuID0ge1xuICBpZDogc3RyaW5nO1xuICBqb2JJZDogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIHVwZGF0ZWRBdDogRGF0ZTtcbn1cblxuZXhwb3J0IHR5cGUgRXhlY3V0aW9uID0ge1xuICBpZDogc3RyaW5nO1xuICBzY2hlZHVsZWRKb2JJZDogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIHVwZGF0ZWRBdDogRGF0ZTtcbiAgc3RhdHVzOiBzdHJpbmc7XG59XG5cblxuZXhwb3J0IHR5cGUgQXZnRXhlY3V0aW9uID0ge1xuICBzY2hlZHVsZWRKb2JJZDogc3RyaW5nO1xuICB0b3RhbEV4ZWN1dGlvbnM6IG51bWJlcjtcbiAgYWN0aXZlRGF5czogbnVtYmVyO1xuICBhdmdFeGVjdXRpb25zUGVyRGF5OiBudW1iZXI7XG59XG5cblxuXG5leHBvcnQgdHlwZSBFeGVjdXRpb25UcmVuZCA9IHtcbiAgbGFiZWxzOiBzdHJpbmdbXTtcbiAgZGF0YXNldHM6IHtcbiAgICBsYWJlbDogc3RyaW5nO1xuICAgIGRhdGE6IG51bWJlcltdO1xuICAgIGJvcmRlckNvbG9yOiBzdHJpbmc7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgRmFpbGVkSm9iID0ge1xuICBsYWJlbHM6IHN0cmluZ1tdO1xuICBkYXRhc2V0czoge1xuICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgZGF0YTogbnVtYmVyW107XG4gICAgYmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XG4gIH1bXTtcbn1cblxuZXhwb3J0IHR5cGUgSm9iU3RhdHMgPSB7XG4gIHNjaGVkdWxlZEpvYklkOiBzdHJpbmc7XG4gIHRvdGFsOiBudW1iZXI7XG4gIGNvbXBsZXRlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbiAgcXVldWVkOiBudW1iZXI7XG4gIGF2Z0RheTogbnVtYmVyO1xuICBhdmdEdXJhdGlvbjogbnVtYmVyO1xuICBsYXN0UnVuOiBzdHJpbmc7XG59XG5cbiJdfQ==
|
package/package.json
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"name": "@appconda/nextjs",
|
3
3
|
"homepage": "https://appconda.io/support",
|
4
4
|
"description": "Appconda is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API",
|
5
|
-
"version": "1.0.
|
5
|
+
"version": "1.0.132",
|
6
6
|
"license": "BSD-3-Clause",
|
7
7
|
"main": "dist/index.js",
|
8
8
|
"types": "dist/index.d.ts",
|
@@ -0,0 +1,103 @@
|
|
1
|
+
|
2
|
+
type TaskPayload = {
|
3
|
+
timestamp: Date;
|
4
|
+
lastTimestamp?: Date;
|
5
|
+
timezone: string;
|
6
|
+
};
|
7
|
+
|
8
|
+
type TaskContext = {
|
9
|
+
retriesLeft: number;
|
10
|
+
};
|
11
|
+
|
12
|
+
type TriggerArgs = {
|
13
|
+
id: string;
|
14
|
+
events: string[];
|
15
|
+
maxDuration?: number; // saniye
|
16
|
+
retries?: number;
|
17
|
+
run: (
|
18
|
+
payload: TaskPayload,
|
19
|
+
tools: { ctx: TaskContext }
|
20
|
+
) => Promise<void> | void;
|
21
|
+
};
|
22
|
+
|
23
|
+
export class Hooks {
|
24
|
+
private lastRunTimestamps: Record<string, Date> = {};
|
25
|
+
private triggers: TriggerArgs[] = [];
|
26
|
+
|
27
|
+
public trigger(args: TriggerArgs) {
|
28
|
+
this.triggers.push(args);
|
29
|
+
}
|
30
|
+
|
31
|
+
public async run(hookId: string) {
|
32
|
+
const now = new Date();
|
33
|
+
const lastTimestamp = this.lastRunTimestamps[hookId];
|
34
|
+
|
35
|
+
const payload: TaskPayload = {
|
36
|
+
timestamp: now,
|
37
|
+
lastTimestamp,
|
38
|
+
timezone: "UTC",
|
39
|
+
};
|
40
|
+
|
41
|
+
this.lastRunTimestamps[hookId] = now;
|
42
|
+
|
43
|
+
const context: TaskContext = {
|
44
|
+
retriesLeft: this.triggers.find(hook => hook.id === hookId)?.retries ?? 0,
|
45
|
+
};
|
46
|
+
|
47
|
+
await this.runWithRetry(this.triggers.find(hook => hook.id === hookId)!, payload, context);
|
48
|
+
|
49
|
+
|
50
|
+
}
|
51
|
+
|
52
|
+
private async runWithRetry(
|
53
|
+
trigger: TriggerArgs,
|
54
|
+
payload: TaskPayload,
|
55
|
+
ctx: TaskContext
|
56
|
+
) {
|
57
|
+
const start = Date.now();
|
58
|
+
|
59
|
+
try {
|
60
|
+
await Promise.race([
|
61
|
+
trigger.run(payload, { ctx }),
|
62
|
+
timeout(trigger.maxDuration ?? 60),
|
63
|
+
]);
|
64
|
+
log("success", { hookId: trigger.id, time: new Date().toISOString() });
|
65
|
+
} catch (err) {
|
66
|
+
//@ts-ignore
|
67
|
+
log("error", { hookId: trigger.id, error: err });
|
68
|
+
|
69
|
+
if (ctx.retriesLeft > 0) {
|
70
|
+
ctx.retriesLeft -= 1;
|
71
|
+
//@ts-ignore
|
72
|
+
log("warn", { hookId: trigger.id, msg: "Retrying..." });
|
73
|
+
await this.runWithRetry(trigger, payload, ctx);
|
74
|
+
}
|
75
|
+
} finally {
|
76
|
+
const duration = Date.now() - start;
|
77
|
+
//@ts-ignore
|
78
|
+
log("info", { hookId: trigger.id, durationMs: duration });
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
public toJSON() {
|
83
|
+
return this.triggers.map(trigger => ({
|
84
|
+
id: trigger.id,
|
85
|
+
events: trigger.events,
|
86
|
+
maxDuration: trigger.maxDuration,
|
87
|
+
retries: trigger.retries,
|
88
|
+
}));
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
function log(arg0: string, arg1: { hookId: string; time: string; }) {
|
93
|
+
// console.log(arg0, arg1);
|
94
|
+
}
|
95
|
+
|
96
|
+
function timeout(seconds: number) {
|
97
|
+
return new Promise((_, reject) =>
|
98
|
+
setTimeout(() => reject(new Error("Timeout reached")), seconds * 1000)
|
99
|
+
);
|
100
|
+
}
|
101
|
+
|
102
|
+
|
103
|
+
export const hooks = new Hooks();
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
2
|
+
|
3
|
+
import './jobs';
|
4
|
+
import { hooks } from './Hooks';
|
5
|
+
|
6
|
+
/* export async function GET() {
|
7
|
+
return NextResponse.json({ schedules: schedules.toJSON() },
|
8
|
+
{ status: 200 });
|
9
|
+
}
|
10
|
+
|
11
|
+
export async function POST(request: Request) {
|
12
|
+
|
13
|
+
} */
|
14
|
+
|
15
|
+
export async function hookHandler(request: NextRequest, res: NextResponse) {
|
16
|
+
if (request.method === 'POST') {
|
17
|
+
const body = await request.json();
|
18
|
+
const hookId = body.hookId;
|
19
|
+
hooks.run(hookId);
|
20
|
+
return NextResponse.json({ message: 'Callback triggered' },
|
21
|
+
{ status: 200 });
|
22
|
+
} else {
|
23
|
+
return NextResponse.json({ hooks: hooks.toJSON() },
|
24
|
+
{ status: 200 });
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
import { hooks } from "../Hooks";
|
3
|
+
|
4
|
+
hooks.trigger({
|
5
|
+
id: "job1",
|
6
|
+
events: ["event1"],
|
7
|
+
run: async () => {
|
8
|
+
console.log("hello from job 1");
|
9
|
+
},
|
10
|
+
});
|
11
|
+
|
12
|
+
|
13
|
+
hooks.trigger({
|
14
|
+
id: "job2",
|
15
|
+
events: ["event2"],
|
16
|
+
run: async () => {
|
17
|
+
console.log("hello from job 2");
|
18
|
+
},
|
19
|
+
});
|
20
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export const wait = {
|
2
|
+
for: ({ seconds }: { seconds: number }) =>
|
3
|
+
new Promise((resolve) => setTimeout(resolve, seconds * 1000)),
|
4
|
+
|
5
|
+
until: ({ date }: { date: Date }) => {
|
6
|
+
const now = new Date();
|
7
|
+
const diff = date.getTime() - now.getTime();
|
8
|
+
|
9
|
+
if (diff <= 0) {
|
10
|
+
// Hedef tarih zaten geçmişse hiç bekleme
|
11
|
+
return Promise.resolve();
|
12
|
+
}
|
13
|
+
|
14
|
+
return new Promise((resolve) => setTimeout(resolve, diff));
|
15
|
+
},
|
16
|
+
};
|
17
|
+
|
package/src/modules/index.ts
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
|
4
4
|
import { actionClient } from '../../actions/actionClient';
|
5
5
|
import { getSDKForCurrentUser } from '../../getSDKForCurrentUser';
|
6
|
-
import { CreateScheduledJobSchema, GetDailyExecutionTrendSchema, GetJobStatsSchema, GetScheduledJobSchema, GetTopFailedJobsSchema, ListExecutionsSchema, ListScheduledJobsSchema } from './schema';
|
7
|
-
import { Execution, ExecutionTrend, FailedJob, JobStats, ScheduledJob } from './types';
|
6
|
+
import { CreateScheduledJobSchema, GetDailyExecutionTrendSchema, GetJobStatsSchema, GetScheduledJobSchema, GetTopFailedJobsSchema, ListAvgExecutionsSchema, ListExecutionsSchema, ListScheduledJobsSchema, UpdateJobSchema } from './schema';
|
7
|
+
import { AvgExecution, Execution, ExecutionTrend, FailedJob, JobStats, ScheduledJob } from './types';
|
8
8
|
|
9
9
|
export const CreateScheduledJob = actionClient
|
10
10
|
.schema(CreateScheduledJobSchema)
|
@@ -62,6 +62,34 @@ export const CreateScheduledJob = actionClient
|
|
62
62
|
}
|
63
63
|
});
|
64
64
|
|
65
|
+
export const ListAvgExecutions = actionClient
|
66
|
+
.schema(ListAvgExecutionsSchema)
|
67
|
+
.action(async ({ parsedInput }): Promise<AvgExecution[]> => {
|
68
|
+
try {
|
69
|
+
|
70
|
+
const { scheduledJob } = await getSDKForCurrentUser();
|
71
|
+
return await scheduledJob.ListAvgExecutions(parsedInput);
|
72
|
+
|
73
|
+
} catch (error) {
|
74
|
+
console.error('Error in ListAvgExecutions:', error);
|
75
|
+
throw new Error('Failed to fetch ListAvgExecutions');
|
76
|
+
}
|
77
|
+
});
|
78
|
+
|
79
|
+
export const UpdateJob = actionClient
|
80
|
+
.schema(UpdateJobSchema)
|
81
|
+
.action(async ({ parsedInput }): Promise<ScheduledJob> => {
|
82
|
+
try {
|
83
|
+
|
84
|
+
const { scheduledJob } = await getSDKForCurrentUser();
|
85
|
+
return await scheduledJob.UpdateJob(parsedInput);
|
86
|
+
|
87
|
+
} catch (error) {
|
88
|
+
console.error('Error in UpdateJob:', error);
|
89
|
+
throw new Error('Failed to fetch UpdateJob');
|
90
|
+
}
|
91
|
+
});
|
92
|
+
|
65
93
|
export const GetDailyExecutionTrend = actionClient
|
66
94
|
.schema(GetDailyExecutionTrendSchema)
|
67
95
|
.action(async ({ parsedInput }): Promise<ExecutionTrend[]> => {
|
@@ -0,0 +1,103 @@
|
|
1
|
+
|
2
|
+
type TaskPayload = {
|
3
|
+
timestamp: Date;
|
4
|
+
lastTimestamp?: Date;
|
5
|
+
timezone: string;
|
6
|
+
};
|
7
|
+
|
8
|
+
type TaskContext = {
|
9
|
+
retriesLeft: number;
|
10
|
+
};
|
11
|
+
|
12
|
+
type TaskArgs = {
|
13
|
+
id: string;
|
14
|
+
cron: string;
|
15
|
+
maxDuration?: number; // saniye
|
16
|
+
retries?: number;
|
17
|
+
run: (
|
18
|
+
payload: TaskPayload,
|
19
|
+
tools: { ctx: TaskContext }
|
20
|
+
) => Promise<void> | void;
|
21
|
+
};
|
22
|
+
|
23
|
+
export class Schedules {
|
24
|
+
private lastRunTimestamps: Record<string, Date> = {};
|
25
|
+
private Tasks: TaskArgs[] = [];
|
26
|
+
|
27
|
+
public task(args: TaskArgs) {
|
28
|
+
this.Tasks.push(args);
|
29
|
+
}
|
30
|
+
|
31
|
+
public async run(taskId: string) {
|
32
|
+
const now = new Date();
|
33
|
+
const lastTimestamp = this.lastRunTimestamps[taskId];
|
34
|
+
|
35
|
+
const payload: TaskPayload = {
|
36
|
+
timestamp: now,
|
37
|
+
lastTimestamp,
|
38
|
+
timezone: "UTC",
|
39
|
+
};
|
40
|
+
|
41
|
+
this.lastRunTimestamps[taskId] = now;
|
42
|
+
|
43
|
+
const context: TaskContext = {
|
44
|
+
retriesLeft: this.Tasks.find(task => task.id === taskId)?.retries ?? 0,
|
45
|
+
};
|
46
|
+
|
47
|
+
await this.runWithRetry(this.Tasks.find(task => task.id === taskId)!, payload, context);
|
48
|
+
|
49
|
+
|
50
|
+
}
|
51
|
+
|
52
|
+
private async runWithRetry(
|
53
|
+
task: TaskArgs,
|
54
|
+
payload: TaskPayload,
|
55
|
+
ctx: TaskContext
|
56
|
+
) {
|
57
|
+
const start = Date.now();
|
58
|
+
|
59
|
+
try {
|
60
|
+
await Promise.race([
|
61
|
+
task.run(payload, { ctx }),
|
62
|
+
timeout(task.maxDuration ?? 60),
|
63
|
+
]);
|
64
|
+
log("success", { taskId: task.id, time: new Date().toISOString() });
|
65
|
+
} catch (err) {
|
66
|
+
//@ts-ignore
|
67
|
+
log("error", { taskId: task.id, error: err });
|
68
|
+
|
69
|
+
if (ctx.retriesLeft > 0) {
|
70
|
+
ctx.retriesLeft -= 1;
|
71
|
+
//@ts-ignore
|
72
|
+
log("warn", { taskId: task.id, msg: "Retrying..." });
|
73
|
+
await this.runWithRetry(task, payload, ctx);
|
74
|
+
}
|
75
|
+
} finally {
|
76
|
+
const duration = Date.now() - start;
|
77
|
+
//@ts-ignore
|
78
|
+
log("info", { taskId: task.id, durationMs: duration });
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
public toJSON() {
|
83
|
+
return this.Tasks.map(task => ({
|
84
|
+
id: task.id,
|
85
|
+
cron: task.cron,
|
86
|
+
maxDuration: task.maxDuration,
|
87
|
+
retries: task.retries,
|
88
|
+
}));
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
function log(arg0: string, arg1: { taskId: string; time: string; }) {
|
93
|
+
// console.log(arg0, arg1);
|
94
|
+
}
|
95
|
+
|
96
|
+
function timeout(seconds: number) {
|
97
|
+
return new Promise((_, reject) =>
|
98
|
+
setTimeout(() => reject(new Error("Timeout reached")), seconds * 1000)
|
99
|
+
);
|
100
|
+
}
|
101
|
+
|
102
|
+
|
103
|
+
export const schedules = new Schedules();
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
2
|
+
|
3
|
+
import './jobs';
|
4
|
+
import { schedules } from './Schedules';
|
5
|
+
|
6
|
+
/* export async function GET() {
|
7
|
+
return NextResponse.json({ schedules: schedules.toJSON() },
|
8
|
+
{ status: 200 });
|
9
|
+
}
|
10
|
+
|
11
|
+
export async function POST(request: Request) {
|
12
|
+
|
13
|
+
} */
|
14
|
+
|
15
|
+
export async function scheduledJobHandler(request: NextRequest, res: NextResponse) {
|
16
|
+
if (request.method === 'POST') {
|
17
|
+
const body = await request.json();
|
18
|
+
const taskId = body.taskId;
|
19
|
+
schedules.run(taskId);
|
20
|
+
return NextResponse.json({ message: 'Callback triggered' },
|
21
|
+
{ status: 200 });
|
22
|
+
} else {
|
23
|
+
return NextResponse.json({ schedules: schedules.toJSON() },
|
24
|
+
{ status: 200 });
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import { schedules } from "../Schedules";
|
2
|
+
|
3
|
+
schedules.task({
|
4
|
+
id: "job1",
|
5
|
+
cron: "*/5 * * * *",
|
6
|
+
run: async () => {
|
7
|
+
console.log("hello from job 1");
|
8
|
+
},
|
9
|
+
});
|
10
|
+
|
11
|
+
|
12
|
+
schedules.task({
|
13
|
+
id: "job2",
|
14
|
+
cron: "*/5 * * * *",
|
15
|
+
run: async () => {
|
16
|
+
console.log("hello from job 2");
|
17
|
+
},
|
18
|
+
});
|
19
|
+
|
20
|
+
schedules.task({
|
21
|
+
id: "job3",
|
22
|
+
cron: "*/5 * * * *",
|
23
|
+
run: async () => {
|
24
|
+
console.log("hello from job 3");
|
25
|
+
},
|
26
|
+
});
|
27
|
+
|
28
|
+
schedules.task({
|
29
|
+
id: "job4",
|
30
|
+
cron: "*/5 * * * *",
|
31
|
+
run: async () => {
|
32
|
+
console.log("hello from job 4");
|
33
|
+
},
|
34
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export const wait = {
|
2
|
+
for: ({ seconds }: { seconds: number }) =>
|
3
|
+
new Promise((resolve) => setTimeout(resolve, seconds * 1000)),
|
4
|
+
|
5
|
+
until: ({ date }: { date: Date }) => {
|
6
|
+
const now = new Date();
|
7
|
+
const diff = date.getTime() - now.getTime();
|
8
|
+
|
9
|
+
if (diff <= 0) {
|
10
|
+
// Hedef tarih zaten geçmişse hiç bekleme
|
11
|
+
return Promise.resolve();
|
12
|
+
}
|
13
|
+
|
14
|
+
return new Promise((resolve) => setTimeout(resolve, diff));
|
15
|
+
},
|
16
|
+
};
|
17
|
+
|