n8n-nodes-advanced-output-parser
Version:
Advanced Output Parser node for n8n with dynamic expression support
118 lines (117 loc) • 4.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateSchemaFromExample = generateSchemaFromExample;
exports.convertJsonSchemaToZod = convertJsonSchemaToZod;
exports.evaluateExpression = evaluateExpression;
exports.validateDynamicSchema = validateDynamicSchema;
exports.hasExpressions = hasExpressions;
const n8n_workflow_1 = require("n8n-workflow");
const zod_1 = require("zod");
function generateSchemaFromExample(exampleJsonString, allFieldsRequired = false) {
const parsedExample = (0, n8n_workflow_1.jsonParse)(exampleJsonString);
const generateSchemaFromObject = (obj) => {
if (Array.isArray(obj)) {
return {
type: "array",
items: obj.length > 0
? generateSchemaFromObject(obj[0])
: { type: "string" },
};
}
else if (typeof obj === "object" && obj !== null) {
const properties = {};
for (const [key, value] of Object.entries(obj)) {
properties[key] = generateSchemaFromObject(value);
}
return {
type: "object",
properties,
required: allFieldsRequired ? Object.keys(properties) : [],
};
}
else if (typeof obj === "string") {
return { type: "string" };
}
else if (typeof obj === "number") {
return { type: "number" };
}
else if (typeof obj === "boolean") {
return { type: "boolean" };
}
else {
return { type: "string" };
}
};
return generateSchemaFromObject(parsedExample);
}
function convertJsonSchemaToZod(schema) {
function convertSchema(jsonSchema) {
if (jsonSchema.type === "object" && jsonSchema.properties) {
const zodObject = {};
for (const [key, prop] of Object.entries(jsonSchema.properties)) {
if (typeof prop === "object" && prop !== null) {
let zodType = convertSchema(prop);
if (!jsonSchema.required?.includes(key)) {
zodType = zodType.optional();
}
zodObject[key] = zodType;
}
}
return zod_1.z.object(zodObject);
}
else if (jsonSchema.type === "array" && jsonSchema.items) {
const itemSchema = convertSchema(jsonSchema.items);
return zod_1.z.array(itemSchema);
}
else {
switch (jsonSchema.type) {
case "string":
return zod_1.z.string();
case "number":
return zod_1.z.number();
case "integer":
return zod_1.z.number().int();
case "boolean":
return zod_1.z.boolean();
case "null":
return zod_1.z.null();
default:
return zod_1.z.any();
}
}
}
return convertSchema(schema);
}
function evaluateExpression(expression, itemIndex) {
try {
if (expression.includes("{{") && expression.includes("}}")) {
return this.evaluateExpression(expression, itemIndex);
}
return expression;
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error evaluating expression: ${expression}. ${error instanceof Error ? error.message : String(error)}`);
}
}
function validateDynamicSchema(resolvedSchema) {
try {
const parsed = JSON.parse(resolvedSchema);
if (typeof parsed !== "object" || parsed === null) {
throw new Error("Schema must be an object");
}
if (!parsed.type &&
!parsed.properties &&
!parsed.items &&
!parsed.oneOf &&
!parsed.anyOf) {
throw new Error("Invalid JSON Schema structure - missing type, properties, items, oneOf, or anyOf");
}
return parsed;
}
catch (error) {
throw new Error(`Invalid dynamic schema: ${error instanceof Error ? error.message : String(error)}. Resolved to: ${resolvedSchema}`);
}
}
function hasExpressions(text) {
return text.includes("{{") && text.includes("}}");
}