UNPKG

netconf-client

Version:
159 lines 5.16 kB
import { tap } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { stringify as yamlStringify } from 'yaml'; import { MultipleEditError } from "../lib/index.js"; import { yellow } from "./output-colors.js"; import { Output } from "./output.js"; import { ResultFormat } from "./parse-args.js"; import { asTree } from 'object-as-tree'; /** * A helper class to manage EPIPE when writing to stdout */ class Writer { static write(data) { const writer = Writer.getInstance(); if (writer.error) { if (writer.error.hasOwnProperty('code') && writer.error.code === 'EPIPE') { // Ignore EPIPE errors } else { throw new Error(`Error writing to stdout: ${writer.error.message}`); } } else { writer.writeStdout(data); } } static instance; static getInstance() { if (!Writer.instance) { Writer.instance = new Writer(); } return Writer.instance; } error; constructor() { process.stdout.on('error', (e) => { const writer = Writer.getInstance(); writer.error = e; if (e.hasOwnProperty('code') && e.code === 'EPIPE') { // Ignore EPIPE errors } else { // This error will not be caught by RxJS throw new Error(`Error writing to stdout: ${e.message}`); } }); } writeStdout(data) { process.stdout.write(data); } } function formatPrimitive(val) { if (typeof val === 'string') { if (val.includes('\n')) { return `'${val.replace(/'/g, '\\\'')}'`; } return val; } return String(val); } function printKeyValue(prefix, obj) { if (Array.isArray(obj)) { // Array of objects: recurse into each item obj.forEach((item, index) => { // In XPath index starts at 1 const indexedPrefix = `${prefix}[${index + 1}]`; printKeyValue(indexedPrefix, item); }); } else if (obj && typeof obj === 'object') { for (const key of Object.keys(obj)) { const keyPrefix = prefix === '/' ? `/${key}` : prefix.length > 0 ? `${prefix}/${key}` : key; printKeyValue(keyPrefix, obj[key]); } } else if (prefix.length > 0 && prefix !== '/') { // Primitive: print the value Writer.write(`${prefix}=${formatPrimitive(obj)}\n`); } } /** * RxJs operator - write the result to the console in the specified format * * @param data - The result to write * @param format - The format to write the result in */ export function writeData(format) { return tap(input => { // If the input is an array, the first element is the result and the second is a boolean // indicating if the result is the root result const [data, isRootResult] = Array.isArray(input) && input.length === 2 && typeof input[1] === 'boolean' ? input : [input, false]; switch (format) { case ResultFormat.XML: Writer.write(data.xml); Writer.write('\n'); break; case ResultFormat.JSON: if (data.result === undefined) { Writer.write(JSON.stringify(null)); } else { Writer.write(JSON.stringify(data.result, null, 2)); } Writer.write('\n'); break; case ResultFormat.YAML: if (data.result === undefined) { Writer.write(yamlStringify(null)); } else { Writer.write(yamlStringify(data.result)); } break; case ResultFormat.KEYVALUE: printKeyValue(isRootResult ? '/' : '', data.result); break; case ResultFormat.TREE: default: Writer.write(data.result === '' ? yellow('no result') : asTree(data.result)); Writer.write('\n'); break; } }); } /** * RxJs operator - throw an error if the operation is not allowed to edit multiple schema branches */ export function catchMultipleEditError() { return catchError(error => { if (error instanceof MultipleEditError) { Output.error('Editing multiple schema branches not allowed. Use --allow-multiple to override.'); throw new Error('Operation not performed'); } throw error; }); } /** * RxJs operator - set the resulting status of the edit-config */ export function setEditConfigStatus() { return setStatus(); } /** * RxJs operator - set the resulting status of the RPC */ export function setRpcConfigStatus() { return setStatus(); } function setStatus() { return map((data) => { if (data.result?.ok !== undefined) { data.result.ok = 'operation successful'; } return data; }); } //# sourceMappingURL=output-operators.js.map