@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.
- package/Constants.js +8 -0
- package/actions/automap.js +73 -0
- package/actions/compile.js +57 -0
- package/actions/debug.js +61 -0
- package/actions/deploy.js +95 -0
- package/actions/discover.js +36 -0
- package/actions/init.js +78 -0
- package/actions/run.js +51 -0
- package/auth/AdminManager.js +48 -0
- package/auth/ApiKeysManager.js +45 -0
- package/auth/JWTManager.js +56 -0
- package/core/Affirm.js +42 -0
- package/core/Algo.js +155 -0
- package/core/dste/DSTE.js +113 -0
- package/core/logger/DebugLogService.js +48 -0
- package/core/logger/DevelopmentLogService.js +70 -0
- package/core/logger/LocalLogService.js +70 -0
- package/core/logger/Logger.js +54 -0
- package/database/DatabaseEngine.js +119 -0
- package/database/DatabaseInitializer.js +80 -0
- package/database/DatabaseStructure.js +27 -0
- package/definitions/agents/DestinationDriver.js +2 -0
- package/definitions/agents/SourceDriver.js +2 -0
- package/definitions/cli.js +2 -0
- package/definitions/database/ApiKeys.js +2 -0
- package/definitions/database/Stored.js +7 -0
- package/definitions/database/UsageStat.js +2 -0
- package/definitions/database/User.js +2 -0
- package/definitions/json_schemas/consumer-schema.json +423 -0
- package/definitions/json_schemas/producer-schema.json +236 -0
- package/definitions/json_schemas/project-schema.json +59 -0
- package/definitions/json_schemas/source-schema.json +109 -0
- package/definitions/requests/ConsumerRequest.js +2 -0
- package/definitions/requests/Developer.js +2 -0
- package/definitions/requests/Mapping.js +2 -0
- package/definitions/requests/ProducerRequest.js +2 -0
- package/definitions/requests/Request.js +2 -0
- package/definitions/resources/Compiled.js +2 -0
- package/definitions/resources/Consumer.js +2 -0
- package/definitions/resources/Environment.js +2 -0
- package/definitions/resources/Library.js +2 -0
- package/definitions/resources/Producer.js +2 -0
- package/definitions/resources/Project.js +2 -0
- package/definitions/resources/Schema.js +2 -0
- package/definitions/resources/Source.js +2 -0
- package/documentation/README.md +123 -0
- package/documentation/default_resources/consumer.json +52 -0
- package/documentation/default_resources/producer.json +32 -0
- package/documentation/default_resources/project.json +14 -0
- package/documentation/default_resources/schema.json +36 -0
- package/documentation/default_resources/source.json +15 -0
- package/drivers/DriverFactory.js +56 -0
- package/drivers/LocalDriver.js +122 -0
- package/drivers/RedshiftDriver.js +179 -0
- package/drivers/S3Driver.js +47 -0
- package/drivers/S3SourceDriver.js +127 -0
- package/engines/CryptoEngine.js +46 -0
- package/engines/Environment.js +139 -0
- package/engines/ParseManager.js +38 -0
- package/engines/ProducerEngine.js +150 -0
- package/engines/UsageManager.js +61 -0
- package/engines/UserManager.js +43 -0
- package/engines/Validator.js +154 -0
- package/engines/ai/AutoMapperEngine.js +37 -0
- package/engines/ai/DeveloperEngine.js +70 -0
- package/engines/ai/LLM.js +299 -0
- package/engines/consumer/ConsumerEngine.js +204 -0
- package/engines/consumer/ConsumerManager.js +155 -0
- package/engines/consumer/PostProcessor.js +143 -0
- package/engines/deployment/DeploymentPlanner.js +46 -0
- package/engines/execution/ExecutionEnvironment.js +114 -0
- package/engines/execution/ExecutionPlanner.js +92 -0
- package/engines/execution/RequestExecutor.js +100 -0
- package/engines/file/FileCompiler.js +28 -0
- package/engines/file/FileExporter.js +116 -0
- package/engines/schema/SchemaEngine.js +33 -0
- package/engines/schema/SchemaValidator.js +67 -0
- package/engines/sql/SQLBuilder.js +96 -0
- package/engines/sql/SQLCompiler.js +140 -0
- package/engines/sql/SQLUtils.js +22 -0
- package/engines/validation/Validator.js +151 -0
- package/helper/Helper.js +64 -0
- package/helper/Settings.js +13 -0
- package/index.js +63 -0
- package/package.json +77 -0
package/Constants.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
exports.automap = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const compile_1 = require("./compile");
|
|
19
|
+
const AutoMapperEngine_1 = __importDefault(require("../engines/ai/AutoMapperEngine"));
|
|
20
|
+
const fs_1 = __importDefault(require("fs"));
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
const Environment_1 = __importDefault(require("../engines/Environment"));
|
|
23
|
+
const ProducerEngine_1 = __importDefault(require("../engines/ProducerEngine"));
|
|
24
|
+
/**
|
|
25
|
+
* e.g. npm run automap -- myclaims Claim
|
|
26
|
+
*/
|
|
27
|
+
const automap = (producerName, schemaNames) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
try {
|
|
29
|
+
(0, compile_1.compile)();
|
|
30
|
+
const spinner = (0, ora_1.default)(chalk_1.default.blue('Auto-mapping producer data...\n')).start();
|
|
31
|
+
// Get the producer
|
|
32
|
+
const producer = Environment_1.default.getProducer(producerName);
|
|
33
|
+
if (!producer) {
|
|
34
|
+
throw new Error(`Producer ${producerName} not found`);
|
|
35
|
+
}
|
|
36
|
+
// Get the specified schemas
|
|
37
|
+
const schemas = [];
|
|
38
|
+
for (const schemaName of schemaNames) {
|
|
39
|
+
const schema = Environment_1.default.getSchema(schemaName);
|
|
40
|
+
if (!schema) {
|
|
41
|
+
throw new Error(`Schema ${schemaName} not found`);
|
|
42
|
+
}
|
|
43
|
+
schemas.push(schema);
|
|
44
|
+
}
|
|
45
|
+
// Read and convert sample data
|
|
46
|
+
const sampleData = yield ProducerEngine_1.default.readSampleData(producer);
|
|
47
|
+
// Convert sample data to strings for AutoMapperEngine
|
|
48
|
+
const sampleStrings = sampleData.map(item => JSON.stringify(item));
|
|
49
|
+
// Call the automapper
|
|
50
|
+
const mapResult = yield AutoMapperEngine_1.default.map(sampleStrings, schemas);
|
|
51
|
+
// Create the producers based on the mapping
|
|
52
|
+
for (const producer of mapResult.producers) {
|
|
53
|
+
const producerPath = path_1.default.join('remora/producers', `${producer.name}.json`);
|
|
54
|
+
fs_1.default.writeFileSync(producerPath, JSON.stringify(producer, null, 4));
|
|
55
|
+
console.log(chalk_1.default.blue(`Created producer: ${producer.name}`));
|
|
56
|
+
}
|
|
57
|
+
// Create the consumers based on the mapping
|
|
58
|
+
for (const consumer of mapResult.consumers) {
|
|
59
|
+
const consumerPath = path_1.default.join('remora/consumers', `${consumer.name}.json`);
|
|
60
|
+
fs_1.default.writeFileSync(consumerPath, JSON.stringify(consumer, null, 4));
|
|
61
|
+
console.log(chalk_1.default.blue(`Created consumer: ${consumer.name}`));
|
|
62
|
+
}
|
|
63
|
+
spinner.succeed('Producer has been successfully mapped');
|
|
64
|
+
console.log(chalk_1.default.green(`\n✅ Created ${mapResult.producers.length} producers!`));
|
|
65
|
+
console.log(chalk_1.default.green(`✅ Created ${mapResult.consumers.length} consumers!`));
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
console.error(chalk_1.default.red.bold('\n❌ Unexpected error during automapping:'), err instanceof Error ? err.message : String(err));
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
exports.automap = automap;
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
exports.compile = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
18
|
+
const ora_1 = __importDefault(require("ora"));
|
|
19
|
+
const Environment_1 = __importDefault(require("../engines/Environment"));
|
|
20
|
+
const compile = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
// TODO compile single file
|
|
22
|
+
let errors = [];
|
|
23
|
+
try {
|
|
24
|
+
const spinner = (0, ora_1.default)(chalk_1.default.blue('Validating project structure...')).start();
|
|
25
|
+
Environment_1.default.load('');
|
|
26
|
+
if (!fs_extra_1.default.existsSync('./remora'))
|
|
27
|
+
errors.push(chalk_1.default.red('Missing directory: ') + chalk_1.default.yellow('./remora'));
|
|
28
|
+
if (!fs_extra_1.default.existsSync('./remora/consumers'))
|
|
29
|
+
errors.push(chalk_1.default.red('Missing directory: ') + chalk_1.default.yellow('./remora/consumers'));
|
|
30
|
+
if (!fs_extra_1.default.existsSync('./remora/producers'))
|
|
31
|
+
errors.push(chalk_1.default.red('Missing directory: ') + chalk_1.default.yellow('./remora/producers'));
|
|
32
|
+
if (!fs_extra_1.default.existsSync('./remora/producers'))
|
|
33
|
+
errors.push(chalk_1.default.red('Missing directory: ') + chalk_1.default.yellow('./remora/producers'));
|
|
34
|
+
if (!fs_extra_1.default.existsSync('./remora/sources'))
|
|
35
|
+
errors.push(chalk_1.default.red('Missing directory: ') + chalk_1.default.yellow('./remora/sources'));
|
|
36
|
+
if (!fs_extra_1.default.existsSync('./remora/schemas'))
|
|
37
|
+
errors.push(chalk_1.default.red('Missing directory: ') + chalk_1.default.yellow('./remora/schemas'));
|
|
38
|
+
const envErrors = Environment_1.default.validate();
|
|
39
|
+
errors = [...errors, ...envErrors];
|
|
40
|
+
if (errors.length === 0) {
|
|
41
|
+
spinner.succeed(chalk_1.default.green('Project structure validated successfully'));
|
|
42
|
+
console.log(chalk_1.default.green.bold('\n✅ Compilation complete!'));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
spinner.fail(chalk_1.default.red('Validation failed with errors:'));
|
|
46
|
+
console.log('');
|
|
47
|
+
errors.forEach(error => console.log(chalk_1.default.red('• ' + error)));
|
|
48
|
+
console.log(chalk_1.default.red.bold('\n❌ Compilation aborted due to errors.'));
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
console.error(chalk_1.default.red.bold('\n❌ Unexpected error during validation:'), err instanceof Error ? err.message : String(err));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
exports.compile = compile;
|
package/actions/debug.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
exports.debug = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const DriverFactory_1 = __importDefault(require("../drivers/DriverFactory"));
|
|
19
|
+
const Environment_1 = __importDefault(require("../engines/Environment"));
|
|
20
|
+
const compile_1 = require("./compile");
|
|
21
|
+
const debug = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
try {
|
|
23
|
+
(0, compile_1.compile)();
|
|
24
|
+
console.log('\n');
|
|
25
|
+
const spinner = (0, ora_1.default)({ text: '⏳ Checking producers connections...', color: 'blue' }).start();
|
|
26
|
+
const producers = Environment_1.default._env.producers;
|
|
27
|
+
const failures = [];
|
|
28
|
+
for (const producer of producers) {
|
|
29
|
+
spinner.text = `🔍 Testing producer "${producer.name}" (source: ${producer.source})`;
|
|
30
|
+
const source = Environment_1.default.getSource(producer.source);
|
|
31
|
+
const driver = yield DriverFactory_1.default.instantiateSource(source);
|
|
32
|
+
const canConnect = yield driver.exist(producer);
|
|
33
|
+
if (canConnect) {
|
|
34
|
+
spinner.succeed(`Producer "${producer.name}" connected successfully.`);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
spinner.fail(chalk_1.default.red(`✖ Producer "${producer.name}" failed to connect.`));
|
|
38
|
+
failures.push(producer.name);
|
|
39
|
+
}
|
|
40
|
+
// Avoid restarting the spinner unless needed
|
|
41
|
+
if (producer !== producers[producers.length - 1]) {
|
|
42
|
+
spinner.start();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (failures.length > 0) {
|
|
46
|
+
console.log(chalk_1.default.red.bold(`\n‼ ${failures.length} producer(s) could not connect:`));
|
|
47
|
+
failures.forEach(name => console.log(chalk_1.default.yellow(` • ${name}`)));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Stop spinner silently (no ✔ line)
|
|
52
|
+
spinner.stop();
|
|
53
|
+
console.log(chalk_1.default.green.bold('\n🎉 All producers are up and running!'));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
console.error(chalk_1.default.red.bold('\n❌ Unexpected error during debug:'), err instanceof Error ? err.message : String(err));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
exports.debug = debug;
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
exports.deploy = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const fs_1 = __importDefault(require("fs"));
|
|
18
|
+
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const Constants_1 = __importDefault(require("../Constants"));
|
|
21
|
+
const deploy = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
console.log(chalk_1.default.blue.bold(`🚀 Deploying to ${options.env}...`));
|
|
23
|
+
try {
|
|
24
|
+
const rootDir = './remora';
|
|
25
|
+
if (!fs_1.default.existsSync('./remora'))
|
|
26
|
+
throw new Error(chalk_1.default.red('Missing directory: ') + chalk_1.default.yellow('./remora'));
|
|
27
|
+
const zip = new adm_zip_1.default();
|
|
28
|
+
// Function to recursively add files to zip
|
|
29
|
+
const addDirectoryToZip = (directoryPath, zipPath = '') => {
|
|
30
|
+
const files = fs_1.default.readdirSync(directoryPath);
|
|
31
|
+
files.forEach(file => {
|
|
32
|
+
const fullPath = path_1.default.join(directoryPath, file);
|
|
33
|
+
const stat = fs_1.default.statSync(fullPath);
|
|
34
|
+
if (file === 'temp')
|
|
35
|
+
return;
|
|
36
|
+
if (stat.isDirectory()) {
|
|
37
|
+
addDirectoryToZip(fullPath, path_1.default.join(zipPath, file));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const fileContent = fs_1.default.readFileSync(fullPath);
|
|
41
|
+
zip.addFile(path_1.default.join(zipPath, file), fileContent);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
addDirectoryToZip(rootDir);
|
|
46
|
+
// Write the zip file to a temporary location
|
|
47
|
+
const tempZipPath = path_1.default.join(process.cwd(), 'temp_deployment.zip');
|
|
48
|
+
zip.writeZipPromise(tempZipPath)
|
|
49
|
+
.then(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
try {
|
|
51
|
+
// Read the zip file as a buffer
|
|
52
|
+
const zipBuffer = fs_1.default.readFileSync(tempZipPath);
|
|
53
|
+
const host = process.env.REMORA_WORKER_HOST;
|
|
54
|
+
const version = Constants_1.default.lambdaVersion;
|
|
55
|
+
const workerAPI = `${host}/cli/v${version}/uploaddeployment`;
|
|
56
|
+
const formData = new FormData();
|
|
57
|
+
const blob = new Blob([zipBuffer], { type: 'application/zip' });
|
|
58
|
+
formData.append('remora_config', blob, 'temp_deployment.zip'); // Updated to match the actual file name
|
|
59
|
+
const apiKey = process.env.REMORA_LICENCE_KEY;
|
|
60
|
+
if (!apiKey)
|
|
61
|
+
throw new Error('REMORA_LICENCE_KEY environment variable is not set');
|
|
62
|
+
console.log('workerAPI', workerAPI);
|
|
63
|
+
const response = yield fetch(workerAPI, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
Authorization: `Bearer ${apiKey}`
|
|
67
|
+
},
|
|
68
|
+
body: formData
|
|
69
|
+
});
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
throw new Error(`Upload failed with status ${response.status}: ${yield response.text()}`);
|
|
72
|
+
}
|
|
73
|
+
console.log(chalk_1.default.green('✅ Deployment package uploaded successfully'));
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
// Clean up the temporary zip file
|
|
77
|
+
fs_1.default.unlinkSync(tempZipPath);
|
|
78
|
+
}
|
|
79
|
+
}))
|
|
80
|
+
.catch(error => {
|
|
81
|
+
throw error;
|
|
82
|
+
});
|
|
83
|
+
// TODO
|
|
84
|
+
// Check if exist remora worker
|
|
85
|
+
// if not pull remora image and doker compose up
|
|
86
|
+
// compile
|
|
87
|
+
// upload configuration into rw
|
|
88
|
+
// create consumers tath require creation ( view, materialized view )
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error(chalk_1.default.red('❌ Deployment error:'), error instanceof Error ? error.message : String(error));
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
exports.deploy = deploy;
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
exports.discover = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const Environment_1 = __importDefault(require("../engines/Environment"));
|
|
19
|
+
const compile_1 = require("./compile");
|
|
20
|
+
const DeveloperEngine_1 = __importDefault(require("../engines/ai/DeveloperEngine"));
|
|
21
|
+
const discover = (producerName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
try {
|
|
23
|
+
(0, compile_1.compile)();
|
|
24
|
+
const spinner = (0, ora_1.default)(chalk_1.default.blue('Discovering producer...\n')).start();
|
|
25
|
+
const producer = Environment_1.default.getProducer(producerName);
|
|
26
|
+
yield DeveloperEngine_1.default.discover(producer);
|
|
27
|
+
spinner.succeed('Producer has been successfully discovered');
|
|
28
|
+
console.log(chalk_1.default.green('\n✅ Discovery complete!'));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
console.error(chalk_1.default.red.bold('\n❌ Unexpected error during discover:'), err instanceof Error ? err.message : String(err));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
exports.discover = discover;
|
package/actions/init.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
exports.init = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
18
|
+
const ora_1 = __importDefault(require("ora"));
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const init = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
// TODO init single folder
|
|
22
|
+
console.log(chalk_1.default.blue.bold('📦 Initializing your application...'));
|
|
23
|
+
try {
|
|
24
|
+
const spinner = (0, ora_1.default)('Creating configuration files...').start();
|
|
25
|
+
const directories = [
|
|
26
|
+
'remora',
|
|
27
|
+
'remora/consumers',
|
|
28
|
+
'remora/producers',
|
|
29
|
+
'remora/schemas',
|
|
30
|
+
'remora/sources'
|
|
31
|
+
];
|
|
32
|
+
const defaultSource = fs_extra_1.default.readFileSync(path_1.default.join(__dirname, `../documentation/default_resources/source.json`), 'utf-8');
|
|
33
|
+
const defaultConsumer = fs_extra_1.default.readFileSync(path_1.default.join(__dirname, `../documentation/default_resources/consumer.json`), 'utf-8');
|
|
34
|
+
const defaultProducer = fs_extra_1.default.readFileSync(path_1.default.join(__dirname, `../documentation/default_resources/producer.json`), 'utf-8');
|
|
35
|
+
const defaultSchema = fs_extra_1.default.readFileSync(path_1.default.join(__dirname, `../documentation/default_resources/schema.json`), 'utf-8');
|
|
36
|
+
const defaultRemoraProject = fs_extra_1.default.readFileSync(path_1.default.join(__dirname, `../documentation/default_resources/project.json`), 'utf-8');
|
|
37
|
+
const readme = fs_extra_1.default.readFileSync(path_1.default.join(__dirname, `../documentation/README.md`), 'utf-8');
|
|
38
|
+
const files = [
|
|
39
|
+
{ path: 'remora/sources/.gitkeep', content: '' },
|
|
40
|
+
{ path: 'remora/sources/default-source.json', content: defaultSource },
|
|
41
|
+
{ path: 'remora/consumers/.gitkeep', content: '' },
|
|
42
|
+
{ path: 'remora/consumers/default-consumer.json', content: defaultConsumer },
|
|
43
|
+
{ path: 'remora/producers/.gitkeep', content: '' },
|
|
44
|
+
{ path: 'remora/producers/default-producer.json', content: defaultProducer },
|
|
45
|
+
{ path: 'remora/schemas/.gitkeep', content: '' },
|
|
46
|
+
{ path: 'remora/schemas/default-schemas.json', content: defaultSchema },
|
|
47
|
+
{ path: 'remora/project.json', content: defaultRemoraProject },
|
|
48
|
+
{ path: 'remora/README.md', content: readme }
|
|
49
|
+
];
|
|
50
|
+
for (let i = 0; i < directories.length; i++) {
|
|
51
|
+
const dir = directories[i];
|
|
52
|
+
yield fs_extra_1.default.ensureDir(dir);
|
|
53
|
+
}
|
|
54
|
+
for (let i = 0; i < files.length; i++) {
|
|
55
|
+
const file = files[i];
|
|
56
|
+
yield fs_extra_1.default.ensureFile(file.path);
|
|
57
|
+
yield fs_extra_1.default.writeFile(file.path, file.content);
|
|
58
|
+
}
|
|
59
|
+
spinner.succeed('Remora configuration files successfully created.');
|
|
60
|
+
console.log(chalk_1.default.green('✅ Initialization complete!'));
|
|
61
|
+
console.log(chalk_1.default.green('📁 A new folder named ') + chalk_1.default.cyan('remora/') + chalk_1.default.green(' has been created in your project.'));
|
|
62
|
+
console.log(chalk_1.default.green('✏️ Customize the generated configuration files inside this folder to setup Remora.'));
|
|
63
|
+
console.log(chalk_1.default.green('\n👣 Next steps: configure your environment variables.'));
|
|
64
|
+
console.log(chalk_1.default.green('\n🔧 Local development (add these to your .env file):'));
|
|
65
|
+
console.log(chalk_1.default.blue('• REMORA_WORKER_HOST') + chalk_1.default.gray(' → URL of your Remora Worker instance'));
|
|
66
|
+
console.log(chalk_1.default.blue('• REMORA_LICENCE_KEY') + chalk_1.default.gray(' → Your valid Remora license key'));
|
|
67
|
+
console.log(chalk_1.default.green('\n🔐 Production environment (store these in your Secret Manager):'));
|
|
68
|
+
console.log(chalk_1.default.yellow('• ROOT_TEMP_PASSWORD') + chalk_1.default.gray(' → Temporary root password for first-time setup'));
|
|
69
|
+
console.log(chalk_1.default.yellow('• INSTALLATION_ID') + chalk_1.default.gray(' → Unique ID for this installation instance'));
|
|
70
|
+
console.log(chalk_1.default.yellow('• ADMIN_JWT_SECRET') + chalk_1.default.gray(' → JWT secret for admin-level access'));
|
|
71
|
+
console.log(chalk_1.default.yellow('• JWT_SECRET') + chalk_1.default.gray(' → JWT secret for regular user authentication'));
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error(chalk_1.default.red('❌ Error during initialization:'), error instanceof Error ? error.message : String(error));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
exports.init = init;
|
package/actions/run.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
exports.run = void 0;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const Environment_1 = __importDefault(require("../engines/Environment"));
|
|
19
|
+
const UserManager_1 = __importDefault(require("../engines/UserManager"));
|
|
20
|
+
const ConsumerEngine_1 = __importDefault(require("../engines/consumer/ConsumerEngine"));
|
|
21
|
+
const compile_1 = require("./compile");
|
|
22
|
+
const run = (options, consumersName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
+
try {
|
|
24
|
+
(0, compile_1.compile)();
|
|
25
|
+
const spinner = (0, ora_1.default)(chalk_1.default.blue('Run Consumers...\n')).start();
|
|
26
|
+
const consumersToExecute = (consumersName && consumersName.length > 0) ? [Environment_1.default.getConsumer(consumersName)] : Environment_1.default._env.consumers;
|
|
27
|
+
const user = UserManager_1.default.getUser();
|
|
28
|
+
const results = [];
|
|
29
|
+
for (let i = 0; i < consumersToExecute.length; i++) {
|
|
30
|
+
const consumer = consumersToExecute[i];
|
|
31
|
+
const response = yield ConsumerEngine_1.default.execute(consumer, {}, user);
|
|
32
|
+
results.push({ consumer, response });
|
|
33
|
+
}
|
|
34
|
+
spinner.succeed('All consumers have been successfully executed');
|
|
35
|
+
results.forEach(result => {
|
|
36
|
+
if (result.response.fileUri) {
|
|
37
|
+
console.log(chalk_1.default.green(`• Consumer ${result.consumer.name} -> ${result.response.fileUri}`));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.log(chalk_1.default.green(`• Consumer ${result.consumer.name} -> ${result.response.data.slice(0, 5).join('\n')}`));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
console.log(chalk_1.default.green('\n✅ Initialization complete!'));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.error(chalk_1.default.red.bold('\n❌ Unexpected error during run:'), err instanceof Error ? err.message : String(err));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
exports.run = run;
|
|
@@ -0,0 +1,48 @@
|
|
|
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("../core/Affirm"));
|
|
16
|
+
const DatabaseEngine_1 = __importDefault(require("../database/DatabaseEngine"));
|
|
17
|
+
const UserManager_1 = __importDefault(require("../engines/UserManager"));
|
|
18
|
+
const Settings_1 = __importDefault(require("../helper/Settings"));
|
|
19
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
20
|
+
const JWTManager_1 = __importDefault(require("./JWTManager"));
|
|
21
|
+
class AdminManagerClass {
|
|
22
|
+
constructor() {
|
|
23
|
+
this.COLLECTION = Settings_1.default.db.collections.users;
|
|
24
|
+
this.rootSignIn = (password) => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
(0, Affirm_1.default)(password, 'Invalid password');
|
|
26
|
+
const rootUser = yield DatabaseEngine_1.default.findOne(this.COLLECTION, { isRoot: true });
|
|
27
|
+
(0, Affirm_1.default)(rootUser, 'Incorrect system configuration: root user not found');
|
|
28
|
+
const isSame = yield bcryptjs_1.default.compare(password, rootUser.rootPasswordHash);
|
|
29
|
+
if (!isSame)
|
|
30
|
+
throw new Error('Invalid credentials');
|
|
31
|
+
rootUser.lastLogin = new Date().toJSON();
|
|
32
|
+
yield UserManager_1.default.update(rootUser);
|
|
33
|
+
const adminSecret = process.env.ADMIN_JWT_SECRET;
|
|
34
|
+
(0, Affirm_1.default)(adminSecret, 'Wrong system config: missing admin jwt secret');
|
|
35
|
+
const payload = {
|
|
36
|
+
apiKeyId: rootUser._id,
|
|
37
|
+
installationId: process.env.INSTALLATION_ID,
|
|
38
|
+
name: rootUser.name,
|
|
39
|
+
scopes: { consumers: ['*'], projects: ['*'] },
|
|
40
|
+
isAdmin: true
|
|
41
|
+
};
|
|
42
|
+
const token = JWTManager_1.default.issue(adminSecret, payload, 8);
|
|
43
|
+
return token;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const AdminManager = new AdminManagerClass();
|
|
48
|
+
exports.default = AdminManager;
|
|
@@ -0,0 +1,45 @@
|
|
|
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("../core/Affirm"));
|
|
16
|
+
const DatabaseEngine_1 = __importDefault(require("../database/DatabaseEngine"));
|
|
17
|
+
const Helper_1 = __importDefault(require("../helper/Helper"));
|
|
18
|
+
const Settings_1 = __importDefault(require("../helper/Settings"));
|
|
19
|
+
const JWTManager_1 = __importDefault(require("./JWTManager"));
|
|
20
|
+
class ApiKeysManagerClass {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.COLLECTION = Settings_1.default.db.collections.apiKeys;
|
|
23
|
+
this.create = (name, scopes) => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
(0, Affirm_1.default)(name, 'Invalid name');
|
|
25
|
+
const apiKeyId = Helper_1.default.uuid();
|
|
26
|
+
const apiSecret = JWTManager_1.default.sign(apiKeyId, name, scopes);
|
|
27
|
+
const newApiKey = {
|
|
28
|
+
_id: apiKeyId,
|
|
29
|
+
_signature: '',
|
|
30
|
+
createdAt: new Date().toJSON(),
|
|
31
|
+
isActive: true,
|
|
32
|
+
name: name,
|
|
33
|
+
scopes: scopes,
|
|
34
|
+
value: apiSecret
|
|
35
|
+
};
|
|
36
|
+
return yield DatabaseEngine_1.default.upsert(this.COLLECTION, newApiKey._id, newApiKey);
|
|
37
|
+
});
|
|
38
|
+
this.get = (apiKeyId) => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
(0, Affirm_1.default)(apiKeyId, 'Invalid api key id');
|
|
40
|
+
return yield DatabaseEngine_1.default.get(this.COLLECTION, apiKeyId);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const ApiKeysManager = new ApiKeysManagerClass();
|
|
45
|
+
exports.default = ApiKeysManager;
|
|
@@ -0,0 +1,56 @@
|
|
|
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 jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
7
|
+
const Affirm_1 = __importDefault(require("../core/Affirm"));
|
|
8
|
+
//
|
|
9
|
+
class JWTManagerClass {
|
|
10
|
+
constructor() {
|
|
11
|
+
// ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!!⚠️ ATTENTION!!
|
|
12
|
+
// ATTENTION!! The remoteSecretKey is saved in CLEAR text because we are studying a way to not make it visible to the customer. ATTENTION!!
|
|
13
|
+
// ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!! ⚠️ ATTENTION!!⚠️ ATTENTION!!
|
|
14
|
+
this.remoraSecretKey = 'violetevergardenisaworkofart';
|
|
15
|
+
this.issue = (secret, payload, expirationHours) => {
|
|
16
|
+
return jsonwebtoken_1.default.sign(payload, secret, { expiresIn: `${expirationHours}h` });
|
|
17
|
+
};
|
|
18
|
+
this.sign = (apiKeyId, name, scopes) => {
|
|
19
|
+
(0, Affirm_1.default)(apiKeyId, 'Invalid api key id');
|
|
20
|
+
(0, Affirm_1.default)(name, 'Invalid name');
|
|
21
|
+
(0, Affirm_1.default)(scopes, 'Invalid scopes');
|
|
22
|
+
const JWT_SECRET = process.env.JWT_SECRET;
|
|
23
|
+
const INSTALLATION_ID = process.env.INSTALLATION_ID;
|
|
24
|
+
(0, Affirm_1.default)(JWT_SECRET, 'Invalid JWT SECRET');
|
|
25
|
+
(0, Affirm_1.default)(INSTALLATION_ID, 'Invalid INSTALLATION ID');
|
|
26
|
+
const payload = {
|
|
27
|
+
apiKeyId: apiKeyId,
|
|
28
|
+
installationId: INSTALLATION_ID,
|
|
29
|
+
name: name,
|
|
30
|
+
scopes: scopes
|
|
31
|
+
};
|
|
32
|
+
return jsonwebtoken_1.default.sign(payload, JWT_SECRET, { expiresIn: '365000d' });
|
|
33
|
+
};
|
|
34
|
+
this.verify = (token) => {
|
|
35
|
+
(0, Affirm_1.default)(token, 'Invalid token');
|
|
36
|
+
const JWT_SECRET = process.env.JWT_SECRET;
|
|
37
|
+
(0, Affirm_1.default)(JWT_SECRET, 'Invalid JWT SECRET');
|
|
38
|
+
return jsonwebtoken_1.default.verify(token, JWT_SECRET);
|
|
39
|
+
};
|
|
40
|
+
this.verifyAdmin = (token) => {
|
|
41
|
+
(0, Affirm_1.default)(token, 'Invalid token');
|
|
42
|
+
const ADMIN_JWT_SECRET = process.env.ADMIN_JWT_SECRET;
|
|
43
|
+
(0, Affirm_1.default)(ADMIN_JWT_SECRET, 'Invalid ADMIN JWT SECRET');
|
|
44
|
+
return jsonwebtoken_1.default.verify(token, ADMIN_JWT_SECRET);
|
|
45
|
+
};
|
|
46
|
+
this.verifyCLI = (token) => {
|
|
47
|
+
(0, Affirm_1.default)(token, 'Invalid token');
|
|
48
|
+
// ⚠️ ATTENTION!! The remoteSecretKey is saved in clear text because we are studying a way to not make it visible to the customer. ATTENTION!!
|
|
49
|
+
const REMORA_KEY_SECRET = this.remoraSecretKey; // process.env.REMORA_KEY_SECRET
|
|
50
|
+
(0, Affirm_1.default)(REMORA_KEY_SECRET, 'Invalid CLI JWT SECRET');
|
|
51
|
+
return jsonwebtoken_1.default.verify(token, REMORA_KEY_SECRET);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const JWTManager = new JWTManagerClass();
|
|
56
|
+
exports.default = JWTManager;
|