@forzalabs/remora 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/Constants.js +8 -0
  2. package/actions/automap.js +73 -0
  3. package/actions/compile.js +57 -0
  4. package/actions/debug.js +61 -0
  5. package/actions/deploy.js +95 -0
  6. package/actions/discover.js +36 -0
  7. package/actions/init.js +78 -0
  8. package/actions/run.js +51 -0
  9. package/auth/AdminManager.js +48 -0
  10. package/auth/ApiKeysManager.js +45 -0
  11. package/auth/JWTManager.js +56 -0
  12. package/core/Affirm.js +42 -0
  13. package/core/Algo.js +155 -0
  14. package/core/dste/DSTE.js +113 -0
  15. package/core/logger/DebugLogService.js +48 -0
  16. package/core/logger/DevelopmentLogService.js +70 -0
  17. package/core/logger/LocalLogService.js +70 -0
  18. package/core/logger/Logger.js +54 -0
  19. package/database/DatabaseEngine.js +119 -0
  20. package/database/DatabaseInitializer.js +80 -0
  21. package/database/DatabaseStructure.js +27 -0
  22. package/definitions/agents/DestinationDriver.js +2 -0
  23. package/definitions/agents/SourceDriver.js +2 -0
  24. package/definitions/cli.js +2 -0
  25. package/definitions/database/ApiKeys.js +2 -0
  26. package/definitions/database/Stored.js +7 -0
  27. package/definitions/database/UsageStat.js +2 -0
  28. package/definitions/database/User.js +2 -0
  29. package/definitions/json_schemas/consumer-schema.json +423 -0
  30. package/definitions/json_schemas/producer-schema.json +236 -0
  31. package/definitions/json_schemas/project-schema.json +59 -0
  32. package/definitions/json_schemas/source-schema.json +109 -0
  33. package/definitions/requests/ConsumerRequest.js +2 -0
  34. package/definitions/requests/Developer.js +2 -0
  35. package/definitions/requests/Mapping.js +2 -0
  36. package/definitions/requests/ProducerRequest.js +2 -0
  37. package/definitions/requests/Request.js +2 -0
  38. package/definitions/resources/Compiled.js +2 -0
  39. package/definitions/resources/Consumer.js +2 -0
  40. package/definitions/resources/Environment.js +2 -0
  41. package/definitions/resources/Library.js +2 -0
  42. package/definitions/resources/Producer.js +2 -0
  43. package/definitions/resources/Project.js +2 -0
  44. package/definitions/resources/Schema.js +2 -0
  45. package/definitions/resources/Source.js +2 -0
  46. package/documentation/README.md +123 -0
  47. package/documentation/default_resources/consumer.json +52 -0
  48. package/documentation/default_resources/producer.json +32 -0
  49. package/documentation/default_resources/project.json +14 -0
  50. package/documentation/default_resources/schema.json +36 -0
  51. package/documentation/default_resources/source.json +15 -0
  52. package/drivers/DriverFactory.js +56 -0
  53. package/drivers/LocalDriver.js +122 -0
  54. package/drivers/RedshiftDriver.js +179 -0
  55. package/drivers/S3Driver.js +47 -0
  56. package/drivers/S3SourceDriver.js +127 -0
  57. package/engines/CryptoEngine.js +46 -0
  58. package/engines/Environment.js +139 -0
  59. package/engines/ParseManager.js +38 -0
  60. package/engines/ProducerEngine.js +150 -0
  61. package/engines/UsageManager.js +61 -0
  62. package/engines/UserManager.js +43 -0
  63. package/engines/Validator.js +154 -0
  64. package/engines/ai/AutoMapperEngine.js +37 -0
  65. package/engines/ai/DeveloperEngine.js +70 -0
  66. package/engines/ai/LLM.js +299 -0
  67. package/engines/consumer/ConsumerEngine.js +204 -0
  68. package/engines/consumer/ConsumerManager.js +155 -0
  69. package/engines/consumer/PostProcessor.js +143 -0
  70. package/engines/deployment/DeploymentPlanner.js +46 -0
  71. package/engines/execution/ExecutionEnvironment.js +114 -0
  72. package/engines/execution/ExecutionPlanner.js +92 -0
  73. package/engines/execution/RequestExecutor.js +100 -0
  74. package/engines/file/FileCompiler.js +28 -0
  75. package/engines/file/FileExporter.js +116 -0
  76. package/engines/schema/SchemaEngine.js +33 -0
  77. package/engines/schema/SchemaValidator.js +67 -0
  78. package/engines/sql/SQLBuilder.js +96 -0
  79. package/engines/sql/SQLCompiler.js +140 -0
  80. package/engines/sql/SQLUtils.js +22 -0
  81. package/engines/validation/Validator.js +151 -0
  82. package/helper/Helper.js +64 -0
  83. package/helper/Settings.js +13 -0
  84. package/index.js +63 -0
  85. package/package.json +77 -0
