@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
131 lines • 5.77 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigQueryDefinition = void 0;
const config_query_executor_1 = require("./config-query-executor");
const ansi_1 = require("../../../util/text/ansi");
const time_1 = require("../../../util/text/time");
const joi_1 = __importDefault(require("joi"));
const json_1 = require("../../../util/json");
function configReplCompleter(partialLine, _startingNewArg, config) {
if (partialLine.length === 0) {
// update specific fields
return { completions: ['+'] };
}
else if (partialLine.length === 1 && partialLine[0].startsWith('+')) {
const path = partialLine[0].slice(1).split('.').filter(p => p.length > 0);
const fullPath = path.slice();
const lastPath = partialLine[0].endsWith('.') ? '' : path.pop() ?? '';
if (lastPath.endsWith('=')) {
return { completions: [] };
}
const subConfig = path.reduce((obj, key) => (obj && obj[key] !== undefined && typeof obj[key] === 'object') ? obj[key] : obj, config);
if (subConfig && !(subConfig[lastPath] !== undefined && typeof subConfig[lastPath] !== 'object')) {
const have = Object.keys(subConfig)
.filter(k => k.startsWith(lastPath) && k !== lastPath)
.map(k => `${partialLine[0].slice(0, 1)}${[...path, k].join('.')}`);
if (have.length > 0) {
return { completions: have };
}
else if (lastPath.length > 0) {
return { completions: [`${partialLine[0].slice(0, 1)}${fullPath.join('.')}.`] };
}
}
return { completions: [`${partialLine[0].slice(0, 1)}${fullPath.join('.')}=`] };
}
return { completions: [] };
}
function configQueryLineParser(output, line, _config) {
if (line.length > 0 && line[0].startsWith('+')) {
const [pathPart, ...valueParts] = line[0].slice(1).split('=');
// build the update object
const path = pathPart.split('.').filter(p => p.length > 0);
if (path.length === 0 || valueParts.length !== 1) {
output.stdout(`Invalid config update syntax, must be of the form ${(0, ansi_1.bold)('+path.to.field=value', output.formatter)}`);
}
else {
const update = {};
const value = valueParts[0];
let current = update;
for (let i = 0; i < path.length; i++) {
const key = path[i];
if (i === path.length - 1) {
// last part, set the value
// try to parse as JSON first
try {
current[key] = JSON.parse(value);
}
catch {
// fallback to string
current[key] = value;
}
}
else {
current[key] = {};
current = current[key];
}
}
return { query: [{ type: 'config', update }]
};
}
}
return { query: [{ type: 'config' }]
};
}
function collectKeysFromUpdate(update, prefix = '') {
// only collect leaf keys
const keys = [];
for (const [key, value] of Object.entries(update)) {
const fullKey = prefix ? `${prefix}.${key}` : key;
if (value && typeof value === 'object' && !Array.isArray(value)) {
keys.push(...collectKeysFromUpdate(value, fullKey));
}
else {
keys.push(fullKey);
}
}
return keys;
}
function getValueAtPath(obj, path) {
let current = obj;
for (const key of path) {
if (current && typeof current === 'object' && current[key] !== undefined) {
current = current[key];
}
else {
return undefined;
}
}
return current;
}
exports.ConfigQueryDefinition = {
executor: config_query_executor_1.executeConfigQuery,
asciiSummarizer: (formatter, _analyzer, queryResults, result, queries) => {
const out = queryResults;
result.push(`Query: ${(0, ansi_1.bold)('config', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
const configQueries = queries.filter(q => q.type === 'config');
if (configQueries.some(q => q.update)) {
const updatedKeys = configQueries.flatMap(q => q.update ? collectKeysFromUpdate(q.update) : []);
result.push(' ╰ Updated configuration:');
for (const key of updatedKeys) {
const path = key.split('.');
const newValue = getValueAtPath(out.config, path);
result.push(` - ${key}: ${JSON.stringify(newValue, json_1.jsonReplacer)}`);
}
}
else {
result.push(` ╰ Config:\n${JSON.stringify(out.config, json_1.jsonReplacer, 4)}`);
}
return true;
},
completer: configReplCompleter,
fromLine: configQueryLineParser,
schema: joi_1.default.object({
type: joi_1.default.string().valid('config').required().description('The type of the query.'),
update: joi_1.default.object().optional().description('An optional partial configuration to update the current configuration with before returning it. Only the provided fields will be updated, all other fields will remain unchanged.')
}).description('The config query retrieves the current configuration of the flowR instance and optionally also updates it.'),
flattenInvolvedNodes: () => []
};
//# sourceMappingURL=config-query-format.js.map