@gluestack-v2/glue-plugin-service-gateway
Version:
Gluestack V2 service Gateway Plugin
310 lines (309 loc) • 15.6 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "path", "fs", "@gluestack-v2/framework-cli/build/helpers/file/write-file", "./replace-handler-names", "./functions-service-template"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateApiGateway = void 0;
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const write_file_1 = __importDefault(require("@gluestack-v2/framework-cli/build/helpers/file/write-file"));
const replace_handler_names_1 = __importDefault(require("./replace-handler-names"));
const functions_service_template_1 = __importDefault(require("./functions-service-template"));
function filePathExtension(filePath) {
var _a;
return (_a = filePath.split('.').pop()) !== null && _a !== void 0 ? _a : '';
}
const eventsTemplate = (eventName, eventHandler) => {
return `
"${eventName}": {
handler: ${eventHandler},
},
`;
};
function camelCaseArray(arr) {
// Join array elements with a space
const joinedString = arr.join(' ');
// Split joinedString by space and capitalize each word except the first
const words = joinedString.split(' ');
for (let i = 1; i < words.length; i++) {
words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);
}
// Concatenate capitalized words
const camelCaseString = words.join('');
return camelCaseString;
}
const removeDashAndCamelCase = (str) => {
const words = str.split('-');
const camelCaseStr = words.reduce((acc, word, index) => {
if (index === 0) {
return word;
}
const capitalizedWord = word.charAt(0).toUpperCase() + word.slice(1);
return acc + capitalizedWord;
}, '');
return camelCaseStr;
};
function getNestedFilePaths(dirPath, fileList = []) {
const files = fs_1.default.readdirSync(dirPath);
files.forEach((file) => {
const filePath = path_1.default.join(dirPath, file);
const stats = fs_1.default.statSync(filePath);
if (stats.isDirectory()) {
// If the file is a directory, recursively call the function
// to get nested file paths
getNestedFilePaths(filePath, fileList);
}
else {
// If the file is a regular file, add its path to the fileList
fileList.push(filePath);
}
});
return fileList;
}
// Usage: Pass the directory path as an argument to the function
// Molecular service Actions/import statement
let moleculerActions = {};
let moleculerImportPaths = ``;
// Private service Actions/import statement
let privateMoleculerActions = {};
let privateMoleculerImportStatements = ``;
const molecularEvents = ``;
let privateMolecularEvents = ``;
const eventsImportPaths = ``;
const handlerTemplate = () => {
return ` (ctx) => {
const sdk = ServiceSDK.getInstance();
const operation = ctx.params.operation;
sdk.minioClient[operation](ctx.params.params, function (err, result) {
if (err) {
console.log(err);
return;
}
console.log("Operation Completed successfully");
});
},`;
};
const writeService = (installationPath, functionPath, functionInstanceName) => __awaiter(void 0, void 0, void 0, function* () {
const files = getNestedFilePaths(functionPath);
files.forEach((functionFile, _index) => {
const filePath = functionFile;
if (['json'].includes(filePathExtension(filePath)) ||
filePath.includes('node_modules')) {
return;
}
if (filePath.endsWith('.map') || filePath === 'package.json') {
return;
}
// Get Private Actions, events, importd
if (filePath.includes('/private/')) {
privateMoleculerActions = Object.assign(Object.assign({}, privateMoleculerActions), getPrivateActions(installationPath, functionInstanceName, filePath)
.actions);
privateMoleculerImportStatements =
privateMoleculerImportStatements +
getPrivateActions(installationPath, functionInstanceName, filePath)
.importPaths;
if (filePath.includes('/private/events/')) {
const privateMolecularData = getEvents(getPrivatePath(filePath, installationPath));
privateMolecularEvents = privateMolecularData.events;
}
return;
}
// if (filePath.includes("/events/")) {
// molecularEvents += getEvents(getPaths(filePath, installationPath)).events;
// eventsImportPaths += getEvents(
// getPaths(filePath, installationPath)
// ).importPaths;
// return;
// }
// Get Actions
moleculerActions = Object.assign(Object.assign({}, moleculerActions), getActions(installationPath, functionInstanceName, filePath).actions);
// moleculerActions = { ...moleculerActions, ...storageRoute };
moleculerImportPaths =
moleculerImportPaths +
getActions(installationPath, functionInstanceName, filePath).importPaths;
});
// Writing Molecular Actions and events for instance
createService(moleculerActions, (0, functions_service_template_1.default)(functionInstanceName), {
actionImportPath: moleculerImportPaths,
eventImportPath: eventsImportPaths,
}, path_1.default.join(installationPath, 'services', `${functionInstanceName}.service.js`), molecularEvents);
// Writing Molecular Actions and events for private service
createService(privateMoleculerActions, (0, functions_service_template_1.default)('private'), { actionImportPath: privateMoleculerImportStatements, eventImportPath: '' }, path_1.default.join(installationPath, 'services', `private.service.js`), privateMolecularEvents);
// console.log('Updating API Gateway', installationPath, functionInstanceName);
updateApiGateway(installationPath, functionInstanceName);
});
function removeExtension(filename) {
return filename.substring(0, filename.lastIndexOf('.')) || filename;
}
function getActions(installationPath, instanceName, filePath) {
const serviceAction = {};
let functionImportStatement = ``;
if (fs_1.default.existsSync(filePath)) {
const finalPathArr = getPaths(filePath, installationPath);
// const finalPath = getFileNameWithoutExtension(finalPathArr.functionPath);
// Create actions object
const action = {};
action.rest = {
method: 'POST',
path: '/' + removeExtension(finalPathArr.funcPath.join('.')),
};
action.handler = `(ctx) => {const context = new Context(ctx); return ${removeExtension(camelCaseArray(finalPathArr.funcPath)) + 'Handler'}(context);},`;
serviceAction[removeExtension(finalPathArr.funcPath.join('.'))] = action;
// Create Import Statement
functionImportStatement = `const ${removeExtension(camelCaseArray(finalPathArr.funcPath))}Handler = require("..${finalPathArr.functionPath}");`;
functionImportStatement += '\n';
}
return {
actions: serviceAction,
importPaths: functionImportStatement,
// events: serviceAction
};
}
const getPrivateActions = (installationPath, instanceName, filePath) => {
const obj = {};
// let privateEvents = ``;
let functionImportStatement = ``;
if (fs_1.default.existsSync(filePath)) {
const finalPathArr = getPrivatePath(filePath, installationPath);
// Create actions object
const action = {};
action.rest = {
method: 'POST',
path: finalPathArr.functionPath,
};
action.handler = `(ctx) => {const context = new Context(ctx); return ${removeExtension(camelCaseArray(finalPathArr.funcPath)) + 'Handler'}(context);},`;
if (!filePath.includes('/events/'))
obj[removeExtension(finalPathArr.funcPath.join('.'))] = action;
// if (filePath.includes("/events/")) {
// privateEvents = getEvents(filePath, installationPath).events;
// }
// Create Import Statement
functionImportStatement = `const ${removeExtension(camelCaseArray(finalPathArr.funcPath.map((str) => removeDashAndCamelCase(str))))}Handler = require("..${finalPathArr.functionPath}");`;
functionImportStatement += '\n';
}
return {
actions: obj,
importPaths: functionImportStatement,
};
};
function getEvents(filePathData) {
// let eventsPath = funcPath.filter((str) => str !== "events");
// let res = getPaths(filePath, installationPath);
let events = ``;
const eventsIndex = filePathData.funcPath.indexOf('events');
let eventNameIndex = filePathData.funcPath[1];
// Check if the separator is present in the array
if (eventsIndex !== -1) {
eventNameIndex = filePathData.funcPath[eventsIndex + 1];
}
let functionImportStatement = ``;
functionImportStatement = `const ${camelCaseArray(filePathData.funcPath)}Handler = require("..${filePathData.functionPath}");`;
functionImportStatement += '\n';
events = eventsTemplate(eventNameIndex, camelCaseArray(filePathData.funcPath.map((str) => removeDashAndCamelCase(str))) + 'Handler');
return { events, importPaths: functionImportStatement };
}
function getWhitelist(apiGatewayPath) {
const data = fs_1.default.readFileSync(apiGatewayPath, {
encoding: 'utf-8',
});
const regex = /whitelist(.*)\n/gm;
const matches = data.match(regex);
// return;
if (!matches) {
const writeData = data.replace('// ***Update Whitlisted services here***', `whitelist: [],`);
fs_1.default.writeFileSync(apiGatewayPath, writeData);
// const data1 = fs.readFileSync(apiGatewayPath, {
// encoding: 'utf-8',
// });
// const regex1 = /whitelist(.*)\n/gm;
// const matches1: any = data1.match(regex1);
return { whitelist: [], match: null, fileData: data };
}
else {
const str = matches[0];
const vals = str.match(/\[(.*?)\]/)[1];
let whitelistArray = vals.split(',');
// Remove extra quotes and trim whitespace
whitelistArray = whitelistArray.map((item) => item.replace(/"/g, '').trim());
// vals.map((val: any) => whitelistArray.push(val));
return { whitelist: whitelistArray, match: matches[0], fileData: data };
}
}
function updateApiGateway(installationPath, instanceName) {
const apiGatewayPath = path_1.default.join(installationPath, 'services', 'api.service.js');
// const whitelistedArr = [`${instanceName}.**`];
let { whitelist } = getWhitelist(apiGatewayPath);
if (!whitelist.includes(`${instanceName}.**`)) {
// // FIX: Remove dbClient from whitelist
whitelist = [...whitelist, `${instanceName}.**`];
const data1 = fs_1.default.readFileSync(apiGatewayPath, {
encoding: 'utf-8',
});
const regex1 = /whitelist(.*)\n/gm;
const matches1 = data1.match(regex1);
const writeData = data1.replace(matches1[0], `whitelist: ${JSON.stringify(whitelist)},`);
fs_1.default.writeFileSync(apiGatewayPath, writeData);
}
// console.log('hello here', whitelist);
// const writeData = fileData.replace(match, JSON.stringify(whitelist));
// fs.writeFileSync(apiGatewayPath, writeData);
}
exports.updateApiGateway = updateApiGateway;
function createService(moleculerActions, moleculerFunctionsServiceTemplate, moleculerImportStatements, path, eventsData) {
return __awaiter(this, void 0, void 0, function* () {
let finalString = moleculerFunctionsServiceTemplate
.replace('// **---Add Actions Here---**', (0, replace_handler_names_1.default)(JSON.stringify(moleculerActions, null, 2)))
.replace('/** Add handler here **/', handlerTemplate());
finalString = finalString.replace('// **---Add Events Here---**', eventsData + '// **---Add Events Here---**');
const uniqueStrings = [];
moleculerImportStatements.actionImportPath
.split('\n')
.forEach((line) => {
if (!uniqueStrings.includes(line)) {
uniqueStrings.push(line);
}
});
const outputString = uniqueStrings.join('\n');
finalString = finalString.replace('// **---Add Imports Here---**', outputString +
moleculerImportStatements.eventImportPath +
`const Context = require("../Context.ts");`);
yield (0, write_file_1.default)(path, finalString);
});
}
function getPrivatePath(filePath, installationPath) {
const functionPath = filePath.replace(installationPath, '');
// functionPath = functionPath.split(".").slice(0, -1).join(".");
let funcPath = functionPath.split('/');
funcPath.splice(0, 2);
funcPath = funcPath.filter((str) => str !== 'private');
return { funcPath, functionPath };
}
function getPaths(filePath, installationPath) {
// Dynamic route of a given action
const functionPath = filePath.replace(installationPath, '');
// functionPath = functionPath.split(".").slice(0, -1).join(".");
// An Array of actions name for nested routes
const funcPath = functionPath.split('/');
funcPath.splice(0, 2);
return { funcPath, functionPath };
}
exports.default = writeService;
});