package/core/Affirm.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Checks if 'value' is truthy. If not, throws an exception with custom 'msg' (if present).
5
+ */
6
+ const affirm = (value, msg) => {
7
+ if (!value)
8
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
9
+ };
10
+ affirm.hasValue = (value, msg) => {
11
+ if (value === null || value === undefined)
12
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
13
+ };
14
+ affirm.hasItems = (value, msg) => {
15
+ if (!value || !Array.isArray(value) || !(value.length > 0))
16
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
17
+ };
18
+ affirm.doesntInclude = (value, array, msg) => {
19
+ affirm(value, msg);
20
+ if (!array || !Array.isArray(array) || array.includes(value))
21
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
22
+ };
23
+ affirm.doesntExist = (item, array, key, msg) => {
24
+ affirm(item, msg);
25
+ if (!array || !Array.isArray(array) || !array.some(arrayItem => arrayItem[key] === item[key]))
26
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
27
+ };
28
+ affirm.noDupes = (array, msg) => {
29
+ if (!array || !Array.isArray(array) || new Set(array).size !== array.length)
30
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
31
+ };
32
+ affirm.noDupedItems = (array, key, msg) => {
33
+ if (!array || !Array.isArray(array))
34
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
35
+ const seen = new Set();
36
+ for (const item of array) {
37
+ if (seen.has(item[key]))
38
+ throw new Error(`Affirm failed${(msg && msg.length > 0) ? `: ${msg}` : ''}`);
39
+ seen.add(item[key]);
40
+ }
41
+ };
42
+ exports.default = affirm;
package/core/Algo.js ADDED
@@ -0,0 +1,155 @@
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
+ const Affirm_1 = __importDefault(require("./Affirm"));
7
+ /**
8
+ * Core Algorithms that are shared between different project/problems.
9
+ * This file needs to be as lean as possible and must not include any external dependencies.
10
+ */
11
+ const algo = {
12
+ hasVal: (value) => value !== null && value !== undefined,
13
+ sleep: (milliseconds) => {
14
+ (0, Affirm_1.default)(milliseconds > 0, 'Invalid @milliseconds parameter. Must be a positive number.');
15
+ return new Promise(resolve => setTimeout(resolve, milliseconds));
16
+ },
17
+ rng: (min, max) => {
18
+ (0, Affirm_1.default)(min, 'Invalid @min parameter. Must be a valid number.');
19
+ (0, Affirm_1.default)(max, 'Invalid @max parameter. Must be a valid number.');
20
+ (0, Affirm_1.default)(min < max, 'The minimum value must be less than the maximum value.');
21
+ return Math.floor(Math.random() * (max - min + 1)) + min;
22
+ },
23
+ uniqBy: (array, pk) => {
24
+ if (!array || array.length === 0)
25
+ return [];
26
+ return Array.from(new Set(array.map(x => x[pk])));
27
+ },
28
+ uniq: (array) => {
29
+ if (!array || array.length === 0)
30
+ return [];
31
+ return Array.from(new Set(array));
32
+ },
33
+ duplicatesObject: (array, pk) => {
34
+ if (!array || array.length === 0)
35
+ return [];
36
+ return array.filter(x => array.filter(k => k[pk] === x[pk]).length > 1);
37
+ },
38
+ duplicates: (array) => {
39
+ if (!array || array.length === 0)
40
+ return [];
41
+ return array.filter(x => array.filter(k => k === x).length > 1);
42
+ },
43
+ locations: (string, substring) => {
44
+ (0, Affirm_1.default)(string, 'Invalid @string parameter.');
45
+ (0, Affirm_1.default)(substring, 'Invalid @substring parameter.');
46
+ const a = [];
47
+ let i = -1;
48
+ while ((i = string.indexOf(substring, i + 1)) >= 0)
49
+ a.push(i);
50
+ return a;
51
+ },
52
+ isNumber: (value) => typeof value === 'number',
53
+ orderBy: (list, key, direction = 'asc') => {
54
+ (0, Affirm_1.default)(list, 'Invalid array.');
55
+ Affirm_1.default.hasItems(list, 'Array must be non-empty.');
56
+ (0, Affirm_1.default)(direction, 'Invalid direction parameter. Must be "asc" or "desc".');
57
+ const sortedList = [...list];
58
+ if (key) {
59
+ sortedList.sort((a, b) => {
60
+ const aValue = a[key];
61
+ const bValue = b[key];
62
+ if (aValue < bValue)
63
+ return direction === 'asc' ? -1 : 1;
64
+ if (aValue > bValue)
65
+ return direction === 'asc' ? 1 : -1;
66
+ return 0;
67
+ });
68
+ return sortedList;
69
+ }
70
+ else {
71
+ sortedList.sort((a, b) => {
72
+ if (a < b)
73
+ return direction === 'asc' ? -1 : 1;
74
+ if (a > b)
75
+ return direction === 'asc' ? 1 : -1;
76
+ return 0;
77
+ });
78
+ return sortedList;
79
+ }
80
+ },
81
+ groupBy: (array, key) => {
82
+ Affirm_1.default.hasItems(array, 'Array must be non-empty');
83
+ (0, Affirm_1.default)(key, 'key is invalid');
84
+ const result = new Map();
85
+ for (let i = 0; i < array.length; i++) {
86
+ const item = array[i];
87
+ const keyVal = item[key];
88
+ if (result.has(keyVal)) {
89
+ const current = result.get(keyVal);
90
+ current.push(item);
91
+ result.set(keyVal, current);
92
+ }
93
+ else {
94
+ result.set(keyVal, [item]);
95
+ }
96
+ }
97
+ return result;
98
+ },
99
+ chunkString: (text, chunkSize) => {
100
+ (0, Affirm_1.default)(text, 'Invalid text');
101
+ (0, Affirm_1.default)(chunkSize, 'Invalid chunk size');
102
+ (0, Affirm_1.default)(text.length > 0, 'Text length must be greater than 0');
103
+ (0, Affirm_1.default)(chunkSize > 0, 'Chunk size must be greater than 0');
104
+ if (text.length <= chunkSize)
105
+ return [text];
106
+ const numChunks = Math.ceil(text.length / chunkSize);
107
+ const chunks = new Array(numChunks);
108
+ for (let i = 0; i < chunks.length; i++) {
109
+ chunks[i] = text.substring(i * chunkSize, chunkSize);
110
+ }
111
+ return chunks;
112
+ },
113
+ first: (arr) => {
114
+ (0, Affirm_1.default)(algo.hasVal(arr), 'Array must not be null or undefined');
115
+ Affirm_1.default.hasItems(arr, 'Array must be non-empty');
116
+ return arr[0];
117
+ },
118
+ last: (arr) => {
119
+ (0, Affirm_1.default)(algo.hasVal(arr), 'Array must not be null or undefined');
120
+ (0, Affirm_1.default)(arr.length > 0, 'Array must be non-empty');
121
+ return arr[arr.length - 1];
122
+ },
123
+ mean: (numbers) => {
124
+ (0, Affirm_1.default)(algo.hasVal(numbers), 'Array must not be null or undefined');
125
+ (0, Affirm_1.default)(numbers.length > 0, 'Array must be non-empty');
126
+ const total = algo.sum(numbers);
127
+ return total / numbers.length;
128
+ },
129
+ sum: (numbers) => {
130
+ (0, Affirm_1.default)(algo.hasVal(numbers), 'Array must not be null or undefined');
131
+ (0, Affirm_1.default)(numbers.length > 0, 'Array must be non-empty');
132
+ let total = 0;
133
+ for (let i = 0; i < numbers.length; i++) {
134
+ total += numbers[i];
135
+ }
136
+ return total;
137
+ },
138
+ round: (number, precision) => {
139
+ (0, Affirm_1.default)(algo.hasVal(number), 'Number must not be null or undefined');
140
+ const factor = Math.pow(10, precision !== null && precision !== void 0 ? precision : 2);
141
+ return Math.round(number * factor) / factor;
142
+ },
143
+ min: (arr) => {
144
+ (0, Affirm_1.default)(algo.hasVal(arr), 'Array must not be null or undefined');
145
+ (0, Affirm_1.default)(arr.length > 0, 'Array must be non-empty');
146
+ return Math.min(...arr);
147
+ },
148
+ max: (arr) => {
149
+ (0, Affirm_1.default)(algo.hasVal(arr), 'Array must not be null or undefined');
150
+ (0, Affirm_1.default)(arr.length > 0, 'Array must be non-empty');
151
+ return Math.max(...arr);
152
+ },
153
+ replaceAll: (text, search, replace) => text.replace(new RegExp(search, 'g'), replace)
154
+ };
155
+ exports.default = algo;
@@ -0,0 +1,113 @@
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 __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ const child_process_1 = require("child_process");
49
+ const Affirm_1 = __importDefault(require("../Affirm"));
50
+ const fs = __importStar(require("fs"));
51
+ const path_1 = __importDefault(require("path"));
52
+ /**
53
+ * This class is used to abstract away all calls that are non-deterministic.
54
+ * As of now they just return non-deterministic values, but in the future the implementation can be easily replaced with deterministic code
55
+ */
56
+ class DeterministicSimulationTestingEngine {
57
+ constructor() {
58
+ this.init = (options) => {
59
+ (0, Affirm_1.default)(options, 'Invalid options');
60
+ this._options = options;
61
+ };
62
+ /**
63
+ * returns a random number between 0 and 1
64
+ */
65
+ this.random = () => Math.random();
66
+ this.now = () => new Date();
67
+ this.simulate = () => {
68
+ const dir = __dirname;
69
+ const root = path_1.default.join(dir, '..', '..', '..');
70
+ const folders = fs.readdirSync(root);
71
+ const testFolder = folders.find(x => x === '_tests');
72
+ if (testFolder) {
73
+ const baseCommand = `npx tsx ./${testFolder}`;
74
+ const testFiles = fs.readdirSync(testFolder);
75
+ for (let i = 0; i < testFiles.length; i++) {
76
+ const testFile = testFiles[i];
77
+ const command = `${baseCommand}/${testFile}`;
78
+ console.log('starting command', command);
79
+ const tt = (0, child_process_1.execSync)(command);
80
+ console.log('completed command', tt);
81
+ // TODO: I can't get the output back from this execution and not even the console gets logged
82
+ }
83
+ }
84
+ };
85
+ this.tests = (tests) => __awaiter(this, void 0, void 0, function* () {
86
+ const results = yield Promise.all(tests);
87
+ console.log(results.map(x => `- ${x.message}`).join('\n'));
88
+ const count = results.length;
89
+ const successCount = results.filter(x => x.success).length;
90
+ const failCount = results.filter(x => !x.success).length;
91
+ console.log(`\nTests summary:\n- test count: ${count}\n- successes: \x1b[42m${successCount}\x1b[0m\n- failures: \x1b[41m${failCount}\x1b[0m`);
92
+ });
93
+ this.test = (name, fn) => __awaiter(this, void 0, void 0, function* () {
94
+ try {
95
+ const res = yield Promise.resolve(fn());
96
+ if (!res)
97
+ return { message: `test "${name}"\x1b[41m failed.\x1b[0m`, success: false };
98
+ else
99
+ return { message: `test "${name}"\x1b[42m succeded.\x1b[0m`, success: true };
100
+ }
101
+ catch (error) {
102
+ const myerror = error;
103
+ return { message: `test "${name}"\x1b[41m crashed\x1b[0m with message: ${myerror.message}; trace: ${myerror.stack}`, success: false };
104
+ }
105
+ });
106
+ }
107
+ }
108
+ /**
109
+ * Deterministic Simulation Testing Engine
110
+ */
111
+ const DSTE = new DeterministicSimulationTestingEngine();
112
+ DSTE.init({ seed: 0 }); // this is going to bite me in the butt...
113
+ exports.default = DSTE;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class DebugLogService {
4
+ constructor() {
5
+ this.id = 'DevelopmentLogService';
6
+ this._folder = 'local_logs';
7
+ this._file = 'logs.txt';
8
+ this._path = this._folder + '/' + this._file;
9
+ this.init = () => {
10
+ return null;
11
+ };
12
+ this.log = (text) => {
13
+ try {
14
+ console.log(text);
15
+ }
16
+ catch (error) {
17
+ console.error('ERROR on log', error);
18
+ }
19
+ finally {
20
+ return null;
21
+ }
22
+ };
23
+ this.info = (text) => {
24
+ try {
25
+ console.info(text);
26
+ }
27
+ catch (error) {
28
+ console.error('ERROR on info', error);
29
+ }
30
+ finally {
31
+ return null;
32
+ }
33
+ };
34
+ this.error = (error) => {
35
+ try {
36
+ console.error(error);
37
+ }
38
+ catch (error) {
39
+ console.error('ERROR on error', error);
40
+ }
41
+ finally {
42
+ return null;
43
+ }
44
+ };
45
+ }
46
+ }
47
+ const DebugLogger = new DebugLogService();
48
+ exports.default = DebugLogger;
@@ -0,0 +1,70 @@
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
+ const fs_1 = require("fs");
7
+ const path_1 = __importDefault(require("path"));
8
+ class DevelopmentLogService {
9
+ constructor() {
10
+ this.id = 'DevelopmentLogService';
11
+ this._folder = 'local_logs';
12
+ this._file = 'logs.txt';
13
+ this._path = path_1.default.join(this._folder, this._file);
14
+ this.init = () => {
15
+ if (!(0, fs_1.existsSync)(this._folder))
16
+ (0, fs_1.mkdirSync)(this._folder);
17
+ return null;
18
+ };
19
+ this.log = (text) => {
20
+ try {
21
+ console.log(text);
22
+ this._write(text, 'LOG');
23
+ }
24
+ catch (error) {
25
+ console.error('ERROR on log', error);
26
+ }
27
+ finally {
28
+ return null;
29
+ }
30
+ };
31
+ this.info = (text) => {
32
+ try {
33
+ console.info(text);
34
+ this._write(text, 'INFO');
35
+ }
36
+ catch (error) {
37
+ console.error('ERROR on info', error);
38
+ }
39
+ finally {
40
+ return null;
41
+ }
42
+ };
43
+ this.error = (error) => {
44
+ try {
45
+ console.error(error);
46
+ this._write(error.message, 'INFO', error.name, error.stack);
47
+ }
48
+ catch (error) {
49
+ console.error('ERROR on error', error);
50
+ }
51
+ finally {
52
+ return null;
53
+ }
54
+ };
55
+ this._write = (text, level, errName, stackTrace) => {
56
+ if (!text || text.length === 0)
57
+ return;
58
+ const date = '"' + new Date().toJSON() + '"';
59
+ const sanitizedLevel = '"' + level + '"';
60
+ const sanitizedText = '"' + text.replace(new RegExp('"', 'g'), '"') + '"';
61
+ const sanitizedErrName = '"' + (errName !== null && errName !== void 0 ? errName : '') + '"';
62
+ const sanitizedStack = '"' + (stackTrace !== null && stackTrace !== void 0 ? stackTrace : '') + '"';
63
+ const line = [date, sanitizedLevel, sanitizedText, sanitizedErrName, sanitizedStack];
64
+ const sanitizedLine = line.join(',') + '\r\n';
65
+ (0, fs_1.appendFileSync)(this._path, sanitizedLine);
66
+ };
67
+ }
68
+ }
69
+ const DevelopmentLogger = new DevelopmentLogService();
70
+ exports.default = DevelopmentLogger;
@@ -0,0 +1,70 @@
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
+ const fs_1 = require("fs");
7
+ const path_1 = __importDefault(require("path"));
8
+ class LocalLogService {
9
+ constructor() {
10
+ this.id = 'DevelopmentLogService';
11
+ this._folder = 'local_logs';
12
+ this._file = 'logs.txt';
13
+ this._path = path_1.default.join(this._folder, this._file);
14
+ this.init = () => {
15
+ if (!(0, fs_1.existsSync)(this._folder))
16
+ (0, fs_1.mkdirSync)(this._folder);
17
+ return null;
18
+ };
19
+ this.log = (text) => {
20
+ try {
21
+ console.log(text);
22
+ this._write(text, 'LOG');
23
+ }
24
+ catch (error) {
25
+ console.error('ERROR on log', error);
26
+ }
27
+ finally {
28
+ return null;
29
+ }
30
+ };
31
+ this.info = (text) => {
32
+ try {
33
+ console.info(text);
34
+ this._write(text, 'INFO');
35
+ }
36
+ catch (error) {
37
+ console.error('ERROR on info', error);
38
+ }
39
+ finally {
40
+ return null;
41
+ }
42
+ };
43
+ this.error = (error) => {
44
+ try {
45
+ console.error(error);
46
+ this._write(error.message, 'INFO', error.name, error.stack);
47
+ }
48
+ catch (error) {
49
+ console.error('ERROR on error', error);
50
+ }
51
+ finally {
52
+ return null;
53
+ }
54
+ };
55
+ this._write = (text, level, errName, stackTrace) => {
56
+ if (!text || text.length === 0)
57
+ return;
58
+ const date = '"' + new Date().toJSON() + '"';
59
+ const sanitizedLevel = '"' + level + '"';
60
+ const sanitizedText = '"' + text.replace(new RegExp('"', 'g'), '"') + '"';
61
+ const sanitizedErrName = '"' + (errName !== null && errName !== void 0 ? errName : '') + '"';
62
+ const sanitizedStack = '"' + (stackTrace !== null && stackTrace !== void 0 ? stackTrace : '') + '"';
63
+ const line = [date, sanitizedLevel, sanitizedText, sanitizedErrName, sanitizedStack];
64
+ const sanitizedLine = line.join(',') + '\r\n';
65
+ (0, fs_1.appendFileSync)(this._path, sanitizedLine);
66
+ };
67
+ }
68
+ }
69
+ const LocalLogger = new LocalLogService();
70
+ exports.default = LocalLogger;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const Affirm_1 = __importDefault(require("../Affirm"));
16
+ class LoggerService {
17
+ constructor() {
18
+ this.outputs = [];
19
+ this.register = (service) => __awaiter(this, void 0, void 0, function* () {
20
+ (0, Affirm_1.default)(this.outputs, 'Unassigned outputs in logging service');
21
+ (0, Affirm_1.default)(service, 'Invalid service passed to logger.register');
22
+ (0, Affirm_1.default)(service.id, 'Invalid id used for registering new logging output service');
23
+ (0, Affirm_1.default)(!this.outputs.some(x => x.id === service.id), 'Trying to register logging output service that was already registered');
24
+ try {
25
+ yield service.init();
26
+ this.outputs.push(service);
27
+ }
28
+ catch (error) {
29
+ this.error(error);
30
+ }
31
+ });
32
+ this.isRegistered = (id) => {
33
+ (0, Affirm_1.default)(this.outputs, 'Unassigned outputs in logging service');
34
+ (0, Affirm_1.default)(id, 'Invalid id used for checking if logging output service is registered');
35
+ return this.outputs.some(x => x.id === id);
36
+ };
37
+ this.log = (text) => {
38
+ this.outputs.forEach(x => x.log(text));
39
+ };
40
+ this.info = (text) => {
41
+ this.outputs.forEach(x => x.info(text));
42
+ };
43
+ this.error = (error) => {
44
+ if (error instanceof Error)
45
+ this.outputs.forEach(x => x.error(error));
46
+ else if (typeof error === 'string')
47
+ this.outputs.forEach(x => x.error(new Error(error)));
48
+ else
49
+ this.outputs.forEach(x => x.error(new Error(error)));
50
+ };
51
+ }
52
+ }
53
+ const logger = new LoggerService();
54
+ exports.default = logger;
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const mongodb_1 = require("mongodb");
16
+ const Settings_1 = __importDefault(require("../helper/Settings"));
17
+ const Helper_1 = __importDefault(require("../helper/Helper"));
18
+ class DatabaseEngineClass {
19
+ constructor() {
20
+ this.MAX_TRY_CONNECTION = 3;
21
+ this.db = () => this._db;
22
+ this.connect = () => __awaiter(this, void 0, void 0, function* () {
23
+ const errors = [];
24
+ for (let i = 0; i < this.MAX_TRY_CONNECTION; i++) {
25
+ if (i < this.MAX_TRY_CONNECTION) {
26
+ try {
27
+ yield this._client.connect();
28
+ this._db = this._client.db(Settings_1.default.db.name);
29
+ console.log('Connected to MongoDB');
30
+ break;
31
+ }
32
+ catch (error) {
33
+ errors.push(i + '° connection to MongoDB throws this error:', error);
34
+ }
35
+ }
36
+ else {
37
+ console.error(`Despite several ${i} retries it was not possible to connect to mongoDb, these are the errors encountered:\n` + errors.join('\n'));
38
+ }
39
+ }
40
+ });
41
+ this.disconnect = () => __awaiter(this, void 0, void 0, function* () {
42
+ try {
43
+ yield this._client.close();
44
+ console.log('Disconnected from MongoDB');
45
+ }
46
+ catch (error) {
47
+ console.error('Error disconnecting from MongoDB:', error);
48
+ }
49
+ });
50
+ this.query = (collectionName, query) => __awaiter(this, void 0, void 0, function* () {
51
+ try {
52
+ const collection = this._db.collection(collectionName);
53
+ const result = yield collection.find(query).toArray();
54
+ return result;
55
+ }
56
+ catch (error) {
57
+ console.error('Error getting documents:', error);
58
+ throw error;
59
+ }
60
+ });
61
+ this.get = (collectionName, id) => __awaiter(this, void 0, void 0, function* () {
62
+ try {
63
+ const collection = this._db.collection(collectionName);
64
+ return yield collection.findOne({ _id: id });
65
+ }
66
+ catch (error) {
67
+ console.error('Error finding document by ID:', error);
68
+ throw error;
69
+ }
70
+ });
71
+ this.findOne = (collectionName, query) => __awaiter(this, void 0, void 0, function* () {
72
+ try {
73
+ const collection = this._db.collection(collectionName);
74
+ return yield collection.findOne(query);
75
+ }
76
+ catch (error) {
77
+ console.error('Error finding one document:', error);
78
+ throw error;
79
+ }
80
+ });
81
+ this.upsert = (collectionName, id, update) => __awaiter(this, void 0, void 0, function* () {
82
+ try {
83
+ const collection = this._db.collection(collectionName);
84
+ const result = yield collection.findOneAndUpdate({ _id: id }, { $set: update }, { upsert: true, returnDocument: 'after' });
85
+ return result;
86
+ }
87
+ catch (error) {
88
+ console.error('Error upserting document:', error);
89
+ throw error;
90
+ }
91
+ });
92
+ this.addToList = (collectionName, id, arrayField, arrayItem) => __awaiter(this, void 0, void 0, function* () {
93
+ try {
94
+ const collection = this._db.collection(collectionName);
95
+ const result = yield collection.findOneAndUpdate({ _id: id }, { $push: { [arrayField]: arrayItem } }, { returnDocument: 'after' });
96
+ return result;
97
+ }
98
+ catch (error) {
99
+ console.error('Error adding item to list:', error);
100
+ throw error;
101
+ }
102
+ });
103
+ this.doUpdate = (collectionName, id, update) => __awaiter(this, void 0, void 0, function* () {
104
+ try {
105
+ const collection = this._db.collection(collectionName);
106
+ const result = yield collection.findOneAndUpdate({ _id: id }, update, { returnDocument: 'after' });
107
+ return result;
108
+ }
109
+ catch (error) {
110
+ console.error('Error adding item to list:', error);
111
+ throw error;
112
+ }
113
+ });
114
+ const uri = Helper_1.default.isDev() ? 'mongodb://mongo:27017/remora' : 'mongodb://localhost:27017/remora';
115
+ this._client = new mongodb_1.MongoClient(uri);
116
+ }
117
+ }
118
+ const DatabaseEngine = new DatabaseEngineClass();
119
+ exports.default = DatabaseEngine;