@lyxa.ai/core 1.0.5 → 1.0.7
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.js +18 -5
- package/dist/index.js.map +1 -1
- package/dist/libraries/configuration/index.js +4 -4
- package/dist/libraries/configuration/index.js.map +1 -1
- package/dist/libraries/event/BaseEvent.js.map +1 -1
- package/dist/libraries/event/test/OrderCreationEvent.d.ts +11 -0
- package/dist/libraries/event/test/OrderCreationEvent.js +43 -0
- package/dist/libraries/event/test/OrderCreationEvent.js.map +1 -0
- package/dist/libraries/firebase/index.d.ts +14 -0
- package/dist/libraries/firebase/index.js +99 -0
- package/dist/libraries/firebase/index.js.map +1 -0
- package/dist/libraries/index.d.ts +5 -0
- package/dist/libraries/index.js +11 -0
- package/dist/libraries/index.js.map +1 -1
- package/dist/libraries/upload/index.d.ts +25 -0
- package/dist/libraries/upload/index.js +136 -0
- package/dist/libraries/upload/index.js.map +1 -0
- package/dist/utilities/error-handler.d.ts +22 -0
- package/dist/utilities/error-handler.js +202 -0
- package/dist/utilities/error-handler.js.map +1 -0
- package/dist/utilities/transformers.d.ts +15 -0
- package/dist/utilities/transformers.js +117 -0
- package/dist/utilities/transformers.js.map +1 -0
- package/dist/utilities/validation.d.ts +25 -0
- package/dist/utilities/validation.js +44 -0
- package/dist/utilities/validation.js.map +1 -0
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -18,6 +18,9 @@ const mongo_1 = require("./libraries/mongo");
|
|
|
18
18
|
const secrets_1 = require("./libraries/secrets");
|
|
19
19
|
const dispatcher_1 = require("./libraries/dispatcher");
|
|
20
20
|
const twilio_1 = require("./libraries/twilio");
|
|
21
|
+
const firebase_1 = require("./libraries/firebase");
|
|
22
|
+
const event_1 = require("./libraries/event");
|
|
23
|
+
const SubscriptionRegistry_1 = require("./libraries/event/registry/SubscriptionRegistry");
|
|
21
24
|
var EnvironmentConfigurationType_2 = require("./libraries/configuration/types/EnvironmentConfigurationType");
|
|
22
25
|
Object.defineProperty(exports, "EnvironmentConfigurationType", { enumerable: true, get: function () { return EnvironmentConfigurationType_2.EnvironmentConfigurationType; } });
|
|
23
26
|
var mongo_2 = require("./libraries/mongo");
|
|
@@ -57,18 +60,28 @@ async function registerLibraries(options) {
|
|
|
57
60
|
await (0, mongo_1.initGlobalConnection)(mongoUrl, options.environment);
|
|
58
61
|
const loggerInstance = new logger_1.LyxaLogger(options.instanceType, mongoUrl);
|
|
59
62
|
typedi_1.Container.set(logger_1.LyxaLogger, loggerInstance);
|
|
63
|
+
const firebaseInstance = new firebase_1.FirebaseService(configurationInstance);
|
|
64
|
+
typedi_1.Container.set(firebase_1.FirebaseService, firebaseInstance);
|
|
60
65
|
const microserviceDispatcherInstance = new dispatcher_1.MicroServiceDispatcher(secretInstance);
|
|
61
66
|
typedi_1.Container.set(dispatcher_1.MicroServiceDispatcher, microserviceDispatcherInstance);
|
|
62
67
|
const twilioServiceInstance = new twilio_1.TwilioService();
|
|
63
68
|
typedi_1.Container.set(twilio_1.TwilioService, twilioServiceInstance);
|
|
64
69
|
console.log("Initialized everything");
|
|
70
|
+
await (0, event_1.initEventBus)("amqps://vgyuplrd:wto6vUYnb4zeBI5lntKT4gj7rT8n1vwg@dog.lmq.cloudamqp.com/vgyuplrd");
|
|
71
|
+
const allSubscriptions = SubscriptionRegistry_1.SubscriptionRegistry.getAllSubscriptions();
|
|
72
|
+
const instantiatedServices = new Map();
|
|
73
|
+
for (const { eventId, targetConstructor, methodName } of allSubscriptions) {
|
|
74
|
+
let instance = instantiatedServices.get(targetConstructor);
|
|
75
|
+
if (!instance) {
|
|
76
|
+
instance = typedi_1.Container.get(targetConstructor);
|
|
77
|
+
instantiatedServices.set(targetConstructor, instance);
|
|
78
|
+
}
|
|
79
|
+
await (0, event_1.subscribeToEvent)(eventId, async (payload) => {
|
|
80
|
+
return instance[methodName](payload);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
65
83
|
}
|
|
66
84
|
function getLibraries() {
|
|
67
85
|
return typedi_1.Container.get(libraries_1.LibraryManager);
|
|
68
86
|
}
|
|
69
|
-
bootstrapCore({
|
|
70
|
-
environment: EnvironmentConfigurationType_1.EnvironmentConfigurationType.DEV,
|
|
71
|
-
instanceType: "catalogue",
|
|
72
|
-
tenet: "lb"
|
|
73
|
-
});
|
|
74
87
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import {LibraryManager} from \"./libraries\";\r\nimport {Container} from \"typedi\";\r\nimport mongoose from \"mongoose\";\r\nimport {ConfigurationOptions, ConfigurationService} from \"./libraries/configuration\";\r\nimport {EnvironmentConfigurationType} from \"./libraries/configuration/types/EnvironmentConfigurationType\";\r\nimport {LyxaLogger} from \"./libraries/logger\";\r\nimport {RedisService} from \"./libraries/redis\";\r\nimport {initGlobalConnection} from \"./libraries/mongo\";\r\nimport {SecretManagerService} from \"./libraries/secrets\";\r\nimport {MicroServiceDispatcher} from \"./libraries/dispatcher\";\r\nimport {TwilioService} from \"./libraries/twilio\";\r\nimport {FirebaseService} from \"./libraries/firebase\";\r\nimport {initEventBus, subscribeToEvent} from \"./libraries/event\";\r\nimport {SubscriptionRegistry} from \"./libraries/event/registry/SubscriptionRegistry\";\r\n\r\nexport { ConfigurationOptions } from \"./libraries/configuration\";\r\nexport { EnvironmentConfigurationType } from \"./libraries/configuration/types/EnvironmentConfigurationType\";\r\nexport {\r\n initGlobalConnection,\r\n createGlobalModel,\r\n createGlobalDiscriminatorModel\r\n} from './libraries/mongo';\r\n\r\nexport async function bootstrapCore(options?: ConfigurationOptions) {\r\n try {\r\n await registerLibraries(options);\r\n\r\n getLibraries().getLogger().logger.info(\"Successfully bootstrapped lyxa-core.\");\r\n\r\n const gracefulShutdown = async () => {\r\n getLibraries().getLogger().logger.info('Received shutdown signal, shutting down gracefully...');\r\n };\r\n\r\n process.on('SIGTERM', gracefulShutdown);\r\n process.on('SIGINT', gracefulShutdown);\r\n process.on('uncaughtException', (err) => {\r\n getLibraries().getLogger().logger.error('Uncaught exception, shutting down...', err);\r\n gracefulShutdown();\r\n });\r\n\r\n console.log(\"Created hooks.\");\r\n } catch (e) {\r\n console.error(e);\r\n }\r\n}\r\n\r\nexport async function registerLibraries(options?: ConfigurationOptions) {\r\n // Setup configuration.\r\n const configurationInstance = new ConfigurationService(options);\r\n Container.set(ConfigurationService, configurationInstance);\r\n\r\n // Setup redis.\r\n const redisInstance = new RedisService(configurationInstance.options.redisURL!);\r\n Container.set(RedisService, redisInstance);\r\n\r\n // Setup secret\r\n const secretInstance = new SecretManagerService(configurationInstance, redisInstance);\r\n Container.set(SecretManagerService, secretInstance);\r\n\r\n const mongoUrl = await getLibraries().getSecretsService()\r\n .getKey(\"MONGO_URL\");\r\n\r\n await mongoose.connect(mongoUrl!, { dbName: `lyxa-${options!.environment}-${options!.tenet}` });\r\n mongoose.set('debug', getLibraries().getConfigurationService().options.environment == EnvironmentConfigurationType.DEV);\r\n\r\n await initGlobalConnection(mongoUrl!, options!.environment);\r\n\r\n // Setup logger\r\n const loggerInstance = new LyxaLogger(options!.instanceType!, mongoUrl!);\r\n Container.set(LyxaLogger, loggerInstance);\r\n\r\n // Setup firebase\r\n const firebaseInstance = new FirebaseService(configurationInstance!);\r\n Container.set(FirebaseService, firebaseInstance);\r\n\r\n // Setup microservice dispatcher\r\n const microserviceDispatcherInstance = new MicroServiceDispatcher(secretInstance);\r\n Container.set(MicroServiceDispatcher, microserviceDispatcherInstance);\r\n\r\n\r\n // Setup twilio\r\n const twilioServiceInstance = new TwilioService();\r\n Container.set(TwilioService, twilioServiceInstance);\r\n\r\n console.log(\"Initialized everything\");\r\n\r\n await initEventBus(\"amqps://vgyuplrd:wto6vUYnb4zeBI5lntKT4gj7rT8n1vwg@dog.lmq.cloudamqp.com/vgyuplrd\");\r\n const allSubscriptions = SubscriptionRegistry.getAllSubscriptions();\r\n\r\n const instantiatedServices = new Map<Function, any>();\r\n\r\n for (const { eventId, targetConstructor, methodName } of allSubscriptions) {\r\n let instance = instantiatedServices.get(targetConstructor);\r\n if (!instance) {\r\n instance = Container.get(targetConstructor as any);\r\n instantiatedServices.set(targetConstructor, instance);\r\n }\r\n\r\n await subscribeToEvent(eventId, async (payload) => {\r\n return instance[methodName](payload);\r\n });\r\n }\r\n}\r\n\r\nexport function getLibraries(): LibraryManager {\r\n return Container.get(LibraryManager)\r\n}\r\n"]}
|
|
@@ -21,14 +21,14 @@ let ConfigurationService = class ConfigurationService {
|
|
|
21
21
|
super: {
|
|
22
22
|
firebaseAdminServiceAccount: {
|
|
23
23
|
projectId: "for-poc-325210",
|
|
24
|
-
privateKey: "-----BEGIN PRIVATE KEY
|
|
24
|
+
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5aI2nsMHkJbZf\nem9ycpd57RjRDsBt9Nb/uMjsFcBRuAKcKgh4lgNO6ZmcRwK10IRygCmbY5XxmtVA\nq9CT5tYlVN4SDzN1y4lL8/CL5owW2RZOURKcM0lsNOB9uGwkv1t3bfbBNc2hh9JX\n72t7URAtrtPAkUxtgEPm6WL03uNu8KCZ0G9uoA/oM7o8OIGkjC575D9V6QjYC9fn\nPjBRQ3K42fUWFmf31jtUBSHB0xE5qJI+MOi+OcXAJLxKQBbW+vqr2KfMwVYpNclp\nk0Ptfe8xZxVfKEJAAkacQ36Hp14wFK/q+2mmhOQlbruksOZCpaIkh5IdvGkkG8ZH\n566FgFHDAgMBAAECggEAJkuuqprLSZTyiOEQoOqDWBc9X3z1CSEfwV0I/x51BUwF\nGf1il4mgsE12wX03VZd2q/HF5kcZAvjQoFV8tPfidn6DieZi4itCthHyNutNNzDq\ntw1u0x2SxktbrQwJJkPyIAZyB7FVwk38B9a3dBanyU/JhAZe62UpYUoGev6IqnKm\nIiw7r4lc47XgJNrDjXhCtTwHBmXA6qt/HrBcu4fSZlnZMhvsgnO6iafXaBo15Rpy\nyVBVCPCGJBqpbqI8w3lVTcUqvD2DS+wGJAZSNFagt5qg+vCN8xVUsyQKrM1qIXZm\nxvPX5oE6CWaD5a7yzpwqKLghKIpsb+3gezyQiFw5rQKBgQDh9U+VdFipH2o8Rezd\n2d9Kp+ya8+kAog4NMeMyD/xyvKbmv6hW2SZqLhc5MacO0GiCnFR+dMLJxRBGnn+e\ngYP26OE2fG9Kn7JrSGafu7siKnonfaN/1IcHcZe/77P/s/o2lNxaVl9i1iPQlzr/\nN8RRaYa+pvazR4VNMS+Z6keD5QKBgQDSDxfKGwOt/GlPKRDmw3bKD4tseK36JsJw\n5u7im6CpiTEgSSbOCr1ggITv6VbHUK/Nv3mExJH6uuzd9szb94JUAxGbZ16Liwn4\nse+K2XlnLEnqxzFSkprOJAJkfbffrH+IxW8gNrK/UbjKT/xgEVH1ZeKUMPLCQG+y\nLAW6NY50hwKBgCYQTPfAQa87u4mrvdsheJv67cCslfOlWPigDsXAK6aoYPU+E/2N\nVwtL+F2KH7o/IVvfOdyTjryula9Pw+/PoYtWb5neHGFVxZiM+byuwzdeMHW2lHRU\nOOroF8gdeRT6HIxVR0lwg2EC8cWRtD6KBmgwfqJfPe+1fJ8kSgCDlsiBAoGBAI1D\nOyNeYW4bBhMHMeeOYY9nPsL2sUE92Zslolbgg/4fVds5dpAvpsWECGJy0Dn/6Ap8\njtMbgnRUSsDGnWP8IjgvTCLvNCSxn0YRG1+L+tnIbfkmdePq1ZJ1oupDpWkVTzsC\nU0Ydor2IzrW3bqiIXU6jculntYmu3a67biqYo7F3AoGBALoinJdtNLLqOqf/MumD\n+YmbzHqsuID2dGyct7GESIBx3a67hwyJQfCK8nyHNyWN7lFg+H1rZlu1Cjmo0hlu\nOxzdbWON5Rg2n3TbGw3AM1M55khsedbmm8MOSRdhIkz5RuYESSNAvVC6CBcfg5gb\nCPq8jrR+oljMjBwAaQmFlPF7\n-----END PRIVATE KEY-----\n",
|
|
25
25
|
clientEmail: "lyxa-core@for-poc-325210.iam.gserviceaccount.com"
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
user: {
|
|
29
29
|
firebaseAdminServiceAccount: {
|
|
30
30
|
projectId: "for-poc-325210",
|
|
31
|
-
privateKey: "-----BEGIN PRIVATE KEY
|
|
31
|
+
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9yUnAC2pQ+dhe\ndJVMS7RQeQdQO7JhT0BXz0MbpCXlEdc3j/GQAY9UfKxQLg1VZh+4An8aUZevOy/v\nUaHsvqSWcWg7UHTOjk861brpjdjhM4S4ahwU2NyVI/o0Bpc5ob4nhHebny9FGqEP\nauwUXiVw7UjA/yGeTN6delZwCxejHxI6zDjFQveo8Ljkfu49CMyyf1XhN9q0So4Q\n2pZ3Xmdz0fZGykSGT9TVBDnPE8Zc3VCQ1XQ7aEKr0e9L+YYidw+iurSNwQSo72uk\nf/G2wCtlAaoDh0lKObEbi1b925BOthP2XpmQ7Kv+iWVFouCY54Md56FxtjKOyYll\n0nS6MkAJAgMBAAECggEAEeee83UoPjQ6BVxAlxJ31BU8+0TshOlwB7C8MywC7rfm\nit2Dw8sf4W/DJmvX0nAYazjiEqKyuaOO98gm64HHX5GarKjgIjoTD7kJAZ6CIOnm\nOis5k75rXg8nPFgIVZW0rb/9tEL5984ltoGG/PtuUxdxwxJ20ptML8VySO8E93yt\n203zMlm/QdlUBBO+XDlpsEoXvUjQ6MzmCSF2LCFD1uBVmj0sVFuPt5fyodhV8gQM\nvDfG4duZ7AE6Nbc5ANgJw8fHMdx+AS+I0P50et936tuFOOeHUWGbg1RMOM1GrWLZ\nH83zfHp33R3rlUgleZetKh/5vLaW29MdJmACk2Z14QKBgQDtrywbz60ULHiyNvDP\nHFweJF/9EBq6MZeo/lYrBDZXuP3sBM7uUa+oYzYad3Lsxo1Vz/Zqb6atWX/BRbHT\nfyy6yTGPRn6geaqYEFuFwfBau3qju6DRwoqplVVlLo8lgOQzIDgXkk0nt7C/bM87\nmkxQI6Xi0TAjIpd3k6miw52laQKBgQDMaTnlL2OGlJlcycBZGxrKdsIwvK2jCLPi\njPTKM163htuzaItEVpJaCPjWaU3k3E1UXjFp9oxxvtDZOZP+DcFwGKvBe2vntFYz\nafCNlYK7wT/t7ChlCUSXuU/bSrXe4Wc4KGnJ6YzNmykMJku2b845layB1PxEhHHA\nRl2NEx9RoQKBgHJvETx+m2UIGEAtZXlBvTQh7TkIxOV6NPt/IHtrdsJ7ZX15vytM\nltbqlUTe160Z1zhGfOw3vzbczT5/UKN0KlPvw/WoShT3HuRBk97tRcxZUS19i2sS\nT/Jf3JJvfSngSX439+mZXZ5OuUEgoRGgMzeuQhLXBmcUI3rF1DlyFvdpAoGAfmq5\nbn8fSzUNn+/6MGFt8Tb/JAscS87vCTZpkb+xXUlfCJaoQqxTuLEBzAC2Nsr0XDAg\n2UqsUxBSs3VDjIRPVJc9adx9wH+sLAHhzn5fquR6OBesZ8gSjs8BjzqmPeAi6P09\nZ60z8lh6S1RH0N1WqhBh7q2dEnbirqoV41CnNuECgYEAr26tTBIvEeZY3gmAmOVl\nCw6gkxaHdzZplFl8Qnv272VllQpwbR1zaF6RfWsTEsrhrT+VtrZO6DDh9O6iJkbB\n7Re3BnMOhGfUS3HlPCFnkdodeaoeVpg4llYwuunmyj+SmNxnC56TiznML1owmUYd\ndLFeY+JZ0GpSBO0qYlY5QGk=\n-----END PRIVATE KEY-----\n",
|
|
32
32
|
clientEmail: "firebase-adminsdk-onusy@for-poc-325210.iam.gserviceaccount.com"
|
|
33
33
|
},
|
|
34
34
|
firebaseAdminAppName: "lyxa-user"
|
|
@@ -36,7 +36,7 @@ let ConfigurationService = class ConfigurationService {
|
|
|
36
36
|
rider: {
|
|
37
37
|
firebaseAdminServiceAccount: {
|
|
38
38
|
projectId: "lyxa-rider-88939",
|
|
39
|
-
privateKey: "-----BEGIN PRIVATE KEY
|
|
39
|
+
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC08zRqUjHFO7Ir\n4UNHIjxVp7oJkK3rrV1UGfHeHsijm6CSWjViVqsFKUZliYXTjg9S8rIMmC3OAMrh\n5FTdNfDell8YHPbVRWZ0OFBNWglvKMgMKMoyQuBKtvEAdZwgVMreOf+51QlZnPxy\nTBNh4Du2ahb8TtAjwxXt7CgMjNIfoMjQFJTrBTAmsxhtOEpYvPU2iX+OtAkHgrs1\nNeWpBGpN4GSwOfA8MdgvorLYbeRDnkY4cH/ReNymTW9nbX1vgsx2AE1NR5PTNxv0\nIuVZQWxMMGPnT5bjzAlCR4z/Nbe89V2zl5kFtBxDBCDqxp+qZxCinJj1QqwC5qzZ\nYLbNVKVPAgMBAAECggEAEHEGwrW24v/NF9KZ3S/zASoX1oBTD+vf4+E69QlMBshV\nxeaKHOYuF5khVd7cjj/wDC6ULLPJJFjga7e7rvaUl80G//cQcIl5STcdXiHqYzN2\nldrroGHWOm5hUJQ0fEroEgV9bc0PJ+7X5f9xRWlCqQz+YKzn7vqYwVZovyyDzS6/\nTus2SeWg0Qh1Uw4+FqveEqGBAMF9COTYJ/rZ5sDE34cYRJeZOgVDeSanF/CW6+VS\nLT5+ysRS8xY/mUFIgs6zvJQr7whDj22OzvZr31LReNUl1IGI1V0wHxCJs3y934dq\nuiAf4iX2w0uwiQs7+IQc6T6GhTEajWHSQqUtbDeecQKBgQDAW/mHk1PCCxZQtc6C\nCkFYONeY0zz7JAk7AvcbeVB6icq9Zv/9botFOvJ/4dduN39+sO/SIvLV+zQzmUGA\nygY58AQIqtYurIc8OjftQ5qZ6t9H1plmj/W+GVAYWadA68P95UBjwVcZySht47s/\ngOje4TF9wXVn9oTuP8XmLpce/wKBgQDw0Onl7EVmkgnyHl1qomqHR+2+xNDZNYMv\njdX0tq2KOXa6JpbO32Yf7LVKQo7bmSOy3M1kn2+lwCXsDufr/a+1GNRxuPucsYiM\nlQeLEKRqfNUni1NnbIUOkZV0fO0Me76Ow5BKqEWrda0E5k9g46p8EgVO5zWUE00w\nZZFTUn7JsQKBgDh9SiREYb6EXwNIwOJzfIkZ+EaLEkd2Z7eKwWKyF65EtOM2Ukrs\nob2s9/YSLp/RcIGWGHePh9zLLqNQiGn36igtkiGxecCvLe/D8RSeW9KDpRqFrPrv\nn+05pcng2js4gZAYOPaSmq+Z4WOUEzMs+jYpz8zseTwUqykEVWuplvulAoGAF8y9\n4RBZx4pVW01u9BP7LUWJlJoE/gKQ5YlCBP5s5kVJm5omu2lOwYb2X9F2JvPamFnE\nHta3BQ2ZcdwDRcp7rA05KcgbbeAJ28L6zN6nMTMHKfJWGtmZyNfQioOyNdKhAaEI\nSKiawhhOMjbEz5GQjtSFG8gz/l9t+IOBOlfj2fECgYBC8gGC7YHm+PvV5F1CVRZD\nUYVlAnqOMJ1VvfTemW/kPzuCMd/JEKSE+b21h3rObMvUZU5AnkM3VT1+hDv6tyEt\nblgh89YsHUor7wXSrYnVmYsrm91JABTWsLhLy92iqylg0xBs3Q5RGCt/s9f3YFFw\nKghNmTDraGggnf5U/Z4LJw==\n-----END PRIVATE KEY-----\n",
|
|
40
40
|
clientEmail: "firebase-adminsdk-qwhrd@lyxa-rider-88939.iam.gserviceaccount.com"
|
|
41
41
|
},
|
|
42
42
|
firebaseAdminAppName: "lyxa-rider"
|
|
@@ -44,7 +44,7 @@ let ConfigurationService = class ConfigurationService {
|
|
|
44
44
|
shop: {
|
|
45
45
|
firebaseAdminServiceAccount: {
|
|
46
46
|
projectId: "lyxa-shop",
|
|
47
|
-
privateKey: "-----BEGIN PRIVATE KEY
|
|
47
|
+
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTWaf/QGSjk7po\nri+6Nzo/tep1UtgMSY4KscT3iCbepiAsw7C8NCQqz3wYEAFRwywbaCwUcUs5KUC7\n/e9TvpSQQksu10P9uP+c7wnAy+l0ay/15vWUV0usmDhMMvfjtDwS2RYTMEAdNUiZ\nOuMC3/DDCBHt0SC5WCNzz11jj/n5bdVOS02qHd8V/lbd46iVEYfFswkI5NBgV7CY\nnR2CoVcakPIeu9kEKdjXsJvf8+zCYtXPaFvcubQcnybOcg6usU+AHD1iwCRd6BrK\n2PpM3gy/eASLJtzg/JoU0CgqJICmfR8LvGk6iHTp7VMfPuCfggwYtO3W1kSHuW4I\nswbXYOJbAgMBAAECggEAMHKZ5xIsv66KiZp8SFSGnrolv7U430AxNlRf0Vo9hsZQ\nE9Lb/Zh6PfIIAUAR/VsfDj1H9XuvAbBqLW3dYbYLOjJoJ5mi9VNmDORiuPZFUrGL\ncfP6kYGdUDgol5cLagAT0UJAJC/oUom3VaDBDxSkjSCZc4l/1dzVa6O6RatoYvuW\nqtJa5WzPH6flqj9HuFZaaNSZKXSYLwMeQC7bzxjbX0lB6b1WM2EIxQopeewrSfKg\nvaw7zYHnu9cO6oA6I4A3VXhySp3G2VIMOIezfI24mP2Bnzori6xCVXcM7R1B2Trr\nlFUrdXb9Rp3ZR0Ul0jSqCmopmMPVgob8lyHhiqk5+QKBgQDd/PcIRP7OE0ZnfXtd\nxWMz1ggp9ub6bN/mFxw/OoyEVSfmlshDCvEeqoo2DxWGC+/0uiGuPHnDKDX+R0Ho\nqmlWcVPTSBmrQvi3+VBKfr6ZCwxoutCQo3SMlEMvqHDkjGhAsDg/yjkI8yS5jqZ5\nXtG+dYQpd9qY3t46Uar1+7lpJwKBgQDzu3CzElfr3xHAEdE+1pkiPixPuW+fHw1v\nwoc5e7hJA1Mtu0Gdj7g41mF37bUXYxIg3FgV5sS76XCxw1a3plj/y0n+qZXMq5xs\nZwgqrh4APjVXVRp9SSOvEXT0NanhWKiHMNncvteqThSEal27MDghEzqDmebkuOII\ng+KDmYp1rQKBgA0dhPrYGLXULbSvlTpVDydg3dqc28iv5gqSEvkpXGP1JAZbojlT\nzCsjqEbJXVwuGF89IABLUmZVWdtMGnjEmLSivXEeMWYM7uTvte6wzlH8dR866leh\nUKF9oPqP2RunsAEiaDBcokIFG4ZbBzrkfz/hcY2Bp0ig4kBP0un1lV7BAoGBAJ4L\n4MOt1Gd2KetzYk0uGPS0fkVgSLpVB4B+EvO6f0CRMGHKOH00UdBBa8i50qEMtBes\n6k2ha9cyQ8pxkYzbCIEuUJgbXbDvYyqEES6j435i2HH+FIRDZilC16T4G2Wt+PJZ\nQhy7f9vGb9WBp7AXT35bGql1pdyQ6rl80+hkKv2tAoGAe4yFOvIdEEdgEokp5Dem\nuPf1rikk5mYPMkXhrX0cH9Wd2rh9MiP2gJuL3PD3R9LLon+9EzdBs31MwpP9C06Y\nZmnuEfgYIewBHZbpRO+nsGX+AK15gbJUNk1RbWmUU7AvkHyo4eE6NnNVbygxaFSk\n0+8aYRpYzZRnyAn8Oo6o2No=\n-----END PRIVATE KEY-----\n",
|
|
48
48
|
clientEmail: "firebase-adminsdk-w4v98@lyxa-shop.iam.gserviceaccount.com"
|
|
49
49
|
},
|
|
50
50
|
firebaseAdminAppName: "lyxa-shop"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/configuration/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,mCAA+B;AAC/B,uFAAkF;AA6B3E,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ,eAAe,GAAyB;QACrD,QAAQ,EAAE,mHAAmH;QAC7H,KAAK,EAAE,SAAS;QAChB,YAAY,EAAE,SAAS;QACvB,aAAa,EAAE;YACX,KAAK,EAAE;gBACH,2BAA2B,EAAE;oBACzB,SAAS,EAAE,gBAAgB;oBAC3B,UAAU,EAAE,kuDAAkuD;oBAC9uD,WAAW,EAAE,kDAAkD;iBAClE;aACJ;YACD,IAAI,EAAE;gBACF,2BAA2B,EAAE;oBACzB,SAAS,EAAE,gBAAgB;oBAC3B,UAAU,EAAE,kuDAAkuD;oBAC9uD,WAAW,EAAE,gEAAgE;iBAChF;gBACD,oBAAoB,EAAE,WAAW;aACpC;YACD,KAAK,EAAE;gBACH,2BAA2B,EAAE;oBACzB,SAAS,EAAE,kBAAkB;oBAC7B,UAAU,EAAE,kuDAAkuD;oBAC9uD,WAAW,EAAE,kEAAkE;iBAClF;gBACD,oBAAoB,EAAE,YAAY;aACrC;YACD,IAAI,EAAE;gBACF,2BAA2B,EAAE;oBACzB,SAAS,EAAE,WAAW;oBACtB,UAAU,EAAE,kuDAAkuD;oBAC9uD,WAAW,EAAE,2DAA2D;iBAC3E;gBACD,oBAAoB,EAAE,WAAW;aACpC;SACJ;QACD,WAAW,EAAE,2DAA4B,CAAC,GAAG;KAChD,CAAC;IAEe,QAAQ,CAAuB;IAEhD,YAAY,OAA8B;QACtC,IAAI,CAAC,QAAQ,GAAG;YACZ,GAAG,IAAI,CAAC,eAAe;YACvB,GAAG,OAAO;SACb,CAAC;IACN,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;CACJ,CAAA;AAtDY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,gBAAO,GAAE;;GACG,oBAAoB,CAsDhC","sourcesContent":["import {FirebaseOptions} from \"firebase/app\";\r\nimport {ServiceAccount} from \"firebase-admin\";\r\nimport {Service} from \"typedi\";\r\nimport {EnvironmentConfigurationType} from \"./types/EnvironmentConfigurationType\";\r\n\r\nexport interface ConfigurationOptions {\r\n tenet?: string;\r\n redisURL?: string;\r\n instanceType?: string;\r\n firebaseAdmin?: {\r\n super: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n },\r\n user: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n },\r\n shop: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n },\r\n rider: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n }\r\n },\r\n environment: EnvironmentConfigurationType\r\n}\r\n\r\n\r\n@Service()\r\nexport class ConfigurationService {\r\n\r\n private readonly _defaultOptions: ConfigurationOptions = {\r\n redisURL: \"redis://default:8RCVCiwXRMo6isHgJanL1pE86cRt29YP@redis-12296.fcrce173.eu-west-1-1.ec2.redns.redis-cloud.com:12296\",\r\n tenet: \"default\",\r\n instanceType: \"unknown\",\r\n firebaseAdmin: {\r\n super: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"for-poc-325210\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5aI2nsMHkJbZf\\\\nem9ycpd57RjRDsBt9Nb/uMjsFcBRuAKcKgh4lgNO6ZmcRwK10IRygCmbY5XxmtVA\\\\nq9CT5tYlVN4SDzN1y4lL8/CL5owW2RZOURKcM0lsNOB9uGwkv1t3bfbBNc2hh9JX\\\\n72t7URAtrtPAkUxtgEPm6WL03uNu8KCZ0G9uoA/oM7o8OIGkjC575D9V6QjYC9fn\\\\nPjBRQ3K42fUWFmf31jtUBSHB0xE5qJI+MOi+OcXAJLxKQBbW+vqr2KfMwVYpNclp\\\\nk0Ptfe8xZxVfKEJAAkacQ36Hp14wFK/q+2mmhOQlbruksOZCpaIkh5IdvGkkG8ZH\\\\n566FgFHDAgMBAAECggEAJkuuqprLSZTyiOEQoOqDWBc9X3z1CSEfwV0I/x51BUwF\\\\nGf1il4mgsE12wX03VZd2q/HF5kcZAvjQoFV8tPfidn6DieZi4itCthHyNutNNzDq\\\\ntw1u0x2SxktbrQwJJkPyIAZyB7FVwk38B9a3dBanyU/JhAZe62UpYUoGev6IqnKm\\\\nIiw7r4lc47XgJNrDjXhCtTwHBmXA6qt/HrBcu4fSZlnZMhvsgnO6iafXaBo15Rpy\\\\nyVBVCPCGJBqpbqI8w3lVTcUqvD2DS+wGJAZSNFagt5qg+vCN8xVUsyQKrM1qIXZm\\\\nxvPX5oE6CWaD5a7yzpwqKLghKIpsb+3gezyQiFw5rQKBgQDh9U+VdFipH2o8Rezd\\\\n2d9Kp+ya8+kAog4NMeMyD/xyvKbmv6hW2SZqLhc5MacO0GiCnFR+dMLJxRBGnn+e\\\\ngYP26OE2fG9Kn7JrSGafu7siKnonfaN/1IcHcZe/77P/s/o2lNxaVl9i1iPQlzr/\\\\nN8RRaYa+pvazR4VNMS+Z6keD5QKBgQDSDxfKGwOt/GlPKRDmw3bKD4tseK36JsJw\\\\n5u7im6CpiTEgSSbOCr1ggITv6VbHUK/Nv3mExJH6uuzd9szb94JUAxGbZ16Liwn4\\\\nse+K2XlnLEnqxzFSkprOJAJkfbffrH+IxW8gNrK/UbjKT/xgEVH1ZeKUMPLCQG+y\\\\nLAW6NY50hwKBgCYQTPfAQa87u4mrvdsheJv67cCslfOlWPigDsXAK6aoYPU+E/2N\\\\nVwtL+F2KH7o/IVvfOdyTjryula9Pw+/PoYtWb5neHGFVxZiM+byuwzdeMHW2lHRU\\\\nOOroF8gdeRT6HIxVR0lwg2EC8cWRtD6KBmgwfqJfPe+1fJ8kSgCDlsiBAoGBAI1D\\\\nOyNeYW4bBhMHMeeOYY9nPsL2sUE92Zslolbgg/4fVds5dpAvpsWECGJy0Dn/6Ap8\\\\njtMbgnRUSsDGnWP8IjgvTCLvNCSxn0YRG1+L+tnIbfkmdePq1ZJ1oupDpWkVTzsC\\\\nU0Ydor2IzrW3bqiIXU6jculntYmu3a67biqYo7F3AoGBALoinJdtNLLqOqf/MumD\\\\n+YmbzHqsuID2dGyct7GESIBx3a67hwyJQfCK8nyHNyWN7lFg+H1rZlu1Cjmo0hlu\\\\nOxzdbWON5Rg2n3TbGw3AM1M55khsedbmm8MOSRdhIkz5RuYESSNAvVC6CBcfg5gb\\\\nCPq8jrR+oljMjBwAaQmFlPF7\\\\n-----END PRIVATE KEY-----\\\\n\",\r\n clientEmail: \"lyxa-core@for-poc-325210.iam.gserviceaccount.com\"\r\n }\r\n },\r\n user: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"for-poc-325210\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9yUnAC2pQ+dhe\\\\ndJVMS7RQeQdQO7JhT0BXz0MbpCXlEdc3j/GQAY9UfKxQLg1VZh+4An8aUZevOy/v\\\\nUaHsvqSWcWg7UHTOjk861brpjdjhM4S4ahwU2NyVI/o0Bpc5ob4nhHebny9FGqEP\\\\nauwUXiVw7UjA/yGeTN6delZwCxejHxI6zDjFQveo8Ljkfu49CMyyf1XhN9q0So4Q\\\\n2pZ3Xmdz0fZGykSGT9TVBDnPE8Zc3VCQ1XQ7aEKr0e9L+YYidw+iurSNwQSo72uk\\\\nf/G2wCtlAaoDh0lKObEbi1b925BOthP2XpmQ7Kv+iWVFouCY54Md56FxtjKOyYll\\\\n0nS6MkAJAgMBAAECggEAEeee83UoPjQ6BVxAlxJ31BU8+0TshOlwB7C8MywC7rfm\\\\nit2Dw8sf4W/DJmvX0nAYazjiEqKyuaOO98gm64HHX5GarKjgIjoTD7kJAZ6CIOnm\\\\nOis5k75rXg8nPFgIVZW0rb/9tEL5984ltoGG/PtuUxdxwxJ20ptML8VySO8E93yt\\\\n203zMlm/QdlUBBO+XDlpsEoXvUjQ6MzmCSF2LCFD1uBVmj0sVFuPt5fyodhV8gQM\\\\nvDfG4duZ7AE6Nbc5ANgJw8fHMdx+AS+I0P50et936tuFOOeHUWGbg1RMOM1GrWLZ\\\\nH83zfHp33R3rlUgleZetKh/5vLaW29MdJmACk2Z14QKBgQDtrywbz60ULHiyNvDP\\\\nHFweJF/9EBq6MZeo/lYrBDZXuP3sBM7uUa+oYzYad3Lsxo1Vz/Zqb6atWX/BRbHT\\\\nfyy6yTGPRn6geaqYEFuFwfBau3qju6DRwoqplVVlLo8lgOQzIDgXkk0nt7C/bM87\\\\nmkxQI6Xi0TAjIpd3k6miw52laQKBgQDMaTnlL2OGlJlcycBZGxrKdsIwvK2jCLPi\\\\njPTKM163htuzaItEVpJaCPjWaU3k3E1UXjFp9oxxvtDZOZP+DcFwGKvBe2vntFYz\\\\nafCNlYK7wT/t7ChlCUSXuU/bSrXe4Wc4KGnJ6YzNmykMJku2b845layB1PxEhHHA\\\\nRl2NEx9RoQKBgHJvETx+m2UIGEAtZXlBvTQh7TkIxOV6NPt/IHtrdsJ7ZX15vytM\\\\nltbqlUTe160Z1zhGfOw3vzbczT5/UKN0KlPvw/WoShT3HuRBk97tRcxZUS19i2sS\\\\nT/Jf3JJvfSngSX439+mZXZ5OuUEgoRGgMzeuQhLXBmcUI3rF1DlyFvdpAoGAfmq5\\\\nbn8fSzUNn+/6MGFt8Tb/JAscS87vCTZpkb+xXUlfCJaoQqxTuLEBzAC2Nsr0XDAg\\\\n2UqsUxBSs3VDjIRPVJc9adx9wH+sLAHhzn5fquR6OBesZ8gSjs8BjzqmPeAi6P09\\\\nZ60z8lh6S1RH0N1WqhBh7q2dEnbirqoV41CnNuECgYEAr26tTBIvEeZY3gmAmOVl\\\\nCw6gkxaHdzZplFl8Qnv272VllQpwbR1zaF6RfWsTEsrhrT+VtrZO6DDh9O6iJkbB\\\\n7Re3BnMOhGfUS3HlPCFnkdodeaoeVpg4llYwuunmyj+SmNxnC56TiznML1owmUYd\\\\ndLFeY+JZ0GpSBO0qYlY5QGk=\\\\n-----END PRIVATE KEY-----\\\\n\",\r\n clientEmail: \"firebase-adminsdk-onusy@for-poc-325210.iam.gserviceaccount.com\"\r\n },\r\n firebaseAdminAppName: \"lyxa-user\"\r\n },\r\n rider: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"lyxa-rider-88939\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\\\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC08zRqUjHFO7Ir\\\\n4UNHIjxVp7oJkK3rrV1UGfHeHsijm6CSWjViVqsFKUZliYXTjg9S8rIMmC3OAMrh\\\\n5FTdNfDell8YHPbVRWZ0OFBNWglvKMgMKMoyQuBKtvEAdZwgVMreOf+51QlZnPxy\\\\nTBNh4Du2ahb8TtAjwxXt7CgMjNIfoMjQFJTrBTAmsxhtOEpYvPU2iX+OtAkHgrs1\\\\nNeWpBGpN4GSwOfA8MdgvorLYbeRDnkY4cH/ReNymTW9nbX1vgsx2AE1NR5PTNxv0\\\\nIuVZQWxMMGPnT5bjzAlCR4z/Nbe89V2zl5kFtBxDBCDqxp+qZxCinJj1QqwC5qzZ\\\\nYLbNVKVPAgMBAAECggEAEHEGwrW24v/NF9KZ3S/zASoX1oBTD+vf4+E69QlMBshV\\\\nxeaKHOYuF5khVd7cjj/wDC6ULLPJJFjga7e7rvaUl80G//cQcIl5STcdXiHqYzN2\\\\nldrroGHWOm5hUJQ0fEroEgV9bc0PJ+7X5f9xRWlCqQz+YKzn7vqYwVZovyyDzS6/\\\\nTus2SeWg0Qh1Uw4+FqveEqGBAMF9COTYJ/rZ5sDE34cYRJeZOgVDeSanF/CW6+VS\\\\nLT5+ysRS8xY/mUFIgs6zvJQr7whDj22OzvZr31LReNUl1IGI1V0wHxCJs3y934dq\\\\nuiAf4iX2w0uwiQs7+IQc6T6GhTEajWHSQqUtbDeecQKBgQDAW/mHk1PCCxZQtc6C\\\\nCkFYONeY0zz7JAk7AvcbeVB6icq9Zv/9botFOvJ/4dduN39+sO/SIvLV+zQzmUGA\\\\nygY58AQIqtYurIc8OjftQ5qZ6t9H1plmj/W+GVAYWadA68P95UBjwVcZySht47s/\\\\ngOje4TF9wXVn9oTuP8XmLpce/wKBgQDw0Onl7EVmkgnyHl1qomqHR+2+xNDZNYMv\\\\njdX0tq2KOXa6JpbO32Yf7LVKQo7bmSOy3M1kn2+lwCXsDufr/a+1GNRxuPucsYiM\\\\nlQeLEKRqfNUni1NnbIUOkZV0fO0Me76Ow5BKqEWrda0E5k9g46p8EgVO5zWUE00w\\\\nZZFTUn7JsQKBgDh9SiREYb6EXwNIwOJzfIkZ+EaLEkd2Z7eKwWKyF65EtOM2Ukrs\\\\nob2s9/YSLp/RcIGWGHePh9zLLqNQiGn36igtkiGxecCvLe/D8RSeW9KDpRqFrPrv\\\\nn+05pcng2js4gZAYOPaSmq+Z4WOUEzMs+jYpz8zseTwUqykEVWuplvulAoGAF8y9\\\\n4RBZx4pVW01u9BP7LUWJlJoE/gKQ5YlCBP5s5kVJm5omu2lOwYb2X9F2JvPamFnE\\\\nHta3BQ2ZcdwDRcp7rA05KcgbbeAJ28L6zN6nMTMHKfJWGtmZyNfQioOyNdKhAaEI\\\\nSKiawhhOMjbEz5GQjtSFG8gz/l9t+IOBOlfj2fECgYBC8gGC7YHm+PvV5F1CVRZD\\\\nUYVlAnqOMJ1VvfTemW/kPzuCMd/JEKSE+b21h3rObMvUZU5AnkM3VT1+hDv6tyEt\\\\nblgh89YsHUor7wXSrYnVmYsrm91JABTWsLhLy92iqylg0xBs3Q5RGCt/s9f3YFFw\\\\nKghNmTDraGggnf5U/Z4LJw==\\\\n-----END PRIVATE KEY-----\\\\n\",\r\n clientEmail: \"firebase-adminsdk-qwhrd@lyxa-rider-88939.iam.gserviceaccount.com\"\r\n },\r\n firebaseAdminAppName: \"lyxa-rider\"\r\n },\r\n shop: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"lyxa-shop\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTWaf/QGSjk7po\\\\nri+6Nzo/tep1UtgMSY4KscT3iCbepiAsw7C8NCQqz3wYEAFRwywbaCwUcUs5KUC7\\\\n/e9TvpSQQksu10P9uP+c7wnAy+l0ay/15vWUV0usmDhMMvfjtDwS2RYTMEAdNUiZ\\\\nOuMC3/DDCBHt0SC5WCNzz11jj/n5bdVOS02qHd8V/lbd46iVEYfFswkI5NBgV7CY\\\\nnR2CoVcakPIeu9kEKdjXsJvf8+zCYtXPaFvcubQcnybOcg6usU+AHD1iwCRd6BrK\\\\n2PpM3gy/eASLJtzg/JoU0CgqJICmfR8LvGk6iHTp7VMfPuCfggwYtO3W1kSHuW4I\\\\nswbXYOJbAgMBAAECggEAMHKZ5xIsv66KiZp8SFSGnrolv7U430AxNlRf0Vo9hsZQ\\\\nE9Lb/Zh6PfIIAUAR/VsfDj1H9XuvAbBqLW3dYbYLOjJoJ5mi9VNmDORiuPZFUrGL\\\\ncfP6kYGdUDgol5cLagAT0UJAJC/oUom3VaDBDxSkjSCZc4l/1dzVa6O6RatoYvuW\\\\nqtJa5WzPH6flqj9HuFZaaNSZKXSYLwMeQC7bzxjbX0lB6b1WM2EIxQopeewrSfKg\\\\nvaw7zYHnu9cO6oA6I4A3VXhySp3G2VIMOIezfI24mP2Bnzori6xCVXcM7R1B2Trr\\\\nlFUrdXb9Rp3ZR0Ul0jSqCmopmMPVgob8lyHhiqk5+QKBgQDd/PcIRP7OE0ZnfXtd\\\\nxWMz1ggp9ub6bN/mFxw/OoyEVSfmlshDCvEeqoo2DxWGC+/0uiGuPHnDKDX+R0Ho\\\\nqmlWcVPTSBmrQvi3+VBKfr6ZCwxoutCQo3SMlEMvqHDkjGhAsDg/yjkI8yS5jqZ5\\\\nXtG+dYQpd9qY3t46Uar1+7lpJwKBgQDzu3CzElfr3xHAEdE+1pkiPixPuW+fHw1v\\\\nwoc5e7hJA1Mtu0Gdj7g41mF37bUXYxIg3FgV5sS76XCxw1a3plj/y0n+qZXMq5xs\\\\nZwgqrh4APjVXVRp9SSOvEXT0NanhWKiHMNncvteqThSEal27MDghEzqDmebkuOII\\\\ng+KDmYp1rQKBgA0dhPrYGLXULbSvlTpVDydg3dqc28iv5gqSEvkpXGP1JAZbojlT\\\\nzCsjqEbJXVwuGF89IABLUmZVWdtMGnjEmLSivXEeMWYM7uTvte6wzlH8dR866leh\\\\nUKF9oPqP2RunsAEiaDBcokIFG4ZbBzrkfz/hcY2Bp0ig4kBP0un1lV7BAoGBAJ4L\\\\n4MOt1Gd2KetzYk0uGPS0fkVgSLpVB4B+EvO6f0CRMGHKOH00UdBBa8i50qEMtBes\\\\n6k2ha9cyQ8pxkYzbCIEuUJgbXbDvYyqEES6j435i2HH+FIRDZilC16T4G2Wt+PJZ\\\\nQhy7f9vGb9WBp7AXT35bGql1pdyQ6rl80+hkKv2tAoGAe4yFOvIdEEdgEokp5Dem\\\\nuPf1rikk5mYPMkXhrX0cH9Wd2rh9MiP2gJuL3PD3R9LLon+9EzdBs31MwpP9C06Y\\\\nZmnuEfgYIewBHZbpRO+nsGX+AK15gbJUNk1RbWmUU7AvkHyo4eE6NnNVbygxaFSk\\\\n0+8aYRpYzZRnyAn8Oo6o2No=\\\\n-----END PRIVATE KEY-----\\\\n\",\r\n clientEmail: \"firebase-adminsdk-w4v98@lyxa-shop.iam.gserviceaccount.com\"\r\n },\r\n firebaseAdminAppName: \"lyxa-shop\"\r\n },\r\n },\r\n environment: EnvironmentConfigurationType.DEV\r\n };\r\n\r\n private readonly _options: ConfigurationOptions;\r\n\r\n constructor(options?: ConfigurationOptions) {\r\n this._options = {\r\n ...this._defaultOptions,\r\n ...options,\r\n };\r\n }\r\n\r\n get options(): ConfigurationOptions {\r\n return this._options;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/configuration/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,mCAA+B;AAC/B,uFAAkF;AA6B3E,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ,eAAe,GAAyB;QACrD,QAAQ,EAAE,mHAAmH;QAC7H,KAAK,EAAE,SAAS;QAChB,YAAY,EAAE,SAAS;QACvB,aAAa,EAAE;YACX,KAAK,EAAE;gBACH,2BAA2B,EAAE;oBACzB,SAAS,EAAE,gBAAgB;oBAC3B,UAAU,EAAE,ssDAAssD;oBACltD,WAAW,EAAE,kDAAkD;iBAClE;aACJ;YACD,IAAI,EAAE;gBACF,2BAA2B,EAAE;oBACzB,SAAS,EAAE,gBAAgB;oBAC3B,UAAU,EAAE,ssDAAssD;oBACltD,WAAW,EAAE,gEAAgE;iBAChF;gBACD,oBAAoB,EAAE,WAAW;aACpC;YACD,KAAK,EAAE;gBACH,2BAA2B,EAAE;oBACzB,SAAS,EAAE,kBAAkB;oBAC7B,UAAU,EAAE,ssDAAssD;oBACltD,WAAW,EAAE,kEAAkE;iBAClF;gBACD,oBAAoB,EAAE,YAAY;aACrC;YACD,IAAI,EAAE;gBACF,2BAA2B,EAAE;oBACzB,SAAS,EAAE,WAAW;oBACtB,UAAU,EAAE,ssDAAssD;oBACltD,WAAW,EAAE,2DAA2D;iBAC3E;gBACD,oBAAoB,EAAE,WAAW;aACpC;SACJ;QACD,WAAW,EAAE,2DAA4B,CAAC,GAAG;KAChD,CAAC;IAEe,QAAQ,CAAuB;IAEhD,YAAY,OAA8B;QACtC,IAAI,CAAC,QAAQ,GAAG;YACZ,GAAG,IAAI,CAAC,eAAe;YACvB,GAAG,OAAO;SACb,CAAC;IACN,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;CACJ,CAAA;AAtDY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,gBAAO,GAAE;;GACG,oBAAoB,CAsDhC","sourcesContent":["import {FirebaseOptions} from \"firebase/app\";\r\nimport {ServiceAccount} from \"firebase-admin\";\r\nimport {Service} from \"typedi\";\r\nimport {EnvironmentConfigurationType} from \"./types/EnvironmentConfigurationType\";\r\n\r\nexport interface ConfigurationOptions {\r\n tenet?: string;\r\n redisURL?: string;\r\n instanceType?: string;\r\n firebaseAdmin?: {\r\n super: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n },\r\n user: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n },\r\n shop: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n },\r\n rider: {\r\n firebaseAdminServiceAccount: ServiceAccount,\r\n firebaseAdminAppName?: string,\r\n }\r\n },\r\n environment: EnvironmentConfigurationType\r\n}\r\n\r\n\r\n@Service()\r\nexport class ConfigurationService {\r\n\r\n private readonly _defaultOptions: ConfigurationOptions = {\r\n redisURL: \"redis://default:8RCVCiwXRMo6isHgJanL1pE86cRt29YP@redis-12296.fcrce173.eu-west-1-1.ec2.redns.redis-cloud.com:12296\",\r\n tenet: \"default\",\r\n instanceType: \"unknown\",\r\n firebaseAdmin: {\r\n super: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"for-poc-325210\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5aI2nsMHkJbZf\\nem9ycpd57RjRDsBt9Nb/uMjsFcBRuAKcKgh4lgNO6ZmcRwK10IRygCmbY5XxmtVA\\nq9CT5tYlVN4SDzN1y4lL8/CL5owW2RZOURKcM0lsNOB9uGwkv1t3bfbBNc2hh9JX\\n72t7URAtrtPAkUxtgEPm6WL03uNu8KCZ0G9uoA/oM7o8OIGkjC575D9V6QjYC9fn\\nPjBRQ3K42fUWFmf31jtUBSHB0xE5qJI+MOi+OcXAJLxKQBbW+vqr2KfMwVYpNclp\\nk0Ptfe8xZxVfKEJAAkacQ36Hp14wFK/q+2mmhOQlbruksOZCpaIkh5IdvGkkG8ZH\\n566FgFHDAgMBAAECggEAJkuuqprLSZTyiOEQoOqDWBc9X3z1CSEfwV0I/x51BUwF\\nGf1il4mgsE12wX03VZd2q/HF5kcZAvjQoFV8tPfidn6DieZi4itCthHyNutNNzDq\\ntw1u0x2SxktbrQwJJkPyIAZyB7FVwk38B9a3dBanyU/JhAZe62UpYUoGev6IqnKm\\nIiw7r4lc47XgJNrDjXhCtTwHBmXA6qt/HrBcu4fSZlnZMhvsgnO6iafXaBo15Rpy\\nyVBVCPCGJBqpbqI8w3lVTcUqvD2DS+wGJAZSNFagt5qg+vCN8xVUsyQKrM1qIXZm\\nxvPX5oE6CWaD5a7yzpwqKLghKIpsb+3gezyQiFw5rQKBgQDh9U+VdFipH2o8Rezd\\n2d9Kp+ya8+kAog4NMeMyD/xyvKbmv6hW2SZqLhc5MacO0GiCnFR+dMLJxRBGnn+e\\ngYP26OE2fG9Kn7JrSGafu7siKnonfaN/1IcHcZe/77P/s/o2lNxaVl9i1iPQlzr/\\nN8RRaYa+pvazR4VNMS+Z6keD5QKBgQDSDxfKGwOt/GlPKRDmw3bKD4tseK36JsJw\\n5u7im6CpiTEgSSbOCr1ggITv6VbHUK/Nv3mExJH6uuzd9szb94JUAxGbZ16Liwn4\\nse+K2XlnLEnqxzFSkprOJAJkfbffrH+IxW8gNrK/UbjKT/xgEVH1ZeKUMPLCQG+y\\nLAW6NY50hwKBgCYQTPfAQa87u4mrvdsheJv67cCslfOlWPigDsXAK6aoYPU+E/2N\\nVwtL+F2KH7o/IVvfOdyTjryula9Pw+/PoYtWb5neHGFVxZiM+byuwzdeMHW2lHRU\\nOOroF8gdeRT6HIxVR0lwg2EC8cWRtD6KBmgwfqJfPe+1fJ8kSgCDlsiBAoGBAI1D\\nOyNeYW4bBhMHMeeOYY9nPsL2sUE92Zslolbgg/4fVds5dpAvpsWECGJy0Dn/6Ap8\\njtMbgnRUSsDGnWP8IjgvTCLvNCSxn0YRG1+L+tnIbfkmdePq1ZJ1oupDpWkVTzsC\\nU0Ydor2IzrW3bqiIXU6jculntYmu3a67biqYo7F3AoGBALoinJdtNLLqOqf/MumD\\n+YmbzHqsuID2dGyct7GESIBx3a67hwyJQfCK8nyHNyWN7lFg+H1rZlu1Cjmo0hlu\\nOxzdbWON5Rg2n3TbGw3AM1M55khsedbmm8MOSRdhIkz5RuYESSNAvVC6CBcfg5gb\\nCPq8jrR+oljMjBwAaQmFlPF7\\n-----END PRIVATE KEY-----\\n\",\r\n clientEmail: \"lyxa-core@for-poc-325210.iam.gserviceaccount.com\"\r\n }\r\n },\r\n user: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"for-poc-325210\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9yUnAC2pQ+dhe\\ndJVMS7RQeQdQO7JhT0BXz0MbpCXlEdc3j/GQAY9UfKxQLg1VZh+4An8aUZevOy/v\\nUaHsvqSWcWg7UHTOjk861brpjdjhM4S4ahwU2NyVI/o0Bpc5ob4nhHebny9FGqEP\\nauwUXiVw7UjA/yGeTN6delZwCxejHxI6zDjFQveo8Ljkfu49CMyyf1XhN9q0So4Q\\n2pZ3Xmdz0fZGykSGT9TVBDnPE8Zc3VCQ1XQ7aEKr0e9L+YYidw+iurSNwQSo72uk\\nf/G2wCtlAaoDh0lKObEbi1b925BOthP2XpmQ7Kv+iWVFouCY54Md56FxtjKOyYll\\n0nS6MkAJAgMBAAECggEAEeee83UoPjQ6BVxAlxJ31BU8+0TshOlwB7C8MywC7rfm\\nit2Dw8sf4W/DJmvX0nAYazjiEqKyuaOO98gm64HHX5GarKjgIjoTD7kJAZ6CIOnm\\nOis5k75rXg8nPFgIVZW0rb/9tEL5984ltoGG/PtuUxdxwxJ20ptML8VySO8E93yt\\n203zMlm/QdlUBBO+XDlpsEoXvUjQ6MzmCSF2LCFD1uBVmj0sVFuPt5fyodhV8gQM\\nvDfG4duZ7AE6Nbc5ANgJw8fHMdx+AS+I0P50et936tuFOOeHUWGbg1RMOM1GrWLZ\\nH83zfHp33R3rlUgleZetKh/5vLaW29MdJmACk2Z14QKBgQDtrywbz60ULHiyNvDP\\nHFweJF/9EBq6MZeo/lYrBDZXuP3sBM7uUa+oYzYad3Lsxo1Vz/Zqb6atWX/BRbHT\\nfyy6yTGPRn6geaqYEFuFwfBau3qju6DRwoqplVVlLo8lgOQzIDgXkk0nt7C/bM87\\nmkxQI6Xi0TAjIpd3k6miw52laQKBgQDMaTnlL2OGlJlcycBZGxrKdsIwvK2jCLPi\\njPTKM163htuzaItEVpJaCPjWaU3k3E1UXjFp9oxxvtDZOZP+DcFwGKvBe2vntFYz\\nafCNlYK7wT/t7ChlCUSXuU/bSrXe4Wc4KGnJ6YzNmykMJku2b845layB1PxEhHHA\\nRl2NEx9RoQKBgHJvETx+m2UIGEAtZXlBvTQh7TkIxOV6NPt/IHtrdsJ7ZX15vytM\\nltbqlUTe160Z1zhGfOw3vzbczT5/UKN0KlPvw/WoShT3HuRBk97tRcxZUS19i2sS\\nT/Jf3JJvfSngSX439+mZXZ5OuUEgoRGgMzeuQhLXBmcUI3rF1DlyFvdpAoGAfmq5\\nbn8fSzUNn+/6MGFt8Tb/JAscS87vCTZpkb+xXUlfCJaoQqxTuLEBzAC2Nsr0XDAg\\n2UqsUxBSs3VDjIRPVJc9adx9wH+sLAHhzn5fquR6OBesZ8gSjs8BjzqmPeAi6P09\\nZ60z8lh6S1RH0N1WqhBh7q2dEnbirqoV41CnNuECgYEAr26tTBIvEeZY3gmAmOVl\\nCw6gkxaHdzZplFl8Qnv272VllQpwbR1zaF6RfWsTEsrhrT+VtrZO6DDh9O6iJkbB\\n7Re3BnMOhGfUS3HlPCFnkdodeaoeVpg4llYwuunmyj+SmNxnC56TiznML1owmUYd\\ndLFeY+JZ0GpSBO0qYlY5QGk=\\n-----END PRIVATE KEY-----\\n\",\r\n clientEmail: \"firebase-adminsdk-onusy@for-poc-325210.iam.gserviceaccount.com\"\r\n },\r\n firebaseAdminAppName: \"lyxa-user\"\r\n },\r\n rider: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"lyxa-rider-88939\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC08zRqUjHFO7Ir\\n4UNHIjxVp7oJkK3rrV1UGfHeHsijm6CSWjViVqsFKUZliYXTjg9S8rIMmC3OAMrh\\n5FTdNfDell8YHPbVRWZ0OFBNWglvKMgMKMoyQuBKtvEAdZwgVMreOf+51QlZnPxy\\nTBNh4Du2ahb8TtAjwxXt7CgMjNIfoMjQFJTrBTAmsxhtOEpYvPU2iX+OtAkHgrs1\\nNeWpBGpN4GSwOfA8MdgvorLYbeRDnkY4cH/ReNymTW9nbX1vgsx2AE1NR5PTNxv0\\nIuVZQWxMMGPnT5bjzAlCR4z/Nbe89V2zl5kFtBxDBCDqxp+qZxCinJj1QqwC5qzZ\\nYLbNVKVPAgMBAAECggEAEHEGwrW24v/NF9KZ3S/zASoX1oBTD+vf4+E69QlMBshV\\nxeaKHOYuF5khVd7cjj/wDC6ULLPJJFjga7e7rvaUl80G//cQcIl5STcdXiHqYzN2\\nldrroGHWOm5hUJQ0fEroEgV9bc0PJ+7X5f9xRWlCqQz+YKzn7vqYwVZovyyDzS6/\\nTus2SeWg0Qh1Uw4+FqveEqGBAMF9COTYJ/rZ5sDE34cYRJeZOgVDeSanF/CW6+VS\\nLT5+ysRS8xY/mUFIgs6zvJQr7whDj22OzvZr31LReNUl1IGI1V0wHxCJs3y934dq\\nuiAf4iX2w0uwiQs7+IQc6T6GhTEajWHSQqUtbDeecQKBgQDAW/mHk1PCCxZQtc6C\\nCkFYONeY0zz7JAk7AvcbeVB6icq9Zv/9botFOvJ/4dduN39+sO/SIvLV+zQzmUGA\\nygY58AQIqtYurIc8OjftQ5qZ6t9H1plmj/W+GVAYWadA68P95UBjwVcZySht47s/\\ngOje4TF9wXVn9oTuP8XmLpce/wKBgQDw0Onl7EVmkgnyHl1qomqHR+2+xNDZNYMv\\njdX0tq2KOXa6JpbO32Yf7LVKQo7bmSOy3M1kn2+lwCXsDufr/a+1GNRxuPucsYiM\\nlQeLEKRqfNUni1NnbIUOkZV0fO0Me76Ow5BKqEWrda0E5k9g46p8EgVO5zWUE00w\\nZZFTUn7JsQKBgDh9SiREYb6EXwNIwOJzfIkZ+EaLEkd2Z7eKwWKyF65EtOM2Ukrs\\nob2s9/YSLp/RcIGWGHePh9zLLqNQiGn36igtkiGxecCvLe/D8RSeW9KDpRqFrPrv\\nn+05pcng2js4gZAYOPaSmq+Z4WOUEzMs+jYpz8zseTwUqykEVWuplvulAoGAF8y9\\n4RBZx4pVW01u9BP7LUWJlJoE/gKQ5YlCBP5s5kVJm5omu2lOwYb2X9F2JvPamFnE\\nHta3BQ2ZcdwDRcp7rA05KcgbbeAJ28L6zN6nMTMHKfJWGtmZyNfQioOyNdKhAaEI\\nSKiawhhOMjbEz5GQjtSFG8gz/l9t+IOBOlfj2fECgYBC8gGC7YHm+PvV5F1CVRZD\\nUYVlAnqOMJ1VvfTemW/kPzuCMd/JEKSE+b21h3rObMvUZU5AnkM3VT1+hDv6tyEt\\nblgh89YsHUor7wXSrYnVmYsrm91JABTWsLhLy92iqylg0xBs3Q5RGCt/s9f3YFFw\\nKghNmTDraGggnf5U/Z4LJw==\\n-----END PRIVATE KEY-----\\n\",\r\n clientEmail: \"firebase-adminsdk-qwhrd@lyxa-rider-88939.iam.gserviceaccount.com\"\r\n },\r\n firebaseAdminAppName: \"lyxa-rider\"\r\n },\r\n shop: {\r\n firebaseAdminServiceAccount: {\r\n projectId: \"lyxa-shop\",\r\n privateKey: \"-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTWaf/QGSjk7po\\nri+6Nzo/tep1UtgMSY4KscT3iCbepiAsw7C8NCQqz3wYEAFRwywbaCwUcUs5KUC7\\n/e9TvpSQQksu10P9uP+c7wnAy+l0ay/15vWUV0usmDhMMvfjtDwS2RYTMEAdNUiZ\\nOuMC3/DDCBHt0SC5WCNzz11jj/n5bdVOS02qHd8V/lbd46iVEYfFswkI5NBgV7CY\\nnR2CoVcakPIeu9kEKdjXsJvf8+zCYtXPaFvcubQcnybOcg6usU+AHD1iwCRd6BrK\\n2PpM3gy/eASLJtzg/JoU0CgqJICmfR8LvGk6iHTp7VMfPuCfggwYtO3W1kSHuW4I\\nswbXYOJbAgMBAAECggEAMHKZ5xIsv66KiZp8SFSGnrolv7U430AxNlRf0Vo9hsZQ\\nE9Lb/Zh6PfIIAUAR/VsfDj1H9XuvAbBqLW3dYbYLOjJoJ5mi9VNmDORiuPZFUrGL\\ncfP6kYGdUDgol5cLagAT0UJAJC/oUom3VaDBDxSkjSCZc4l/1dzVa6O6RatoYvuW\\nqtJa5WzPH6flqj9HuFZaaNSZKXSYLwMeQC7bzxjbX0lB6b1WM2EIxQopeewrSfKg\\nvaw7zYHnu9cO6oA6I4A3VXhySp3G2VIMOIezfI24mP2Bnzori6xCVXcM7R1B2Trr\\nlFUrdXb9Rp3ZR0Ul0jSqCmopmMPVgob8lyHhiqk5+QKBgQDd/PcIRP7OE0ZnfXtd\\nxWMz1ggp9ub6bN/mFxw/OoyEVSfmlshDCvEeqoo2DxWGC+/0uiGuPHnDKDX+R0Ho\\nqmlWcVPTSBmrQvi3+VBKfr6ZCwxoutCQo3SMlEMvqHDkjGhAsDg/yjkI8yS5jqZ5\\nXtG+dYQpd9qY3t46Uar1+7lpJwKBgQDzu3CzElfr3xHAEdE+1pkiPixPuW+fHw1v\\nwoc5e7hJA1Mtu0Gdj7g41mF37bUXYxIg3FgV5sS76XCxw1a3plj/y0n+qZXMq5xs\\nZwgqrh4APjVXVRp9SSOvEXT0NanhWKiHMNncvteqThSEal27MDghEzqDmebkuOII\\ng+KDmYp1rQKBgA0dhPrYGLXULbSvlTpVDydg3dqc28iv5gqSEvkpXGP1JAZbojlT\\nzCsjqEbJXVwuGF89IABLUmZVWdtMGnjEmLSivXEeMWYM7uTvte6wzlH8dR866leh\\nUKF9oPqP2RunsAEiaDBcokIFG4ZbBzrkfz/hcY2Bp0ig4kBP0un1lV7BAoGBAJ4L\\n4MOt1Gd2KetzYk0uGPS0fkVgSLpVB4B+EvO6f0CRMGHKOH00UdBBa8i50qEMtBes\\n6k2ha9cyQ8pxkYzbCIEuUJgbXbDvYyqEES6j435i2HH+FIRDZilC16T4G2Wt+PJZ\\nQhy7f9vGb9WBp7AXT35bGql1pdyQ6rl80+hkKv2tAoGAe4yFOvIdEEdgEokp5Dem\\nuPf1rikk5mYPMkXhrX0cH9Wd2rh9MiP2gJuL3PD3R9LLon+9EzdBs31MwpP9C06Y\\nZmnuEfgYIewBHZbpRO+nsGX+AK15gbJUNk1RbWmUU7AvkHyo4eE6NnNVbygxaFSk\\n0+8aYRpYzZRnyAn8Oo6o2No=\\n-----END PRIVATE KEY-----\\n\",\r\n clientEmail: \"firebase-adminsdk-w4v98@lyxa-shop.iam.gserviceaccount.com\"\r\n },\r\n firebaseAdminAppName: \"lyxa-shop\"\r\n },\r\n },\r\n environment: EnvironmentConfigurationType.DEV\r\n };\r\n\r\n private readonly _options: ConfigurationOptions;\r\n\r\n constructor(options?: ConfigurationOptions) {\r\n this._options = {\r\n ...this._defaultOptions,\r\n ...options,\r\n };\r\n }\r\n\r\n get options(): ConfigurationOptions {\r\n return this._options;\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseEvent.js","sourceRoot":"/","sources":["libraries/event/BaseEvent.ts"],"names":[],"mappings":";;;AAAA,MAAsB,SAAS;IACV,QAAQ,CAAS;IACjB,QAAQ,CAAW;IAEpC,YAAsB,OAAe,EAAE,OAAiB;QACpD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;CACJ;AAhBD,8BAgBC","sourcesContent":["export abstract class BaseEvent<TPayload extends Record<string, unknown>> {\r\n private readonly _eventId: string;\r\n private readonly _payload: TPayload;\r\n\r\n protected constructor(eventId: string, payload: TPayload) {\r\n this._eventId = eventId;\r\n this._payload = payload;\r\n }\r\n\r\n get eventId(): string {\r\n return this._eventId;\r\n }\r\n\r\n get payload(): TPayload {\r\n return this._payload;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"BaseEvent.js","sourceRoot":"/","sources":["libraries/event/BaseEvent.ts"],"names":[],"mappings":";;;AAAA,MAAsB,SAAS;IACV,QAAQ,CAAS;IACjB,QAAQ,CAAW;IAEpC,YAAsB,OAAe,EAAE,OAAiB;QACpD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;CACJ;AAhBD,8BAgBC","sourcesContent":["export abstract class BaseEvent<TPayload extends Record<string, unknown>> {\r\n private readonly _eventId: string;\r\n private readonly _payload: TPayload;\r\n \r\n protected constructor(eventId: string, payload: TPayload) {\r\n this._eventId = eventId;\r\n this._payload = payload;\r\n }\r\n\r\n get eventId(): string {\r\n return this._eventId;\r\n }\r\n\r\n get payload(): TPayload {\r\n return this._payload;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseEvent } from "../BaseEvent";
|
|
2
|
+
export type OrderCreationEventParams = {
|
|
3
|
+
user: string;
|
|
4
|
+
shop: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class OrderCreationEvent extends BaseEvent<OrderCreationEventParams> {
|
|
7
|
+
constructor(parameters: OrderCreationEventParams);
|
|
8
|
+
}
|
|
9
|
+
export declare class OrderListenEvent {
|
|
10
|
+
doSomethingWithOrderCreation(parameters: Record<string, unknown>): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.OrderListenEvent = exports.OrderCreationEvent = void 0;
|
|
13
|
+
const BaseEvent_1 = require("../BaseEvent");
|
|
14
|
+
const metadata_1 = require("../decorators/metadata");
|
|
15
|
+
const index_1 = require("../index");
|
|
16
|
+
const subscribe_1 = require("../decorators/subscribe");
|
|
17
|
+
let OrderCreationEvent = class OrderCreationEvent extends BaseEvent_1.BaseEvent {
|
|
18
|
+
constructor(parameters) {
|
|
19
|
+
super("order.creation", parameters);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
exports.OrderCreationEvent = OrderCreationEvent;
|
|
23
|
+
exports.OrderCreationEvent = OrderCreationEvent = __decorate([
|
|
24
|
+
(0, metadata_1.EventMetadata)("order.creation", [{ name: "user", type: "string" }, { name: "shop", type: "string" }]),
|
|
25
|
+
__metadata("design:paramtypes", [Object])
|
|
26
|
+
], OrderCreationEvent);
|
|
27
|
+
(0, index_1.publishEvent)(new OrderCreationEvent({
|
|
28
|
+
user: "",
|
|
29
|
+
shop: ""
|
|
30
|
+
}));
|
|
31
|
+
class OrderListenEvent {
|
|
32
|
+
doSomethingWithOrderCreation(parameters) {
|
|
33
|
+
parameters[""];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.OrderListenEvent = OrderListenEvent;
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, subscribe_1.Subscribe)("order.creation"),
|
|
39
|
+
__metadata("design:type", Function),
|
|
40
|
+
__metadata("design:paramtypes", [Object]),
|
|
41
|
+
__metadata("design:returntype", void 0)
|
|
42
|
+
], OrderListenEvent.prototype, "doSomethingWithOrderCreation", null);
|
|
43
|
+
//# sourceMappingURL=OrderCreationEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderCreationEvent.js","sourceRoot":"/","sources":["libraries/event/test/OrderCreationEvent.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,4CAAuC;AACvC,qDAAqD;AACrD,oCAAsC;AACtC,uDAAkD;AAQ3C,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,qBAAmC;IACvE,YAAY,UAAoC;QAC5C,KAAK,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;IACxC,CAAC;CACJ,CAAA;AAJY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,wBAAa,EAAC,gBAAgB,EAAE,CAAC,EAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAC,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAC,CAAC,CAAC;;GACrF,kBAAkB,CAI9B;AAED,IAAA,oBAAY,EAAC,IAAI,kBAAkB,CAAC;IAChC,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;CACX,CAAC,CAAC,CAAA;AAEH,MAAa,gBAAgB;IAElB,4BAA4B,CAAC,UAAmC;QACnE,UAAU,CAAC,EAAE,CAAC,CAAA;IAClB,CAAC;CACJ;AALD,4CAKC;AAHU;IADN,IAAA,qBAAS,EAAC,gBAAgB,CAAC;;;;oEAG3B","sourcesContent":["import {BaseEvent} from \"../BaseEvent\";\r\nimport {EventMetadata} from \"../decorators/metadata\";\r\nimport {publishEvent} from \"../index\";\r\nimport {Subscribe} from \"../decorators/subscribe\";\r\n\r\nexport type OrderCreationEventParams = {\r\n user: string;\r\n shop: string;\r\n}\r\n\r\n@EventMetadata(\"order.creation\", [{name: \"user\", type: \"string\"}, {name: \"shop\", type: \"string\"}])\r\nexport class OrderCreationEvent extends BaseEvent<OrderCreationEventParams> {\r\n constructor(parameters: OrderCreationEventParams) {\r\n super(\"order.creation\", parameters);\r\n }\r\n}\r\n\r\npublishEvent(new OrderCreationEvent({\r\n user: \"\",\r\n shop: \"\"\r\n}))\r\n\r\nexport class OrderListenEvent {\r\n @Subscribe(\"order.creation\")\r\n public doSomethingWithOrderCreation(parameters: Record<string, unknown>) {\r\n parameters[\"\"]\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as admin from 'firebase-admin';
|
|
2
|
+
import { ConfigurationService } from "../configuration";
|
|
3
|
+
export declare class FirebaseService {
|
|
4
|
+
private configService;
|
|
5
|
+
private readonly _superApp;
|
|
6
|
+
private readonly _userApp;
|
|
7
|
+
private readonly _shopApp;
|
|
8
|
+
private readonly _riderApp;
|
|
9
|
+
constructor(configService: ConfigurationService);
|
|
10
|
+
get superApp(): admin.app.App;
|
|
11
|
+
get userApp(): admin.app.App;
|
|
12
|
+
get shopApp(): admin.app.App;
|
|
13
|
+
get riderApp(): admin.app.App;
|
|
14
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.FirebaseService = void 0;
|
|
46
|
+
const admin = __importStar(require("firebase-admin"));
|
|
47
|
+
const typedi_1 = require("typedi");
|
|
48
|
+
const configuration_1 = require("../configuration");
|
|
49
|
+
const mongoose_1 = require("mongoose");
|
|
50
|
+
const DEFAULT_STORAGE_BUCKET = process.env.FIREBASE_STORAGE_BUCKET || 'lyxa-default';
|
|
51
|
+
let FirebaseService = class FirebaseService {
|
|
52
|
+
configService;
|
|
53
|
+
_superApp;
|
|
54
|
+
_userApp;
|
|
55
|
+
_shopApp;
|
|
56
|
+
_riderApp;
|
|
57
|
+
constructor(configService) {
|
|
58
|
+
this.configService = configService;
|
|
59
|
+
const config = this.configService.options;
|
|
60
|
+
if (!config.firebaseAdmin) {
|
|
61
|
+
throw new mongoose_1.Error('Firebase Admin configuration is missing.');
|
|
62
|
+
}
|
|
63
|
+
const { super: superConfig, user, shop, rider } = config.firebaseAdmin;
|
|
64
|
+
this._superApp = admin.initializeApp({
|
|
65
|
+
credential: admin.credential.cert(superConfig.firebaseAdminServiceAccount),
|
|
66
|
+
storageBucket: DEFAULT_STORAGE_BUCKET,
|
|
67
|
+
}, superConfig.firebaseAdminAppName || 'super-app');
|
|
68
|
+
this._userApp = admin.initializeApp({
|
|
69
|
+
credential: admin.credential.cert(user.firebaseAdminServiceAccount),
|
|
70
|
+
storageBucket: DEFAULT_STORAGE_BUCKET,
|
|
71
|
+
}, user.firebaseAdminAppName || 'user-app');
|
|
72
|
+
this._shopApp = admin.initializeApp({
|
|
73
|
+
credential: admin.credential.cert(shop.firebaseAdminServiceAccount),
|
|
74
|
+
storageBucket: DEFAULT_STORAGE_BUCKET,
|
|
75
|
+
}, shop.firebaseAdminAppName || 'shop-app');
|
|
76
|
+
this._riderApp = admin.initializeApp({
|
|
77
|
+
credential: admin.credential.cert(rider.firebaseAdminServiceAccount),
|
|
78
|
+
storageBucket: DEFAULT_STORAGE_BUCKET,
|
|
79
|
+
}, rider.firebaseAdminAppName || 'rider-app');
|
|
80
|
+
}
|
|
81
|
+
get superApp() {
|
|
82
|
+
return this._superApp;
|
|
83
|
+
}
|
|
84
|
+
get userApp() {
|
|
85
|
+
return this._userApp;
|
|
86
|
+
}
|
|
87
|
+
get shopApp() {
|
|
88
|
+
return this._shopApp;
|
|
89
|
+
}
|
|
90
|
+
get riderApp() {
|
|
91
|
+
return this._riderApp;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
exports.FirebaseService = FirebaseService;
|
|
95
|
+
exports.FirebaseService = FirebaseService = __decorate([
|
|
96
|
+
(0, typedi_1.Service)(),
|
|
97
|
+
__metadata("design:paramtypes", [configuration_1.ConfigurationService])
|
|
98
|
+
], FirebaseService);
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/firebase/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAAwC;AACxC,mCAAiC;AAEjC,oDAAsD;AACtD,uCAA+B;AAE/B,MAAM,sBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,cAAc,CAAC;AAG9E,IAAM,eAAe,GAArB,MAAM,eAAe;IAMJ;IALH,SAAS,CAAgB;IACzB,QAAQ,CAAgB;IACxB,QAAQ,CAAgB;IACxB,SAAS,CAAgB;IAE1C,YAAoB,aAAmC;QAAnC,kBAAa,GAAb,aAAa,CAAsB;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,gBAAK,CAAC,0CAA0C,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC;QAEvE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC;YACjC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,2BAA6C,CAAC;YAC5F,aAAa,EAAE,sBAAsB;SACxC,EAAE,WAAW,CAAC,oBAAoB,IAAI,WAAW,CAAC,CAAC;QAEpD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC;YAChC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA6C,CAAC;YACrF,aAAa,EAAE,sBAAsB;SACxC,EAAE,IAAI,CAAC,oBAAoB,IAAI,UAAU,CAAC,CAAC;QAE5C,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC;YAChC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA6C,CAAC;YACrF,aAAa,EAAE,sBAAsB;SACxC,EAAE,IAAI,CAAC,oBAAoB,IAAI,UAAU,CAAC,CAAC;QAE5C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC;YACjC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,2BAA6C,CAAC;YACtF,aAAa,EAAE,sBAAsB;SACxC,EAAE,KAAK,CAAC,oBAAoB,IAAI,WAAW,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;CACJ,CAAA;AAnDY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,gBAAO,GAAE;qCAO6B,oCAAoB;GAN9C,eAAe,CAmD3B","sourcesContent":["import * as admin from 'firebase-admin';\r\nimport { Service } from 'typedi';\r\nimport { ServiceAccount } from 'firebase-admin';\r\nimport {ConfigurationService} from \"../configuration\";\r\nimport {Error} from \"mongoose\";\r\n\r\nconst DEFAULT_STORAGE_BUCKET = process.env.FIREBASE_STORAGE_BUCKET || 'lyxa-default';\r\n\r\n@Service()\r\nexport class FirebaseService {\r\n private readonly _superApp: admin.app.App;\r\n private readonly _userApp: admin.app.App;\r\n private readonly _shopApp: admin.app.App;\r\n private readonly _riderApp: admin.app.App;\r\n\r\n constructor(private configService: ConfigurationService) {\r\n const config = this.configService.options;\r\n\r\n if (!config.firebaseAdmin) {\r\n throw new Error('Firebase Admin configuration is missing.');\r\n }\r\n\r\n const { super: superConfig, user, shop, rider } = config.firebaseAdmin;\r\n\r\n this._superApp = admin.initializeApp({\r\n credential: admin.credential.cert(superConfig.firebaseAdminServiceAccount as ServiceAccount),\r\n storageBucket: DEFAULT_STORAGE_BUCKET,\r\n }, superConfig.firebaseAdminAppName || 'super-app');\r\n\r\n this._userApp = admin.initializeApp({\r\n credential: admin.credential.cert(user.firebaseAdminServiceAccount as ServiceAccount),\r\n storageBucket: DEFAULT_STORAGE_BUCKET,\r\n }, user.firebaseAdminAppName || 'user-app');\r\n\r\n this._shopApp = admin.initializeApp({\r\n credential: admin.credential.cert(shop.firebaseAdminServiceAccount as ServiceAccount),\r\n storageBucket: DEFAULT_STORAGE_BUCKET,\r\n }, shop.firebaseAdminAppName || 'shop-app');\r\n\r\n this._riderApp = admin.initializeApp({\r\n credential: admin.credential.cert(rider.firebaseAdminServiceAccount as ServiceAccount),\r\n storageBucket: DEFAULT_STORAGE_BUCKET,\r\n }, rider.firebaseAdminAppName || 'rider-app');\r\n }\r\n\r\n get superApp(): admin.app.App {\r\n return this._superApp;\r\n }\r\n\r\n get userApp(): admin.app.App {\r\n return this._userApp;\r\n }\r\n\r\n get shopApp(): admin.app.App {\r\n return this._shopApp;\r\n }\r\n\r\n get riderApp(): admin.app.App {\r\n return this._riderApp;\r\n }\r\n}\r\n"]}
|
|
@@ -4,6 +4,8 @@ import { MicroServiceDispatcher } from "./dispatcher";
|
|
|
4
4
|
import { SecretManagerService } from "./secrets";
|
|
5
5
|
import { RedisService } from "./redis";
|
|
6
6
|
import { ConfigurationService } from "./configuration";
|
|
7
|
+
import { UploadService } from "./upload";
|
|
8
|
+
import { FirebaseService } from "./firebase";
|
|
7
9
|
export declare class LibraryManager {
|
|
8
10
|
getLogger(): LyxaLogger;
|
|
9
11
|
getMicroServiceDispatcher(): MicroServiceDispatcher;
|
|
@@ -11,4 +13,7 @@ export declare class LibraryManager {
|
|
|
11
13
|
getSecretsService(): SecretManagerService;
|
|
12
14
|
getRedisService(): RedisService;
|
|
13
15
|
getConfigurationService(): ConfigurationService;
|
|
16
|
+
getFirebaseService(): FirebaseService;
|
|
17
|
+
getGlobalUploadService(): UploadService;
|
|
18
|
+
getTenetUploadService(): UploadService;
|
|
14
19
|
}
|
package/dist/libraries/index.js
CHANGED
|
@@ -14,6 +14,8 @@ const dispatcher_1 = require("./dispatcher");
|
|
|
14
14
|
const secrets_1 = require("./secrets");
|
|
15
15
|
const redis_1 = require("./redis");
|
|
16
16
|
const configuration_1 = require("./configuration");
|
|
17
|
+
const upload_1 = require("./upload");
|
|
18
|
+
const firebase_1 = require("./firebase");
|
|
17
19
|
let LibraryManager = class LibraryManager {
|
|
18
20
|
getLogger() {
|
|
19
21
|
return typedi_1.Container.get(logger_1.LyxaLogger);
|
|
@@ -33,6 +35,15 @@ let LibraryManager = class LibraryManager {
|
|
|
33
35
|
getConfigurationService() {
|
|
34
36
|
return typedi_1.Container.get(configuration_1.ConfigurationService);
|
|
35
37
|
}
|
|
38
|
+
getFirebaseService() {
|
|
39
|
+
return typedi_1.Container.get(firebase_1.FirebaseService);
|
|
40
|
+
}
|
|
41
|
+
getGlobalUploadService() {
|
|
42
|
+
return new upload_1.UploadService();
|
|
43
|
+
}
|
|
44
|
+
getTenetUploadService() {
|
|
45
|
+
return new upload_1.UploadService("lyxa-" + this.getConfigurationService().options.tenet);
|
|
46
|
+
}
|
|
36
47
|
};
|
|
37
48
|
exports.LibraryManager = LibraryManager;
|
|
38
49
|
exports.LibraryManager = LibraryManager = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,mCAA0C;AAC1C,qCAAuC;AACvC,qCAAoC;AACpC,6CAAoD;AACpD,uCAA+C;AAC/C,mCAAqC;AACrC,mDAAqD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,mCAA0C;AAC1C,qCAAuC;AACvC,qCAAoC;AACpC,6CAAoD;AACpD,uCAA+C;AAC/C,mCAAqC;AACrC,mDAAqD;AACrD,qCAAuC;AACvC,yCAA2C;AAGpC,IAAM,cAAc,GAApB,MAAM,cAAc;IAChB,SAAS;QACZ,OAAO,kBAAS,CAAC,GAAG,CAAC,mBAAU,CAAC,CAAC;IACrC,CAAC;IACM,yBAAyB;QAC5B,OAAO,kBAAS,CAAC,GAAG,CAAC,mCAAsB,CAAC,CAAC;IACjD,CAAC;IACM,gBAAgB;QACnB,OAAO,kBAAS,CAAC,GAAG,CAAC,sBAAa,CAAC,CAAC;IACxC,CAAC;IACM,iBAAiB;QACpB,OAAO,kBAAS,CAAC,GAAG,CAAC,8BAAoB,CAAC,CAAC;IAC/C,CAAC;IACM,eAAe;QAClB,OAAO,kBAAS,CAAC,GAAG,CAAC,oBAAY,CAAC,CAAC;IACvC,CAAC;IACM,uBAAuB;QAC1B,OAAO,kBAAS,CAAC,GAAG,CAAC,oCAAoB,CAAC,CAAC;IAC/C,CAAC;IACM,kBAAkB;QACrB,OAAO,kBAAS,CAAC,GAAG,CAAC,0BAAe,CAAC,CAAC;IAC1C,CAAC;IACM,sBAAsB;QACzB,OAAO,IAAI,sBAAa,EAAE,CAAC;IAC/B,CAAC;IACM,qBAAqB;QACxB,OAAO,IAAI,sBAAa,CAAC,OAAO,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrF,CAAC;CACJ,CAAA;AA5BY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,gBAAO,GAAE;GACG,cAAc,CA4B1B","sourcesContent":["import {Container, Service} from \"typedi\";\r\nimport {TwilioService} from \"./twilio\";\r\nimport {LyxaLogger} from \"./logger\";\r\nimport {MicroServiceDispatcher} from \"./dispatcher\";\r\nimport {SecretManagerService} from \"./secrets\";\r\nimport {RedisService} from \"./redis\";\r\nimport {ConfigurationService} from \"./configuration\";\r\nimport {UploadService} from \"./upload\";\r\nimport {FirebaseService} from \"./firebase\";\r\n\r\n@Service()\r\nexport class LibraryManager {\r\n public getLogger(): LyxaLogger {\r\n return Container.get(LyxaLogger);\r\n }\r\n public getMicroServiceDispatcher(): MicroServiceDispatcher {\r\n return Container.get(MicroServiceDispatcher);\r\n }\r\n public getTwilioService(): TwilioService {\r\n return Container.get(TwilioService);\r\n }\r\n public getSecretsService(): SecretManagerService {\r\n return Container.get(SecretManagerService);\r\n }\r\n public getRedisService(): RedisService {\r\n return Container.get(RedisService);\r\n }\r\n public getConfigurationService(): ConfigurationService {\r\n return Container.get(ConfigurationService);\r\n }\r\n public getFirebaseService(): FirebaseService {\r\n return Container.get(FirebaseService);\r\n }\r\n public getGlobalUploadService(): UploadService {\r\n return new UploadService();\r\n }\r\n public getTenetUploadService(): UploadService {\r\n return new UploadService(\"lyxa-\" + this.getConfigurationService().options.tenet);\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare class UploadService {
|
|
2
|
+
private bucket;
|
|
3
|
+
private readonly websiteName;
|
|
4
|
+
constructor(bucketName?: string);
|
|
5
|
+
private generateFilename;
|
|
6
|
+
uploadImage(buffer: Buffer, originalFilename: string): Promise<{
|
|
7
|
+
filename: string;
|
|
8
|
+
url: string;
|
|
9
|
+
}>;
|
|
10
|
+
transcodeImage(buffer: Buffer, originalFilename: string, resolutions: number[]): Promise<{
|
|
11
|
+
originalUrl: string;
|
|
12
|
+
resizedResults: Array<{
|
|
13
|
+
resolution: number;
|
|
14
|
+
url: string;
|
|
15
|
+
}>;
|
|
16
|
+
}>;
|
|
17
|
+
private uploadBuffer;
|
|
18
|
+
getListFiles(): Promise<Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
url: string;
|
|
21
|
+
}>>;
|
|
22
|
+
downloadFile(filename: string): Promise<Buffer>;
|
|
23
|
+
deleteFile(filename: string): Promise<void>;
|
|
24
|
+
downloadImage(url: string): Promise<Buffer>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
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.UploadService = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const sharp_1 = __importDefault(require("sharp"));
|
|
9
|
+
const moment_1 = __importDefault(require("moment"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const index_1 = require("../../index");
|
|
12
|
+
function makeSlug(input) {
|
|
13
|
+
return input
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
16
|
+
.replace(/(^-|-$)/g, '');
|
|
17
|
+
}
|
|
18
|
+
class UploadService {
|
|
19
|
+
bucket;
|
|
20
|
+
websiteName;
|
|
21
|
+
constructor(bucketName) {
|
|
22
|
+
if (!bucketName) {
|
|
23
|
+
bucketName = "lyxa-global";
|
|
24
|
+
}
|
|
25
|
+
this.bucket = (0, index_1.getLibraries)().getFirebaseService().superApp.storage().bucket(bucketName);
|
|
26
|
+
this.websiteName = "lyxa-" + (0, index_1.getLibraries)().getConfigurationService().options.tenet;
|
|
27
|
+
}
|
|
28
|
+
generateFilename(originalFilename) {
|
|
29
|
+
const nameWithoutExt = path_1.default.parse(originalFilename).name;
|
|
30
|
+
const extension = path_1.default.extname(originalFilename);
|
|
31
|
+
const timestamp = (0, moment_1.default)().format('DDMMYYHmmss');
|
|
32
|
+
const randomId = Math.floor(Math.random() * 100);
|
|
33
|
+
const baseName = `${makeSlug(nameWithoutExt)}-${this.websiteName}-${timestamp}-${randomId}`;
|
|
34
|
+
return baseName + extension;
|
|
35
|
+
}
|
|
36
|
+
async uploadImage(buffer, originalFilename) {
|
|
37
|
+
const newFilename = this.generateFilename(originalFilename);
|
|
38
|
+
const extension = path_1.default.extname(newFilename).toLowerCase();
|
|
39
|
+
let processedImage;
|
|
40
|
+
let contentType;
|
|
41
|
+
if (extension === '.png') {
|
|
42
|
+
processedImage = (0, sharp_1.default)(buffer).png({ quality: 80 });
|
|
43
|
+
contentType = 'image/png';
|
|
44
|
+
}
|
|
45
|
+
else if (extension === '.webp') {
|
|
46
|
+
processedImage = (0, sharp_1.default)(buffer).webp({ quality: 80 });
|
|
47
|
+
contentType = 'image/webp';
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
processedImage = (0, sharp_1.default)(buffer).jpeg({ quality: 80 });
|
|
51
|
+
contentType = 'image/jpeg';
|
|
52
|
+
}
|
|
53
|
+
const file = this.bucket.file(newFilename);
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const blobStream = file.createWriteStream({
|
|
56
|
+
resumable: false,
|
|
57
|
+
contentType,
|
|
58
|
+
});
|
|
59
|
+
blobStream.on('error', (err) => {
|
|
60
|
+
reject(err);
|
|
61
|
+
});
|
|
62
|
+
blobStream.on('finish', async () => {
|
|
63
|
+
try {
|
|
64
|
+
await file.makePublic();
|
|
65
|
+
const publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;
|
|
66
|
+
resolve({ filename: file.name, url: publicUrl });
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
reject(err);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
processedImage.pipe(blobStream);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async transcodeImage(buffer, originalFilename, resolutions) {
|
|
76
|
+
const extension = path_1.default.extname(originalFilename);
|
|
77
|
+
const contentType = `image/${extension.replace('.', '') || 'jpeg'}`;
|
|
78
|
+
const timestamp = (0, moment_1.default)().format('DDMMYYHmmss');
|
|
79
|
+
const randomId = Math.floor(Math.random() * 100);
|
|
80
|
+
const baseFilename = `${makeSlug(path_1.default.parse(originalFilename).name)}-${this.websiteName}-${timestamp}-${randomId}`;
|
|
81
|
+
const originalFileName = `${baseFilename}${extension}`;
|
|
82
|
+
const originalUrl = await this.uploadBuffer(buffer, originalFileName, contentType);
|
|
83
|
+
const metadata = await (0, sharp_1.default)(buffer).metadata();
|
|
84
|
+
const isLandscape = metadata.width && metadata.height ? metadata.width > metadata.height : true;
|
|
85
|
+
const resizedResults = await Promise.all(resolutions.map(async (resolution) => {
|
|
86
|
+
const resizeOptions = isLandscape ? { width: resolution } : { height: resolution };
|
|
87
|
+
const formatKey = (extension.replace('.', '') || 'jpeg');
|
|
88
|
+
const resizedBuffer = await (0, sharp_1.default)(buffer)
|
|
89
|
+
.resize({
|
|
90
|
+
...resizeOptions,
|
|
91
|
+
withoutEnlargement: true,
|
|
92
|
+
})
|
|
93
|
+
.toFormat(formatKey, { quality: 80 })
|
|
94
|
+
.toBuffer();
|
|
95
|
+
const resizedFilename = `${baseFilename}-${resolution}${extension}`;
|
|
96
|
+
const resizedUrl = await this.uploadBuffer(resizedBuffer, resizedFilename, contentType);
|
|
97
|
+
return { resolution, url: resizedUrl };
|
|
98
|
+
}));
|
|
99
|
+
return { originalUrl, resizedResults };
|
|
100
|
+
}
|
|
101
|
+
async uploadBuffer(buffer, filename, contentType) {
|
|
102
|
+
const file = this.bucket.file(filename);
|
|
103
|
+
await file.save(buffer, {
|
|
104
|
+
resumable: false,
|
|
105
|
+
contentType,
|
|
106
|
+
});
|
|
107
|
+
await file.makePublic();
|
|
108
|
+
return `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;
|
|
109
|
+
}
|
|
110
|
+
async getListFiles() {
|
|
111
|
+
const [files] = await this.bucket.getFiles();
|
|
112
|
+
return files.map((file) => ({
|
|
113
|
+
name: file.name,
|
|
114
|
+
url: file.metadata.mediaLink,
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
async downloadFile(filename) {
|
|
118
|
+
const file = this.bucket.file(filename);
|
|
119
|
+
const [buffer] = await file.download();
|
|
120
|
+
return buffer;
|
|
121
|
+
}
|
|
122
|
+
async deleteFile(filename) {
|
|
123
|
+
const file = this.bucket.file(filename);
|
|
124
|
+
const [exists] = await file.exists();
|
|
125
|
+
if (!exists) {
|
|
126
|
+
throw new Error('File does not exist.');
|
|
127
|
+
}
|
|
128
|
+
await file.delete();
|
|
129
|
+
}
|
|
130
|
+
async downloadImage(url) {
|
|
131
|
+
const response = await axios_1.default.get(url, { responseType: 'arraybuffer' });
|
|
132
|
+
return Buffer.from(response.data, 'binary');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.UploadService = UploadService;
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/upload/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Storage } from '@google-cloud/storage';\r\nimport axios from 'axios';\r\nimport sharp, {FormatEnum} from 'sharp';\r\nimport moment from 'moment';\r\nimport path from 'path';\r\nimport {Service} from \"typedi\";\r\nimport {ConfigurationService} from \"../configuration\";\r\nimport {FirebaseService} from \"../firebase\";\r\nimport {getLibraries} from \"../../index\";\r\n\r\nfunction makeSlug(input: string): string {\r\n return input\r\n .toLowerCase()\r\n .replace(/[^a-z0-9]+/g, '-')\r\n .replace(/(^-|-$)/g, '');\r\n}\r\n\r\nexport class UploadService {\r\n private bucket;\r\n private readonly websiteName;\r\n\r\n constructor(bucketName?: string) {\r\n if(!bucketName) {\r\n bucketName = \"lyxa-global\";\r\n }\r\n\r\n this.bucket = getLibraries().getFirebaseService().superApp.storage().bucket(bucketName);\r\n this.websiteName = \"lyxa-\" + getLibraries().getConfigurationService().options.tenet;\r\n }\r\n\r\n /**\r\n * Generates a unique filename using the original filename.\r\n */\r\n private generateFilename(originalFilename: string): string {\r\n const nameWithoutExt = path.parse(originalFilename).name;\r\n const extension = path.extname(originalFilename);\r\n const timestamp = moment().format('DDMMYYHmmss');\r\n const randomId = Math.floor(Math.random() * 100);\r\n const baseName = `${makeSlug(nameWithoutExt)}-${this.websiteName}-${timestamp}-${randomId}`;\r\n return baseName + extension;\r\n }\r\n\r\n /**\r\n * Uploads an image buffer after processing it with Sharp.\r\n * An optional destinationPath can be provided (e.g., 'images/product.jpg').\r\n */\r\n async uploadImage(\r\n buffer: Buffer,\r\n originalFilename: string,\r\n ): Promise<{ filename: string; url: string }> {\r\n const newFilename = this.generateFilename(originalFilename);\r\n const extension = path.extname(newFilename).toLowerCase();\r\n let processedImage: sharp.Sharp;\r\n let contentType: string;\r\n if (extension === '.png') {\r\n processedImage = sharp(buffer).png({ quality: 80 });\r\n contentType = 'image/png';\r\n } else if (extension === '.webp') {\r\n processedImage = sharp(buffer).webp({ quality: 80 });\r\n contentType = 'image/webp';\r\n } else {\r\n processedImage = sharp(buffer).jpeg({ quality: 80 });\r\n contentType = 'image/jpeg';\r\n }\r\n\r\n const file = this.bucket.file(newFilename);\r\n return new Promise((resolve, reject) => {\r\n const blobStream = file.createWriteStream({\r\n resumable: false,\r\n contentType,\r\n });\r\n\r\n blobStream.on('error', (err: Error) => {\r\n reject(err);\r\n });\r\n\r\n blobStream.on('finish', async () => {\r\n try {\r\n await file.makePublic();\r\n const publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\r\n resolve({ filename: file.name, url: publicUrl });\r\n } catch (err) {\r\n reject(err);\r\n }\r\n });\r\n\r\n processedImage.pipe(blobStream);\r\n });\r\n }\r\n\r\n /**\r\n * Transcodes (resizes) an image buffer into multiple resolutions.\r\n * An optional destinationPrefix can be provided to force a specific path or filename base.\r\n *\r\n * For example, if destinationPrefix is 'images/product', then the original might be\r\n * uploaded as 'images/product.jpg' and the resized versions as 'images/product-480.jpg', etc.\r\n */\r\n async transcodeImage(\r\n buffer: Buffer,\r\n originalFilename: string,\r\n resolutions: number[],\r\n ): Promise<{\r\n originalUrl: string;\r\n resizedResults: Array<{ resolution: number; url: string }>;\r\n }> {\r\n const extension = path.extname(originalFilename);\r\n const contentType = `image/${extension.replace('.', '') || 'jpeg'}`;\r\n const timestamp = moment().format('DDMMYYHmmss');\r\n const randomId = Math.floor(Math.random() * 100);\r\n\r\n const baseFilename = `${makeSlug(path.parse(originalFilename).name)}-${this.websiteName}-${timestamp}-${randomId}`;\r\n\r\n const originalFileName = `${baseFilename}${extension}`;\r\n const originalUrl = await this.uploadBuffer(buffer, originalFileName, contentType);\r\n\r\n const metadata = await sharp(buffer).metadata();\r\n const isLandscape =\r\n metadata.width && metadata.height ? metadata.width > metadata.height : true;\r\n\r\n const resizedResults = await Promise.all(\r\n resolutions.map(async (resolution) => {\r\n const resizeOptions = isLandscape ? { width: resolution } : { height: resolution };\r\n const formatKey = (extension.replace('.', '') || 'jpeg') as keyof sharp.FormatEnum;\r\n const resizedBuffer = await sharp(buffer)\r\n .resize({\r\n ...resizeOptions,\r\n withoutEnlargement: true,\r\n })\r\n .toFormat(formatKey, { quality: 80 })\r\n .toBuffer();\r\n const resizedFilename = `${baseFilename}-${resolution}${extension}`;\r\n const resizedUrl = await this.uploadBuffer(resizedBuffer, resizedFilename, contentType);\r\n return { resolution, url: resizedUrl };\r\n })\r\n );\r\n\r\n return { originalUrl, resizedResults };\r\n }\r\n\r\n /**\r\n * Helper function to upload a buffer to a specified filename.\r\n */\r\n private async uploadBuffer(\r\n buffer: Buffer,\r\n filename: string,\r\n contentType: string\r\n ): Promise<string> {\r\n const file = this.bucket.file(filename);\r\n await file.save(buffer, {\r\n resumable: false,\r\n contentType,\r\n });\r\n await file.makePublic();\r\n return `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\r\n }\r\n\r\n async getListFiles(): Promise<Array<{ name: string; url: string }>> {\r\n const [files] = await this.bucket.getFiles();\r\n return files.map((file) => ({\r\n name: file.name!,\r\n url: file.metadata.mediaLink!,\r\n }));\r\n }\r\n\r\n async downloadFile(filename: string): Promise<Buffer> {\r\n const file = this.bucket.file(filename);\r\n const [buffer] = await file.download();\r\n return buffer;\r\n }\r\n\r\n async deleteFile(filename: string): Promise<void> {\r\n const file = this.bucket.file(filename);\r\n const [exists] = await file.exists();\r\n if (!exists) {\r\n throw new Error('File does not exist.');\r\n }\r\n await file.delete();\r\n }\r\n\r\n async downloadImage(url: string): Promise<Buffer> {\r\n const response = await axios.get(url, { responseType: 'arraybuffer' });\r\n return Buffer.from(response.data, 'binary');\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class ErrorHandler {
|
|
2
|
+
private static readonly CONFIG;
|
|
3
|
+
private static readonly MONGO_ERROR_CODES;
|
|
4
|
+
private static logError;
|
|
5
|
+
static handleError(error: unknown, customMessage?: string, context?: Record<string, unknown>): never;
|
|
6
|
+
private static isMongoError;
|
|
7
|
+
private static createMongoTRPCError;
|
|
8
|
+
private static mapNodeErrorCode;
|
|
9
|
+
static wrapAsync<T>(fn: () => Promise<T>, context?: Record<string, unknown>): Promise<T>;
|
|
10
|
+
static withRetry<T>(fn: () => Promise<T>, options?: {
|
|
11
|
+
maxAttempts?: number;
|
|
12
|
+
delayMs?: number;
|
|
13
|
+
backoffFactor?: number;
|
|
14
|
+
context?: Record<string, unknown>;
|
|
15
|
+
}): Promise<T>;
|
|
16
|
+
private static isRetryableError;
|
|
17
|
+
static extractErrorMetadata(error: unknown): {
|
|
18
|
+
type: string;
|
|
19
|
+
originalError: unknown;
|
|
20
|
+
details?: Record<string, unknown>;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ErrorHandler = void 0;
|
|
4
|
+
const server_1 = require("@trpc/server");
|
|
5
|
+
const mongodb_1 = require("mongodb");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
class ErrorHandler {
|
|
8
|
+
static CONFIG = {
|
|
9
|
+
shouldLogErrors: true,
|
|
10
|
+
maxStackTraceLines: 10,
|
|
11
|
+
retryableErrors: new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EPIPE']),
|
|
12
|
+
};
|
|
13
|
+
static MONGO_ERROR_CODES = {
|
|
14
|
+
11000: { code: 'CONFLICT', message: 'Duplicate key error: A record with this value already exists.' },
|
|
15
|
+
11001: { code: 'CONFLICT', message: 'Duplicate key error on index update.' },
|
|
16
|
+
121: { code: 'BAD_REQUEST', message: 'Document validation failed.' },
|
|
17
|
+
7: { code: 'INTERNAL_SERVER_ERROR', message: 'Not primary - database is in recovery mode.' },
|
|
18
|
+
89: { code: 'FORBIDDEN', message: 'Unauthorized operation attempted.' },
|
|
19
|
+
91: { code: 'TIMEOUT', message: 'Operation timeout exceeded.' },
|
|
20
|
+
189: { code: 'BAD_REQUEST', message: 'Invalid modification - document would exceed size limit.' },
|
|
21
|
+
50: { code: 'INTERNAL_SERVER_ERROR', message: 'Database execution error.' },
|
|
22
|
+
};
|
|
23
|
+
static logError(error, context = {}) {
|
|
24
|
+
if (!this.CONFIG.shouldLogErrors)
|
|
25
|
+
return;
|
|
26
|
+
const errorMeta = this.extractErrorMetadata(error);
|
|
27
|
+
const timestamp = new Date().toISOString();
|
|
28
|
+
const logData = {
|
|
29
|
+
timestamp,
|
|
30
|
+
type: errorMeta.type,
|
|
31
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
32
|
+
stack: error instanceof Error
|
|
33
|
+
? error.stack?.split('\n').slice(0, this.CONFIG.maxStackTraceLines).join('\n')
|
|
34
|
+
: undefined,
|
|
35
|
+
context,
|
|
36
|
+
metadata: errorMeta,
|
|
37
|
+
};
|
|
38
|
+
console.error('[ErrorHandler]:', JSON.stringify(logData, null, 2));
|
|
39
|
+
}
|
|
40
|
+
static handleError(error, customMessage = 'An unexpected error occurred', context = {}) {
|
|
41
|
+
this.logError(error, context);
|
|
42
|
+
if (error instanceof server_1.TRPCError) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
if (error instanceof zod_1.ZodError) {
|
|
46
|
+
throw new server_1.TRPCError({
|
|
47
|
+
code: 'BAD_REQUEST',
|
|
48
|
+
message: 'Validation error',
|
|
49
|
+
cause: error.flatten(),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (error instanceof mongodb_1.MongoNetworkError) {
|
|
53
|
+
throw new server_1.TRPCError({
|
|
54
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
55
|
+
message: 'Database connection error',
|
|
56
|
+
cause: error,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (this.isMongoError(error)) {
|
|
60
|
+
throw this.createMongoTRPCError(error);
|
|
61
|
+
}
|
|
62
|
+
if (error instanceof Error) {
|
|
63
|
+
throw new server_1.TRPCError({
|
|
64
|
+
code: this.mapNodeErrorCode(error),
|
|
65
|
+
message: error.message || customMessage,
|
|
66
|
+
cause: error,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
throw new server_1.TRPCError({
|
|
70
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
71
|
+
message: customMessage,
|
|
72
|
+
cause: error,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
static isMongoError(error) {
|
|
76
|
+
return (error instanceof mongodb_1.MongoServerError ||
|
|
77
|
+
error instanceof mongodb_1.MongoError ||
|
|
78
|
+
(typeof error === 'object' &&
|
|
79
|
+
error !== null &&
|
|
80
|
+
'code' in error &&
|
|
81
|
+
'name' in error &&
|
|
82
|
+
(error.name === 'MongoServerError' ||
|
|
83
|
+
error.name === 'MongoError')));
|
|
84
|
+
}
|
|
85
|
+
static createMongoTRPCError(error) {
|
|
86
|
+
const errorCode = typeof error.code === 'number' ? error.code : 0;
|
|
87
|
+
const errorInfo = this.MONGO_ERROR_CODES[errorCode] || {
|
|
88
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
89
|
+
message: `Database error occurred. Code: ${errorCode}`,
|
|
90
|
+
};
|
|
91
|
+
return new server_1.TRPCError({
|
|
92
|
+
code: errorInfo.code,
|
|
93
|
+
message: errorInfo.message,
|
|
94
|
+
cause: error,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
static mapNodeErrorCode(error) {
|
|
98
|
+
const nodeErrorMap = {
|
|
99
|
+
ENOENT: 'NOT_FOUND',
|
|
100
|
+
EACCES: 'FORBIDDEN',
|
|
101
|
+
ECONNREFUSED: 'INTERNAL_SERVER_ERROR',
|
|
102
|
+
ECONNRESET: 'INTERNAL_SERVER_ERROR',
|
|
103
|
+
ETIMEDOUT: 'TIMEOUT',
|
|
104
|
+
EPIPE: 'INTERNAL_SERVER_ERROR',
|
|
105
|
+
ENOTFOUND: 'NOT_FOUND',
|
|
106
|
+
EINVAL: 'BAD_REQUEST',
|
|
107
|
+
EMFILE: 'INTERNAL_SERVER_ERROR',
|
|
108
|
+
EPERM: 'FORBIDDEN',
|
|
109
|
+
};
|
|
110
|
+
const code = error.code;
|
|
111
|
+
return code ? nodeErrorMap[code] || 'INTERNAL_SERVER_ERROR' : 'INTERNAL_SERVER_ERROR';
|
|
112
|
+
}
|
|
113
|
+
static async wrapAsync(fn, context = {}) {
|
|
114
|
+
try {
|
|
115
|
+
return await fn();
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
this.handleError(error, undefined, context);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
static async withRetry(fn, options = {}) {
|
|
122
|
+
const { maxAttempts = 3, delayMs = 1000, backoffFactor = 2, context = {} } = options;
|
|
123
|
+
let lastError;
|
|
124
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
125
|
+
try {
|
|
126
|
+
return await fn();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
lastError = error;
|
|
130
|
+
const isRetryable = this.isRetryableError(error);
|
|
131
|
+
const isLastAttempt = attempt === maxAttempts;
|
|
132
|
+
if (!isRetryable || isLastAttempt) {
|
|
133
|
+
this.handleError(error, undefined, { ...context, attempt });
|
|
134
|
+
}
|
|
135
|
+
await new Promise(resolve => setTimeout(resolve, delayMs * Math.pow(backoffFactor, attempt - 1)));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
throw lastError;
|
|
139
|
+
}
|
|
140
|
+
static isRetryableError(error) {
|
|
141
|
+
if (error instanceof mongodb_1.MongoNetworkError)
|
|
142
|
+
return true;
|
|
143
|
+
if (error instanceof Error) {
|
|
144
|
+
const code = error.code;
|
|
145
|
+
return code ? this.CONFIG.retryableErrors.has(code) : false;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
static extractErrorMetadata(error) {
|
|
150
|
+
if (error instanceof server_1.TRPCError) {
|
|
151
|
+
return {
|
|
152
|
+
type: 'TRPCError',
|
|
153
|
+
originalError: error.cause ?? error,
|
|
154
|
+
details: {
|
|
155
|
+
code: error.code,
|
|
156
|
+
message: error.message,
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (error instanceof zod_1.ZodError) {
|
|
161
|
+
return {
|
|
162
|
+
type: 'ZodError',
|
|
163
|
+
originalError: error,
|
|
164
|
+
details: error.flatten(),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (error instanceof mongodb_1.MongoNetworkError) {
|
|
168
|
+
return {
|
|
169
|
+
type: 'MongoNetworkError',
|
|
170
|
+
originalError: error,
|
|
171
|
+
details: {
|
|
172
|
+
message: error.message,
|
|
173
|
+
isRetryable: true,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (this.isMongoError(error)) {
|
|
178
|
+
return {
|
|
179
|
+
type: 'MongoError',
|
|
180
|
+
originalError: error,
|
|
181
|
+
details: {
|
|
182
|
+
code: error.code,
|
|
183
|
+
codeName: error.codeName,
|
|
184
|
+
keyPattern: error.keyPattern,
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
if (error instanceof Error) {
|
|
189
|
+
return {
|
|
190
|
+
type: 'NodeError',
|
|
191
|
+
originalError: error,
|
|
192
|
+
details: {
|
|
193
|
+
name: error.name,
|
|
194
|
+
code: error.code,
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return { type: 'UnknownError', originalError: error };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
exports.ErrorHandler = ErrorHandler;
|
|
202
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"/","sources":["utilities/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * @fileoverview Error handling utility for TRPC and MongoDB operations.\r\n * Provides centralized error handling, logging, and retry mechanisms.\r\n */\r\n\r\nimport { TRPCError } from '@trpc/server';\r\nimport { MongoServerError, MongoError, MongoNetworkError } from 'mongodb';\r\nimport { ZodError } from 'zod';\r\n\r\n/**\r\n * A utility class for handling various types of errors in a TRPC-MongoDB application.\r\n * Provides error transformation, logging, and retry mechanisms.\r\n */\r\nexport class ErrorHandler {\r\n /**\r\n * Configuration options for error handling behavior\r\n * @private\r\n */\r\n private static readonly CONFIG = {\r\n /** Whether to log errors to console */\r\n shouldLogErrors: true,\r\n /** Maximum number of stack trace lines to include in logs */\r\n maxStackTraceLines: 10,\r\n /** Set of error codes that are considered retryable */\r\n retryableErrors: new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EPIPE']),\r\n };\r\n\r\n /**\r\n * Mapping of MongoDB error codes to TRPC error types and messages\r\n * @private\r\n */\r\n private static readonly MONGO_ERROR_CODES: Record<\r\n number,\r\n {\r\n code: TRPCError['code'];\r\n message: string;\r\n }\r\n > = {\r\n 11000: { code: 'CONFLICT', message: 'Duplicate key error: A record with this value already exists.' },\r\n 11001: { code: 'CONFLICT', message: 'Duplicate key error on index update.' },\r\n 121: { code: 'BAD_REQUEST', message: 'Document validation failed.' },\r\n 7: { code: 'INTERNAL_SERVER_ERROR', message: 'Not primary - database is in recovery mode.' },\r\n 89: { code: 'FORBIDDEN', message: 'Unauthorized operation attempted.' },\r\n 91: { code: 'TIMEOUT', message: 'Operation timeout exceeded.' },\r\n 189: { code: 'BAD_REQUEST', message: 'Invalid modification - document would exceed size limit.' },\r\n 50: { code: 'INTERNAL_SERVER_ERROR', message: 'Database execution error.' },\r\n };\r\n\r\n /**\r\n * Logs error information with metadata and stack trace\r\n * @private\r\n * @param error - The error to log\r\n * @param context - Additional context information for the error\r\n */\r\n private static logError(error: unknown, context: Record<string, unknown> = {}): void {\r\n if (!this.CONFIG.shouldLogErrors) return;\r\n\r\n const errorMeta = this.extractErrorMetadata(error);\r\n const timestamp = new Date().toISOString();\r\n\r\n const logData = {\r\n timestamp,\r\n type: errorMeta.type,\r\n message: error instanceof Error ? error.message : 'Unknown error',\r\n stack:\r\n error instanceof Error\r\n ? error.stack?.split('\\n').slice(0, this.CONFIG.maxStackTraceLines).join('\\n')\r\n : undefined,\r\n context,\r\n metadata: errorMeta,\r\n };\r\n\r\n console.error('[ErrorHandler]:', JSON.stringify(logData, null, 2));\r\n }\r\n\r\n /**\r\n * Main error handling method that transforms various error types into TRPC errors\r\n * @param error - The error to handle\r\n * @param customMessage - Optional custom error message\r\n * @param context - Additional context information\r\n * @throws {TRPCError} Transformed error with appropriate error code and message\r\n */\r\n public static handleError(\r\n error: unknown,\r\n customMessage = 'An unexpected error occurred',\r\n context: Record<string, unknown> = {}\r\n ): never {\r\n this.logError(error, context);\r\n\r\n if (error instanceof TRPCError) {\r\n throw error;\r\n }\r\n\r\n if (error instanceof ZodError) {\r\n throw new TRPCError({\r\n code: 'BAD_REQUEST',\r\n message: 'Validation error',\r\n cause: error.flatten(),\r\n });\r\n }\r\n\r\n if (error instanceof MongoNetworkError) {\r\n throw new TRPCError({\r\n code: 'INTERNAL_SERVER_ERROR',\r\n message: 'Database connection error',\r\n cause: error,\r\n });\r\n }\r\n\r\n if (this.isMongoError(error)) {\r\n throw this.createMongoTRPCError(error);\r\n }\r\n\r\n if (error instanceof Error) {\r\n throw new TRPCError({\r\n code: this.mapNodeErrorCode(error),\r\n message: error.message || customMessage,\r\n cause: error,\r\n });\r\n }\r\n\r\n throw new TRPCError({\r\n code: 'INTERNAL_SERVER_ERROR',\r\n message: customMessage,\r\n cause: error,\r\n });\r\n }\r\n\r\n /**\r\n * Type guard to check if an error is a MongoDB error\r\n * @private\r\n * @param error - The error to check\r\n * @returns True if the error is a MongoDB error\r\n */\r\n private static isMongoError(error: unknown): error is MongoServerError {\r\n return (\r\n error instanceof MongoServerError ||\r\n error instanceof MongoError ||\r\n (typeof error === 'object' &&\r\n error !== null &&\r\n 'code' in error &&\r\n 'name' in error &&\r\n ((error as MongoServerError).name === 'MongoServerError' ||\r\n (error as MongoServerError).name === 'MongoError'))\r\n );\r\n }\r\n\r\n /**\r\n * Creates a TRPC error from a MongoDB error\r\n * @private\r\n * @param error - MongoDB error to transform\r\n * @returns Transformed TRPC error\r\n */\r\n private static createMongoTRPCError(error: MongoServerError): TRPCError {\r\n const errorCode = typeof error.code === 'number' ? error.code : 0;\r\n const errorInfo = this.MONGO_ERROR_CODES[errorCode] || {\r\n code: 'INTERNAL_SERVER_ERROR',\r\n message: `Database error occurred. Code: ${errorCode}`,\r\n };\r\n\r\n return new TRPCError({\r\n code: errorInfo.code,\r\n message: errorInfo.message,\r\n cause: error,\r\n });\r\n }\r\n\r\n /**\r\n * Maps Node.js error codes to TRPC error codes\r\n * @private\r\n * @param error - Node.js error to map\r\n * @returns Appropriate TRPC error code\r\n */\r\n private static mapNodeErrorCode(error: Error): TRPCError['code'] {\r\n const nodeErrorMap: Record<string, TRPCError['code']> = {\r\n ENOENT: 'NOT_FOUND',\r\n EACCES: 'FORBIDDEN',\r\n ECONNREFUSED: 'INTERNAL_SERVER_ERROR',\r\n ECONNRESET: 'INTERNAL_SERVER_ERROR',\r\n ETIMEDOUT: 'TIMEOUT',\r\n EPIPE: 'INTERNAL_SERVER_ERROR',\r\n ENOTFOUND: 'NOT_FOUND',\r\n EINVAL: 'BAD_REQUEST',\r\n EMFILE: 'INTERNAL_SERVER_ERROR',\r\n EPERM: 'FORBIDDEN',\r\n };\r\n\r\n const code = (error as NodeJS.ErrnoException).code;\r\n return code ? nodeErrorMap[code] || 'INTERNAL_SERVER_ERROR' : 'INTERNAL_SERVER_ERROR';\r\n }\r\n\r\n /**\r\n * Wraps an async function with error handling\r\n * @param fn - Async function to wrap\r\n * @param context - Additional context information\r\n * @returns Promise resolving to the function's return type\r\n * @throws {TRPCError} If the function throws an error\r\n */\r\n public static async wrapAsync<T>(fn: () => Promise<T>, context: Record<string, unknown> = {}): Promise<T> {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n this.handleError(error, undefined, context);\r\n }\r\n }\r\n\r\n /**\r\n * Executes an async function with retry mechanism for transient errors\r\n * @param fn - Async function to execute\r\n * @param options - Retry configuration options\r\n * @returns Promise resolving to the function's return type\r\n * @throws {TRPCError} If all retry attempts fail\r\n */\r\n public static async withRetry<T>(\r\n fn: () => Promise<T>,\r\n options: {\r\n maxAttempts?: number;\r\n delayMs?: number;\r\n backoffFactor?: number;\r\n context?: Record<string, unknown>;\r\n } = {}\r\n ): Promise<T> {\r\n const { maxAttempts = 3, delayMs = 1000, backoffFactor = 2, context = {} } = options;\r\n\r\n let lastError: unknown;\r\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error;\r\n\r\n const isRetryable = this.isRetryableError(error);\r\n const isLastAttempt = attempt === maxAttempts;\r\n\r\n if (!isRetryable || isLastAttempt) {\r\n this.handleError(error, undefined, { ...context, attempt });\r\n }\r\n\r\n await new Promise(resolve => setTimeout(resolve, delayMs * Math.pow(backoffFactor, attempt - 1)));\r\n }\r\n }\r\n\r\n throw lastError;\r\n }\r\n\r\n /**\r\n * Determines if an error is retryable\r\n * @private\r\n * @param error - The error to check\r\n * @returns True if the error is retryable\r\n */\r\n private static isRetryableError(error: unknown): boolean {\r\n if (error instanceof MongoNetworkError) return true;\r\n if (error instanceof Error) {\r\n const code = (error as NodeJS.ErrnoException).code;\r\n return code ? this.CONFIG.retryableErrors.has(code) : false;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Extracts metadata from an error for logging and analysis\r\n * @param error - The error to extract metadata from\r\n * @returns Object containing error type, original error, and additional details\r\n */\r\n public static extractErrorMetadata(error: unknown): {\r\n type: string;\r\n originalError: unknown;\r\n details?: Record<string, unknown>;\r\n } {\r\n if (error instanceof TRPCError) {\r\n return {\r\n type: 'TRPCError',\r\n originalError: error.cause ?? error,\r\n details: {\r\n code: error.code,\r\n message: error.message,\r\n },\r\n };\r\n }\r\n\r\n if (error instanceof ZodError) {\r\n return {\r\n type: 'ZodError',\r\n originalError: error,\r\n details: error.flatten(),\r\n };\r\n }\r\n\r\n if (error instanceof MongoNetworkError) {\r\n return {\r\n type: 'MongoNetworkError',\r\n originalError: error,\r\n details: {\r\n message: error.message,\r\n isRetryable: true,\r\n },\r\n };\r\n }\r\n\r\n if (this.isMongoError(error)) {\r\n return {\r\n type: 'MongoError',\r\n originalError: error,\r\n details: {\r\n code: (error as MongoServerError).code,\r\n codeName: (error as MongoServerError).codeName,\r\n keyPattern: (error as MongoServerError).keyPattern,\r\n },\r\n };\r\n }\r\n\r\n if (error instanceof Error) {\r\n return {\r\n type: 'NodeError',\r\n originalError: error,\r\n details: {\r\n name: error.name,\r\n code: (error as NodeJS.ErrnoException).code,\r\n },\r\n };\r\n }\r\n\r\n return { type: 'UnknownError', originalError: error };\r\n }\r\n}"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DocumentType } from '@typegoose/typegoose';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare class GlobalTransformer<ModelType, DTOType> {
|
|
4
|
+
private schema;
|
|
5
|
+
constructor(schema: z.ZodType<any>);
|
|
6
|
+
transformToBasicView(record: DocumentType<ModelType>): DTOType;
|
|
7
|
+
transformToBasicViewArray(records: DocumentType<ModelType>[]): DTOType[];
|
|
8
|
+
transformToPartialView(record: DocumentType<ModelType>, fields: (keyof DTOType)[]): Partial<DTOType>;
|
|
9
|
+
transformToPartialViewArray(records: DocumentType<ModelType>[], fields: (keyof DTOType)[]): Partial<DTOType>[];
|
|
10
|
+
transformWithAdditionalData(record: DocumentType<ModelType>, additionalData: Partial<Record<string, any>>): DTOType & Record<string, any>;
|
|
11
|
+
transformWithMapping<OutputType = DTOType>(record: DocumentType<ModelType>, mapFn: (input: DTOType) => OutputType): OutputType;
|
|
12
|
+
transformNestedProperty<NestedType>(record: DocumentType<ModelType>, path: string, nestedSchema: z.ZodType<any>): NestedType;
|
|
13
|
+
transformWithDefaults(record: DocumentType<ModelType>, defaults: Partial<DTOType>): DTOType;
|
|
14
|
+
}
|
|
15
|
+
export declare function createTransformer<ModelType, DTOType>(schema: z.ZodType<any>): GlobalTransformer<ModelType, DTOType>;
|
|
@@ -0,0 +1,117 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.GlobalTransformer = void 0;
|
|
46
|
+
exports.createTransformer = createTransformer;
|
|
47
|
+
const typedi_1 = __importStar(require("typedi"));
|
|
48
|
+
const zod_1 = require("zod");
|
|
49
|
+
let GlobalTransformer = class GlobalTransformer {
|
|
50
|
+
schema;
|
|
51
|
+
constructor(schema) {
|
|
52
|
+
this.schema = schema;
|
|
53
|
+
}
|
|
54
|
+
transformToBasicView(record) {
|
|
55
|
+
if (!record) {
|
|
56
|
+
throw new Error('Record not found');
|
|
57
|
+
}
|
|
58
|
+
return this.schema.parse(record);
|
|
59
|
+
}
|
|
60
|
+
transformToBasicViewArray(records) {
|
|
61
|
+
return records.map(record => this.transformToBasicView(record));
|
|
62
|
+
}
|
|
63
|
+
transformToPartialView(record, fields) {
|
|
64
|
+
const fullView = this.transformToBasicView(record);
|
|
65
|
+
const partialView = {};
|
|
66
|
+
fields.forEach(field => {
|
|
67
|
+
const dto = fullView;
|
|
68
|
+
partialView[field] = dto[field];
|
|
69
|
+
});
|
|
70
|
+
return partialView;
|
|
71
|
+
}
|
|
72
|
+
transformToPartialViewArray(records, fields) {
|
|
73
|
+
return records.map(record => this.transformToPartialView(record, fields));
|
|
74
|
+
}
|
|
75
|
+
transformWithAdditionalData(record, additionalData) {
|
|
76
|
+
const basicView = this.transformToBasicView(record);
|
|
77
|
+
return { ...basicView, ...additionalData };
|
|
78
|
+
}
|
|
79
|
+
transformWithMapping(record, mapFn) {
|
|
80
|
+
const basicView = this.transformToBasicView(record);
|
|
81
|
+
return mapFn(basicView);
|
|
82
|
+
}
|
|
83
|
+
transformNestedProperty(record, path, nestedSchema) {
|
|
84
|
+
if (!record) {
|
|
85
|
+
throw new Error('Record not found');
|
|
86
|
+
}
|
|
87
|
+
const parts = path.split('.');
|
|
88
|
+
let current = record;
|
|
89
|
+
for (const part of parts) {
|
|
90
|
+
if (current && part in current) {
|
|
91
|
+
current = current[part];
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
throw new Error(`Path ${path} not found in record`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return nestedSchema.parse(current);
|
|
98
|
+
}
|
|
99
|
+
transformWithDefaults(record, defaults) {
|
|
100
|
+
const transformed = this.transformToBasicView(record);
|
|
101
|
+
return { ...defaults, ...transformed };
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
exports.GlobalTransformer = GlobalTransformer;
|
|
105
|
+
exports.GlobalTransformer = GlobalTransformer = __decorate([
|
|
106
|
+
(0, typedi_1.Service)(),
|
|
107
|
+
__metadata("design:paramtypes", [zod_1.z.ZodType])
|
|
108
|
+
], GlobalTransformer);
|
|
109
|
+
function createTransformer(schema) {
|
|
110
|
+
try {
|
|
111
|
+
return typedi_1.default.get(GlobalTransformer);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
return new GlobalTransformer(schema);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=transformers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformers.js","sourceRoot":"/","sources":["utilities/transformers.ts"],"names":[],"mappings":"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","sourcesContent":["import { DocumentType } from '@typegoose/typegoose';\r\nimport Container, { Service } from 'typedi';\r\nimport { z } from 'zod';\r\n\r\n/**\r\n * GlobalTransformer provides a reusable way to transform Mongoose documents\r\n * into DTOs using Zod schemas for validation and type safety.\r\n * \r\n * @template ModelType - The Mongoose model type\r\n * @template DTOType - The output DTO type\r\n */\r\n@Service()\r\nexport class GlobalTransformer<ModelType, DTOType> {\r\n\t/**\r\n\t * Creates a new GlobalTransformer\r\n\t * \r\n\t * @param {z.ZodType<any>} schema - Zod schema used for validation and transformation\r\n\t */\r\n\tconstructor(private schema: z.ZodType<any>) {}\r\n\r\n\t/**\r\n\t * Transforms a single document to a DTO\r\n\t * \r\n\t * @param {DocumentType<ModelType>} record - The document to transform\r\n\t * @returns {DTOType} The transformed DTO\r\n\t * @throws {Error} When record is not found\r\n\t */\r\n\tpublic transformToBasicView(record: DocumentType<ModelType>): DTOType {\r\n\t\tif (!record) {\r\n\t\t\tthrow new Error('Record not found');\r\n\t\t}\r\n\r\n\t\treturn this.schema.parse(record) as DTOType;\r\n\t}\r\n\r\n\t/**\r\n\t * Transforms an array of documents to DTOs\r\n\t * \r\n\t * @param {DocumentType<ModelType>[]} records - Array of documents to transform\r\n\t * @returns {DTOType[]} Array of transformed DTOs\r\n\t */\r\n\tpublic transformToBasicViewArray(records: DocumentType<ModelType>[]): DTOType[] {\r\n\t\treturn records.map(record => this.transformToBasicView(record));\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a partial view with only the specified fields\r\n\t * \r\n\t * @param {DocumentType<ModelType>} record - The document to transform\r\n\t * @param {(keyof DTOType)[]} fields - Fields to include in the output\r\n\t * @returns {Partial<DTOType>} Partial DTO with only the specified fields\r\n\t */\r\n\tpublic transformToPartialView(\r\n\t\trecord: DocumentType<ModelType>,\r\n\t\tfields: (keyof DTOType)[]\r\n\t): Partial<DTOType> {\r\n\t\tconst fullView = this.transformToBasicView(record);\r\n\t\tconst partialView: Partial<DTOType> = {};\r\n\r\n\t\tfields.forEach(field => {\r\n\t\t\tconst dto = fullView as Record<keyof DTOType, any>;\r\n\t\t\tpartialView[field] = dto[field];\r\n\t\t});\r\n\r\n\t\treturn partialView;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates partial views for an array of documents\r\n\t * \r\n\t * @param {DocumentType<ModelType>[]} records - Array of documents to transform\r\n\t * @param {(keyof DTOType)[]} fields - Fields to include in the output\r\n\t * @returns {Partial<DTOType>[]} Array of partial DTOs\r\n\t */\r\n\tpublic transformToPartialViewArray(\r\n\t\trecords: DocumentType<ModelType>[],\r\n\t\tfields: (keyof DTOType)[]\r\n\t): Partial<DTOType>[] {\r\n\t\treturn records.map(record => this.transformToPartialView(record, fields));\r\n\t}\r\n\r\n\t/**\r\n\t * Transforms a document and adds additional computed fields\r\n\t * \r\n\t * @param {DocumentType<ModelType>} record - The document to transform\r\n\t * @param {Partial<Record<string, any>>} additionalData - Additional fields to add\r\n\t * @returns {DTOType & Record<string, any>} DTO with additional fields\r\n\t */\r\n\tpublic transformWithAdditionalData(\r\n\t\trecord: DocumentType<ModelType>,\r\n\t\tadditionalData: Partial<Record<string, any>>\r\n\t): DTOType & Record<string, any> {\r\n\t\tconst basicView = this.transformToBasicView(record);\r\n\t\treturn { ...basicView, ...additionalData };\r\n\t}\r\n\r\n\t/**\r\n\t * Transforms a document using a custom mapping function\r\n\t * \r\n\t * @template OutputType - The output type after mapping\r\n\t * @param {DocumentType<ModelType>} record - The document to transform\r\n\t * @param {(input: DTOType) => OutputType} mapFn - Mapping function for custom transformation\r\n\t * @returns {OutputType} Custom transformed output\r\n\t */\r\n\tpublic transformWithMapping<OutputType = DTOType>(\r\n\t\trecord: DocumentType<ModelType>,\r\n\t\tmapFn: (input: DTOType) => OutputType\r\n\t): OutputType {\r\n\t\tconst basicView = this.transformToBasicView(record);\r\n\t\treturn mapFn(basicView);\r\n\t}\r\n\r\n\t/**\r\n\t * Transforms a nested property of the document\r\n\t * \r\n\t * @template NestedType - The type of the nested property\r\n\t * @param {DocumentType<ModelType>} record - The document to transform\r\n\t * @param {string} path - Dot-notation path to the nested property\r\n\t * @param {z.ZodType<any>} nestedSchema - Zod schema for the nested property\r\n\t * @returns {NestedType} The transformed nested property\r\n\t * @throws {Error} When path is not found in record\r\n\t */\r\n\tpublic transformNestedProperty<NestedType>(\r\n\t\trecord: DocumentType<ModelType>,\r\n\t\tpath: string,\r\n\t\tnestedSchema: z.ZodType<any>\r\n\t): NestedType {\r\n\t\tif (!record) {\r\n\t\t\tthrow new Error('Record not found');\r\n\t\t}\r\n\r\n\t\tconst parts = path.split('.');\r\n\t\tlet current: any = record;\r\n\r\n\t\tfor (const part of parts) {\r\n\t\t\tif (current && part in current) {\r\n\t\t\t\tcurrent = current[part];\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Path ${path} not found in record`);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn nestedSchema.parse(current) as NestedType;\r\n\t}\r\n\r\n\t/**\r\n\t * Transforms a document with default values for missing fields\r\n\t * \r\n\t * @param {DocumentType<ModelType>} record - The document to transform\r\n\t * @param {Partial<DTOType>} defaults - Default values for fields\r\n\t * @returns {DTOType} DTO with defaults applied\r\n\t */\r\n\tpublic transformWithDefaults(\r\n\t\trecord: DocumentType<ModelType>, \r\n\t\tdefaults: Partial<DTOType>\r\n\t): DTOType {\r\n\t\tconst transformed = this.transformToBasicView(record);\r\n\t\treturn { ...defaults, ...transformed };\r\n\t}\r\n}\r\n\r\n/**\r\n * Creates a transformer instance for the given schema.\r\n * Uses dependency injection if available, falls back to creating a new instance.\r\n * \r\n * @template ModelType - The Mongoose model type\r\n * @template DTOType - The output DTO type\r\n * @param {z.ZodType<any>} schema - Zod schema for validation and transformation\r\n * @returns {GlobalTransformer<ModelType, DTOType>} Instance of GlobalTransformer\r\n */\r\nexport function createTransformer<ModelType, DTOType>(\r\n\tschema: z.ZodType<any>\r\n): GlobalTransformer<ModelType, DTOType> {\r\n\ttry {\r\n\t\treturn Container.get(GlobalTransformer) as GlobalTransformer<ModelType, DTOType>;\r\n\t} catch (error) {\r\n\t\treturn new GlobalTransformer<ModelType, DTOType>(schema);\r\n\t}\r\n}"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const FilterSchema: z.ZodOptional<z.ZodObject<{
|
|
3
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
4
|
+
skip: z.ZodDefault<z.ZodNumber>;
|
|
5
|
+
sort: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodLiteral<1>, z.ZodLiteral<-1>, z.ZodLiteral<"asc">, z.ZodLiteral<"desc">]>>>;
|
|
6
|
+
query: z.ZodOptional<z.ZodType<Record<string, any>, z.ZodTypeDef, Record<string, any>>>;
|
|
7
|
+
select: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
8
|
+
populate: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
skip: number;
|
|
11
|
+
limit: number;
|
|
12
|
+
sort?: Record<string, 1 | "desc" | -1 | "asc"> | undefined;
|
|
13
|
+
select?: string[] | undefined;
|
|
14
|
+
query?: Record<string, any> | undefined;
|
|
15
|
+
populate?: string[] | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
sort?: Record<string, 1 | "desc" | -1 | "asc"> | undefined;
|
|
18
|
+
select?: string[] | undefined;
|
|
19
|
+
query?: Record<string, any> | undefined;
|
|
20
|
+
skip?: number | undefined;
|
|
21
|
+
limit?: number | undefined;
|
|
22
|
+
populate?: string[] | undefined;
|
|
23
|
+
}>>;
|
|
24
|
+
export type FilterDTO = z.infer<typeof FilterSchema>;
|
|
25
|
+
export declare const StringSchema: z.ZodString;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StringSchema = exports.FilterSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const SortOrderSchema = zod_1.z.union([
|
|
6
|
+
zod_1.z.literal(1),
|
|
7
|
+
zod_1.z.literal(-1),
|
|
8
|
+
zod_1.z.literal("asc"),
|
|
9
|
+
zod_1.z.literal("desc"),
|
|
10
|
+
]);
|
|
11
|
+
const MongoQuerySchema = zod_1.z.lazy(() => zod_1.z.record(zod_1.z.union([zod_1.z.any(), MongoOperatorsSchema])));
|
|
12
|
+
const MongoOperatorsSchema = zod_1.z.object({
|
|
13
|
+
$eq: zod_1.z.any().optional(),
|
|
14
|
+
$ne: zod_1.z.any().optional(),
|
|
15
|
+
$gt: zod_1.z.any().optional(),
|
|
16
|
+
$gte: zod_1.z.any().optional(),
|
|
17
|
+
$lt: zod_1.z.any().optional(),
|
|
18
|
+
$lte: zod_1.z.any().optional(),
|
|
19
|
+
$in: zod_1.z.array(zod_1.z.any()).optional(),
|
|
20
|
+
$nin: zod_1.z.array(zod_1.z.any()).optional(),
|
|
21
|
+
$exists: zod_1.z.boolean().optional(),
|
|
22
|
+
$regex: zod_1.z.string().optional(),
|
|
23
|
+
$and: zod_1.z.array(MongoQuerySchema).optional(),
|
|
24
|
+
$or: zod_1.z.array(MongoQuerySchema).optional(),
|
|
25
|
+
$not: MongoQuerySchema.optional(),
|
|
26
|
+
$nor: zod_1.z.array(MongoQuerySchema).optional(),
|
|
27
|
+
});
|
|
28
|
+
exports.FilterSchema = zod_1.z.object({
|
|
29
|
+
limit: zod_1.z
|
|
30
|
+
.number()
|
|
31
|
+
.min(1, { message: "Limit must be greater than 0." })
|
|
32
|
+
.max(100, { message: "Limit cannot exceed 100." })
|
|
33
|
+
.default(10),
|
|
34
|
+
skip: zod_1.z.number().min(0, { message: "Skip cannot be negative." }).default(0),
|
|
35
|
+
sort: zod_1.z.record(zod_1.z.string(), SortOrderSchema).optional(),
|
|
36
|
+
query: MongoQuerySchema.optional(),
|
|
37
|
+
select: zod_1.z.array(zod_1.z.string()).optional(),
|
|
38
|
+
populate: zod_1.z.array(zod_1.z.string()).optional(),
|
|
39
|
+
}).optional();
|
|
40
|
+
exports.StringSchema = zod_1.z
|
|
41
|
+
.string()
|
|
42
|
+
.min(1, "String cannot be empty")
|
|
43
|
+
.max(255, "String is too long");
|
|
44
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"/","sources":["utilities/validation.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAKxB,MAAM,eAAe,GAAG,OAAC,CAAC,KAAK,CAAC;IAC9B,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACZ,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACb,OAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAChB,OAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CAClB,CAAC,CAAC;AAKH,MAAM,gBAAgB,GAAmC,OAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CACnE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC,CACnD,CAAC;AAKF,MAAM,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,GAAG,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACvB,GAAG,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACvB,GAAG,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACvB,IAAI,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACxB,GAAG,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACvB,IAAI,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACxB,GAAG,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;IAChC,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;IACjC,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE;IAC1C,GAAG,EAAE,OAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE;IACzC,IAAI,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IACjC,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAKU,QAAA,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,OAAC;SACL,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;SACpD,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;SACjD,OAAO,CAAC,EAAE,CAAC;IACd,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3E,IAAI,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE;IACtD,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IAClC,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAUD,QAAA,YAAY,GAAG,OAAC;KAC1B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC;KAChC,GAAG,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\r\n\r\n/**\r\n * Define allowed MongoDB sort orders\r\n */\r\nconst SortOrderSchema = z.union([\r\n z.literal(1),\r\n z.literal(-1),\r\n z.literal(\"asc\"),\r\n z.literal(\"desc\"),\r\n]);\r\n\r\n/**\r\n * Define MongoDB query schema (fields + operators) using lazy evaluation to avoid circular dependency\r\n */\r\nconst MongoQuerySchema: z.ZodType<Record<string, any>> = z.lazy(() =>\r\n z.record(z.union([z.any(), MongoOperatorsSchema]))\r\n);\r\n\r\n/**\r\n * Define allowed MongoDB query operators\r\n */\r\nconst MongoOperatorsSchema = z.object({\r\n $eq: z.any().optional(), \r\n $ne: z.any().optional(),\r\n $gt: z.any().optional(),\r\n $gte: z.any().optional(),\r\n $lt: z.any().optional(),\r\n $lte: z.any().optional(),\r\n $in: z.array(z.any()).optional(),\r\n $nin: z.array(z.any()).optional(),\r\n $exists: z.boolean().optional(),\r\n $regex: z.string().optional(),\r\n $and: z.array(MongoQuerySchema).optional(),\r\n $or: z.array(MongoQuerySchema).optional(),\r\n $not: MongoQuerySchema.optional(),\r\n $nor: z.array(MongoQuerySchema).optional(),\r\n});\r\n\r\n/**\r\n * Define the filter schema using MongoQuerySchema\r\n */\r\nexport const FilterSchema = z.object({\r\n limit: z\r\n .number()\r\n .min(1, { message: \"Limit must be greater than 0.\" })\r\n .max(100, { message: \"Limit cannot exceed 100.\" })\r\n .default(10),\r\n skip: z.number().min(0, { message: \"Skip cannot be negative.\" }).default(0),\r\n sort: z.record(z.string(), SortOrderSchema).optional(),\r\n query: MongoQuerySchema.optional(),\r\n select: z.array(z.string()).optional(),\r\n populate: z.array(z.string()).optional(),\r\n}).optional();\r\n\r\n/**\r\n * Infer TypeScript type from Zod schema\r\n */\r\nexport type FilterDTO = z.infer<typeof FilterSchema>;\r\n\r\n/**\r\n * Define String schema\r\n */\r\nexport const StringSchema = z\r\n .string()\r\n .min(1, \"String cannot be empty\")\r\n .max(255, \"String is too long\");\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lyxa.ai/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "The Core system of the Lyxa services.",
|
|
5
5
|
"author": "elie <42282499+Internalizable@users.noreply.github.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
"firebase-admin": "^13.0.1",
|
|
29
29
|
"ioredis": "^5.4.1",
|
|
30
30
|
"jsonwebtoken": "^9.0.2",
|
|
31
|
+
"moment": "^2.30.1",
|
|
31
32
|
"mongoose": "^8.9.1",
|
|
32
33
|
"pino": "^9.5.0",
|
|
33
34
|
"pino-mongodb": "^4.3.0",
|
|
34
35
|
"pino-pretty": "^13.0.0",
|
|
36
|
+
"sharp": "^0.33.5",
|
|
35
37
|
"twilio": "^5.4.0",
|
|
36
38
|
"typedi": "^0.10.0",
|
|
37
39
|
"typescript": "^5.7.2",
|