Files
bruno/packages/bruno-requests/src/grpc/grpcMessageGenerator.js
2025-12-04 01:37:20 +05:30

132 lines
4.0 KiB
JavaScript

import { faker } from '@faker-js/faker';
/**
* Generates a sample message based on method parameter fields
* @param {Object} fields - Method parameter fields
* @param {Object} options - Generation options
* @returns {Object} Generated message
*/
const generateSampleMessageFromFields = (fields, options = {}) => {
const result = {};
if (!fields || !Array.isArray(fields)) {
return {};
}
fields.forEach((field) => {
// Generate a value based on field name and type
if (field.type === 'TYPE_MESSAGE') {
// Handle nested message
if (field.messageType && field.messageType.field) {
if (field.label === 'LABEL_REPEATED') {
// Generate array of nested messages
const count = options.arraySize || faker.number.int({ min: 1, max: 3 });
result[field.name] = Array.from({ length: count }, () =>
generateSampleMessageFromFields(field.messageType.field, options)
);
} else {
// Generate single nested message
result[field.name] = generateSampleMessageFromFields(field.messageType.field, options);
}
} else {
// No field info for nested message, generate a simple object
result[field.name] = field.label === 'LABEL_REPEATED' ? [{}] : {};
}
} else if (field.type === 'TYPE_ENUM') {
result[field.name] = field.label === 'LABEL_REPEATED' ? [0] : 0;
} else {
// Generate value based on primitive type and name
let value;
switch (field.type) {
case 'TYPE_DOUBLE':
case 'TYPE_FLOAT':
value = faker.number.float({ min: 0, max: 1000, precision: 0.01 });
break;
case 'TYPE_INT32':
case 'TYPE_INT64':
case 'TYPE_SINT32':
case 'TYPE_SINT64':
case 'TYPE_UINT32':
case 'TYPE_UINT64':
case 'TYPE_FIXED32':
case 'TYPE_FIXED64':
value = faker.number.int({ min: 0, max: 1000 });
break;
case 'TYPE_BOOL':
value = faker.datatype.boolean();
break;
case 'TYPE_STRING':
value = faker.lorem.word();
break;
case 'TYPE_BYTES':
value = Buffer.from(faker.string.alpha({ length: { min: 5, max: 10 } })).toString('base64');
break;
default:
value = faker.lorem.word();
}
if (field.label === 'LABEL_REPEATED') {
// Generate array of values
const count = options.arraySize || faker.number.int({ min: 1, max: 3 });
result[field.name] = Array.from({ length: count }, () => value);
} else {
result[field.name] = value;
}
}
});
return result;
};
/**
* Extracts field definitions from a method's request type
* @param {Object} method - The gRPC method
* @returns {Array|null} Array of field definitions or null
*/
const getMethodRequestFields = (method) => {
try {
// Navigate through various potential property paths to find fields
if (method.requestType?.type?.field) {
return method.requestType.type.field;
}
if (method.requestType?.field) {
return method.requestType.field;
}
if (method.requestType?.type) {
return method.requestType.type;
}
} catch (error) {
console.error('Error extracting method request fields:', error);
return null;
}
};
/**
* Generates a sample gRPC message based on a method definition
* @param {Object} method - gRPC method definition
* @param {Object} options - Generation options
* @returns {Object} Generated message
*/
export const generateGrpcSampleMessage = (method, options = {}) => {
try {
if (!method) {
return {};
}
const fields = getMethodRequestFields(method);
if (fields) {
return generateSampleMessageFromFields(fields, options);
}
// If method exists but no field information could be extracted,
// generate a generic message that matches common patterns
return {};
} catch (error) {
console.error('Error generating gRPC sample message:', error);
}
};