@geniehr/utilities 1.0.13 → 1.0.15

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.
@@ -0,0 +1,11 @@
1
+ export declare class ConductorClient {
2
+ private client;
3
+ private workers;
4
+ constructor(serviceName?: string);
5
+ startWorkflow(name: string, input: any, correlationId?: string, version?: number): Promise<any>;
6
+ registerWorker(taskType: string, execute: (input: any) => Promise<any>, pollInterval?: number, domain?: string): Promise<void>;
7
+ private poll;
8
+ updateTask(taskId: string, workflowInstanceId: string, status: string, outputData: any, reasonForIncompletion?: string): Promise<void>;
9
+ getTask(workflowInstanceId: string, taskReferenceName: string): Promise<any>;
10
+ getWorkflow(workflowInstanceId: string, includeTasks?: boolean): Promise<any>;
11
+ }
@@ -0,0 +1,120 @@
1
+ import axios from 'axios';
2
+ const WORKFLOW_API_URL = process.env.CONDUCTOR_SERVER_URL || 'http://localhost:8080/api';
3
+ export class ConductorClient {
4
+ client;
5
+ workers = {};
6
+ constructor(serviceName = 'claims-service') {
7
+ this.client = axios.create({
8
+ baseURL: WORKFLOW_API_URL,
9
+ headers: {
10
+ 'Content-Type': 'application/json',
11
+ }
12
+ });
13
+ console.log(`ConductorClient initialized for ${serviceName}`);
14
+ }
15
+ async startWorkflow(name, input, correlationId, version) {
16
+ try {
17
+ const payload = {
18
+ name,
19
+ input,
20
+ correlationId
21
+ };
22
+ if (version) {
23
+ payload.version = version;
24
+ }
25
+ const response = await this.client.post('/workflow', payload);
26
+ console.log(`Started workflow ${name} v${version}: ${JSON.stringify(response.data)}`);
27
+ return response.data;
28
+ }
29
+ catch (error) {
30
+ console.error(`Error starting workflow ${name}:`, error.message);
31
+ throw error;
32
+ }
33
+ }
34
+ async registerWorker(taskType, execute, pollInterval = 1000, domain) {
35
+ if (this.workers[taskType]) {
36
+ console.warn(`Worker for ${taskType} already registered.`);
37
+ return;
38
+ }
39
+ this.workers[taskType] = true;
40
+ console.log(`Registered worker for ${taskType}`);
41
+ this.poll(taskType, execute, pollInterval, domain);
42
+ }
43
+ async poll(taskType, execute, interval, domain) {
44
+ while (this.workers[taskType]) {
45
+ try {
46
+ // Poll for a task
47
+ // GET /tasks/poll/{taskType}?workerid=...&domain=...
48
+ const workerId = `worker-${process.pid}`;
49
+ const response = await this.client.get(`/tasks/poll/${taskType}`, {
50
+ params: {
51
+ workerid: workerId,
52
+ domain
53
+ }
54
+ });
55
+ const task = response.data;
56
+ if (task && task.taskId) {
57
+ console.log(`Received task ${taskType} (ID: ${task.taskId})`);
58
+ let status = 'COMPLETED';
59
+ let outputData = {};
60
+ let reasonForIncompletion = '';
61
+ try {
62
+ outputData = await execute(task.inputData);
63
+ }
64
+ catch (err) {
65
+ console.error(`Error executing task ${taskType}:`, err.message);
66
+ status = 'FAILED';
67
+ reasonForIncompletion = err.message || 'Unknown error';
68
+ }
69
+ // Update task status
70
+ await this.updateTask(task.taskId, task.workflowInstanceId, status, outputData, reasonForIncompletion);
71
+ }
72
+ }
73
+ catch (error) {
74
+ // If polling fails (e.g. 204 No Content or connection error), just log debug/warn and wait
75
+ // console.debug(`Polling error for ${taskType}: ${error}`);
76
+ }
77
+ // Wait before next poll
78
+ await new Promise(resolve => setTimeout(resolve, interval));
79
+ }
80
+ }
81
+ async updateTask(taskId, workflowInstanceId, status, outputData, reasonForIncompletion) {
82
+ try {
83
+ await this.client.post('/tasks', {
84
+ taskId,
85
+ workflowInstanceId,
86
+ status,
87
+ outputData,
88
+ reasonForIncompletion
89
+ });
90
+ console.log(`Updated task ${taskId} to ${status}`);
91
+ }
92
+ catch (error) {
93
+ console.error(`Failed to update task ${taskId}:`, error.message);
94
+ }
95
+ }
96
+ async getTask(workflowInstanceId, taskReferenceName) {
97
+ try {
98
+ const response = await this.client.get(`/workflow/${workflowInstanceId}`);
99
+ const workflow = response.data;
100
+ if (workflow && workflow.tasks) {
101
+ return workflow.tasks.find((t) => t.referenceTaskName === taskReferenceName && t.status === 'IN_PROGRESS');
102
+ }
103
+ return null;
104
+ }
105
+ catch (error) {
106
+ console.error(`Error getting workflow tasks:`, error.message);
107
+ return null;
108
+ }
109
+ }
110
+ async getWorkflow(workflowInstanceId, includeTasks = true) {
111
+ try {
112
+ const response = await this.client.get(`/workflow/${workflowInstanceId}?includeTasks=${includeTasks}`);
113
+ return response.data;
114
+ }
115
+ catch (error) {
116
+ console.error(`Error getting workflow:`, error.message);
117
+ throw error;
118
+ }
119
+ }
120
+ }
package/dist/index.d.ts CHANGED
@@ -4,9 +4,10 @@ export { getContext, setExtras, setContext } from './shared/context/index.js';
4
4
  export { LoggerService as Logger } from './logger/LoggerService.js';
