UNPKG

apim-policy-utils

Version:

An XML file scripts maniputaling and debugging tool targeting to help working with Azure APIM Policy files in xml format.

190 lines 7.77 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.combineScript = void 0; const fs = __importStar(require("fs")); const path_1 = __importDefault(require("path")); const constants_1 = require("./constants"); async function combineScript(directoryPath, destinationPath) { const filenames = await getFilenamesInDirectory(directoryPath); // Compute the xml filename for storing the result const dirArray = directoryPath.split('/'); const xmlFilename = `${dirArray[dirArray.length - 1]}.xml`; // Read xmlContent from the generated xmlfile let xmlFileContent = fs.readFileSync(`${directoryPath}/replaced.xml`, 'utf8'); // Get code outside of block-xxx.csx file and inline-xxx.csx file filenames.forEach(filename => { if ((filename.startsWith('inline') || filename.startsWith('block')) && filename.endsWith('.csx')) { let codeSnippet = getCodeInMethod(`${directoryPath}/${filename}`, 'ExtractedScript'); codeSnippet = refineCode(filename, codeSnippet); const xmlPlaceholder = filename.slice(0, -4); xmlFileContent = replaceAll(xmlFileContent, xmlPlaceholder, codeSnippet); } // Write the combined XML to a file if (!destinationPath) { fs.writeFileSync(`${directoryPath}/${xmlFilename}`, xmlFileContent); } else { updateFileInDirectory(destinationPath, xmlFilename, xmlFileContent) .then(() => { console.log('File update complete.'); }) .catch((error) => { console.error('An error occurred while updating the file:', error); }); } }); } exports.combineScript = combineScript; function refineCode(file, codeSnippet) { var _a; if (codeSnippet === null) { return ''; } const inlinePrefix = "return "; if (file.startsWith('inline')) { codeSnippet = codeSnippet.trim(); if (codeSnippet.startsWith(inlinePrefix)) { codeSnippet = codeSnippet.substring(inlinePrefix.length).trim(); // remove "return " prefix return codeSnippet.slice(0, -1); // remove ";" suffix } } if (file.startsWith('block')) { const lines = codeSnippet.split('\n').map(line => line); const nonEmptyLines = lines.filter(line => line !== ''); const indentation = (_a = nonEmptyLines[0].match(/^\s*/)) === null || _a === void 0 ? void 0 : _a[0]; const formattedContent = nonEmptyLines.map((line, index) => { if (index === 0 || index === nonEmptyLines.length - 1) { return line; } return `${indentation}${line}`; }).join('\n'); return `${formattedContent}`; } return codeSnippet; } function getFilenamesInDirectory(directoryPath) { return new Promise((resolve, reject) => { fs.readdir(directoryPath, (err, files) => { if (err) { reject(err); } else { const filenames = []; files.forEach((file) => { filenames.push(file); }); resolve(filenames); } }); }); } function getCodeInMethod(csxFilePath, methodName) { try { // Read the contents of the file at the given path const fileContents = fs.readFileSync(csxFilePath, 'utf8'); // Find the starting index of the desired method const startRegex = new RegExp(`(?<=\\b(?:public|private|internal)?\\s+(?:async\\s+)?(?:static\\s+)?(?:readonly\\s+)?(?:partial\\s+)?(?:unsafe\\s+)?(?:virtual\\s+)?(?:override\\s+)?\\w+\\s+${methodName}\\s*\\()`); const startIndex = fileContents.search(startRegex); if (startIndex === -1) { console.error(`Method '${methodName}' not found in file at path '${csxFilePath}'`); return null; } // Find the ending index of the desired method let openBraces = 0; let actualStartIndex = startIndex; let endIndex = startIndex; for (let i = startIndex; i < fileContents.length; i++) { if (fileContents[i] === '{') { openBraces++; if (openBraces === 1) { actualStartIndex = i; } } else if (fileContents[i] === '}') { openBraces--; if (openBraces === 0) { endIndex = i; break; } } } // The code within the method let codeInMethod = fileContents.slice(actualStartIndex, endIndex + 1); codeInMethod = removeSurroundingChars(codeInMethod); // Remove everything before the generated sepatators codeInMethod = removeCodeAboveSeparator(codeInMethod); codeInMethod = convertNamedValue(codeInMethod); return codeInMethod; } catch (error) { console.error(`Error reading file at path '${csxFilePath}': ${error.message}`); return null; } } function replaceAll(xml, toReplace, replacement) { const regex = new RegExp(toReplace, 'g'); replacement = replacement ? replacement : ''; xml = xml.replace(regex, replacement); return xml; } function removeSurroundingChars(str) { if (str.startsWith('{') && str.endsWith('}')) { str = str.slice(1, -1); } return str; } function removeCodeAboveSeparator(input) { const separatorIndex = input.indexOf(constants_1.separator); if (separatorIndex === -1) { return ""; } return input.substring(separatorIndex + constants_1.separator.length); } function convertNamedValue(input) { const regex = /{nv_(\w+)}/g; return input.replace(regex, (match, p1) => `{{${p1.replace(/_/g, "-")}}}`); } async function updateFileInDirectory(destinationPath, fileName, content) { const files = fs.readdirSync(destinationPath); if (files.includes(fileName)) { const filePath = path_1.default.join(destinationPath, fileName); fs.writeFileSync(filePath, content); return; } for (const file of files) { const filePath = path_1.default.join(destinationPath, file); const isDirectory = fs.statSync(filePath).isDirectory(); if (isDirectory) { await updateFileInDirectory(filePath, fileName, content); } } const rootFilePath = path_1.default.join(destinationPath, fileName); fs.writeFileSync(rootFilePath, content); } //# sourceMappingURL=scriptCombiner.js.map