UNPKG

wrekenfile-converter

Version:

Convert OpenAPI and Postman specs into Wrekenfiles, with chunking for vector database storage

150 lines 5.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.cleanYaml = cleanYaml; exports.checkYamlForHiddenChars = checkYamlForHiddenChars; exports.validateYaml = validateYaml; exports.removeTypeQuotes = removeTypeQuotes; exports.removeUndefinedValues = removeUndefinedValues; exports.generateYamlString = generateYamlString; const js_yaml_1 = require("js-yaml"); const constants_1 = require("./constants"); const constants_2 = require("./constants"); const TAB_REPLACEMENT = ' '; const NEWLINE = '\n'; const DOUBLE_NEWLINE = '\n\n'; const CONTROL_CHARS_REGEX = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g; const TAB_REGEX = /\t/g; const NON_BREAKING_SPACE_REGEX = /[\u00A0]/g; const CRLF_REGEX = /\r\n/g; const TRAILING_WHITESPACE_REGEX = /[ \t]+$/gm; const EXCESSIVE_NEWLINES_REGEX = /\n{3,}/g; const LEADING_WHITESPACE_REGEX = /^\s+/; const TRAILING_WHITESPACE_NEWLINES_REGEX = /[\s\n]+$/; function cleanYaml(yamlString) { let cleaned = yamlString .replace(TAB_REGEX, TAB_REPLACEMENT) .replace(NON_BREAKING_SPACE_REGEX, ' ') .replace(CONTROL_CHARS_REGEX, '') .replace(CRLF_REGEX, NEWLINE) .replace(TRAILING_WHITESPACE_REGEX, ''); const lines = cleaned.split(NEWLINE); const filteredLines = []; let isFirstLine = true; for (const line of lines) { const trimmed = line.trim(); if (trimmed === constants_1.YAML_DOCUMENT_SEPARATOR_START && !isFirstLine) { continue; } if (trimmed === constants_1.YAML_DOCUMENT_SEPARATOR_END) { continue; } if (constants_1.YAML_SEPARATOR_LINES.includes(trimmed)) { continue; } filteredLines.push(line); if (trimmed !== '') { isFirstLine = false; } } cleaned = filteredLines.join(NEWLINE) .replace(EXCESSIVE_NEWLINES_REGEX, DOUBLE_NEWLINE) .replace(LEADING_WHITESPACE_REGEX, '') .replace(TRAILING_WHITESPACE_NEWLINES_REGEX, ''); if (cleaned) { cleaned += NEWLINE; } return cleaned; } function checkYamlForHiddenChars(yamlString) { const lines = yamlString.split(NEWLINE); for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNum = i + 1; if (TAB_REGEX.test(line)) { throw new Error(`YAML contains a TAB character at line ${lineNum}:\n${line}`); } if (NON_BREAKING_SPACE_REGEX.test(line)) { throw new Error(`YAML contains a non-breaking space (U+00A0) at line ${lineNum}:\n${line}`); } if (CONTROL_CHARS_REGEX.test(line)) { throw new Error(`YAML contains a non-printable character at line ${lineNum}:\n${line}`); } } } function validateYaml(yamlString) { try { (0, js_yaml_1.load)(yamlString); } catch (e) { throw new Error(`Generated YAML is invalid: ${e.message}`); } } const BLOCK_SCALAR_REGEX = /^(\s+)(-?\s*)(TYPE|RETURNTYPE):\s*\|\-\s*\n(\s+)(\[\]STRUCT\([^)]+\)|\[\][A-Z]+)/gm; const STRUCT_QUOTED_REGEX = /(TYPE|RETURNTYPE):\s*"STRUCT\(([^)]+)\)"/g; const ARRAY_TYPE_REGEX = /^(\s+)(-?\s*)(TYPE|RETURNTYPE):\s*(\[\]STRUCT\([^)]+\)|\[\][A-Z]+)(\s*)$/gm; const QUOTE_START_REGEX = /^["']/; function removeTypeQuotes(yamlString) { yamlString = yamlString.replace(BLOCK_SCALAR_REGEX, (_match, indent, arrayPrefix, key, _valueIndent, value) => { return `${indent}${arrayPrefix}${key}: ${value}`; }); yamlString = yamlString.replace(STRUCT_QUOTED_REGEX, '$1: STRUCT($2)'); yamlString = yamlString.replace(ARRAY_TYPE_REGEX, (match, indent, arrayPrefix, key, value, trailing) => { if (!QUOTE_START_REGEX.test(value)) { return `${indent}${arrayPrefix}${key}: "${value}"${trailing}`; } return match; }); return yamlString; } /** * Recursively removes undefined values from an object. * This prevents js-yaml from generating invalid YAML or unexpected output. */ function removeUndefinedValues(obj) { if (obj === null || obj === undefined) { return undefined; } if (Array.isArray(obj)) { return obj .map(item => removeUndefinedValues(item)) .filter(item => item !== undefined); } if (typeof obj === 'object') { const cleaned = {}; for (const [key, value] of Object.entries(obj)) { const cleanedValue = removeUndefinedValues(value); if (cleanedValue !== undefined) { cleaned[key] = cleanedValue; } } return cleaned; } return obj; } /** * Complete YAML generation pipeline: * 1. Remove undefined values * 2. Dump to YAML string * 3. Remove type quotes * 4. Clean YAML * 5. Check for hidden characters * 6. Validate YAML * * This is the standard pipeline used by all converters. */ function generateYamlString(data) { // Remove undefined values before dumping to YAML const cleanedData = removeUndefinedValues(data); // Dump to YAML string let yamlString = (0, js_yaml_1.dump)(cleanedData, constants_2.YAML_DUMP_OPTIONS); // Post-process to remove quotes from type strings yamlString = removeTypeQuotes(yamlString); // Clean YAML (remove tabs, normalize newlines, etc.) yamlString = cleanYaml(yamlString); // Check for hidden characters checkYamlForHiddenChars(yamlString); // Validate YAML validateYaml(yamlString); return yamlString; } //# sourceMappingURL=yaml-utils.js.map