@trm-market-pulse/utils 1.0.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.
- package/README.md +123 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications/build-message.d.ts +3 -0
- package/dist/notifications/build-message.d.ts.map +1 -0
- package/dist/notifications/build-message.js +84 -0
- package/dist/notifications/build-message.js.map +1 -0
- package/dist/notifications/notification-factory.d.ts +3 -0
- package/dist/notifications/notification-factory.d.ts.map +1 -0
- package/dist/notifications/notification-factory.js +108 -0
- package/dist/notifications/notification-factory.js.map +1 -0
- package/dist/notifications/subscription-update-factory.d.ts +3 -0
- package/dist/notifications/subscription-update-factory.d.ts.map +1 -0
- package/dist/notifications/subscription-update-factory.js +161 -0
- package/dist/notifications/subscription-update-factory.js.map +1 -0
- package/dist/validators/check-conditions.d.ts +3 -0
- package/dist/validators/check-conditions.d.ts.map +1 -0
- package/dist/validators/check-conditions.js +41 -0
- package/dist/validators/check-conditions.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# @trm-market-pulse/utils
|
|
2
|
+
|
|
3
|
+
Utils functions for Tracker projects.
|
|
4
|
+
|
|
5
|
+
## How to publish a new version?
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm publish --access public --scope=@trm-market-pulse
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
This is a private package. You can install it using one of the following methods:
|
|
14
|
+
|
|
15
|
+
### Option 1: Install from Git Repository (Recommended for Serverless Functions)
|
|
16
|
+
|
|
17
|
+
If you have a private Git repository (GitHub, GitLab, Bitbucket), you can install directly from it:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Using npm
|
|
21
|
+
npm install git+https://github.com/your-org/shared-types.git
|
|
22
|
+
|
|
23
|
+
# Using pnpm
|
|
24
|
+
pnpm add git+https://github.com/your-org/shared-types.git
|
|
25
|
+
|
|
26
|
+
# Using yarn
|
|
27
|
+
yarn add git+https://github.com/your-org/shared-types.git
|
|
28
|
+
|
|
29
|
+
# For a specific branch or tag
|
|
30
|
+
pnpm add git+https://github.com/your-org/shared-types.git#branch-name
|
|
31
|
+
pnpm add git+https://github.com/your-org/shared-types.git#v1.0.0
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**For serverless functions**, this is the recommended approach as it works seamlessly during deployment.
|
|
35
|
+
|
|
36
|
+
### Option 2: Install from Private npm Registry
|
|
37
|
+
|
|
38
|
+
If you're using a private npm registry (GitHub Packages, npm Enterprise, etc.):
|
|
39
|
+
|
|
40
|
+
1. **Publish the package** to your registry:
|
|
41
|
+
```bash
|
|
42
|
+
npm publish --registry=https://npm.pkg.github.com
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. **Configure authentication** in your `.npmrc` or serverless environment:
|
|
46
|
+
```
|
|
47
|
+
@trm-market-pulse:registry=https://npm.pkg.github.com
|
|
48
|
+
//npm.pkg.github.com/:_authToken=YOUR_TOKEN
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
3. **Install the package**:
|
|
52
|
+
```bash
|
|
53
|
+
npm install @trm-market-pulse/utils
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Option 3: Install from Local Path (Development)
|
|
57
|
+
|
|
58
|
+
For local development, you can link the package:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# In the shared-types package directory
|
|
62
|
+
pnpm link
|
|
63
|
+
|
|
64
|
+
# In your project directory
|
|
65
|
+
pnpm link @trm-market-pulse/utils
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Import everything
|
|
72
|
+
import {
|
|
73
|
+
checkCondition
|
|
74
|
+
} from '@trm-market-pulse/utils';
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
### Building
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm install
|
|
84
|
+
pnpm build
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This will compile TypeScript files to the `dist` directory.
|
|
88
|
+
|
|
89
|
+
### Publishing
|
|
90
|
+
|
|
91
|
+
Before publishing, make sure to:
|
|
92
|
+
|
|
93
|
+
1. Update the version in `package.json`
|
|
94
|
+
2. Build the package: `pnpm build`
|
|
95
|
+
3. Publish to your registry or push to Git
|
|
96
|
+
|
|
97
|
+
## Structure
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
## Serverless Functions Setup
|
|
102
|
+
|
|
103
|
+
For serverless functions (AWS Lambda, Vercel, etc.), ensure your deployment configuration can access the Git repository:
|
|
104
|
+
|
|
105
|
+
### AWS Lambda / Serverless Framework
|
|
106
|
+
|
|
107
|
+
Add to your `serverless.yml`:
|
|
108
|
+
```yaml
|
|
109
|
+
package:
|
|
110
|
+
patterns:
|
|
111
|
+
- '!node_modules/**'
|
|
112
|
+
- 'node_modules/@trm-market-pulse/utils/**'
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Vercel
|
|
116
|
+
|
|
117
|
+
Vercel automatically installs dependencies from Git during build. Make sure your repository is accessible and the build has the necessary permissions.
|
|
118
|
+
|
|
119
|
+
### Environment Variables
|
|
120
|
+
|
|
121
|
+
If using a private npm registry, set these in your serverless environment:
|
|
122
|
+
- `NPM_TOKEN` - Your npm authentication token
|
|
123
|
+
- `NPM_REGISTRY` - Your private registry URL (if different from default)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAK9C,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./validators/check-conditions"), exports);
|
|
18
|
+
__exportStar(require("./notifications/notification-factory"), exports);
|
|
19
|
+
__exportStar(require("./notifications/build-message"), exports);
|
|
20
|
+
__exportStar(require("./notifications/subscription-update-factory"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAGA,gEAA8C;AAK9C,uEAAqD;AACrD,gEAA8C;AAC9C,8EAA4D"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { INotificationMessage, ITreshold, RateSource } from "@trm-market-pulse/shared-types";
|
|
2
|
+
export declare function buildNotificationMessage(threshold: ITreshold, currentRate: number, source: RateSource): INotificationMessage;
|
|
3
|
+
//# sourceMappingURL=build-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-message.d.ts","sourceRoot":"","sources":["../../src/notifications/build-message.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,SAAS,EACT,UAAU,EAEX,MAAM,gCAAgC,CAAC;AAiExC,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,oBAAoB,CAkCtB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildNotificationMessage = buildNotificationMessage;
|
|
4
|
+
const shared_types_1 = require("@trm-market-pulse/shared-types");
|
|
5
|
+
function buildHtmlEmail(threshold, currentRate, formattedRate, formattedTarget) {
|
|
6
|
+
const conditionEmojis = {
|
|
7
|
+
[shared_types_1.TresholdCondition.ABOVE]: "🚨",
|
|
8
|
+
[shared_types_1.TresholdCondition.BELOW]: "📉",
|
|
9
|
+
[shared_types_1.TresholdCondition.EQUAL]: "⚖️",
|
|
10
|
+
};
|
|
11
|
+
const conditionMessages = {
|
|
12
|
+
[shared_types_1.TresholdCondition.ABOVE]: `El dólar ha subido por encima de ${formattedTarget}`,
|
|
13
|
+
[shared_types_1.TresholdCondition.BELOW]: `El dólar ha bajado por debajo de ${formattedTarget}`,
|
|
14
|
+
[shared_types_1.TresholdCondition.EQUAL]: `El dólar ha alcanzado el valor de ${formattedTarget}`,
|
|
15
|
+
};
|
|
16
|
+
const emoji = conditionEmojis[threshold.condition] || "📊";
|
|
17
|
+
const message = conditionMessages[threshold.condition] || "Alerta activada";
|
|
18
|
+
return `
|
|
19
|
+
<!DOCTYPE html>
|
|
20
|
+
<html>
|
|
21
|
+
<head>
|
|
22
|
+
<meta charset="UTF-8">
|
|
23
|
+
<style>
|
|
24
|
+
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
|
25
|
+
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
|
26
|
+
.header { background-color: #f4f4f4; padding: 20px; border-radius: 5px; }
|
|
27
|
+
.content { padding: 20px; }
|
|
28
|
+
.rate { font-size: 24px; font-weight: bold; color: #2c3e50; }
|
|
29
|
+
.target { font-size: 18px; color: #7f8c8d; }
|
|
30
|
+
.footer { margin-top: 20px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 12px; color: #7f8c8d; }
|
|
31
|
+
</style>
|
|
32
|
+
</head>
|
|
33
|
+
<body>
|
|
34
|
+
<div class="container">
|
|
35
|
+
<div class="header">
|
|
36
|
+
<h1>${emoji} Alerta de Tipo de Cambio USD/COP</h1>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="content">
|
|
39
|
+
<p>${message}</p>
|
|
40
|
+
<p class="rate">Valor actual: ${formattedRate}</p>
|
|
41
|
+
<p class="target">Valor objetivo: ${formattedTarget}</p>
|
|
42
|
+
<p><strong>Threshold:</strong> ${threshold.name}</p>
|
|
43
|
+
<p><strong>Fuente:</strong> ${threshold.source}</p>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="footer">
|
|
46
|
+
<p>Esta es una notificación automática del sistema TRM Market Pulse.</p>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</body>
|
|
50
|
+
</html>
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
function buildNotificationMessage(threshold, currentRate, source) {
|
|
54
|
+
const formattedRate = new Intl.NumberFormat("es-CO", {
|
|
55
|
+
style: "currency",
|
|
56
|
+
currency: "COP",
|
|
57
|
+
}).format(currentRate);
|
|
58
|
+
const formattedTarget = new Intl.NumberFormat("es-CO", {
|
|
59
|
+
style: "currency",
|
|
60
|
+
currency: "COP",
|
|
61
|
+
}).format(threshold.targetValue);
|
|
62
|
+
const conditionMessages = {
|
|
63
|
+
[shared_types_1.TresholdCondition.ABOVE]: `🚨 Alerta: El dólar ha subido por encima de ${formattedTarget}. Valor actual: ${formattedRate}`,
|
|
64
|
+
[shared_types_1.TresholdCondition.BELOW]: `📉 Alerta: El dólar ha bajado por debajo de ${formattedTarget}. Valor actual: ${formattedRate}`,
|
|
65
|
+
[shared_types_1.TresholdCondition.EQUAL]: `⚖️ Alerta: El dólar ha alcanzado el valor de ${formattedTarget}. Valor actual: ${formattedRate}`,
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
title: "Alerta de Tipo de Cambio USD/COP",
|
|
69
|
+
body: conditionMessages[threshold.condition] ||
|
|
70
|
+
`Alerta activada. Valor actual: ${formattedRate}`,
|
|
71
|
+
data: {
|
|
72
|
+
threshold_id: threshold.uuid,
|
|
73
|
+
condition: threshold.condition,
|
|
74
|
+
target_value: threshold.targetValue,
|
|
75
|
+
current_value: currentRate,
|
|
76
|
+
source: source,
|
|
77
|
+
timestamp: new Date().toISOString(),
|
|
78
|
+
formatted_rate: formattedRate,
|
|
79
|
+
formatted_target: formattedTarget,
|
|
80
|
+
},
|
|
81
|
+
html: buildHtmlEmail(threshold, currentRate, formattedRate, formattedTarget),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=build-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-message.js","sourceRoot":"","sources":["../../src/notifications/build-message.ts"],"names":[],"mappings":";;AAsEA,4DAsCC;AA5GD,iEAKwC;AAKxC,SAAS,cAAc,CACrB,SAAoB,EACpB,WAAmB,EACnB,aAAqB,EACrB,eAAuB;IAEvB,MAAM,eAAe,GAA2B;QAC9C,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,IAAI;QAC/B,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,IAAI;QAC/B,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,IAAI;KAChC,CAAC;IAEF,MAAM,iBAAiB,GAA2B;QAChD,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,oCAAoC,eAAe,EAAE;QAChF,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,oCAAoC,eAAe,EAAE;QAChF,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,qCAAqC,eAAe,EAAE;KAClF,CAAC;IAEF,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IAC3D,MAAM,OAAO,GAAG,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,iBAAiB,CAAC;IAE5E,OAAO;;;;;;;;;;;;;;;;;;gBAkBO,KAAK;;;eAGN,OAAO;0CACoB,aAAa;8CACT,eAAe;2CAClB,SAAS,CAAC,IAAI;wCACjB,SAAS,CAAC,MAAM;;;;;;;;GAQrD,CAAC;AACJ,CAAC;AAKD,SAAgB,wBAAwB,CACtC,SAAoB,EACpB,WAAmB,EACnB,MAAkB;IAElB,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;QACnD,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAEvB,MAAM,eAAe,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;QACrD,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAEjC,MAAM,iBAAiB,GAA2B;QAChD,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,+CAA+C,eAAe,mBAAmB,aAAa,EAAE;QAC3H,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,+CAA+C,eAAe,mBAAmB,aAAa,EAAE;QAC3H,CAAC,gCAAiB,CAAC,KAAK,CAAC,EAAE,gDAAgD,eAAe,mBAAmB,aAAa,EAAE;KAC7H,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,kCAAkC;QACzC,IAAI,EACF,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC;YACtC,kCAAkC,aAAa,EAAE;QACnD,IAAI,EAAE;YACJ,YAAY,EAAE,SAAS,CAAC,IAAI;YAC5B,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,YAAY,EAAE,SAAS,CAAC,WAAW;YACnC,aAAa,EAAE,WAAW;YAC1B,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,cAAc,EAAE,aAAa;YAC7B,gBAAgB,EAAE,eAAe;SAClC;QACD,IAAI,EAAE,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,CAAC;KAC7E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-factory.d.ts","sourceRoot":"","sources":["../../src/notifications/notification-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAQf,MAAM,gCAAgC,CAAC;AAOxC,eAAO,MAAM,mBAAmB,QAAO,cAiIrC,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.notificationFactory = void 0;
|
|
4
|
+
const shared_types_1 = require("@trm-market-pulse/shared-types");
|
|
5
|
+
const build_message_1 = require("./build-message");
|
|
6
|
+
const notificationFactory = () => ({
|
|
7
|
+
buildNotificationMessage: build_message_1.buildNotificationMessage,
|
|
8
|
+
sendNotification: async (subscription, threshold, currentRate, source, handlers) => {
|
|
9
|
+
try {
|
|
10
|
+
let user;
|
|
11
|
+
if (handlers.getUserById) {
|
|
12
|
+
user = await handlers.getUserById(subscription.userId);
|
|
13
|
+
if (!user) {
|
|
14
|
+
return {
|
|
15
|
+
success: false,
|
|
16
|
+
error: `Usuario no encontrado: ${subscription.userId}`,
|
|
17
|
+
timestamp: new Date(),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return {
|
|
23
|
+
success: false,
|
|
24
|
+
error: "getUserById handler is required",
|
|
25
|
+
timestamp: new Date(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const messageData = (0, build_message_1.buildNotificationMessage)(threshold, currentRate, source);
|
|
29
|
+
let notificationResult;
|
|
30
|
+
switch (subscription.notificationMethod) {
|
|
31
|
+
case shared_types_1.NotificationMethod.EMAIL:
|
|
32
|
+
if (!handlers.sendEmail) {
|
|
33
|
+
return {
|
|
34
|
+
success: false,
|
|
35
|
+
error: "sendEmail handler is required for EMAIL notifications",
|
|
36
|
+
timestamp: new Date(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
notificationResult = await handlers.sendEmail(user, messageData);
|
|
40
|
+
break;
|
|
41
|
+
case shared_types_1.NotificationMethod.PUSH:
|
|
42
|
+
if (!handlers.sendPush) {
|
|
43
|
+
return {
|
|
44
|
+
success: false,
|
|
45
|
+
error: "sendPush handler is required for PUSH notifications",
|
|
46
|
+
timestamp: new Date(),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
notificationResult = await handlers.sendPush(user, messageData);
|
|
50
|
+
break;
|
|
51
|
+
case shared_types_1.NotificationMethod.SMS:
|
|
52
|
+
if (!handlers.sendSms) {
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
error: "sendSms handler is required for SMS notifications",
|
|
56
|
+
timestamp: new Date(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
notificationResult = await handlers.sendSms(user, messageData);
|
|
60
|
+
break;
|
|
61
|
+
case shared_types_1.NotificationMethod.WHATS_APP:
|
|
62
|
+
if (!handlers.sendWhatsApp) {
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
error: "sendWhatsApp handler is required for WHATS_APP notifications",
|
|
66
|
+
timestamp: new Date(),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
notificationResult = await handlers.sendWhatsApp(user, messageData);
|
|
70
|
+
break;
|
|
71
|
+
case shared_types_1.NotificationMethod.IN_APP:
|
|
72
|
+
if (!handlers.sendInApp) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
error: "sendInApp handler is required for IN_APP notifications",
|
|
76
|
+
timestamp: new Date(),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
notificationResult = await handlers.sendInApp(user, messageData);
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
error: `Método de notificación no soportado: ${subscription.notificationMethod}`,
|
|
85
|
+
timestamp: new Date(),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (notificationResult.success) {
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
method: subscription.notificationMethod,
|
|
92
|
+
timestamp: new Date(),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return notificationResult;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
const errorMessage = error instanceof Error ? error.message : "Error desconocido";
|
|
99
|
+
return {
|
|
100
|
+
success: false,
|
|
101
|
+
error: `Error enviando notificación: ${errorMessage}`,
|
|
102
|
+
timestamp: new Date(),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
exports.notificationFactory = notificationFactory;
|
|
108
|
+
//# sourceMappingURL=notification-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-factory.js","sourceRoot":"","sources":["../../src/notifications/notification-factory.ts"],"names":[],"mappings":";;;AAAA,iEASwC;AACxC,mDAA2D;AAMpD,MAAM,mBAAmB,GAAG,GAAmB,EAAE,CAAC,CAAC;IACxD,wBAAwB,EAAxB,wCAAwB;IAMxB,gBAAgB,EAAE,KAAK,EACrB,YAAmC,EACnC,SAAoB,EACpB,WAAmB,EACnB,MAAkB,EAClB,QAA+B,EACD,EAAE;QAChC,IAAI,CAAC;YAEH,IAAI,IAAI,CAAC;YACT,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACzB,IAAI,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;gBACvD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,0BAA0B,YAAY,CAAC,MAAM,EAAE;wBACtD,SAAS,EAAE,IAAI,IAAI,EAAE;qBACtB,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,CAAC;gBAEN,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,iCAAiC;oBACxC,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC;YACJ,CAAC;YAGD,MAAM,WAAW,GAAyB,IAAA,wCAAwB,EAChE,SAAS,EACT,WAAW,EACX,MAAM,CACP,CAAC;YAEF,IAAI,kBAAuC,CAAC;YAG5C,QAAQ,YAAY,CAAC,kBAAkB,EAAE,CAAC;gBACxC,KAAK,iCAAkB,CAAC,KAAK;oBAC3B,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;wBACxB,OAAO;4BACL,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,uDAAuD;4BAC9D,SAAS,EAAE,IAAI,IAAI,EAAE;yBACtB,CAAC;oBACJ,CAAC;oBACD,kBAAkB,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBACjE,MAAM;gBAER,KAAK,iCAAkB,CAAC,IAAI;oBAC1B,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;wBACvB,OAAO;4BACL,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,qDAAqD;4BAC5D,SAAS,EAAE,IAAI,IAAI,EAAE;yBACtB,CAAC;oBACJ,CAAC;oBACD,kBAAkB,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBAChE,MAAM;gBAER,KAAK,iCAAkB,CAAC,GAAG;oBACzB,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;wBACtB,OAAO;4BACL,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,mDAAmD;4BAC1D,SAAS,EAAE,IAAI,IAAI,EAAE;yBACtB,CAAC;oBACJ,CAAC;oBACD,kBAAkB,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBAC/D,MAAM;gBAER,KAAK,iCAAkB,CAAC,SAAS;oBAC/B,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;wBAC3B,OAAO;4BACL,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,8DAA8D;4BACrE,SAAS,EAAE,IAAI,IAAI,EAAE;yBACtB,CAAC;oBACJ,CAAC;oBACD,kBAAkB,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBACpE,MAAM;gBAER,KAAK,iCAAkB,CAAC,MAAM;oBAC5B,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;wBACxB,OAAO;4BACL,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,wDAAwD;4BAC/D,SAAS,EAAE,IAAI,IAAI,EAAE;yBACtB,CAAC;oBACJ,CAAC;oBACD,kBAAkB,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBACjE,MAAM;gBAER;oBACE,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,wCAAwC,YAAY,CAAC,kBAAkB,EAAE;wBAChF,SAAS,EAAE,IAAI,IAAI,EAAE;qBACtB,CAAC;YACN,CAAC;YAGD,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;gBAC/B,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,YAAY,CAAC,kBAAkB;oBACvC,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC;YACJ,CAAC;YAED,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;YAC/D,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,gCAAgC,YAAY,EAAE;gBACrD,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAjIU,QAAA,mBAAmB,uBAiI7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription-update-factory.d.ts","sourceRoot":"","sources":["../../src/notifications/subscription-update-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAKpB,MAAM,gCAAgC,CAAC;AAcxC,eAAO,MAAM,yBAAyB,QAAO,mBAkK3C,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.subscriptionUpdateFactory = void 0;
|
|
4
|
+
const DEFAULT_RETRY_CONFIG = {
|
|
5
|
+
maxRetries: 3,
|
|
6
|
+
retryDelayMinutes: [5, 30, 60],
|
|
7
|
+
};
|
|
8
|
+
const subscriptionUpdateFactory = () => ({
|
|
9
|
+
updateSubscriptionAfterNotification: async (subscription, notificationResult, handlers) => {
|
|
10
|
+
let transactionSession = null;
|
|
11
|
+
try {
|
|
12
|
+
if (handlers.startTransaction) {
|
|
13
|
+
transactionSession = await handlers.startTransaction();
|
|
14
|
+
}
|
|
15
|
+
const now = new Date();
|
|
16
|
+
const session = transactionSession?.session;
|
|
17
|
+
if (handlers.updateSubscription) {
|
|
18
|
+
const updateResult = await handlers.updateSubscription({
|
|
19
|
+
subscriptionId: subscription.uuid,
|
|
20
|
+
lastTriggeredAt: now,
|
|
21
|
+
updatedAt: now,
|
|
22
|
+
}, session);
|
|
23
|
+
if (!updateResult.success) {
|
|
24
|
+
throw new Error(`Failed to update subscription: ${updateResult.error}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (handlers.updateThreshold && subscription.lastTriggeredAt === null) {
|
|
28
|
+
const thresholdResult = await handlers.updateThreshold({
|
|
29
|
+
thresholdId: subscription.thresholdId,
|
|
30
|
+
incrementActiveSubscriberCount: true,
|
|
31
|
+
}, session);
|
|
32
|
+
if (!thresholdResult.success) {
|
|
33
|
+
console.warn(`Failed to update threshold: ${thresholdResult.error}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (handlers.insertNotificationHistory) {
|
|
37
|
+
const historyResult = await handlers.insertNotificationHistory({
|
|
38
|
+
thresholdId: subscription.thresholdId,
|
|
39
|
+
userId: subscription.userId,
|
|
40
|
+
subscriptionId: subscription.uuid,
|
|
41
|
+
triggerValue: notificationResult.data?.current_value || null,
|
|
42
|
+
triggerSource: notificationResult.data?.source || null,
|
|
43
|
+
notificationMethod: subscription.notificationMethod,
|
|
44
|
+
triggeredAt: now,
|
|
45
|
+
notificationSent: notificationResult.success,
|
|
46
|
+
errorMessage: notificationResult.error || null,
|
|
47
|
+
retryCount: 0,
|
|
48
|
+
metadata: {
|
|
49
|
+
app_version: "1.0.0",
|
|
50
|
+
user_agent: "threshold-service",
|
|
51
|
+
},
|
|
52
|
+
}, session);
|
|
53
|
+
if (!historyResult.success) {
|
|
54
|
+
throw new Error(`Failed to insert notification history: ${historyResult.error}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!notificationResult.success && handlers.scheduleRetryNotification) {
|
|
58
|
+
await scheduleRetryNotification(subscription, notificationResult, handlers, session);
|
|
59
|
+
}
|
|
60
|
+
if (transactionSession) {
|
|
61
|
+
await transactionSession.commit();
|
|
62
|
+
}
|
|
63
|
+
return { success: true };
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (transactionSession) {
|
|
67
|
+
try {
|
|
68
|
+
await transactionSession.abort();
|
|
69
|
+
}
|
|
70
|
+
catch (abortError) {
|
|
71
|
+
console.error(`Error aborting transaction: ${abortError}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
75
|
+
console.error(`Error updating subscription: ${errorMessage}`);
|
|
76
|
+
if (handlers.insertNotificationHistory) {
|
|
77
|
+
try {
|
|
78
|
+
await handlers.insertNotificationHistory({
|
|
79
|
+
thresholdId: subscription.thresholdId,
|
|
80
|
+
userId: subscription.userId,
|
|
81
|
+
subscriptionId: subscription.uuid,
|
|
82
|
+
triggerValue: notificationResult.data?.current_value || null,
|
|
83
|
+
triggerSource: notificationResult.data?.source || null,
|
|
84
|
+
notificationMethod: subscription.notificationMethod,
|
|
85
|
+
triggeredAt: new Date(),
|
|
86
|
+
notificationSent: false,
|
|
87
|
+
errorMessage: `Transaction failed: ${errorMessage}`,
|
|
88
|
+
retryCount: 0,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (fallbackError) {
|
|
92
|
+
console.error(`Fallback notification history insert also failed: ${fallbackError}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { success: false, error: errorMessage };
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
if (transactionSession) {
|
|
99
|
+
try {
|
|
100
|
+
await transactionSession.end();
|
|
101
|
+
}
|
|
102
|
+
catch (endError) {
|
|
103
|
+
console.error(`Error ending transaction session: ${endError}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
exports.subscriptionUpdateFactory = subscriptionUpdateFactory;
|
|
110
|
+
async function scheduleRetryNotification(subscription, notificationResult, handlers, session) {
|
|
111
|
+
if (!handlers.scheduleRetryNotification || !handlers.getExistingRetry) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const config = DEFAULT_RETRY_CONFIG;
|
|
115
|
+
try {
|
|
116
|
+
const existingRetry = await handlers.getExistingRetry(subscription.uuid, session);
|
|
117
|
+
if (!existingRetry) {
|
|
118
|
+
await handlers.scheduleRetryNotification({
|
|
119
|
+
subscriptionId: subscription.uuid,
|
|
120
|
+
userId: subscription.userId,
|
|
121
|
+
thresholdId: subscription.thresholdId,
|
|
122
|
+
attemptCount: 1,
|
|
123
|
+
nextRetryAt: new Date(Date.now() + config.retryDelayMinutes[0] * 60000),
|
|
124
|
+
maxRetries: config.maxRetries,
|
|
125
|
+
errorHistory: [
|
|
126
|
+
{
|
|
127
|
+
attempt: 1,
|
|
128
|
+
error: notificationResult.error || "Unknown error",
|
|
129
|
+
timestamp: new Date(),
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
}, session);
|
|
133
|
+
}
|
|
134
|
+
else if (existingRetry.attemptCount < existingRetry.maxRetries &&
|
|
135
|
+
!existingRetry.resolved) {
|
|
136
|
+
const nextAttempt = existingRetry.attemptCount + 1;
|
|
137
|
+
const delayIndex = Math.min(nextAttempt - 1, config.retryDelayMinutes.length - 1);
|
|
138
|
+
if (handlers.updateRetry) {
|
|
139
|
+
await handlers.updateRetry(existingRetry.id, {
|
|
140
|
+
subscriptionId: subscription.uuid,
|
|
141
|
+
userId: subscription.userId,
|
|
142
|
+
thresholdId: subscription.thresholdId,
|
|
143
|
+
attemptCount: nextAttempt,
|
|
144
|
+
nextRetryAt: new Date(Date.now() + config.retryDelayMinutes[delayIndex] * 60000),
|
|
145
|
+
maxRetries: existingRetry.maxRetries,
|
|
146
|
+
errorHistory: [
|
|
147
|
+
{
|
|
148
|
+
attempt: nextAttempt,
|
|
149
|
+
error: notificationResult.error || "Unknown error",
|
|
150
|
+
timestamp: new Date(),
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
}, session);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error(`Error scheduling retry notification: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=subscription-update-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription-update-factory.js","sourceRoot":"","sources":["../../src/notifications/subscription-update-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-conditions.d.ts","sourceRoot":"","sources":["../../src/validators/check-conditions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAqB,MAAM,gCAAgC,CAAC;AAEnF,eAAO,MAAM,sBAAsB,QAAO,cAoCxC,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
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.checkConditionsFactory = void 0;
|
|
7
|
+
const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
8
|
+
const shared_types_1 = require("@trm-market-pulse/shared-types");
|
|
9
|
+
const checkConditionsFactory = () => ({
|
|
10
|
+
checkCondition: (currentRate, treshold, previousRate) => {
|
|
11
|
+
const { condition, targetValue } = treshold;
|
|
12
|
+
switch (condition) {
|
|
13
|
+
case shared_types_1.TresholdCondition.ABOVE:
|
|
14
|
+
if (previousRate !== null) {
|
|
15
|
+
return previousRate <= targetValue && currentRate > targetValue;
|
|
16
|
+
}
|
|
17
|
+
return currentRate > targetValue;
|
|
18
|
+
case shared_types_1.TresholdCondition.BELOW:
|
|
19
|
+
if (previousRate !== null) {
|
|
20
|
+
return previousRate >= targetValue && currentRate < targetValue;
|
|
21
|
+
}
|
|
22
|
+
return currentRate < targetValue;
|
|
23
|
+
case shared_types_1.TresholdCondition.EQUAL:
|
|
24
|
+
if (previousRate !== null) {
|
|
25
|
+
return previousRate === targetValue && currentRate === targetValue;
|
|
26
|
+
}
|
|
27
|
+
return currentRate === targetValue;
|
|
28
|
+
default:
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
calculateHoursSinceLastTrigger: (lastTriggeredAt) => {
|
|
33
|
+
if (!lastTriggeredAt)
|
|
34
|
+
return Infinity;
|
|
35
|
+
const now = (0, moment_timezone_1.default)().utc();
|
|
36
|
+
const lastTriggered = (0, moment_timezone_1.default)(lastTriggeredAt).utc();
|
|
37
|
+
return now.diff(lastTriggered, 'hours');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
exports.checkConditionsFactory = checkConditionsFactory;
|
|
41
|
+
//# sourceMappingURL=check-conditions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-conditions.js","sourceRoot":"","sources":["../../src/validators/check-conditions.ts"],"names":[],"mappings":";;;;;;AAAA,sEAAqC;AACrC,iEAAmF;AAE5E,MAAM,sBAAsB,GAAG,GAAmB,EAAE,CAAC,CAAC;IAC3D,cAAc,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE;QACtD,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC;QAE5C,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,gCAAiB,CAAC,KAAK;gBAC1B,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;oBAC1B,OAAO,YAAY,IAAI,WAAW,IAAI,WAAW,GAAG,WAAW,CAAC;gBAClE,CAAC;gBAED,OAAO,WAAW,GAAG,WAAW,CAAC;YACnC,KAAK,gCAAiB,CAAC,KAAK;gBAC1B,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;oBAC1B,OAAO,YAAY,IAAI,WAAW,IAAI,WAAW,GAAG,WAAW,CAAC;gBAClE,CAAC;gBAED,OAAO,WAAW,GAAG,WAAW,CAAC;YACnC,KAAK,gCAAiB,CAAC,KAAK;gBAC1B,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;oBAC1B,OAAO,YAAY,KAAK,WAAW,IAAI,WAAW,KAAK,WAAW,CAAC;gBACrE,CAAC;gBAED,OAAO,WAAW,KAAK,WAAW,CAAC;YAErC;gBACE,OAAO,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;IACD,8BAA8B,EAAE,CAAC,eAAe,EAAE,EAAE;QAClD,IAAI,CAAC,eAAe;YAAE,OAAO,QAAQ,CAAC;QAEtC,MAAM,GAAG,GAAG,IAAA,yBAAM,GAAE,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,aAAa,GAAG,IAAA,yBAAM,EAAC,eAAe,CAAC,CAAC,GAAG,EAAE,CAAC;QAEpD,OAAO,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;CACF,CAAC,CAAA;AApCW,QAAA,sBAAsB,0BAoCjC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trm-market-pulse/utils",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Utils functions for Tracker projects",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"prepublishOnly": "pnpm run build",
|
|
14
|
+
"clean": "rm -rf dist"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"types",
|
|
18
|
+
"typescript",
|
|
19
|
+
"shared"
|
|
20
|
+
],
|
|
21
|
+
"author": "",
|
|
22
|
+
"license": "ISC",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"typescript": "^5.9.3",
|
|
25
|
+
"@types/express": "^5.0.5",
|
|
26
|
+
"@types/node": "^24.10.0",
|
|
27
|
+
"@trm-market-pulse/shared-types": "workspace:*",
|
|
28
|
+
"moment-timezone": "^0.6.0"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"express": "^5.1.0",
|
|
32
|
+
"winston": "^3.18.3",
|
|
33
|
+
"mongodb": "^6.2.0"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|