plenna_utilities 1.5.2 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +6 -0
  3. package/dist/src/alerts/application/send-alert-impl.service.d.ts +8 -0
  4. package/dist/src/alerts/application/send-alert-impl.service.js +20 -0
  5. package/dist/src/alerts/domain/interfaces/alerts.d.ts +49 -0
  6. package/dist/src/alerts/domain/interfaces/alerts.js +2 -0
  7. package/dist/src/alerts/domain/services/send-alert.service.d.ts +4 -0
  8. package/dist/src/alerts/domain/services/send-alert.service.js +6 -0
  9. package/dist/src/alerts/domain/usecases/send-alert.usecase.d.ts +9 -0
  10. package/dist/src/alerts/domain/usecases/send-alert.usecase.js +48 -0
  11. package/dist/src/alerts/presenter/index.d.ts +2 -0
  12. package/dist/src/alerts/presenter/index.js +11 -0
  13. package/dist/src/common/domain/alerts/alerts.d.ts +4 -0
  14. package/dist/src/common/domain/alerts/alerts.js +6 -0
  15. package/dist/src/common/domain/configurations/configurations.d.ts +3 -0
  16. package/dist/src/common/domain/configurations/configurations.js +6 -0
  17. package/dist/src/common/domain/interfaces/products.interfaces.d.ts +3 -0
  18. package/dist/src/common/domain/interfaces/products.interfaces.js +7 -0
  19. package/dist/src/common/domain/interfaces/usecases.interface.d.ts +3 -0
  20. package/dist/src/common/domain/interfaces/usecases.interface.js +2 -0
  21. package/dist/src/common/domain/shared/interpolation.transformer.d.ts +2 -0
  22. package/dist/src/common/domain/shared/interpolation.transformer.js +13 -0
  23. package/dist/src/common/infrastructure/slack/slack.d.ts +7 -0
  24. package/dist/src/common/infrastructure/slack/slack.js +37 -0
  25. package/dist/src/common/infrastructure/yaml-converter/configurations/slack.yaml +32 -0
  26. package/dist/src/common/infrastructure/yaml-converter/yaml-converter.d.ts +4 -0
  27. package/dist/src/common/infrastructure/yaml-converter/yaml-converter.js +28 -0
  28. package/dist/src/customerio/index.d.ts +3 -1
  29. package/dist/src/customerio/index.js +13 -0
  30. package/dist/src/time/index.d.ts +1 -0
  31. package/dist/src/time/index.js +5 -1
  32. package/package.json +10 -5
package/dist/index.d.ts CHANGED
@@ -6,3 +6,4 @@ export * from './src/general';
6
6
  export * from './src/customerio';
7
7
  export * from './src/mailer';
8
8
  export * from './src/airTable';
9
+ export * from './src/alerts/presenter';
package/dist/index.js CHANGED
@@ -13,7 +13,12 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
13
13
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
16
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
+ const dotenv_1 = __importDefault(require("dotenv"));
21
+ dotenv_1.default.config();
17
22
  __exportStar(require("./src/lambdas"), exports);
18
23
  __exportStar(require("./src/time"), exports);
19
24
  __exportStar(require("./src/s3"), exports);
@@ -22,3 +27,4 @@ __exportStar(require("./src/general"), exports);
22
27
  __exportStar(require("./src/customerio"), exports);
23
28
  __exportStar(require("./src/mailer"), exports);
24
29
  __exportStar(require("./src/airTable"), exports);