5
5
  export { HttpStatusCode } from './shared/enums/HttpStatusCodes.js';
6
6
  export { InvalidRequestException, InvalidEnvironmentException, AppException } from './shared/exceptions/index.js';
7
- export { getAWSParameters, matchFace, registerFace, generatePresignedUrl, getCustomAttribute, updateCustomAttribute, executeS3Action } from './secrets/aws.js';
7
+ export { getAWSParameters, matchFace, registerFace, generatePresignedUrl, getCustomAttribute, updateCustomAttribute, executeS3Action, sendEmail } from './secrets/aws.js';
8
8
  export { CognitoUserService } from './secrets/CognitoUserService.js';
9
9
  export { HttpClient, GraphQLClient } from './apiUtils/httpUtils.js';
10
10
  export { sendResponse } from './apiUtils/api.js';
11
11
  export { services } from './shared/services.js';
12
12
  export { ImageCompressor } from './shared/helper/ImageCompressor.js';
13
+ export { ConductorClient } from './conductor/ConductorClient.js';
package/dist/index.js CHANGED
@@ -4,9 +4,10 @@ export { getContext, setExtras, setContext } from './shared/context/index.js';
4
4
  export { LoggerService as Logger } from './logger/LoggerService.js';
5
5
  export { HttpStatusCode } from './shared/enums/HttpStatusCodes.js';
6
6
  export { InvalidRequestException, InvalidEnvironmentException, AppException } from './shared/exceptions/index.js';
7
- export { getAWSParameters, matchFace, registerFace, generatePresignedUrl, getCustomAttribute, updateCustomAttribute, executeS3Action } from './secrets/aws.js';
7
+ export { getAWSParameters, matchFace, registerFace, generatePresignedUrl, getCustomAttribute, updateCustomAttribute, executeS3Action, sendEmail } from './secrets/aws.js';
8
8
  export { CognitoUserService } from './secrets/CognitoUserService.js';
9
9
  export { HttpClient, GraphQLClient } from './apiUtils/httpUtils.js';
10
10
  export { sendResponse } from './apiUtils/api.js';
11
11
  export { services } from './shared/services.js';
12
12
  export { ImageCompressor } from './shared/helper/ImageCompressor.js';
13
+ export { ConductorClient } from './conductor/ConductorClient.js';
@@ -17,3 +17,4 @@ export declare function getCustomAttribute(username: string, userPoolId: string,
17
17
  value?: string;
18
18
  message: string;
19
19
  }>;
20
+ export declare function sendEmail(fromAddress: string, to: string[], displayName: string, cc: string[] | undefined, bcc: string[] | undefined, subject: string, htmlBody: string, metaData?: Record<string, any>): Promise<import("@aws-sdk/client-ses").SendEmailCommandOutput>;
@@ -4,6 +4,7 @@ import { AppException } from '../shared/exceptions/index.js';
4
4
  import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
5
5
  import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
6
6
  import { CognitoIdentityProviderClient, AdminUpdateUserAttributesCommand, AdminGetUserCommand } from '@aws-sdk/client-cognito-identity-provider';
7
+ import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";
7
8
  let ssm;
8
9
  let rand = Math.random().toString();
9
10
  const env = process.env.NODE_ENV || rand;
@@ -21,6 +22,10 @@ const client = new CognitoIdentityProviderClient({
21
22
  region: 'ap-south-1',
22
23
  credentials: env === 'local' ? fromIni({ profile: 'ghr-aws-dev-profile' }) : undefined
23
24
  });
25
+ const ses = new SESClient({
26
+ region: 'ap-south-1',
27
+ credentials: env === 'local' ? fromIni({ profile: 'ghr-aws-dev-profile' }) : undefined
28
+ });
24
29
  /**
25
30
  * Fetch a single parameter or all parameters under a prefix.
26
31
  * @param nameOrPrefix Full name (e.g. /dev/mysql/person) or prefix (e.g. /dev/mysql/)
@@ -219,3 +224,32 @@ export async function getCustomAttribute(username, userPoolId, attributeName) {
219
224
  };
220
225
  }
221
226
  }
227
+ export async function sendEmail(fromAddress, to, displayName, cc = [], bcc = [], subject, htmlBody, metaData = {}) {
228
+ try {
229
+ const command = new SendEmailCommand({
230
+ Source: displayName ? `"${displayName}" <${fromAddress}>` : fromAddress,
231
+ Destination: {
232
+ ToAddresses: to,
233
+ CcAddresses: cc,
234
+ BccAddresses: bcc,
235
+ },
236
+ Message: {
237
+ Subject: {
238
+ Data: subject,
239
+ Charset: "UTF-8",
240
+ },
241
+ Body: {
242
+ Html: {
243
+ Data: htmlBody,
244
+ Charset: "UTF-8",
245
+ },
246
+ },
247
+ },
248
+ });
249
+ const result = await ses.send(command);
250
+ return result;
251
+ }
252
+ catch (error) {
253
+ throw new AppException(`Failed to send email: ${error instanceof Error ? error.message : "Unknown error"}`, "E-Send-Email-Failed");
254
+ }
255
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geniehr/utilities",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/Genie-HR/ghr-utilities#readme",
6
6
  "bugs": {
@@ -31,6 +31,7 @@
31
31
  "@aws-sdk/client-cognito-identity-provider": "^3.859.0",
32
32
  "@aws-sdk/client-rekognition": "^3.846.0",
33
33
  "@aws-sdk/client-s3": "^3.848.0",
34
+ "@aws-sdk/client-ses": "^3.986.0",
34
35
  "@aws-sdk/client-ssm": "^3.839.0",
35
36
  "@aws-sdk/credential-providers": "^3.839.0",
36
37
  "@aws-sdk/s3-request-presigner": "^3.848.0",