@polygonlabs/servercore 1.5.1-dev.0 → 1.5.1
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/index.d.ts +443 -31
- package/dist/index.js +951 -8
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/dist/api/health-check.d.ts +0 -8
- package/dist/api/health-check.js +0 -89
- package/dist/api/health-check.js.map +0 -1
- package/dist/api/index.d.ts +0 -9
- package/dist/api/index.js +0 -4
- package/dist/api/index.js.map +0 -1
- package/dist/api/response_handler.d.ts +0 -15
- package/dist/api/response_handler.js +0 -23
- package/dist/api/response_handler.js.map +0 -1
- package/dist/api/zod_utils.d.ts +0 -7
- package/dist/api/zod_utils.js +0 -42
- package/dist/api/zod_utils.js.map +0 -1
- package/dist/constants/error_codes.d.ts +0 -29
- package/dist/constants/error_codes.js +0 -34
- package/dist/constants/error_codes.js.map +0 -1
- package/dist/constants/http_success_codes.d.ts +0 -5
- package/dist/constants/http_success_codes.js +0 -7
- package/dist/constants/http_success_codes.js.map +0 -1
- package/dist/constants/index.d.ts +0 -2
- package/dist/constants/index.js +0 -3
- package/dist/constants/index.js.map +0 -1
- package/dist/consumers/abstract_cron_event_consumer.d.ts +0 -23
- package/dist/consumers/abstract_cron_event_consumer.js +0 -30
- package/dist/consumers/abstract_cron_event_consumer.js.map +0 -1
- package/dist/consumers/abstract_event_consumer.d.ts +0 -34
- package/dist/consumers/abstract_event_consumer.js +0 -41
- package/dist/consumers/abstract_event_consumer.js.map +0 -1
- package/dist/consumers/event_consumer.d.ts +0 -26
- package/dist/consumers/event_consumer.js +0 -141
- package/dist/consumers/event_consumer.js.map +0 -1
- package/dist/consumers/index.d.ts +0 -11
- package/dist/consumers/index.js +0 -4
- package/dist/consumers/index.js.map +0 -1
- package/dist/consumers/rest_api_consumer.d.ts +0 -30
- package/dist/consumers/rest_api_consumer.js +0 -131
- package/dist/consumers/rest_api_consumer.js.map +0 -1
- package/dist/errors/api_errors.d.ts +0 -32
- package/dist/errors/api_errors.js +0 -96
- package/dist/errors/api_errors.js.map +0 -1
- package/dist/errors/base_error.d.ts +0 -22
- package/dist/errors/base_error.js +0 -30
- package/dist/errors/base_error.js.map +0 -1
- package/dist/errors/consumer_errors.d.ts +0 -13
- package/dist/errors/consumer_errors.js +0 -18
- package/dist/errors/consumer_errors.js.map +0 -1
- package/dist/errors/database_errors.d.ts +0 -13
- package/dist/errors/database_errors.js +0 -18
- package/dist/errors/database_errors.js.map +0 -1
- package/dist/errors/external_dependency_error.d.ts +0 -15
- package/dist/errors/external_dependency_error.js +0 -29
- package/dist/errors/external_dependency_error.js.map +0 -1
- package/dist/errors/index.d.ts +0 -5
- package/dist/errors/index.js +0 -6
- package/dist/errors/index.js.map +0 -1
- package/dist/logger/index.d.ts +0 -3
- package/dist/logger/index.js +0 -2
- package/dist/logger/index.js.map +0 -1
- package/dist/logger/logger.d.ts +0 -54
- package/dist/logger/logger.js +0 -124
- package/dist/logger/logger.js.map +0 -1
- package/dist/storage/cache_interface.d.ts +0 -13
- package/dist/storage/cache_interface.js +0 -1
- package/dist/storage/cache_interface.js.map +0 -1
- package/dist/storage/db_interface.d.ts +0 -18
- package/dist/storage/db_interface.js +0 -1
- package/dist/storage/db_interface.js.map +0 -1
- package/dist/storage/index.d.ts +0 -5
- package/dist/storage/index.js +0 -4
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/queue_interface.d.ts +0 -11
- package/dist/storage/queue_interface.js +0 -1
- package/dist/storage/queue_interface.js.map +0 -1
- package/dist/types/database.d.ts +0 -62
- package/dist/types/database.js +0 -1
- package/dist/types/database.js.map +0 -1
- package/dist/types/event_consumer_config.d.ts +0 -19
- package/dist/types/event_consumer_config.js +0 -1
- package/dist/types/event_consumer_config.js.map +0 -1
- package/dist/types/index.d.ts +0 -9
- package/dist/types/index.js +0 -8
- package/dist/types/index.js.map +0 -1
- package/dist/types/logger_config.d.ts +0 -18
- package/dist/types/logger_config.js +0 -2
- package/dist/types/logger_config.js.map +0 -1
- package/dist/types/observer.d.ts +0 -8
- package/dist/types/observer.js +0 -1
- package/dist/types/observer.js.map +0 -1
- package/dist/types/queue_job_opts.d.ts +0 -5
- package/dist/types/queue_job_opts.js +0 -1
- package/dist/types/queue_job_opts.js.map +0 -1
- package/dist/types/response_context.d.ts +0 -6
- package/dist/types/response_context.js +0 -1
- package/dist/types/response_context.js.map +0 -1
- package/dist/types/rest_api_consumer_config.d.ts +0 -17
- package/dist/types/rest_api_consumer_config.js +0 -1
- package/dist/types/rest_api_consumer_config.js.map +0 -1
- package/dist/utils/decoder.d.ts +0 -10
- package/dist/utils/decoder.js +0 -12
- package/dist/utils/decoder.js.map +0 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -3
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/ulid.d.ts +0 -3
- package/dist/utils/ulid.js +0 -24
- package/dist/utils/ulid.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,952 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
// src/constants/error_codes.ts
|
|
2
|
+
var errorCodes = {
|
|
3
|
+
// Base error identifier
|
|
4
|
+
base: { BASE_ERROR: 100 },
|
|
5
|
+
// Consumer related error codes
|
|
6
|
+
consumer: {
|
|
7
|
+
UNKNOWN_CONSUMER_ERR: 1e3
|
|
8
|
+
},
|
|
9
|
+
// Datastore related error codes
|
|
10
|
+
datastore: {
|
|
11
|
+
UNKNOWN_DATASTORE_ERR: 2e3,
|
|
12
|
+
DATASTORE_AUTH_ERR: 2001,
|
|
13
|
+
DATASTORE_READ_ERROR: 2002,
|
|
14
|
+
DATASTORE_WRITE_ERROR: 2003
|
|
15
|
+
},
|
|
16
|
+
// External dependencies errors codes
|
|
17
|
+
external: {
|
|
18
|
+
UNKNOWN_EXTERNAL_DEPENDENCY_ERROR: 3e3
|
|
19
|
+
},
|
|
20
|
+
// API related error codes
|
|
21
|
+
api: {
|
|
22
|
+
BAD_REQUEST: 400,
|
|
23
|
+
UNAUTHORIZED: 401,
|
|
24
|
+
FORBIDDEN: 403,
|
|
25
|
+
NOT_FOUND: 404,
|
|
26
|
+
TOO_MANY_REQUESTS: 429,
|
|
27
|
+
INTERNAL_SERVER_ERROR: 500,
|
|
28
|
+
GATEWAY_ERROR: 502,
|
|
29
|
+
TIMEOUT_ERROR: 504
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/constants/http_success_codes.ts
|
|
34
|
+
var httpResponseCodes = {
|
|
35
|
+
OK_RESPONSE: 200
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/errors/base_error.ts
|
|
39
|
+
var BaseError = class extends Error {
|
|
40
|
+
name;
|
|
41
|
+
code;
|
|
42
|
+
isFatal;
|
|
43
|
+
origin;
|
|
44
|
+
context;
|
|
45
|
+
/**
|
|
46
|
+
* @param name {string} - The error name
|
|
47
|
+
* @param code {number} - The error code
|
|
48
|
+
* @param isFatal {boolean} - Flag to know if it is a fatal error
|
|
49
|
+
* @param message {string} - The actual error message
|
|
50
|
+
* @param origin {string} - The point this error originated
|
|
51
|
+
* @param context Record<string, any> - The stack trace
|
|
52
|
+
*/
|
|
53
|
+
constructor(name, code, message = "Unknown error", isFatal, origin, context) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = name;
|
|
56
|
+
this.code = code;
|
|
57
|
+
this.isFatal = isFatal ?? true;
|
|
58
|
+
this.origin = origin ?? "base_error";
|
|
59
|
+
this.context = context ?? {};
|
|
60
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
61
|
+
}
|
|
62
|
+
identifier = errorCodes.base.BASE_ERROR;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/errors/api_errors.ts
|
|
66
|
+
var ApiError = class extends BaseError {
|
|
67
|
+
constructor(message, {
|
|
68
|
+
name = "INTERNAL_SERVER_ERROR",
|
|
69
|
+
code = errorCodes.api.INTERNAL_SERVER_ERROR,
|
|
70
|
+
isFatal = false,
|
|
71
|
+
origin = "api_errors",
|
|
72
|
+
context = {}
|
|
73
|
+
} = {}) {
|
|
74
|
+
super(name, code, message, isFatal, origin, context);
|
|
75
|
+
Error.captureStackTrace(this, this.constructor);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
var UnauthorizedError = class extends ApiError {
|
|
79
|
+
constructor(message = "Invalid auth credentials", context = {}, origin = "api_errors") {
|
|
80
|
+
super(message, {
|
|
81
|
+
name: "UNAUTHORIZED",
|
|
82
|
+
code: errorCodes.api.UNAUTHORIZED,
|
|
83
|
+
isFatal: false,
|
|
84
|
+
origin,
|
|
85
|
+
context
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
var ForbiddenError = class extends ApiError {
|
|
90
|
+
constructor(message = "You do not have permission to perform this action", context = {}, origin = "api_errors") {
|
|
91
|
+
super(message, {
|
|
92
|
+
name: "FORBIDDEN",
|
|
93
|
+
code: errorCodes.api.FORBIDDEN,
|
|
94
|
+
isFatal: false,
|
|
95
|
+
origin,
|
|
96
|
+
context
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var BadRequestError = class extends ApiError {
|
|
101
|
+
validationErrors;
|
|
102
|
+
constructor(message = "Malformed or invalid request", validationErrors = {}, context = {}, origin = "api_errors") {
|
|
103
|
+
super(message, {
|
|
104
|
+
name: "BAD_REQUEST",
|
|
105
|
+
code: errorCodes.api.BAD_REQUEST,
|
|
106
|
+
isFatal: false,
|
|
107
|
+
origin,
|
|
108
|
+
context
|
|
109
|
+
});
|
|
110
|
+
this.validationErrors = validationErrors;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
var NotFoundError = class extends ApiError {
|
|
114
|
+
constructor(message, entity = "Path", identifier, context = {}, origin = "api_errors") {
|
|
115
|
+
if (!message) {
|
|
116
|
+
message = identifier ? `${entity} with identifier ${identifier} not found` : `${entity} not found`;
|
|
117
|
+
}
|
|
118
|
+
super(message, {
|
|
119
|
+
name: "NOT_FOUND",
|
|
120
|
+
code: errorCodes.api.NOT_FOUND,
|
|
121
|
+
isFatal: false,
|
|
122
|
+
origin,
|
|
123
|
+
context: { entity, identifier, ...context }
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var RateLimitError = class extends ApiError {
|
|
128
|
+
constructor(message = "Rate limit exceeded", context = {}, origin = "api_errors") {
|
|
129
|
+
super(message, {
|
|
130
|
+
name: "RATE_LIMIT",
|
|
131
|
+
code: errorCodes.api.TOO_MANY_REQUESTS,
|
|
132
|
+
isFatal: false,
|
|
133
|
+
origin,
|
|
134
|
+
context
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
var TimeoutError = class extends ApiError {
|
|
139
|
+
constructor(operation, timeoutMs, context = {}, origin = "api_errors") {
|
|
140
|
+
super(`Operation '${operation}' timed out after ${timeoutMs}ms`, {
|
|
141
|
+
name: "TIMEOUT",
|
|
142
|
+
code: errorCodes.api.TIMEOUT_ERROR,
|
|
143
|
+
// Gateway Timeout
|
|
144
|
+
isFatal: false,
|
|
145
|
+
origin,
|
|
146
|
+
context: { operation, timeoutMs, ...context }
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// src/errors/database_errors.ts
|
|
152
|
+
var DatabaseError = class extends BaseError {
|
|
153
|
+
constructor(message, originalError, {
|
|
154
|
+
name = "DATABASE_ERROR",
|
|
155
|
+
code = errorCodes.consumer.UNKNOWN_CONSUMER_ERR,
|
|
156
|
+
isFatal = true,
|
|
157
|
+
origin = "databse_errors",
|
|
158
|
+
context = {}
|
|
159
|
+
} = {}) {
|
|
160
|
+
super(name, code, message, isFatal, origin, context);
|
|
161
|
+
Error.captureStackTrace(this, this.constructor);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// src/errors/external_dependency_error.ts
|
|
166
|
+
var ExternalDependencyError = class extends BaseError {
|
|
167
|
+
apiName;
|
|
168
|
+
externalCode;
|
|
169
|
+
rawError;
|
|
170
|
+
constructor(apiName, message, {
|
|
171
|
+
externalCode,
|
|
172
|
+
rawError,
|
|
173
|
+
context = {},
|
|
174
|
+
origin = "external_dependency_error"
|
|
175
|
+
} = {}) {
|
|
176
|
+
super(
|
|
177
|
+
"EXTERNAL_DEPENDENCY_ERROR",
|
|
178
|
+
errorCodes.external.UNKNOWN_EXTERNAL_DEPENDENCY_ERROR,
|
|
179
|
+
`${apiName} API error: ${message}`,
|
|
180
|
+
false,
|
|
181
|
+
origin,
|
|
182
|
+
{ apiName, externalCode, ...context }
|
|
183
|
+
);
|
|
184
|
+
this.apiName = apiName;
|
|
185
|
+
this.externalCode = externalCode;
|
|
186
|
+
this.rawError = rawError;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// src/errors/consumer_errors.ts
|
|
191
|
+
var ConsumerError = class extends BaseError {
|
|
192
|
+
constructor(message, {
|
|
193
|
+
name = "CONSUMER_ERROR",
|
|
194
|
+
code = errorCodes.consumer.UNKNOWN_CONSUMER_ERR,
|
|
195
|
+
isFatal = true,
|
|
196
|
+
origin = "consumer_errors",
|
|
197
|
+
context = {}
|
|
198
|
+
} = {}) {
|
|
199
|
+
super(name, code, message, isFatal, origin, context);
|
|
200
|
+
Error.captureStackTrace(this, this.constructor);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// src/api/response_handler.ts
|
|
205
|
+
var handleResponse = (c, data, pagination) => {
|
|
206
|
+
return c.status(httpResponseCodes.OK_RESPONSE).json({
|
|
207
|
+
status: "success",
|
|
208
|
+
data,
|
|
209
|
+
pagination
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
var handleError = (c, error) => {
|
|
213
|
+
return c.status(error.code ?? errorCodes.api.INTERNAL_SERVER_ERROR).json({
|
|
214
|
+
status: "error",
|
|
215
|
+
message: error.message,
|
|
216
|
+
name: error.name,
|
|
217
|
+
code: error.code,
|
|
218
|
+
details: error.context
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/api/zod_utils.ts
|
|
223
|
+
import "zod";
|
|
224
|
+
var validateBody = (schema, data) => {
|
|
225
|
+
const result = schema.safeParse(data);
|
|
226
|
+
if (!result.success) {
|
|
227
|
+
throw new Error(
|
|
228
|
+
`Invalid body: ${JSON.stringify(result.error.format(), null, 2)}`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
return result.data;
|
|
232
|
+
};
|
|
233
|
+
var validateQuery = (schema, query) => {
|
|
234
|
+
const result = schema.safeParse(query);
|
|
235
|
+
if (!result.success) {
|
|
236
|
+
throw new Error(
|
|
237
|
+
`Invalid query params: ${JSON.stringify(
|
|
238
|
+
result.error.format(),
|
|
239
|
+
null,
|
|
240
|
+
2
|
|
241
|
+
)}`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
return result.data;
|
|
245
|
+
};
|
|
246
|
+
var validateParams = (schema, params) => {
|
|
247
|
+
const result = schema.safeParse(params);
|
|
248
|
+
if (!result.success) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
`Invalid path params: ${JSON.stringify(
|
|
251
|
+
result.error.format(),
|
|
252
|
+
null,
|
|
253
|
+
2
|
|
254
|
+
)}`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return result.data;
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// src/api/health-check.ts
|
|
261
|
+
var HealthCheck = class {
|
|
262
|
+
constructor(urls) {
|
|
263
|
+
this.urls = urls;
|
|
264
|
+
}
|
|
265
|
+
async checkHealth() {
|
|
266
|
+
try {
|
|
267
|
+
const results = await Promise.all(
|
|
268
|
+
this.urls.map(async (url) => {
|
|
269
|
+
const response = await fetch(`${url}`);
|
|
270
|
+
if (!response.ok) {
|
|
271
|
+
throw new Error(`Health check failed for ${url}`);
|
|
272
|
+
}
|
|
273
|
+
return response;
|
|
274
|
+
})
|
|
275
|
+
);
|
|
276
|
+
if (results.every((res) => res.ok)) {
|
|
277
|
+
return "ok";
|
|
278
|
+
}
|
|
279
|
+
throw new Error("One or more URLs failed the health check.");
|
|
280
|
+
} catch (error) {
|
|
281
|
+
const failedUrlChecks = await Promise.all(
|
|
282
|
+
this.urls.map(async (url) => {
|
|
283
|
+
try {
|
|
284
|
+
const response = await fetch(`${url}`);
|
|
285
|
+
return { url, failed: !response.ok };
|
|
286
|
+
} catch {
|
|
287
|
+
return { url, failed: true };
|
|
288
|
+
}
|
|
289
|
+
})
|
|
290
|
+
);
|
|
291
|
+
const failedUrls = failedUrlChecks.filter((check) => check.failed).map((check) => check.url);
|
|
292
|
+
throw new ApiError(
|
|
293
|
+
`Health check failed for the following URLs: ${failedUrls.join(
|
|
294
|
+
", "
|
|
295
|
+
)}. Original error: ${error.message}`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
function createResponseContext(c) {
|
|
301
|
+
c.status = c.status || 200;
|
|
302
|
+
return {
|
|
303
|
+
status: (statusCode) => {
|
|
304
|
+
c.status = statusCode;
|
|
305
|
+
return createResponseContext(c);
|
|
306
|
+
},
|
|
307
|
+
json: (body) => {
|
|
308
|
+
return new Response(JSON.stringify(body), {
|
|
309
|
+
status: c.status,
|
|
310
|
+
headers: { "Content-Type": "application/json" }
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
function setupHealthCheckServer(urls, serverPort, func) {
|
|
316
|
+
const healthCheck = new HealthCheck(urls);
|
|
317
|
+
Bun.serve({
|
|
318
|
+
port: serverPort,
|
|
319
|
+
routes: {
|
|
320
|
+
"/health-check": {
|
|
321
|
+
GET: async (c) => {
|
|
322
|
+
try {
|
|
323
|
+
if (func) {
|
|
324
|
+
await func();
|
|
325
|
+
} else {
|
|
326
|
+
await healthCheck.checkHealth();
|
|
327
|
+
}
|
|
328
|
+
return handleResponse(createResponseContext(c), "ok");
|
|
329
|
+
} catch (error) {
|
|
330
|
+
return handleError(
|
|
331
|
+
createResponseContext(c),
|
|
332
|
+
error
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
console.log(
|
|
340
|
+
`Health check server running on http://localhost:${serverPort}/health-check`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// src/logger/logger.ts
|
|
345
|
+
import winston from "winston";
|
|
346
|
+
|
|
347
|
+
// src/logger/sentry_transport.ts
|
|
348
|
+
import * as Sentry from "@sentry/node";
|
|
349
|
+
import Transport from "winston-transport";
|
|
350
|
+
import { LEVEL } from "triple-beam";
|
|
351
|
+
var DEFAULT_LEVELS_MAP = {
|
|
352
|
+
silly: "debug" /* Debug */,
|
|
353
|
+
verbose: "debug" /* Debug */,
|
|
354
|
+
info: "info" /* Info */,
|
|
355
|
+
debug: "debug" /* Debug */,
|
|
356
|
+
warn: "warning" /* Warning */,
|
|
357
|
+
error: "error" /* Error */
|
|
358
|
+
};
|
|
359
|
+
var ExtendedError = class extends Error {
|
|
360
|
+
constructor(info) {
|
|
361
|
+
super(info.message);
|
|
362
|
+
this.name = info.name || "Error";
|
|
363
|
+
if (info.stack && typeof info.stack === "string") {
|
|
364
|
+
this.stack = info.stack;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
var SentryTransport = class _SentryTransport extends Transport {
|
|
369
|
+
silent = false;
|
|
370
|
+
levelsMap = {};
|
|
371
|
+
constructor(opts) {
|
|
372
|
+
super(opts);
|
|
373
|
+
this.levelsMap = this.setLevelsMap(opts && opts.levelsMap);
|
|
374
|
+
this.silent = opts && opts.silent || false;
|
|
375
|
+
if (!opts || !opts.skipSentryInit) {
|
|
376
|
+
Sentry.init(_SentryTransport.withDefaults(opts && opts.sentry || {}));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
log(info, callback) {
|
|
380
|
+
setImmediate(() => {
|
|
381
|
+
this.emit("logged", info);
|
|
382
|
+
});
|
|
383
|
+
if (this.silent) return callback();
|
|
384
|
+
const { message, tags, user, ...meta } = info;
|
|
385
|
+
const winstonLevel = info[LEVEL];
|
|
386
|
+
const sentryLevel = this.levelsMap[winstonLevel];
|
|
387
|
+
const scope = Sentry.getCurrentScope();
|
|
388
|
+
scope.clear();
|
|
389
|
+
if (tags !== void 0 && _SentryTransport.isObject(tags)) {
|
|
390
|
+
scope.setTags(tags);
|
|
391
|
+
}
|
|
392
|
+
scope.setExtras(meta);
|
|
393
|
+
if (user !== void 0 && _SentryTransport.isObject(user)) {
|
|
394
|
+
scope.setUser(user);
|
|
395
|
+
}
|
|
396
|
+
if (_SentryTransport.shouldLogException(sentryLevel)) {
|
|
397
|
+
const error = Object.values(info).find((value) => value instanceof Error) ?? new ExtendedError(info);
|
|
398
|
+
Sentry.captureException(error, { tags, level: sentryLevel });
|
|
399
|
+
return callback();
|
|
400
|
+
}
|
|
401
|
+
Sentry.captureMessage(message, sentryLevel);
|
|
402
|
+
return callback();
|
|
403
|
+
}
|
|
404
|
+
end(...args) {
|
|
405
|
+
Sentry.flush().then(() => {
|
|
406
|
+
super.end(...args);
|
|
407
|
+
});
|
|
408
|
+
return this;
|
|
409
|
+
}
|
|
410
|
+
get sentry() {
|
|
411
|
+
return Sentry;
|
|
412
|
+
}
|
|
413
|
+
setLevelsMap = (options) => {
|
|
414
|
+
if (!options) return DEFAULT_LEVELS_MAP;
|
|
415
|
+
const customLevelsMap = Object.keys(options).reduce(
|
|
416
|
+
(acc, winstonSeverity) => {
|
|
417
|
+
acc[winstonSeverity] = options[winstonSeverity];
|
|
418
|
+
return acc;
|
|
419
|
+
},
|
|
420
|
+
{}
|
|
421
|
+
);
|
|
422
|
+
return { ...DEFAULT_LEVELS_MAP, ...customLevelsMap };
|
|
423
|
+
};
|
|
424
|
+
static withDefaults(options) {
|
|
425
|
+
return {
|
|
426
|
+
...options,
|
|
427
|
+
dsn: options && options.dsn || process.env.SENTRY_DSN || "",
|
|
428
|
+
serverName: options && options.serverName || "winston-transport-sentry-node",
|
|
429
|
+
environment: options && options.environment || process.env.SENTRY_ENVIRONMENT || process.env.NODE_ENV || "production",
|
|
430
|
+
debug: options && options.debug || !!process.env.SENTRY_DEBUG || false,
|
|
431
|
+
sampleRate: options && options.sampleRate || 1,
|
|
432
|
+
maxBreadcrumbs: options && options.maxBreadcrumbs || 100
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
static isObject(obj) {
|
|
436
|
+
const type = typeof obj;
|
|
437
|
+
return type === "function" || type === "object" && !!obj;
|
|
438
|
+
}
|
|
439
|
+
static shouldLogException(level) {
|
|
440
|
+
return level === "fatal" /* Fatal */ || level === "error" /* Error */;
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
// src/logger/logger.ts
|
|
445
|
+
var Logger = class {
|
|
446
|
+
static logger;
|
|
447
|
+
/**
|
|
448
|
+
* @static
|
|
449
|
+
* Create method must first be called before using the logger. It creates a singleton, which will then
|
|
450
|
+
* be referred to throughout the application.
|
|
451
|
+
*/
|
|
452
|
+
static create(config) {
|
|
453
|
+
if (!this.logger) {
|
|
454
|
+
this.logger = winston.createLogger({
|
|
455
|
+
format: winston.format.json(),
|
|
456
|
+
transports: [
|
|
457
|
+
new winston.transports.Console({
|
|
458
|
+
level: config.console?.level || "info"
|
|
459
|
+
}),
|
|
460
|
+
new SentryTransport({
|
|
461
|
+
sentry: {
|
|
462
|
+
dsn: config.sentry?.dsn
|
|
463
|
+
},
|
|
464
|
+
level: config.sentry?.level || "error"
|
|
465
|
+
})
|
|
466
|
+
],
|
|
467
|
+
...config.winston
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
static ensureInitialized() {
|
|
472
|
+
if (!this.logger) {
|
|
473
|
+
throw new BaseError(
|
|
474
|
+
"LOGGER_ERROR",
|
|
475
|
+
errorCodes.base.BASE_ERROR,
|
|
476
|
+
"Logger not initialized. Please call Logger.create() first.",
|
|
477
|
+
true,
|
|
478
|
+
"Logger",
|
|
479
|
+
void 0
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* @static
|
|
485
|
+
* Method to log for level - "info", this should not be called if it has been custom levels are
|
|
486
|
+
* set which does not include "info"
|
|
487
|
+
*
|
|
488
|
+
* @param {string|object} message - String or object to log.
|
|
489
|
+
*/
|
|
490
|
+
static info(message) {
|
|
491
|
+
this.ensureInitialized();
|
|
492
|
+
if (typeof message === "string") {
|
|
493
|
+
this.logger.info(message);
|
|
494
|
+
} else {
|
|
495
|
+
this.logger.info(JSON.stringify(message));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* @static
|
|
500
|
+
* Method to log for level - "debug", this should not be called if it has been custom levels are
|
|
501
|
+
* set which does not include "debug"
|
|
502
|
+
*
|
|
503
|
+
* @param {string|object} message - String or object to log.
|
|
504
|
+
*/
|
|
505
|
+
static debug(message) {
|
|
506
|
+
this.ensureInitialized();
|
|
507
|
+
if (typeof message === "string") {
|
|
508
|
+
this.logger?.debug(message);
|
|
509
|
+
} else {
|
|
510
|
+
this.logger?.debug(JSON.stringify(message));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* @static
|
|
515
|
+
* Method to log for level - "error", this should not be called if it has been custom levels are
|
|
516
|
+
* set which does not include "error"
|
|
517
|
+
*
|
|
518
|
+
* @param {string|object} error - String or object to log.
|
|
519
|
+
*/
|
|
520
|
+
static error(error) {
|
|
521
|
+
this.ensureInitialized();
|
|
522
|
+
if (typeof error === "string") {
|
|
523
|
+
this.logger?.error(error);
|
|
524
|
+
} else {
|
|
525
|
+
this.logger?.error(
|
|
526
|
+
`${error.message ? `${error.message} : ` : ""}${JSON.stringify(error)}`
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* @static
|
|
532
|
+
* Method to log for level - "warn", this should not be called if it has been custom levels are
|
|
533
|
+
* set which does not include "warn"
|
|
534
|
+
*
|
|
535
|
+
* @param {string|object} message - String or object to log.
|
|
536
|
+
*/
|
|
537
|
+
static warn(message) {
|
|
538
|
+
this.ensureInitialized();
|
|
539
|
+
if (typeof message === "string") {
|
|
540
|
+
this.logger?.warn(message);
|
|
541
|
+
} else {
|
|
542
|
+
this.logger?.warn(JSON.stringify(message));
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* @static
|
|
547
|
+
* Method to log for any level, which should be used to log all custom levels that may be added.
|
|
548
|
+
*
|
|
549
|
+
* @param {string|object} message - String or object to log.
|
|
550
|
+
*/
|
|
551
|
+
static log(level, message) {
|
|
552
|
+
this.ensureInitialized();
|
|
553
|
+
if (typeof message === "string") {
|
|
554
|
+
this.logger?.log(level, message);
|
|
555
|
+
} else {
|
|
556
|
+
this.logger?.log(level, JSON.stringify(message));
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
// src/types/logger_config.ts
|
|
562
|
+
import "winston";
|
|
563
|
+
|
|
564
|
+
// src/consumers/event_consumer.ts
|
|
565
|
+
import { createPublicClient, http } from "viem";
|
|
566
|
+
|
|
567
|
+
// src/consumers/abstract_event_consumer.ts
|
|
568
|
+
import { EventEmitter } from "events";
|
|
569
|
+
var AbstractEventConsumer = class extends EventEmitter {
|
|
570
|
+
constructor() {
|
|
571
|
+
super();
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* @public
|
|
575
|
+
*
|
|
576
|
+
* Method to register listener for events. The Abstract Event Consumer emits fatalError
|
|
577
|
+
* event.
|
|
578
|
+
*
|
|
579
|
+
* @param {"fatalError"} eventName - Event name to register listener for.
|
|
580
|
+
* @param listener - Listener to be called when emitting the event.
|
|
581
|
+
*
|
|
582
|
+
* @returns {this} - Returns an instance of the class.
|
|
583
|
+
*/
|
|
584
|
+
on(eventName, listener) {
|
|
585
|
+
return super.on(eventName, listener);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* @public
|
|
589
|
+
*
|
|
590
|
+
* Method to register listener for events that will be called only once. The Abstract Event Consumer emits fatalError
|
|
591
|
+
* event.
|
|
592
|
+
*
|
|
593
|
+
* @param {"fatalError"} eventName - Event name to register listener for.
|
|
594
|
+
* @param listener - Listener to be called when emitting the event.
|
|
595
|
+
*
|
|
596
|
+
* @returns {this} - Returns an instance of the class.
|
|
597
|
+
*/
|
|
598
|
+
once(eventName, listener) {
|
|
599
|
+
return super.on(eventName, listener);
|
|
600
|
+
}
|
|
601
|
+
onFatalError(error) {
|
|
602
|
+
this.emit("fatalError", error);
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// src/consumers/event_consumer.ts
|
|
607
|
+
var EventConsumer = class extends AbstractEventConsumer {
|
|
608
|
+
constructor(config) {
|
|
609
|
+
super();
|
|
610
|
+
this.config = config;
|
|
611
|
+
this.client = createPublicClient({
|
|
612
|
+
chain: {
|
|
613
|
+
id: config.chainId,
|
|
614
|
+
name: "custom",
|
|
615
|
+
rpcUrls: { default: { http: [config.rpcUrl] } },
|
|
616
|
+
nativeCurrency: config.nativeCurrency
|
|
617
|
+
},
|
|
618
|
+
transport: http(config.rpcUrl)
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
client = null;
|
|
622
|
+
observer = null;
|
|
623
|
+
isBackfillingInProcess = false;
|
|
624
|
+
unWatchFunction;
|
|
625
|
+
async _backfillEvents(fromBlock, toBlock, step) {
|
|
626
|
+
Logger.info({
|
|
627
|
+
location: "event_consumer",
|
|
628
|
+
functon: "_backfillEvents",
|
|
629
|
+
status: `[Backfill] Starting backfill from block ${fromBlock.toString()} to ${toBlock.toString()}`
|
|
630
|
+
});
|
|
631
|
+
for (let start = fromBlock; start <= toBlock; start += step) {
|
|
632
|
+
const end = start + step - 1n > toBlock ? toBlock : start + step - 1n;
|
|
633
|
+
Logger.debug({
|
|
634
|
+
location: "event_consumer",
|
|
635
|
+
functon: "_backfillEvents",
|
|
636
|
+
status: `[Backfill] Fetching logs from block ${start.toString()} to ${end.toString()}`
|
|
637
|
+
});
|
|
638
|
+
const getLogsConfig = {
|
|
639
|
+
address: this.config.contractAddress,
|
|
640
|
+
fromBlock: start,
|
|
641
|
+
toBlock: end
|
|
642
|
+
};
|
|
643
|
+
if (this.config.events.length > 1) {
|
|
644
|
+
getLogsConfig.events = this.config.events;
|
|
645
|
+
} else {
|
|
646
|
+
getLogsConfig.event = this.config.events[0];
|
|
647
|
+
}
|
|
648
|
+
const logs = await this.client?.getLogs(getLogsConfig);
|
|
649
|
+
Logger.debug({
|
|
650
|
+
location: "event_consumer",
|
|
651
|
+
functon: "_backfillEvents",
|
|
652
|
+
status: `[Backfill] ${logs?.length} logs from block ${start.toString()} to ${end.toString()}`
|
|
653
|
+
});
|
|
654
|
+
await this.observer?.next(logs);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
async start(observer) {
|
|
658
|
+
try {
|
|
659
|
+
this.isBackfillingInProcess = true;
|
|
660
|
+
this.observer = observer;
|
|
661
|
+
const latestBlock = await this.client?.getBlockNumber() ?? BigInt(0);
|
|
662
|
+
Logger.debug({
|
|
663
|
+
location: "event_consumer",
|
|
664
|
+
functon: "start",
|
|
665
|
+
data: {
|
|
666
|
+
latestBlock: latestBlock.toString(),
|
|
667
|
+
startBlock: this.config.startBlock.toString(),
|
|
668
|
+
pollBatchSize: this.config.pollBatchSize.toString()
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
if (latestBlock - this.config.startBlock > BigInt(0)) {
|
|
672
|
+
await this._backfillEvents(
|
|
673
|
+
this.config.startBlock,
|
|
674
|
+
latestBlock,
|
|
675
|
+
this.config.pollBatchSize
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
this.isBackfillingInProcess = false;
|
|
679
|
+
Logger.debug({
|
|
680
|
+
location: "event_consumer",
|
|
681
|
+
functon: "start",
|
|
682
|
+
status: `Starting event subscription`
|
|
683
|
+
});
|
|
684
|
+
this.unWatchFunction = this.client?.watchEvent({
|
|
685
|
+
address: this.config.contractAddress,
|
|
686
|
+
events: this.config.events,
|
|
687
|
+
fromBlock: latestBlock,
|
|
688
|
+
onLogs: (logs) => {
|
|
689
|
+
const transformedLogs = logs;
|
|
690
|
+
this.observer?.next(transformedLogs);
|
|
691
|
+
},
|
|
692
|
+
onError: (error) => {
|
|
693
|
+
this.onDisconnect();
|
|
694
|
+
this.onFatalError(
|
|
695
|
+
new ConsumerError(error.name, {
|
|
696
|
+
name: "CONSUMER_ERROR",
|
|
697
|
+
code: 1001,
|
|
698
|
+
isFatal: true,
|
|
699
|
+
origin: "EventConsumer",
|
|
700
|
+
context: { eventName: this.config.events }
|
|
701
|
+
})
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
Logger.debug({
|
|
706
|
+
location: "event_consumer",
|
|
707
|
+
functon: "start",
|
|
708
|
+
status: `Subscribed to event`
|
|
709
|
+
});
|
|
710
|
+
} catch (error) {
|
|
711
|
+
this.onDisconnect();
|
|
712
|
+
this.onFatalError(
|
|
713
|
+
new ExternalDependencyError(
|
|
714
|
+
this.config.rpcUrl,
|
|
715
|
+
"Failed to start the event consumer",
|
|
716
|
+
{
|
|
717
|
+
externalCode: errorCodes.external.UNKNOWN_EXTERNAL_DEPENDENCY_ERROR,
|
|
718
|
+
rawError: error,
|
|
719
|
+
origin: "EventConsumer",
|
|
720
|
+
context: { eventName: this.config.events }
|
|
721
|
+
}
|
|
722
|
+
)
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Private method which updates the connection status of consumer to disconnected, and removes all listeners.
|
|
728
|
+
*
|
|
729
|
+
* @returns {void}
|
|
730
|
+
*/
|
|
731
|
+
onDisconnect() {
|
|
732
|
+
this.removeAllListeners();
|
|
733
|
+
if (this.unWatchFunction) {
|
|
734
|
+
this.unWatchFunction();
|
|
735
|
+
}
|
|
736
|
+
this.observer?.closed();
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
// src/consumers/abstract_cron_event_consumer.ts
|
|
741
|
+
import { Cron } from "croner";
|
|
742
|
+
var AbstractCronEventConsumer = class extends AbstractEventConsumer {
|
|
743
|
+
cronJob = null;
|
|
744
|
+
/**
|
|
745
|
+
* Start the cron job with the given cron expression.
|
|
746
|
+
* @param cronExpr Cron expression string
|
|
747
|
+
*/
|
|
748
|
+
startCron(cronExpr) {
|
|
749
|
+
if (this.cronJob) {
|
|
750
|
+
this.cronJob.stop();
|
|
751
|
+
}
|
|
752
|
+
this.cronJob = new Cron(cronExpr, { protect: true }, async () => {
|
|
753
|
+
await this.onTick();
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Stop the cron job.
|
|
758
|
+
*/
|
|
759
|
+
stopCron() {
|
|
760
|
+
if (this.cronJob) {
|
|
761
|
+
this.cronJob.stop();
|
|
762
|
+
this.cronJob = null;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
// src/consumers/rest_api_consumer.ts
|
|
768
|
+
var RestAPIConsumer = class extends AbstractCronEventConsumer {
|
|
769
|
+
constructor(config) {
|
|
770
|
+
super();
|
|
771
|
+
this.config = config;
|
|
772
|
+
this.highestValueSeen = this.config.startCount.value;
|
|
773
|
+
}
|
|
774
|
+
observer = null;
|
|
775
|
+
currentPage = 0;
|
|
776
|
+
highestValueSeen = 0;
|
|
777
|
+
async start(observer) {
|
|
778
|
+
this.observer = observer;
|
|
779
|
+
this.currentPage = 1;
|
|
780
|
+
if (this.config.cronExpr) {
|
|
781
|
+
this.startCron(this.config.cronExpr);
|
|
782
|
+
} else {
|
|
783
|
+
await this.onTick();
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
stop() {
|
|
787
|
+
this.stopCron();
|
|
788
|
+
}
|
|
789
|
+
async onTick() {
|
|
790
|
+
this.currentPage = 1;
|
|
791
|
+
let shouldFetchNextPage = true;
|
|
792
|
+
while (shouldFetchNextPage) {
|
|
793
|
+
shouldFetchNextPage = await this.fetchPage();
|
|
794
|
+
}
|
|
795
|
+
this.config.startCount.value = this.highestValueSeen;
|
|
796
|
+
this.observer?.summary({
|
|
797
|
+
[`${this.config.startCount.key}`]: this.config.startCount.value
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
async fetchPage() {
|
|
801
|
+
try {
|
|
802
|
+
const paginationParam = this.config.paginationParam || "page";
|
|
803
|
+
const params = {
|
|
804
|
+
...this.config.params || {},
|
|
805
|
+
[paginationParam]: this.currentPage.toString()
|
|
806
|
+
};
|
|
807
|
+
let url = this.config.apiUrl.toString();
|
|
808
|
+
if (Object.keys(params).length > 0) {
|
|
809
|
+
const queryString = new URLSearchParams(params).toString();
|
|
810
|
+
url += (url.includes("?") ? "&" : "?") + queryString;
|
|
811
|
+
}
|
|
812
|
+
const response = await fetch(url, {
|
|
813
|
+
method: this.config.method || "GET",
|
|
814
|
+
headers: this.config.headers,
|
|
815
|
+
body: this.config.body ? JSON.stringify(this.config.body) : void 0
|
|
816
|
+
});
|
|
817
|
+
if (!response.ok) {
|
|
818
|
+
throw new ConsumerError(
|
|
819
|
+
`Failed to fetch from API: ${response.statusText}`,
|
|
820
|
+
{
|
|
821
|
+
code: errorCodes.external.UNKNOWN_EXTERNAL_DEPENDENCY_ERROR,
|
|
822
|
+
isFatal: true,
|
|
823
|
+
origin: "rest_api_consumer"
|
|
824
|
+
}
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
let data = await response.json();
|
|
828
|
+
if (this.config.resultPath) {
|
|
829
|
+
data = this.getValueByPath(data, this.config.resultPath);
|
|
830
|
+
}
|
|
831
|
+
const countKey = this.config.startCount.key;
|
|
832
|
+
let currentValue = void 0;
|
|
833
|
+
if (Array.isArray(data)) {
|
|
834
|
+
if (data.length === 0) {
|
|
835
|
+
return false;
|
|
836
|
+
}
|
|
837
|
+
for (const elem of data) {
|
|
838
|
+
currentValue = this.processDataForCurrentCountValue(
|
|
839
|
+
elem,
|
|
840
|
+
countKey
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
} else {
|
|
844
|
+
currentValue = this.processDataForCurrentCountValue(
|
|
845
|
+
data,
|
|
846
|
+
countKey
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
this.observer?.next(data);
|
|
850
|
+
this.currentPage++;
|
|
851
|
+
if (currentValue === void 0) {
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
return currentValue >= this.config.startCount.value;
|
|
855
|
+
} catch (error) {
|
|
856
|
+
this.onFatalError(error);
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
// Utility to get nested values using dot notation (e.g., "response.data.count")
|
|
861
|
+
getValueByPath(obj, path) {
|
|
862
|
+
return path.split(".").reduce((prev, curr) => {
|
|
863
|
+
return prev && prev[curr] !== void 0 ? prev[curr] : void 0;
|
|
864
|
+
}, obj);
|
|
865
|
+
}
|
|
866
|
+
processDataForCurrentCountValue(item, countKey) {
|
|
867
|
+
const value = this.getValueByPath(item, countKey);
|
|
868
|
+
if (value === void 0) {
|
|
869
|
+
throw new ConsumerError(
|
|
870
|
+
`Count key '${countKey}' not found in API response`,
|
|
871
|
+
{
|
|
872
|
+
code: errorCodes.external.UNKNOWN_EXTERNAL_DEPENDENCY_ERROR,
|
|
873
|
+
isFatal: false,
|
|
874
|
+
origin: "rest_api_consumer"
|
|
875
|
+
}
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
this.highestValueSeen = Math.max(this.highestValueSeen, value);
|
|
879
|
+
return value;
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Updates the start count value to a specific value.
|
|
883
|
+
* This allows reprocessing data from a specified point.
|
|
884
|
+
*
|
|
885
|
+
* @param value The value to set as the new start count
|
|
886
|
+
*/
|
|
887
|
+
setStartValue(value) {
|
|
888
|
+
this.config.startCount.value = value;
|
|
889
|
+
this.highestValueSeen = value;
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
|
|
893
|
+
// src/utils/decoder.ts
|
|
894
|
+
import { decodeEventLog, parseAbi, decodeAbiParameters } from "viem";
|
|
895
|
+
var parseEventLog = (eventSignature, data, topics) => {
|
|
896
|
+
return decodeEventLog({ abi: parseAbi(eventSignature), data, topics });
|
|
897
|
+
};
|
|
898
|
+
var decodeAbiParams = (params, data) => {
|
|
899
|
+
return decodeAbiParameters(params, data);
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
// src/utils/ulid.ts
|
|
903
|
+
import { monotonicFactory, ulid } from "ulid";
|
|
904
|
+
function deterministicPRNG(seed) {
|
|
905
|
+
let t = seed;
|
|
906
|
+
return () => {
|
|
907
|
+
t += 1831565813;
|
|
908
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
909
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
910
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
function generateDeterministicULID(dataToEncode, timeSeed, separator) {
|
|
914
|
+
if (!Array.isArray(dataToEncode) || !dataToEncode.every((item) => typeof item === "string")) {
|
|
915
|
+
throw new Error("dataToEncode must be an array of strings");
|
|
916
|
+
}
|
|
917
|
+
const monotonicULID = monotonicFactory();
|
|
918
|
+
const timestampPart = timeSeed ? ulid(timeSeed, deterministicPRNG(timeSeed)) : monotonicULID();
|
|
919
|
+
return [timestampPart, ...dataToEncode.filter(Boolean)].join(
|
|
920
|
+
separator || "-"
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
export {
|
|
924
|
+
AbstractCronEventConsumer,
|
|
925
|
+
ApiError,
|
|
926
|
+
BadRequestError,
|
|
927
|
+
BaseError,
|
|
928
|
+
ConsumerError,
|
|
929
|
+
DatabaseError,
|
|
930
|
+
EventConsumer,
|
|
931
|
+
ExternalDependencyError,
|
|
932
|
+
ForbiddenError,
|
|
933
|
+
HealthCheck,
|
|
934
|
+
Logger,
|
|
935
|
+
NotFoundError,
|
|
936
|
+
RateLimitError,
|
|
937
|
+
RestAPIConsumer,
|
|
938
|
+
TimeoutError,
|
|
939
|
+
UnauthorizedError,
|
|
940
|
+
decodeAbiParams,
|
|
941
|
+
errorCodes,
|
|
942
|
+
generateDeterministicULID,
|
|
943
|
+
handleError,
|
|
944
|
+
handleResponse,
|
|
945
|
+
httpResponseCodes,
|
|
946
|
+
parseEventLog,
|
|
947
|
+
setupHealthCheckServer,
|
|
948
|
+
validateBody,
|
|
949
|
+
validateParams,
|
|
950
|
+
validateQuery
|
|
951
|
+
};
|
|
9
952
|
//# sourceMappingURL=index.js.map
|