apim-policy-utils
Version:
An XML file scripts maniputaling and debugging tool targeting to help working with Azure APIM Policy files in xml format.
116 lines • 5.88 kB
JavaScript
;
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractScript = void 0;
const fs = __importStar(require("fs"));
const constants_1 = require("./constants");
const path = require("path");
// Define RegEx patterns
const blockPattern = /@{((?:[^{}]|{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*})*)}/g;
const inlinePattern = /@\((?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*\)/g;
const namedValuePattern = /({{)(.*?)(}})/g;
function extractScript(directoryPath, filename) {
var _a;
// Read the policy file
let xmlFile = fs.readFileSync(`${directoryPath}/${filename}`, "utf8");
// Find all the C# expressions in the policy file as blocks
const blocks = Array.from(xmlFile.matchAll(blockPattern), (m) => m[1] || m[2]);
// Find all the C# expressions in the policy file as inline expressions
const inline = ((_a = xmlFile.match(inlinePattern)) === null || _a === void 0 ? void 0 : _a.map((m) => m.slice(2, -1))) || [];
// Read the template file
const template = fs.readFileSync(path.resolve(__dirname, '../src/templates/script.csx'), "utf8");
// Define the output directory name
const output = `${path.dirname(directoryPath)}/scripts/${filename.replace(".xml", "")}`;
// Create the output directory
fs.mkdirSync(output, { recursive: true });
// Copy the context class into the output directory
fs.copyFile(path.resolve(__dirname, '../src/templates/context.csx'), `${output}/context.csx`, (err) => {
if (err) {
console.error(err);
return;
}
});
// Copy the context settings into the output directory
fs.copyFile(path.resolve(__dirname, '../src/templates/context.json'), `${output}/context.json`, (err) => {
if (err) {
console.error(err);
return;
}
});
// Write the snippets out as C# scripts
blocks.forEach((match, index) => {
let variables = "";
let found;
let scriptBody = match;
while ((found = namedValuePattern.exec(match)) !== null) {
if (variables === "") {
variables += `\t// The following named values have been extracted from the script and replaced with variables\r\n\t// Please check the script to ensure the string begins with a $ sign for string interpolation\r\n`;
}
const variableName = `nv_${found[2].replace("-", "_").trim()}`;
if (variables.includes(variableName) === false) {
variables += `\tstring ${variableName} = ""; // Named Value: ${found[2].trim()}\r\n`;
}
scriptBody = scriptBody.replace((found[1] + found[2] + found[3]), `{${variableName}}`);
}
variables += `\t${constants_1.separator}\n`;
const blockTemplate = template.replace("{0}", variables);
const name = `block-${(index + 1).toString().padStart(3, "0")}`;
xmlFile = xmlFile.replace(match, `${name}`);
fs.writeFileSync(`${output}/${name}.csx`, blockTemplate.replace('return "{1}";', addDollarSign(scriptBody)));
});
// Write the snippets out as C# scripts
inline.forEach((match, index) => {
const name = `inline-${(index + 1).toString().padStart(3, "0")}`;
xmlFile = xmlFile.replace(match, `${name}`);
let variables = "";
let found;
let scriptBody = match;
while ((found = namedValuePattern.exec(match)) !== null) {
if (variables === "") {
variables += `\t// The following named values have been extracted from the script and replaced with variables\r\n\t// Please check the script to ensure the string begins with a $ sign for string interpolation\r\n\t// Please put non-policy related code above the separator. e.g named_value strings. Anything below separator would be added to policy file when running combiner\r\n`;
}
const variableName = `nv_${found[2].replace("-", "_").trim()}`;
if (variables.includes(variableName) === false) {
variables += `\tstring ${variableName} = ""; // Named Value: ${found[2].trim()}\r\n`;
}
scriptBody = scriptBody.replace((found[1] + found[2] + found[3]), `{${variableName}}`);
}
variables += `\t${constants_1.separator}\n`;
const inlineTemplate = template.replace("{0}", variables);
fs.writeFileSync(`${output}/${name}.csx`, inlineTemplate.replace('"{1}"', scriptBody));
});
// Create a new xml file
fs.writeFile(`${output}/replaced.xml`, xmlFile, (err) => {
if (err) {
console.error(err);
}
});
}
exports.extractScript = extractScript;
function addDollarSign(input) {
const pattern = /("[^"]*\{nv_\w+}[^"]*")/g;
return input.replace(pattern, (match) => match.replace(/^"/, '$"'));
}
//# sourceMappingURL=scriptExtractor.js.map