30
+ __exportStar(require("./src/alerts/presenter"), exports);
@@ -0,0 +1,8 @@
1
+ import { type AlertsHandler } from '../../common/domain/alerts/alerts';
2
+ import { type AlertResponse, type IAlert } from '../domain/interfaces/alerts';
3
+ import { AlertService } from '../domain/services/send-alert.service';
4
+ export declare class AlertServiceImpl extends AlertService {
5
+ private readonly alertImpl;
6
+ constructor(alertImpl: AlertsHandler);
7
+ sendAlert(alert: IAlert): Promise<AlertResponse | undefined>;
8
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AlertServiceImpl = void 0;
4
+ const send_alert_service_1 = require("../domain/services/send-alert.service");
5
+ class AlertServiceImpl extends send_alert_service_1.AlertService {
6
+ alertImpl;
7
+ constructor(alertImpl) {
8
+ super();
9
+ this.alertImpl = alertImpl;
10
+ }
11
+ async sendAlert(alert) {
12
+ try {
13
+ return await this.alertImpl.sendAlert(alert);
14
+ }
15
+ catch (error) {
16
+ console.info(error);
17
+ }
18
+ }
19
+ }
20
+ exports.AlertServiceImpl = AlertServiceImpl;
@@ -0,0 +1,49 @@
1
+ export interface TextObject {
2
+ type: 'plain_text' | 'mrkdwn';
3
+ text: string;
4
+ emoji?: boolean;
5
+ }
6
+ export interface FieldObject {
7
+ type: 'mrkdwn';
8
+ text: string;
9
+ }
10
+ export interface HeaderBlock {
11
+ type: 'header';
12
+ text: TextObject;
13
+ }
14
+ export interface SectionBlock {
15
+ type: 'section';
16
+ text: TextObject;
17
+ fields?: FieldObject[];
18
+ }
19
+ export interface DividerBlock {
20
+ type: 'divider';
21
+ }
22
+ export interface ContextBlock {
23
+ type: 'context';
24
+ elements: TextObject[];
25
+ }
26
+ export type Block = HeaderBlock | SectionBlock | DividerBlock | ContextBlock;
27
+ export interface IAlert {
28
+ channel: string;
29
+ text: string;
30
+ blocks?: Block[];
31
+ threadTs?: string;
32
+ }
33
+ export interface ITemplatesConfiguration {
34
+ templates: Record<string, IAlert>;
35
+ }
36
+ export interface AlertTemplateInput {
37
+ template?: string;
38
+ date?: string;
39
+ text?: string;
40
+ bookingUser?: string;
41
+ channel?: string;
42
+ origin?: string;
43
+ huliId?: string;
44
+ threadTs?: string;
45
+ }
46
+ export interface AlertResponse {
47
+ channel: string;
48
+ ts: string;
49
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ import { type AlertResponse, type IAlert } from '../interfaces/alerts';
2
+ export declare abstract class AlertService {
3
+ abstract sendAlert(alert: IAlert): Promise<AlertResponse | undefined>;
4
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AlertService = void 0;
4
+ class AlertService {
5
+ }
6
+ exports.AlertService = AlertService;
@@ -0,0 +1,9 @@
1
+ import { type Configuration } from '../../../common/domain/configurations/configurations';
2
+ import { type UseCase } from '../../../common/domain/interfaces/usecases.interface';
3
+ import { type AlertService } from '../services/send-alert.service';
4
+ export declare class SendAlertUseCase implements UseCase {
5
+ private readonly configuration;
6
+ private readonly alertService;
7
+ constructor(configuration: Configuration, alertService: AlertService);
8
+ exec(...args: any[]): Promise<any>;
9
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SendAlertUseCase = void 0;
4
+ const products_interfaces_1 = require("../../../common/domain/interfaces/products.interfaces");
5
+ const interpolation_transformer_1 = require("../../../common/domain/shared/interpolation.transformer");
6
+ class SendAlertUseCase {
7
+ configuration;
8
+ alertService;
9
+ constructor(configuration, alertService) {
10
+ this.configuration = configuration;
11
+ this.alertService = alertService;
12
+ }
13
+ async exec(...args) {
14
+ try {
15
+ const [input] = args;
16
+ const alertData = input;
17
+ if (alertData?.origin === null || alertData?.origin === undefined)
18
+ return;
19
+ if (alertData?.channel !== '' && alertData?.channel !== undefined) {
20
+ const alert = {
21
+ channel: alertData.channel ?? '',
22
+ text: alertData.text ?? '',
23
+ threadTs: alertData?.threadTs
24
+ };
25
+ return await this.alertService.sendAlert(alert);
26
+ }
27
+ const getConfiguration = await this.configuration.getConfiguration(products_interfaces_1.Products.SLACK);
28
+ if (getConfiguration === undefined)
29
+ throw new Error('configuration not found');
30
+ const templateKey = alertData.template ?? '';
31
+ const templateInfo = getConfiguration.templates[templateKey];
32
+ if (templateInfo === null && templateInfo === undefined)
33
+ throw new Error('template not found');
34
+ if (templateInfo.blocks !== undefined) {
35
+ templateInfo.blocks.forEach((block) => {
36
+ if (block.type === 'section' && block.fields != null) {
37
+ block.fields = (0, interpolation_transformer_1.interpolateFields)(block.fields, alertData);
38
+ }
39
+ });
40
+ }
41
+ return await this.alertService.sendAlert(templateInfo);
42
+ }
43
+ catch (error) {
44
+ console.error(error);
45
+ }
46
+ }
47
+ }
48
+ exports.SendAlertUseCase = SendAlertUseCase;
@@ -0,0 +1,2 @@
1
+ import { SendAlertUseCase } from '../domain/usecases/send-alert.usecase';
2
+ export declare const sendAlert: SendAlertUseCase;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendAlert = void 0;
4
+ const slack_1 = require("../../common/infrastructure/slack/slack");
5
+ const yaml_converter_1 = require("../../common/infrastructure/yaml-converter/yaml-converter");
6
+ const send_alert_impl_service_1 = require("../application/send-alert-impl.service");
7
+ const send_alert_usecase_1 = require("../domain/usecases/send-alert.usecase");
8
+ const alertImpl = new slack_1.SlackImpl(process.env.SLACK_TOKEN ?? '');
9
+ const configuration = new yaml_converter_1.ConfigurationYaml();
10
+ const alertService = new send_alert_impl_service_1.AlertServiceImpl(alertImpl);
11
+ exports.sendAlert = new send_alert_usecase_1.SendAlertUseCase(configuration, alertService);
@@ -0,0 +1,4 @@
1
+ import { type AlertResponse } from '../../../alerts/domain/interfaces/alerts';
2
+ export declare abstract class AlertsHandler {
3
+ abstract sendAlert(...args: any[]): Promise<AlertResponse | undefined>;
4
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AlertsHandler = void 0;
4
+ class AlertsHandler {
5
+ }
6
+ exports.AlertsHandler = AlertsHandler;
@@ -0,0 +1,3 @@
1
+ export declare abstract class Configuration {
2
+ abstract getConfiguration<T>(product: string, customPath?: string): Promise<T | undefined>;
3
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Configuration = void 0;
4
+ class Configuration {
5
+ }
6
+ exports.Configuration = Configuration;
@@ -0,0 +1,3 @@
1
+ export declare enum Products {
2
+ SLACK = "slack"
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Products = void 0;
4
+ var Products;
5
+ (function (Products) {
6
+ Products["SLACK"] = "slack";
7
+ })(Products || (exports.Products = Products = {}));
@@ -0,0 +1,3 @@
1
+ export interface UseCase {
2
+ exec: (...args: any[]) => Promise<any>;
3
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import { type AlertTemplateInput, type FieldObject } from '../../../alerts/domain/interfaces/alerts';
2
+ export declare function interpolateFields(fields: FieldObject[], input: AlertTemplateInput): FieldObject[];
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.interpolateFields = interpolateFields;
4
+ function interpolateFields(fields, input) {
5
+ return fields.map((field) => {
6
+ let text = field.text;
7
+ text = text.replace(/\{(\w+)\}/g, (_, key) => {
8
+ const value = input[key];
9
+ return value ?? `{${key}}`;
10
+ });
11
+ return { ...field, text };
12
+ });
13
+ }
@@ -0,0 +1,7 @@
1
+ import { type AlertResponse } from '../../../alerts/domain/interfaces/alerts';
2
+ import { AlertsHandler } from '../../domain/alerts/alerts';
3
+ export declare class SlackImpl extends AlertsHandler {
4
+ private readonly client;
5
+ constructor(token: string);
6
+ sendAlert(...args: any[]): Promise<AlertResponse | undefined>;
7
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SlackImpl = void 0;
4
+ const alerts_1 = require("../../domain/alerts/alerts");
5
+ const web_api_1 = require("@slack/web-api");
6
+ class SlackImpl extends alerts_1.AlertsHandler {
7
+ client;
8
+ constructor(token) {
9
+ super();
10
+ this.client = new web_api_1.WebClient(token);
11
+ }
12
+ async sendAlert(...args) {
13
+ try {
14
+ const [input] = args;
15
+ const data = input;
16
+ const { channel, text, blocks, threadTs } = data;
17
+ if (typeof channel !== 'string' || channel.trim() === '' ||
18
+ typeof text !== 'string' || text.trim() === '') {
19
+ return;
20
+ }
21
+ const response = await this.client.chat.postMessage({
22
+ channel,
23
+ text,
24
+ blocks,
25
+ thread_ts: threadTs
26
+ });
27
+ return {
28
+ channel: response?.channel ?? '',
29
+ ts: response?.ts ?? ''
30
+ };
31
+ }
32
+ catch (error) {
33
+ console.info(JSON.stringify(error));
34
+ }
35
+ }
36
+ }
37
+ exports.SlackImpl = SlackImpl;
@@ -0,0 +1,32 @@
1
+ templates:
2
+ noInfo:
3
+ channel: 'C08S575SWCF'
4
+ text: 'Alerta !!!'
5
+ blocks:
6
+ - type: header
7
+ text:
8
+ type: plain_text
9
+ text: '🚨 Error de Agenda'
10
+ emoji: true
11
+ - type: section
12
+ text:
13
+ type: mrkdwn
14
+ text: '*Motivo:* Se ha creado una agenda con información erronea!!'
15
+ fields:
16
+ - type: mrkdwn
17
+ text: "*ID de cita en Huli:*\n{huliId}"
18
+ - type: mrkdwn
19
+ text: "*Persona que intentó agendar:*\n<{bookingUser}>"
20
+ - type: mrkdwn
21
+ text: "*¿Qué pasó?:*\n{text}"
22
+ - type: mrkdwn
23
+ text: "*¿Qué debes hacer?:*\ncancelar y volver a crear la cita correctamente."
24
+ - type: mrkdwn
25
+ text: "*Fecha:*\n{date}"
26
+ - type: mrkdwn
27
+ text: "*Origen:*\n{origin}"
28
+ - type: divider
29
+ - type: context
30
+ elements:
31
+ - type: mrkdwn
32
+ text: 'Generado automáticamente por el sistema de validación de agendas.'
@@ -0,0 +1,4 @@
1
+ import { Configuration } from '../../../common/domain/configurations/configurations';
2
+ export declare class ConfigurationYaml extends Configuration {
3
+ getConfiguration<T>(product: string, customPath?: string): Promise<T | undefined>;
4
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ConfigurationYaml = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const yaml_1 = __importDefault(require("yaml"));
10
+ const configurations_1 = require("../../../common/domain/configurations/configurations");
11
+ class ConfigurationYaml extends configurations_1.Configuration {
12
+ async getConfiguration(product, customPath) {
13
+ try {
14
+ const finalPath = typeof customPath === 'string' && customPath.trim() !== ''
15
+ ? path_1.default.resolve(customPath)
16
+ : path_1.default.resolve(__dirname, 'configurations');
17
+ const yamlFilePath = path_1.default.join(finalPath, `${product.replace(/ /g, '_').toLocaleLowerCase()}.yaml`);
18
+ const yamlContent = fs_1.default.readFileSync(yamlFilePath, 'utf-8');
19
+ const yamlObject = yaml_1.default.parse(yamlContent);
20
+ return yamlObject;
21
+ }
22
+ catch (error) {
23
+ console.error(`Error loading YAML configuration for ${product}:`, error);
24
+ return undefined;
25
+ }
26
+ }
27
+ }
28
+ exports.ConfigurationYaml = ConfigurationYaml;
@@ -1,7 +1,9 @@
1
- import { type SendPushRequestOptions } from 'customerio-node/dist/lib/api/requests';
1
+ import { type SendEmailRequestOptions, type SendPushRequestOptions } from 'customerio-node/dist/lib/api/requests';
2
2
  export type PushRequestOptions = SendPushRequestOptions;
3
+ export type EmailRequestOptions = SendEmailRequestOptions;
3
4
  export declare class CustomerIo {
4
5
  private readonly key;
5
6
  constructor(key: string);
6
7
  sendPushNotification(requestOptions: PushRequestOptions): Promise<boolean>;
8
+ sendEmail(requestOptions: EmailRequestOptions): Promise<boolean>;
7
9
  }
@@ -20,5 +20,18 @@ class CustomerIo {
20
20
  return false;
21
21
  }
22
22
  }
23
+ async sendEmail(requestOptions) {
24
+ try {
25
+ const request = new customerio_node_1.SendEmailRequest(requestOptions);
26
+ const api = new customerio_node_1.APIClient(this.key, { region: customerio_node_1.RegionUS });
27
+ const response = await api.sendEmail(request);
28
+ console.log('Sent email success: ', response);
29
+ return true;
30
+ }
31
+ catch (error) {
32
+ console.error('Failed to send email: ', error);
33
+ return false;
34
+ }
35
+ }
23
36
  }
24
37
  exports.CustomerIo = CustomerIo;
@@ -5,3 +5,4 @@ export declare const getAge: (date: Date) => string;
5
5
  export declare const getDeltaTime: (start: Date, end: Date) => number;
6
6
  export declare const getMonthDifference: (startDate: Date, endDate: Date) => number;
7
7
  export declare const addWorkDays: (startDate: Date, days: number) => Date;
8
+ export declare const helloTime: () => void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addWorkDays = exports.getMonthDifference = exports.getDeltaTime = exports.getAge = exports.compare = exports.isValidNumeric = exports.fixAppointmentDateStart = void 0;
3
+ exports.helloTime = exports.addWorkDays = exports.getMonthDifference = exports.getDeltaTime = exports.getAge = exports.compare = exports.isValidNumeric = exports.fixAppointmentDateStart = void 0;
4
4
  const fixAppointmentDateStart = (date, start) => {
5
5
  const [hour, minutes] = start.split(':');
6
6
  const fixedDate = new Date(date).setUTCHours(parseInt(hour ?? 0) + 6, parseInt(minutes ?? 0));
@@ -47,3 +47,7 @@ const addWorkDays = (startDate, days) => {
47
47
  return targetDate;
48
48
  };
49
49
  exports.addWorkDays = addWorkDays;
50
+ const helloTime = () => {
51
+ console.log('hola');
52
+ };
53
+ exports.helloTime = helloTime;
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "plenna_utilities",
3
- "version": "1.5.2",
3
+ "version": "1.7.0",
4
4
  "description": "plenna's utils for backend projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
- "dist/"
8
+ "dist/**/*"
9
9
  ],
10
10
  "scripts": {
11
- "lint": "rm -rf dist && eslint '**/*.{ts,tsx}'",
12
- "build": "npm run lint && tsc"
11
+ "lint": "eslint '**/*.{ts,tsx}' --fix",
12
+ "build": "npm run lint && tsc && npm run copy-assets",
13
+ "copy-assets": "npx copyfiles -u 1 \"src/**/*.yaml\" dist/src/"
13
14
  },
14
15
  "repository": {
15
16
  "type": "git"
@@ -30,6 +31,7 @@
30
31
  "eslint-plugin-import": "^2.29.1",
31
32
  "eslint-plugin-n": "^16.6.2",
32
33
  "eslint-plugin-promise": "^6.1.1",
34
+ "@types/yamljs": "^0.2.34",
33
35
  "typescript": "^5.4.5"
34
36
  },
35
37
  "dependencies": {
@@ -39,6 +41,9 @@
39
41
  "@googleapis/drive": "^8.10.0",
40
42
  "@googleapis/sheets": "^8.0.0",
41
43
  "customerio-node": "^4.1.1",
42
- "google-auth-library": "^9.11.0"
44
+ "google-auth-library": "^9.11.0",
45
+ "yaml": "^2.3.0",
46
+ "@slack/web-api": "^6.9.1",
47
+ "dotenv": "^16.4.5"
43
48
  }
44
49
  }