@solidxai/core 0.1.6-beta.7 → 0.1.6
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/controllers/scheduled-job.controller.d.ts +0 -1
- package/dist/controllers/scheduled-job.controller.d.ts.map +1 -1
- package/dist/controllers/scheduled-job.controller.js +0 -12
- package/dist/controllers/scheduled-job.controller.js.map +1 -1
- package/dist/entities/chatter-message-details.entity.d.ts +0 -1
- package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message-details.entity.js +1 -5
- package/dist/entities/chatter-message-details.entity.js.map +1 -1
- package/dist/entities/common.entity.js +1 -1
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/legacy-common.entity.d.ts.map +1 -1
- package/dist/entities/legacy-common.entity.js +1 -1
- package/dist/entities/legacy-common.entity.js.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +1 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +8 -9
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
- package/dist/interfaces.d.ts +1 -4
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +3 -73
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +21 -45
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +0 -26
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/dashboard-question.service.d.ts +0 -4
- package/dist/services/dashboard-question.service.d.ts.map +1 -1
- package/dist/services/dashboard-question.service.js +8 -22
- package/dist/services/dashboard-question.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +6 -101
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts +4 -2
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts.map +1 -1
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js +1 -2
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js.map +1 -1
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts +5 -2
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts.map +1 -1
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js +1 -2
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js.map +1 -1
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts +5 -2
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts.map +1 -1
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js +1 -2
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.d.ts +2 -4
- package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +1 -9
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/publisher-factory.service.d.ts.map +1 -1
- package/dist/services/queues/publisher-factory.service.js +6 -4
- package/dist/services/queues/publisher-factory.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts +2 -4
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +1 -9
- package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
- package/dist/services/scheduled-job.service.d.ts +1 -6
- package/dist/services/scheduled-job.service.d.ts.map +1 -1
- package/dist/services/scheduled-job.service.js +2 -26
- package/dist/services/scheduled-job.service.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.interface.d.ts +0 -2
- package/dist/services/scheduled-jobs/scheduler.interface.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.interface.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.d.ts +2 -6
- package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js +15 -55
- package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts.map +1 -1
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js +1 -4
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js.map +1 -1
- package/dist/transformers/typeorm/local-date-time-transformer.d.ts +4 -4
- package/dist/transformers/typeorm/local-date-time-transformer.d.ts.map +1 -1
- package/dist/transformers/typeorm/local-date-time-transformer.js +28 -25
- package/dist/transformers/typeorm/local-date-time-transformer.js.map +1 -1
- package/package.json +1 -1
- package/src/controllers/scheduled-job.controller.ts +0 -6
- package/src/entities/chatter-message-details.entity.ts +0 -3
- package/src/entities/common.entity.ts +2 -2
- package/src/entities/legacy-common.entity.ts +4 -3
- package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +9 -9
- package/src/interfaces.ts +1 -7
- package/src/seeders/seed-data/solid-core-metadata.json +3 -73
- package/src/services/authentication.service.ts +24 -47
- package/src/services/chatter-message.service.ts +0 -26
- package/src/services/dashboard-question.service.ts +4 -23
- package/src/services/model-metadata.service.ts +7 -109
- package/src/services/question-data-providers/chartjs-sql-data-provider.service.ts +7 -3
- package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts +8 -4
- package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts +8 -4
- package/src/services/queues/database-subscriber.service.ts +1 -12
- package/src/services/queues/publisher-factory.service.ts +6 -8
- package/src/services/queues/rabbitmq-subscriber.service.ts +1 -12
- package/src/services/scheduled-job.service.ts +2 -31
- package/src/services/scheduled-jobs/scheduler.interface.ts +1 -4
- package/src/services/scheduled-jobs/scheduler.service.ts +16 -60
- package/src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts +1 -4
- package/src/transformers/typeorm/local-date-time-transformer.ts +33 -41
- package/dist/services/question-data-providers/interfaces.d.ts +0 -1
- package/dist/services/question-data-providers/interfaces.d.ts.map +0 -1
- package/dist/services/question-data-providers/interfaces.js +0 -1
- package/dist/services/question-data-providers/interfaces.js.map +0 -1
- package/src/services/question-data-providers/interfaces.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.interface.js","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.interface.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"scheduler.interface.js","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.interface.ts"],"names":[],"mappings":"","sourcesContent":["export interface ISchedulerService {\n runScheduledJobs(): Promise<void>;\n}"]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ScheduledJob } from 'src/entities/scheduled-job.entity';
|
|
2
1
|
import { SolidRegistry } from 'src/helpers/solid-registry';
|
|
3
2
|
import { ScheduledJobRepository } from 'src/repository/scheduled-job.repository';
|
|
4
3
|
import { ISchedulerService } from './scheduler.interface';
|
|
@@ -10,10 +9,7 @@ export declare class SchedulerServiceImpl implements ISchedulerService {
|
|
|
10
9
|
constructor(scheduledJobRepo: ScheduledJobRepository, solidRegistry: SolidRegistry);
|
|
11
10
|
runScheduledJobs(): Promise<void>;
|
|
12
11
|
private shouldRunNow;
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private toHHMM;
|
|
16
|
-
computeNextRunForCustomCron(job: ScheduledJob, from: Date): Date;
|
|
17
|
-
computeNextRunAt(job: ScheduledJob, from: Date): Date;
|
|
12
|
+
private computeNextRunForCustomCron;
|
|
13
|
+
private computeNextRunAt;
|
|
18
14
|
}
|
|
19
15
|
//# sourceMappingURL=scheduler.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.service.d.ts","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scheduler.service.d.ts","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1D,qBACa,oBAAqB,YAAW,iBAAiB;IAOtD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAPlC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAK5B,gBAAgB,EAAE,sBAAsB,EACxC,aAAa,EAAE,aAAa;IAI3C,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAwEvC,OAAO,CAAC,YAAY;IA0CpB,OAAO,CAAC,2BAA2B;IA8BnC,OAAO,CAAC,gBAAgB;CAwB3B"}
|
|
@@ -82,27 +82,28 @@ let SchedulerServiceImpl = SchedulerServiceImpl_1 = class SchedulerServiceImpl {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
shouldRunNow(job, now) {
|
|
85
|
-
const today =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const startDate = this.toDateOnly(job.startDate);
|
|
89
|
-
const endDate = this.toDateOnly(job.endDate);
|
|
90
|
-
if (startDate && today < startDate)
|
|
85
|
+
const today = now.toISOString().split('T')[0];
|
|
86
|
+
const timeNow = now.toTimeString().slice(0, 5);
|
|
87
|
+
if (job.startDate && new Date(today) < new Date(job.startDate))
|
|
91
88
|
return false;
|
|
92
|
-
if (endDate && today > endDate)
|
|
93
|
-
return false;
|
|
94
|
-
const jobStart = this.toHHMM(job.startTime);
|
|
95
|
-
const jobEnd = this.toHHMM(job.endTime);
|
|
96
|
-
if (jobStart && timeNow < jobStart)
|
|
97
|
-
return false;
|
|
98
|
-
if (jobEnd && timeNow > jobEnd)
|
|
89
|
+
if (job.endDate && new Date(today) > new Date(job.endDate))
|
|
99
90
|
return false;
|
|
91
|
+
if (job.startTime) {
|
|
92
|
+
const jobStart = job.startTime.toTimeString().slice(0, 5);
|
|
93
|
+
if (timeNow < jobStart)
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (job.endTime) {
|
|
97
|
+
const jobEnd = job.endTime.toTimeString().slice(0, 5);
|
|
98
|
+
if (timeNow > jobEnd)
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
100
101
|
if (job.frequency.toLowerCase() === 'custom') {
|
|
101
102
|
return true;
|
|
102
103
|
}
|
|
103
104
|
if (job.frequency.toLowerCase() === 'weekly' && job.dayOfWeek) {
|
|
104
105
|
const todayName = now.toLocaleString('en-US', { weekday: 'long' });
|
|
105
|
-
const days =
|
|
106
|
+
const days = JSON.parse(job.dayOfWeek);
|
|
106
107
|
if (!days.includes(todayName))
|
|
107
108
|
return false;
|
|
108
109
|
}
|
|
@@ -113,47 +114,6 @@ let SchedulerServiceImpl = SchedulerServiceImpl_1 = class SchedulerServiceImpl {
|
|
|
113
114
|
}
|
|
114
115
|
return true;
|
|
115
116
|
}
|
|
116
|
-
parseDayOfWeek(dayOfWeek) {
|
|
117
|
-
try {
|
|
118
|
-
const parsed = JSON.parse(dayOfWeek);
|
|
119
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
120
|
-
}
|
|
121
|
-
catch (error) {
|
|
122
|
-
this.logger.warn(`Invalid dayOfWeek JSON '${dayOfWeek}'`, error);
|
|
123
|
-
return [];
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
toDateOnly(value) {
|
|
127
|
-
if (!value)
|
|
128
|
-
return null;
|
|
129
|
-
if (value instanceof Date) {
|
|
130
|
-
const d = new Date(value);
|
|
131
|
-
d.setHours(0, 0, 0, 0);
|
|
132
|
-
return d;
|
|
133
|
-
}
|
|
134
|
-
const parsed = new Date(value);
|
|
135
|
-
if (Number.isNaN(parsed.getTime()))
|
|
136
|
-
return null;
|
|
137
|
-
parsed.setHours(0, 0, 0, 0);
|
|
138
|
-
return parsed;
|
|
139
|
-
}
|
|
140
|
-
toHHMM(value) {
|
|
141
|
-
if (!value)
|
|
142
|
-
return null;
|
|
143
|
-
if (value instanceof Date) {
|
|
144
|
-
return value.toTimeString().slice(0, 5);
|
|
145
|
-
}
|
|
146
|
-
if (typeof value === 'string') {
|
|
147
|
-
const match = value.match(/^(\d{2}):(\d{2})/);
|
|
148
|
-
if (match)
|
|
149
|
-
return `${match[1]}:${match[2]}`;
|
|
150
|
-
const parsed = new Date(value);
|
|
151
|
-
if (!Number.isNaN(parsed.getTime())) {
|
|
152
|
-
return parsed.toTimeString().slice(0, 5);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
117
|
computeNextRunForCustomCron(job, from) {
|
|
158
118
|
const base = new Date(from);
|
|
159
119
|
if (!job.cronExpression) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.service.js","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport { IsNull, LessThanOrEqual } from 'typeorm';\n\nimport { Cron, CronExpression } from '@nestjs/schedule';\nimport { ScheduledJob } from 'src/entities/scheduled-job.entity';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { ScheduledJobRepository } from 'src/repository/scheduled-job.repository';\nimport { ISchedulerService } from './scheduler.interface';\nimport { CronExpressionParser } from 'cron-parser';\n\n@Injectable()\nexport class SchedulerServiceImpl implements ISchedulerService {\n private readonly logger = new Logger(SchedulerServiceImpl.name);\n private readonly runningJobs = new Set<string>();\n\n constructor(\n // @InjectRepository(ScheduledJob)\n // private readonly scheduledJobRepo: Repository<ScheduledJob>,\n private readonly scheduledJobRepo: ScheduledJobRepository,\n private readonly solidRegistry: SolidRegistry,\n ) { }\n\n @Cron(CronExpression.EVERY_MINUTE)\n async runScheduledJobs(): Promise<void> {\n const solidSchedulerEnabled = process.env.SOLID_SCHEDULER_ENABLED || \"true\";\n if (solidSchedulerEnabled.toLowerCase() !== \"true\") {\n // this.logger.debug('Solid scheduler is disabled via environment variable');\n return;\n }\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n if (solidCliRunning === \"true\") {\n return;\n }\n\n const now = new Date();\n\n // this.logger.log(`[${now.getTime()}]: scheduler service started run...`);\n const dueJobs = await this.scheduledJobRepo.find({\n where: [\n {\n isActive: true,\n nextRunAt: LessThanOrEqual(now),\n },\n // Newly created jobs are also picked for examination \n {\n isActive: true,\n nextRunAt: IsNull(),\n },\n ],\n });\n\n // this.logger.log(`[${now.getTime()}]: scheduler service identified ${dueJobs.length} jobs to run...`);\n\n for (const job of dueJobs) {\n const jobKey = String(job.id ?? job.scheduleName ?? job.job);\n\n if (this.runningJobs.has(jobKey)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job} because a run is already in progress`);\n continue;\n }\n\n if (!this.shouldRunNow(job, now)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job}`);\n continue;\n }\n\n const handler = this.solidRegistry.getScheduledJobProviderInstance(job.job);\n if (!handler) {\n this.logger.warn(`[${now.getTime()}]: scheduler service skipping because job handler not found: ${job.job}`);\n continue;\n }\n\n this.runningJobs.add(jobKey);\n this.logger.log(`[${now.getTime()}]: scheduler service attempting to run job ${job.job}`);\n try {\n // this.logger.log(`[${now.getTime()}]: scheduler service about to run job ${job.job}`);\n await handler.execute(job);\n // this.logger.log(`[${now.getTime()}]: scheduler service finished running job ${job.job}`);\n\n job.isActive = true;\n const finishedAt = new Date();\n job.lastRunAt = finishedAt;\n job.nextRunAt = this.computeNextRunAt(job, finishedAt);\n this.logger.log(`[${now.getTime()}]: scheduler service coomputed next run for ${job.job} as ${job.nextRunAt}`);\n\n await this.scheduledJobRepo.save(job);\n this.logger.log(`[${now.getTime()}]: scheduler service finished running job: ${job.job}`);\n } catch (err) {\n this.logger.error(`[${now.getTime()}]: scheduler service failed to run job ${job.job}`, err.stack);\n } finally {\n this.runningJobs.delete(jobKey);\n }\n }\n }\n\n private shouldRunNow(job: ScheduledJob, now: Date): boolean {\n const today = new Date(now);\n today.setHours(0, 0, 0, 0);\n const timeNow = this.toHHMM(now); // hh:mm\n\n // 1. Check startDate / endDate\n const startDate = this.toDateOnly(job.startDate as unknown as Date | string | null);\n const endDate = this.toDateOnly(job.endDate as unknown as Date | string | null);\n if (startDate && today < startDate) return false;\n if (endDate && today > endDate) return false;\n\n // 2. Check startTime / endTime\n const jobStart = this.toHHMM(job.startTime as unknown as Date | string | null);\n const jobEnd = this.toHHMM(job.endTime as unknown as Date | string | null);\n if (jobStart && timeNow < jobStart) return false;\n if (jobEnd && timeNow > jobEnd) return false;\n\n // 3. Check custom frequency\n if (job.frequency.toLowerCase() === 'custom') {\n // Custom cron expressions handle their own scheduling logic\n // Just check if nextRunAt is due, which was already checked in the query\n return true;\n }\n\n // 3. Check dayOfWeek (for weekly)\n if (job.frequency.toLowerCase() === 'weekly' && job.dayOfWeek) {\n const todayName = now.toLocaleString('en-US', { weekday: 'long' }); // e.g., \"Monday\"\n const days = this.parseDayOfWeek(job.dayOfWeek);\n if (!days.includes(todayName)) return false;\n }\n\n // 4. Check dayOfMonth (for monthly)\n if (job.frequency.toLowerCase() === 'monthly' && job.dayOfMonth) {\n const dom = now.getDate();\n if (dom !== job.dayOfMonth) return false;\n }\n\n return true;\n }\n\n private parseDayOfWeek(dayOfWeek: string): string[] {\n try {\n const parsed = JSON.parse(dayOfWeek);\n return Array.isArray(parsed) ? parsed : [];\n } catch (error) {\n this.logger.warn(`Invalid dayOfWeek JSON '${dayOfWeek}'`, error as any);\n return [];\n }\n }\n\n private toDateOnly(value: Date | string | null | undefined): Date | null {\n if (!value) return null;\n\n if (value instanceof Date) {\n const d = new Date(value);\n d.setHours(0, 0, 0, 0);\n return d;\n }\n\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) return null;\n\n parsed.setHours(0, 0, 0, 0);\n return parsed;\n }\n\n private toHHMM(value: Date | string | null | undefined): string | null {\n if (!value) return null;\n\n if (value instanceof Date) {\n return value.toTimeString().slice(0, 5);\n }\n\n if (typeof value === 'string') {\n const match = value.match(/^(\\d{2}):(\\d{2})/);\n if (match) return `${match[1]}:${match[2]}`;\n\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed.toTimeString().slice(0, 5);\n }\n }\n\n return null;\n }\n\n public computeNextRunForCustomCron(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n if (!job.cronExpression) {\n this.logger.error(`Custom frequency requires cronExpression for job ${job.scheduleName}`);\n // Fallback to daily if cron expression is missing\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n\n try {\n const interval = CronExpressionParser.parse(job.cronExpression, {\n currentDate: from,\n tz: 'UTC'\n });\n const nextRun = interval.next().toDate();\n\n // Validate minimum 1 minute interval\n if (nextRun.getTime() - from.getTime() < 60000) {\n throw new Error('Cron expression interval must be at least 1 minute');\n }\n \n this.logger.log(`Custom cron '${job.cronExpression}' next run: ${nextRun}`);\n return nextRun;\n } catch (error) {\n this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}`, error);\n // Fallback to daily if cron parsing fails\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n\n public computeNextRunAt(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n switch (job.frequency.toLowerCase()) {\n // case 'once':\n // return null; // don't reschedule\n case 'every minute':\n return new Date(base.getTime() + 1 * 60 * 1000);\n case 'hourly':\n return new Date(base.getTime() + 60 * 60 * 1000);\n case 'daily':\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n case 'weekly':\n return new Date(base.getTime() + 7 * 24 * 60 * 60 * 1000);\n case 'monthly':\n const next = new Date(base);\n next.setMonth(base.getMonth() + 1);\n return next;\n case 'custom':\n return this.computeNextRunForCustomCron(job, from);\n default:\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scheduler.service.js","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport { IsNull, LessThanOrEqual } from 'typeorm';\n\nimport { Cron, CronExpression } from '@nestjs/schedule';\nimport { ScheduledJob } from 'src/entities/scheduled-job.entity';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { ScheduledJobRepository } from 'src/repository/scheduled-job.repository';\nimport { ISchedulerService } from './scheduler.interface';\nimport { CronExpressionParser } from 'cron-parser';\n\n@Injectable()\nexport class SchedulerServiceImpl implements ISchedulerService {\n private readonly logger = new Logger(SchedulerServiceImpl.name);\n private readonly runningJobs = new Set<string>();\n\n constructor(\n // @InjectRepository(ScheduledJob)\n // private readonly scheduledJobRepo: Repository<ScheduledJob>,\n private readonly scheduledJobRepo: ScheduledJobRepository,\n private readonly solidRegistry: SolidRegistry,\n ) { }\n\n @Cron(CronExpression.EVERY_MINUTE)\n async runScheduledJobs(): Promise<void> {\n const solidSchedulerEnabled = process.env.SOLID_SCHEDULER_ENABLED || \"true\";\n if (solidSchedulerEnabled.toLowerCase() !== \"true\") {\n // this.logger.debug('Solid scheduler is disabled via environment variable');\n return;\n }\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n if (solidCliRunning === \"true\") {\n return;\n }\n\n const now = new Date();\n\n // this.logger.log(`[${now.getTime()}]: scheduler service started run...`);\n const dueJobs = await this.scheduledJobRepo.find({\n where: [\n {\n isActive: true,\n nextRunAt: LessThanOrEqual(now),\n },\n // Newly created jobs are also picked for examination \n {\n isActive: true,\n nextRunAt: IsNull(),\n },\n ],\n });\n\n // this.logger.log(`[${now.getTime()}]: scheduler service identified ${dueJobs.length} jobs to run...`);\n\n for (const job of dueJobs) {\n const jobKey = String(job.id ?? job.scheduleName ?? job.job);\n\n if (this.runningJobs.has(jobKey)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job} because a run is already in progress`);\n continue;\n }\n\n if (!this.shouldRunNow(job, now)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job}`);\n continue;\n }\n\n const handler = this.solidRegistry.getScheduledJobProviderInstance(job.job);\n if (!handler) {\n this.logger.warn(`[${now.getTime()}]: scheduler service skipping because job handler not found: ${job.job}`);\n continue;\n }\n\n this.runningJobs.add(jobKey);\n this.logger.log(`[${now.getTime()}]: scheduler service attempting to run job ${job.job}`);\n try {\n // this.logger.log(`[${now.getTime()}]: scheduler service about to run job ${job.job}`);\n await handler.execute(job);\n // this.logger.log(`[${now.getTime()}]: scheduler service finished running job ${job.job}`);\n\n job.isActive = true;\n const finishedAt = new Date();\n job.lastRunAt = finishedAt;\n job.nextRunAt = this.computeNextRunAt(job, finishedAt);\n this.logger.log(`[${now.getTime()}]: scheduler service coomputed next run for ${job.job} as ${job.nextRunAt}`);\n\n await this.scheduledJobRepo.save(job);\n this.logger.log(`[${now.getTime()}]: scheduler service finished running job: ${job.job}`);\n } catch (err) {\n this.logger.error(`[${now.getTime()}]: scheduler service failed to run job ${job.job}`, err.stack);\n } finally {\n this.runningJobs.delete(jobKey);\n }\n }\n }\n\n private shouldRunNow(job: ScheduledJob, now: Date): boolean {\n const today = now.toISOString().split('T')[0]; // yyyy-mm-dd\n const timeNow = now.toTimeString().slice(0, 5); // hh:mm\n\n // 1. Check startDate / endDate\n if (job.startDate && new Date(today) < new Date(job.startDate)) return false;\n if (job.endDate && new Date(today) > new Date(job.endDate)) return false;\n\n // 2. Check startTime / endTime\n if (job.startTime) {\n const jobStart = job.startTime.toTimeString().slice(0, 5);\n if (timeNow < jobStart) return false;\n }\n if (job.endTime) {\n const jobEnd = job.endTime.toTimeString().slice(0, 5);\n if (timeNow > jobEnd) return false;\n }\n\n // 3. Check custom frequency\n if (job.frequency.toLowerCase() === 'custom') {\n // Custom cron expressions handle their own scheduling logic\n // Just check if nextRunAt is due, which was already checked in the query\n return true;\n }\n\n // 3. Check dayOfWeek (for weekly)\n if (job.frequency.toLowerCase() === 'weekly' && job.dayOfWeek) {\n const todayName = now.toLocaleString('en-US', { weekday: 'long' }); // e.g., \"Monday\"\n // const days = job.dayOfWeek.split(',').map(d => d.trim());\n const days = JSON.parse(job.dayOfWeek) as string[];\n if (!days.includes(todayName)) return false;\n }\n\n // 4. Check dayOfMonth (for monthly)\n if (job.frequency.toLowerCase() === 'monthly' && job.dayOfMonth) {\n const dom = now.getDate();\n if (dom !== job.dayOfMonth) return false;\n }\n\n return true;\n }\n\n private computeNextRunForCustomCron(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n if (!job.cronExpression) {\n this.logger.error(`Custom frequency requires cronExpression for job ${job.scheduleName}`);\n // Fallback to daily if cron expression is missing\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n\n try {\n const interval = CronExpressionParser.parse(job.cronExpression, {\n currentDate: from,\n tz: 'UTC'\n });\n const nextRun = interval.next().toDate();\n\n // Validate minimum 1 minute interval\n if (nextRun.getTime() - from.getTime() < 60000) {\n throw new Error('Cron expression interval must be at least 1 minute');\n }\n \n this.logger.log(`Custom cron '${job.cronExpression}' next run: ${nextRun}`);\n return nextRun;\n } catch (error) {\n this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}`, error);\n // Fallback to daily if cron parsing fails\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n\n private computeNextRunAt(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n switch (job.frequency.toLowerCase()) {\n // case 'once':\n // return null; // don't reschedule\n case 'every minute':\n return new Date(base.getTime() + 1 * 60 * 1000);\n case 'hourly':\n return new Date(base.getTime() + 60 * 60 * 1000);\n case 'daily':\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n case 'weekly':\n return new Date(base.getTime() + 7 * 24 * 60 * 60 * 1000);\n case 'monthly':\n const next = new Date(base);\n next.setMonth(base.getMonth() + 1);\n return next;\n case 'custom':\n return this.computeNextRunForCustomCron(job, from);\n default:\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-of-dashboard-question-providers-selection-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAuE,kBAAkB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"list-of-dashboard-question-providers-selection-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAuE,kBAAkB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAIhL,qBAEa,iDAAkD,YAAW,kBAAkB,CAAC,yBAAyB,CAAC;IAG/G,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAIjD,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,GAAG,GAAG,CAAC;IASpG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;CAO7G"}
|
|
@@ -13,7 +13,6 @@ exports.ListOfDashboardQuestionProvidersSelectionProvider = void 0;
|
|
|
13
13
|
const common_1 = require("@nestjs/common");
|
|
14
14
|
const selection_provider_decorator_1 = require("../../decorators/selection-provider.decorator");
|
|
15
15
|
const solid_registry_1 = require("../../helpers/solid-registry");
|
|
16
|
-
const dashboard_question_service_1 = require("../dashboard-question.service");
|
|
17
16
|
let ListOfDashboardQuestionProvidersSelectionProvider = class ListOfDashboardQuestionProvidersSelectionProvider {
|
|
18
17
|
constructor(solidRegistry) {
|
|
19
18
|
this.solidRegistry = solidRegistry;
|
|
@@ -33,9 +32,7 @@ let ListOfDashboardQuestionProvidersSelectionProvider = class ListOfDashboardQue
|
|
|
33
32
|
}
|
|
34
33
|
async values(query, ctxt) {
|
|
35
34
|
const dashboardSelectionProviders = this.solidRegistry.getDashboardQuestionDataProviders();
|
|
36
|
-
return dashboardSelectionProviders
|
|
37
|
-
.filter(provider => !dashboard_question_service_1.INBUILT_SQL_DATA_PROVIDERS.includes(provider.name()))
|
|
38
|
-
.map(i => {
|
|
35
|
+
return dashboardSelectionProviders.map(i => {
|
|
39
36
|
return { label: i.name, value: i.name };
|
|
40
37
|
});
|
|
41
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-of-dashboard-question-providers-selection-provider.service.js","sourceRoot":"","sources":["../../../src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,gGAAgF;AAChF,iEAA2D;
|
|
1
|
+
{"version":3,"file":"list-of-dashboard-question-providers-selection-provider.service.js","sourceRoot":"","sources":["../../../src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,gGAAgF;AAChF,iEAA2D;AAOpD,IAAM,iDAAiD,GAAvD,MAAM,iDAAiD;IAE1D,YACqB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAEjD,CAAC;IAED,IAAI;QACA,OAAO,mGAAmG,CAAC;IAC/G,CAAC;IAED,IAAI;QACA,OAAO,mDAAmD,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAmB,EAAE,IAA+B;QAC5D,MAAM,0BAA0B,GAAyD,IAAI,CAAC,aAAa,CAAC,wCAAwC,CAAC,WAAW,CAAC,CAAC;QAClK,IAAI,CAAC,0BAA0B,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,0BAA0B,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,0BAA0B,CAAC,IAAI,EAAE,EAAE,CAAC;IAClG,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,IAA+B;QACvD,MAAM,2BAA2B,GAAG,IAAI,CAAC,aAAa,CAAC,iCAAiC,EAAE,CAAA;QAE1F,OAAO,2BAA2B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YACvC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,CAAC,CAAC,CAAC;IACP,CAAC;CACJ,CAAA;AA/BY,8GAAiD;4DAAjD,iDAAiD;IAF7D,IAAA,gDAAiB,GAAE;IACnB,IAAA,mBAAU,GAAE;qCAI2B,8BAAa;GAHxC,iDAAiD,CA+B7D","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { SelectionProvider } from \"src/decorators/selection-provider.decorator\";\nimport { SolidRegistry } from \"src/helpers/solid-registry\";\nimport { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from \"../../interfaces\";\nimport { SQL_DYNAMIC_PROVIDER_NAME } from \"../dashboard.service\";\n\n\n@SelectionProvider()\n@Injectable()\nexport class ListOfDashboardQuestionProvidersSelectionProvider implements ISelectionProvider<ISelectionProviderContext> {\n\n constructor(\n private readonly solidRegistry: SolidRegistry,\n ) {\n }\n\n help(): string {\n return \"# Allows one to dynamically fetch all the dashboard providers that are registered in the system. \";\n }\n\n name(): string {\n return 'ListOfDashboardQuestionProvidersSelectionProvider';\n }\n\n async value(optionValue: string, ctxt: ISelectionProviderContext): Promise<ISelectionProviderValues | any> {\n const dashboardSelectionProvider: IDashboardQuestionDataProvider<any, any> | undefined = this.solidRegistry.getDashboardQuestionDataProviderInstance(optionValue);\n if (!dashboardSelectionProvider) {\n return null;\n }\n\n return { label: dashboardSelectionProvider.name(), value: dashboardSelectionProvider.name() };\n }\n\n async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {\n const dashboardSelectionProviders = this.solidRegistry.getDashboardQuestionDataProviders()\n //Exclude the SQL dynamic provider from the list, (since although it is a dashboard selection provider, it is not a valid option for the user to select)\n return dashboardSelectionProviders.map(i => {\n return { label: i.name, value: i.name };\n });\n }\n}"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import dayjs from "dayjs";
|
|
2
1
|
import { ValueTransformer } from "typeorm";
|
|
3
|
-
export declare
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export declare const LocalDateTimeTransformer: ValueTransformer & {
|
|
3
|
+
utc: ValueTransformer;
|
|
4
|
+
};
|
|
5
|
+
export declare const UtcDateTimeTransformer: ValueTransformer;
|
|
6
6
|
//# sourceMappingURL=local-date-time-transformer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-date-time-transformer.d.ts","sourceRoot":"","sources":["../../../src/transformers/typeorm/local-date-time-transformer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"local-date-time-transformer.d.ts","sourceRoot":"","sources":["../../../src/transformers/typeorm/local-date-time-transformer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAsB3C,eAAO,MAAM,wBAAwB,EAAE,gBAAgB,GAAG;IAAE,GAAG,EAAE,gBAAgB,CAAA;CAiDhF,CAAC;AAEF,eAAO,MAAM,sBAAsB,kBAA+B,CAAC"}
|
|
@@ -3,9 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.LocalDateTimeTransformer = void 0;
|
|
7
|
-
exports.parseDate = parseDate;
|
|
8
|
-
exports.serializeDate = serializeDate;
|
|
6
|
+
exports.UtcDateTimeTransformer = exports.LocalDateTimeTransformer = void 0;
|
|
9
7
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
10
8
|
const utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
11
9
|
const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
|
|
@@ -22,44 +20,49 @@ function dateToUtcComponentString(d) {
|
|
|
22
20
|
const ms = pad(d.getUTCMilliseconds(), 3);
|
|
23
21
|
return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}.${ms}`;
|
|
24
22
|
}
|
|
25
|
-
function getWallClockConfig() {
|
|
26
|
-
return {
|
|
27
|
-
tz: process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || "UTC",
|
|
28
|
-
wallTimeMode: (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || "").toLowerCase() === "true",
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function parseDate(date) {
|
|
32
|
-
const { tz, wallTimeMode } = getWallClockConfig();
|
|
33
|
-
if (!wallTimeMode)
|
|
34
|
-
return dayjs_1.default.utc(date);
|
|
35
|
-
return (0, dayjs_1.default)(date).tz(tz);
|
|
36
|
-
}
|
|
37
|
-
function serializeDate(date) {
|
|
38
|
-
const { wallTimeMode } = getWallClockConfig();
|
|
39
|
-
if (!wallTimeMode)
|
|
40
|
-
return date.toISOString();
|
|
41
|
-
return parseDate(date).format("YYYY-MM-DD HH:mm:ss.SSS");
|
|
42
|
-
}
|
|
43
23
|
exports.LocalDateTimeTransformer = {
|
|
44
24
|
from(value) {
|
|
25
|
+
const SOLIDX_WALL_TIME_TZ = process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || "UTC";
|
|
26
|
+
const SOLIDX_TIME_STORED_AS_WALL_TIME = (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || "").toLowerCase() === "true";
|
|
45
27
|
if (value === undefined)
|
|
46
28
|
return undefined;
|
|
47
29
|
if (value === null)
|
|
48
30
|
return null;
|
|
49
|
-
|
|
50
|
-
if (!wallTimeMode) {
|
|
31
|
+
if (!SOLIDX_TIME_STORED_AS_WALL_TIME) {
|
|
51
32
|
return (0, dayjs_1.default)(value).toDate();
|
|
52
33
|
}
|
|
53
34
|
const naive = value instanceof Date ? dateToUtcComponentString(value) : String(value);
|
|
54
|
-
return dayjs_1.default.tz(naive,
|
|
35
|
+
return dayjs_1.default.tz(naive, SOLIDX_WALL_TIME_TZ).utc().toDate();
|
|
55
36
|
},
|
|
56
37
|
to(value) {
|
|
38
|
+
const SOLIDX_WALL_TIME_TZ = process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || "UTC";
|
|
39
|
+
const SOLIDX_TIME_STORED_AS_WALL_TIME = (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || "").toLowerCase() === "true";
|
|
57
40
|
if (value === undefined)
|
|
58
41
|
return undefined;
|
|
59
42
|
if (value === null)
|
|
60
43
|
return null;
|
|
61
|
-
|
|
44
|
+
if (!SOLIDX_TIME_STORED_AS_WALL_TIME) {
|
|
45
|
+
return (0, dayjs_1.default)(value).toDate();
|
|
46
|
+
}
|
|
47
|
+
const wallTimeStr = (0, dayjs_1.default)(value).tz(SOLIDX_WALL_TIME_TZ).format("YYYY-MM-DD HH:mm:ss.SSS");
|
|
62
48
|
return dayjs_1.default.utc(wallTimeStr).toDate();
|
|
63
49
|
},
|
|
50
|
+
utc: {
|
|
51
|
+
from(value) {
|
|
52
|
+
if (value === undefined)
|
|
53
|
+
return undefined;
|
|
54
|
+
if (value === null)
|
|
55
|
+
return null;
|
|
56
|
+
return (0, dayjs_1.default)(value).toDate();
|
|
57
|
+
},
|
|
58
|
+
to(value) {
|
|
59
|
+
if (value === undefined)
|
|
60
|
+
return undefined;
|
|
61
|
+
if (value === null)
|
|
62
|
+
return null;
|
|
63
|
+
return (0, dayjs_1.default)(value).toDate();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
64
66
|
};
|
|
67
|
+
exports.UtcDateTimeTransformer = exports.LocalDateTimeTransformer.utc;
|
|
65
68
|
//# sourceMappingURL=local-date-time-transformer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-date-time-transformer.js","sourceRoot":"","sources":["../../../src/transformers/typeorm/local-date-time-transformer.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"local-date-time-transformer.js","sourceRoot":"","sources":["../../../src/transformers/typeorm/local-date-time-transformer.ts"],"names":[],"mappings":"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","sourcesContent":["import dayjs from \"dayjs\";\nimport utc from \"dayjs/plugin/utc\";\nimport timezone from \"dayjs/plugin/timezone\";\n\nimport { ValueTransformer } from \"typeorm\";\n\ndayjs.extend(utc);\ndayjs.extend(timezone);\n\nfunction dateToUtcComponentString(d: Date): string {\n // Requires MSSQL driver option: useUTC: true\n // so that DB \"2026-01-08 10:00:00\" -> Date with UTC parts 2026-01-08 10:00:00\n const pad = (n: number, w = 2) => String(n).padStart(w, \"0\");\n\n const yyyy = d.getUTCFullYear();\n const mm = pad(d.getUTCMonth() + 1);\n const dd = pad(d.getUTCDate());\n const hh = pad(d.getUTCHours());\n const mi = pad(d.getUTCMinutes());\n const ss = pad(d.getUTCSeconds());\n const ms = pad(d.getUTCMilliseconds(), 3);\n\n // A “naive” timestamp string representing the DB wall-clock components\n return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}.${ms}`;\n}\n\nexport const LocalDateTimeTransformer: ValueTransformer & { utc: ValueTransformer } = {\n // DB → Entity\n from(value: Date | string | null | undefined): Date | null | undefined {\n\n const SOLIDX_WALL_TIME_TZ = process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || \"UTC\";\n const SOLIDX_TIME_STORED_AS_WALL_TIME = (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || \"\").toLowerCase() === \"true\";\n\n // critical... super important to return undefined here \n if (value === undefined) return undefined;\n if (value === null) return null;\n\n if (!SOLIDX_TIME_STORED_AS_WALL_TIME) {\n return dayjs(value).toDate();\n }\n\n const naive = value instanceof Date ? dateToUtcComponentString(value) : String(value);\n return dayjs.tz(naive, SOLIDX_WALL_TIME_TZ).utc().toDate();\n },\n\n // Entity → DB\n to(value: Date | null | undefined): Date | null | undefined {\n\n const SOLIDX_WALL_TIME_TZ = process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || \"UTC\";\n const SOLIDX_TIME_STORED_AS_WALL_TIME = (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || \"\").toLowerCase() === \"true\";\n\n // critical... super important to return undefined here \n if (value === undefined) return undefined;\n if (value === null) return null;\n\n if (!SOLIDX_TIME_STORED_AS_WALL_TIME) {\n return dayjs(value).toDate();\n }\n\n const wallTimeStr = dayjs(value).tz(SOLIDX_WALL_TIME_TZ).format(\"YYYY-MM-DD HH:mm:ss.SSS\");\n return dayjs.utc(wallTimeStr).toDate();\n },\n\n utc: {\n from(value: Date | string | null | undefined): Date | null | undefined {\n if (value === undefined) return undefined;\n if (value === null) return null;\n return dayjs(value).toDate();\n },\n to(value: Date | null | undefined): Date | null | undefined {\n if (value === undefined) return undefined;\n if (value === null) return null;\n return dayjs(value).toDate();\n }\n }\n};\n\nexport const UtcDateTimeTransformer = LocalDateTimeTransformer.utc;"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Exclude, Expose } from "class-transformer";
|
|
2
|
-
import { LocalDateTimeTransformer } from "src/transformers/typeorm/local-date-time-transformer";
|
|
3
1
|
import { Column, CreateDateColumn, DeleteDateColumn, Index, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
|
2
|
+
import { Exclude, Expose } from "class-transformer";
|
|
3
|
+
import { LocalDateTimeTransformer, UtcDateTimeTransformer } from "src/transformers/typeorm/local-date-time-transformer";
|
|
4
4
|
|
|
5
5
|
@Exclude()
|
|
6
6
|
export abstract class CommonEntity {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Exclude, Expose } from "class-transformer";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Exclude, Expose, Type } from "class-transformer";
|
|
2
|
+
import { Column, CreateDateColumn, DeleteDateColumn, Index, JoinColumn, ManyToOne, UpdateDateColumn } from "typeorm";
|
|
3
|
+
import type { User } from "./user.entity";
|
|
4
|
+
import { LocalDateTimeTransformer, UtcDateTimeTransformer } from "src/transformers/typeorm/local-date-time-transformer";
|
|
4
5
|
|
|
5
6
|
export const LEGACY_TABLE_FIELDS_PREFIX = 'ss';
|
|
6
7
|
|
|
@@ -11,6 +11,7 @@ export interface MediaFieldOptions {
|
|
|
11
11
|
fieldName: string | undefined | null;
|
|
12
12
|
mediaMaxSizeKb: number | undefined | null;
|
|
13
13
|
mediaTypes: string[];
|
|
14
|
+
isUpdate: boolean | undefined | null;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
type MediaType = 'image' | 'audio' | 'video' | 'file' | 'pdf';
|
|
@@ -119,25 +120,24 @@ export class MediaFieldCrudManager implements FieldCrudManager {
|
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
validate(dto: any, files: Array<Express.Multer.File>): ValidationError[] {
|
|
122
|
-
const isValidateForUpdate = dto.id !== undefined; //FIXME: This is a hack, since we are using PUT for update. Once we support PATCH, this will be removed
|
|
123
123
|
const fieldFiles = files.filter(file => file.fieldname === this.options.fieldName);
|
|
124
|
-
return this.applyValidations(fieldFiles
|
|
124
|
+
return this.applyValidations(fieldFiles);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
private applyValidations(fieldFiles: Array<Express.Multer.File
|
|
127
|
+
private applyValidations(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
|
|
128
128
|
switch (this.options.type) {
|
|
129
129
|
case SolidMediaType.mediaSingle:
|
|
130
|
-
return this.validateMediaSingle(fieldFiles
|
|
130
|
+
return this.validateMediaSingle(fieldFiles);
|
|
131
131
|
case SolidMediaType.mediaMultiple:
|
|
132
|
-
return this.validateMediaMultiple(fieldFiles
|
|
132
|
+
return this.validateMediaMultiple(fieldFiles);
|
|
133
133
|
default:
|
|
134
134
|
return [];
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
private validateMediaSingle(fieldFiles: Array<Express.Multer.File
|
|
138
|
+
private validateMediaSingle(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
|
|
139
139
|
const errors: ValidationError[] = [];
|
|
140
|
-
if (!
|
|
140
|
+
if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
|
|
141
141
|
errors.push({
|
|
142
142
|
field: this.options.fieldName,
|
|
143
143
|
error: `${this.options.fieldName} is required`
|
|
@@ -184,9 +184,9 @@ export class MediaFieldCrudManager implements FieldCrudManager {
|
|
|
184
184
|
return errors;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
private validateMediaMultiple(fieldFiles: Array<Express.Multer.File
|
|
187
|
+
private validateMediaMultiple(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
|
|
188
188
|
const errors: ValidationError[] = [];
|
|
189
|
-
if (!
|
|
189
|
+
if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
|
|
190
190
|
errors.push({
|
|
191
191
|
field: this.options.fieldName,
|
|
192
192
|
error: `${this.options.fieldName} is required`
|
package/src/interfaces.ts
CHANGED
|
@@ -136,18 +136,12 @@ export interface IMcpToolResponseHandler {
|
|
|
136
136
|
apply(aiInteraction: AiInteraction);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
export interface QuestionSqlDataProviderContext {
|
|
140
|
-
// questionSqlDatasetConfig: QuestionSqlDatasetConfig;
|
|
141
|
-
// questionId: number;
|
|
142
|
-
// question: Question;
|
|
143
|
-
expressions?: SqlExpression[]
|
|
144
|
-
}
|
|
145
139
|
export interface IDashboardQuestionDataProvider<TContext, TData> {
|
|
146
140
|
help(): string;
|
|
147
141
|
|
|
148
142
|
name(): string;
|
|
149
143
|
|
|
150
|
-
getData(question: DashboardQuestion, ctxt?: TContext): Promise<TData[] | TData>;
|
|
144
|
+
getData(question: DashboardQuestion, expressions?: SqlExpression[], ctxt?: TContext): Promise<TData[] | TData>;
|
|
151
145
|
}
|
|
152
146
|
|
|
153
147
|
/**
|
|
@@ -5721,7 +5721,7 @@
|
|
|
5721
5721
|
"modelUserKey": "listOfValues"
|
|
5722
5722
|
},
|
|
5723
5723
|
{
|
|
5724
|
-
"displayName": "Import Transactions",
|
|
5724
|
+
"displayName": "Import Transactions List Action",
|
|
5725
5725
|
"name": "importTransaction-list-action",
|
|
5726
5726
|
"type": "solid",
|
|
5727
5727
|
"domain": "",
|
|
@@ -5734,7 +5734,7 @@
|
|
|
5734
5734
|
"modelUserKey": "importTransaction"
|
|
5735
5735
|
},
|
|
5736
5736
|
{
|
|
5737
|
-
"displayName": "User Activity History",
|
|
5737
|
+
"displayName": "User Activity History List Action",
|
|
5738
5738
|
"name": "userActivityHistory-list-action",
|
|
5739
5739
|
"type": "solid",
|
|
5740
5740
|
"domain": "",
|
|
@@ -5746,19 +5746,6 @@
|
|
|
5746
5746
|
"moduleUserKey": "solid-core",
|
|
5747
5747
|
"modelUserKey": "userActivityHistory"
|
|
5748
5748
|
},
|
|
5749
|
-
{
|
|
5750
|
-
"displayName": "User Activity History",
|
|
5751
|
-
"name": "userActivityHistory-tree-action",
|
|
5752
|
-
"type": "solid",
|
|
5753
|
-
"domain": "",
|
|
5754
|
-
"context": "",
|
|
5755
|
-
"customComponent": "",
|
|
5756
|
-
"customIsModal": true,
|
|
5757
|
-
"serverEndpoint": "",
|
|
5758
|
-
"viewUserKey": "userActivityHistory-tree-view",
|
|
5759
|
-
"moduleUserKey": "solid-core",
|
|
5760
|
-
"modelUserKey": "userActivityHistory"
|
|
5761
|
-
},
|
|
5762
5749
|
{
|
|
5763
5750
|
"displayName": "App Settings",
|
|
5764
5751
|
"name": "appSettings-action",
|
|
@@ -11170,64 +11157,7 @@
|
|
|
11170
11157
|
{
|
|
11171
11158
|
"type": "field",
|
|
11172
11159
|
"attrs": {
|
|
11173
|
-
"name": "
|
|
11174
|
-
"sortable": true,
|
|
11175
|
-
"filterable": true
|
|
11176
|
-
}
|
|
11177
|
-
}
|
|
11178
|
-
]
|
|
11179
|
-
}
|
|
11180
|
-
},
|
|
11181
|
-
{
|
|
11182
|
-
"name": "userActivityHistory-tree-view",
|
|
11183
|
-
"displayName": "User Activity History",
|
|
11184
|
-
"type": "tree",
|
|
11185
|
-
"context": "{}",
|
|
11186
|
-
"moduleUserKey": "solid-core",
|
|
11187
|
-
"modelUserKey": "userActivityHistory",
|
|
11188
|
-
"layout": {
|
|
11189
|
-
"type": "tree",
|
|
11190
|
-
"attrs": {
|
|
11191
|
-
"pagination": true,
|
|
11192
|
-
"pageSizeOptions": [
|
|
11193
|
-
10,
|
|
11194
|
-
25,
|
|
11195
|
-
50
|
|
11196
|
-
],
|
|
11197
|
-
"enableGlobalSearch": true,
|
|
11198
|
-
"create": true,
|
|
11199
|
-
"edit": true,
|
|
11200
|
-
"delete": true
|
|
11201
|
-
},
|
|
11202
|
-
"children": [
|
|
11203
|
-
{
|
|
11204
|
-
"type": "field",
|
|
11205
|
-
"attrs": {
|
|
11206
|
-
"name": "id",
|
|
11207
|
-
"sortable": true,
|
|
11208
|
-
"filterable": true
|
|
11209
|
-
}
|
|
11210
|
-
},
|
|
11211
|
-
{
|
|
11212
|
-
"type": "field",
|
|
11213
|
-
"attrs": {
|
|
11214
|
-
"name": "user",
|
|
11215
|
-
"sortable": true,
|
|
11216
|
-
"filterable": true
|
|
11217
|
-
}
|
|
11218
|
-
},
|
|
11219
|
-
{
|
|
11220
|
-
"type": "field",
|
|
11221
|
-
"attrs": {
|
|
11222
|
-
"name": "event",
|
|
11223
|
-
"sortable": true,
|
|
11224
|
-
"filterable": true
|
|
11225
|
-
}
|
|
11226
|
-
},
|
|
11227
|
-
{
|
|
11228
|
-
"type": "field",
|
|
11229
|
-
"attrs": {
|
|
11230
|
-
"name": "ipAddress",
|
|
11160
|
+
"name": "userAgent",
|
|
11231
11161
|
"sortable": true,
|
|
11232
11162
|
"filterable": true
|
|
11233
11163
|
}
|