UNPKG

donobu

Version:

Create browser automations with an LLM agent and replay them as Playwright scripts.

124 lines 4.73 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.JsonUtils = void 0; const MiscUtils_1 = require("./MiscUtils"); const path_1 = __importDefault(require("path")); const Logger_1 = require("./Logger"); const promises_1 = __importDefault(require("fs/promises")); class JsonUtils { constructor() { } static getJsonSchemaFromTypeName(typeName) { return JSON.parse(MiscUtils_1.MiscUtils.getResourceFileAsString(path_1.default.join('generated', 'parameter-schemas.json')))[typeName]; } static objectToJson(object) { const getCircularReplacer = () => { const seen = new WeakSet(); return (_key, value) => { if (typeof value === 'object' && value !== null) { if (seen.has(value)) { return undefined; } seen.add(value); } return value; }; }; return JSON.parse(JSON.stringify(object, getCircularReplacer())); } static readResourceAsJson(source) { try { const jsonString = MiscUtils_1.MiscUtils.getResourceFileAsString(source); return JSON.parse(jsonString); } catch (error) { Logger_1.appLogger.error('Failed to read resource as JSON:', error); return null; } } static jsonStringToJsonObject(jsonString) { try { return JSON.parse(jsonString); } catch (error) { Logger_1.appLogger.error('Failed to parse JSON string to object: ', error); return null; } } /** * Post-process the given schema to conform with OpenAI constraints * @see https://platform.openai.com/docs/guides/structured-outputs/additionalproperties-false-must-always-be-set-in-objects */ static postProcessJsonSchema(schema) { if (schema.type === 'object') { schema.additionalProperties = false; if (schema.properties) { const properties = schema.properties; schema.required = schema.required || []; Object.entries(properties).forEach(([fieldName, fieldSchema]) => { if (!schema.required?.includes(fieldName)) { schema.required?.push(fieldName); if (typeof fieldSchema.type === 'string') { fieldSchema.type = [fieldSchema.type, 'null']; } else if (Array.isArray(fieldSchema.type) && !fieldSchema.type.includes('null')) { fieldSchema.type.push('null'); } } }); } } // Recursively process nested schemas if (schema.properties) { Object.values(schema.properties).forEach((prop) => { if (typeof prop === 'object') { this.postProcessJsonSchema(prop); } }); } if (schema.items) { const items = Array.isArray(schema.items) ? schema.items : [schema.items]; items.forEach((item) => { if (typeof item === 'object') { this.postProcessJsonSchema(item); } }); } } /** * Ensures the given file path exists. If the file does not initially exist, * all directories to it will be created and the file will be created with a * value of an empty JSON object (AKA {}). */ static async maybeInitEmptyJsonFile(filePath) { // Ensure the directory exists const directory = path_1.default.dirname(filePath); await promises_1.default .mkdir(directory, { recursive: true }) .catch((dirError) => { // Directory already exists, continue... if (dirError.code !== 'EEXIST') { throw dirError; } }); // Try to access the file to check if it exists try { await promises_1.default.access(filePath); } catch (error) { const fsError = error; // File doesn't exist, create it. if (fsError.code === 'ENOENT') { await promises_1.default.writeFile(filePath, '{}', 'utf8'); } else { throw error; } } } } exports.JsonUtils = JsonUtils; //# sourceMappingURL=JsonUtils.js.map