Simplify JavaScript transformer and add post-processing for scientific notation

pull/21253/head
baonudesifeizhai 11 months ago
parent 9480795d00
commit 4199fa27f3

@ -11,57 +11,16 @@ class NodeJsTemplateTransformer(TemplateTransformer):
// declare main function // declare main function
{cls._code_placeholder} {cls._code_placeholder}
try {{ // decode and prepare input object
// decode and prepare input object var inputs_obj = JSON.parse(Buffer.from('{cls._inputs_placeholder}', 'base64').toString('utf-8'))
var inputs_obj = JSON.parse(Buffer.from('{cls._inputs_placeholder}', 'base64').toString('utf-8'))
// Preprocess inputs to handle number precision issues // execute main function
function preprocessInputs(obj) {{ var output_obj = main(inputs_obj)
if (typeof obj === 'object' && obj !== null) {{
for (var key in obj) {{
if (obj.hasOwnProperty(key)) {{
if (typeof obj[key] === 'string') {{
// Try to parse string as number if it looks like a number
var num = parseFloat(obj[key]);
if (!isNaN(num) && obj[key].trim() === num.toString()) {{
obj[key] = num;
}}
}} else if (typeof obj[key] === 'object') {{
preprocessInputs(obj[key]);
}}
}}
}}
}}
return obj;
}}
// Preprocess inputs
inputs_obj = preprocessInputs(inputs_obj);
// execute main function // convert output to json and print
var output_obj = main(inputs_obj) var output_json = JSON.stringify(output_obj)
var result = `<<RESULT>>${{output_json}}<<RESULT>>`
// Handle precision numbers properly in JSON.stringify console.log(result)
var output_json = JSON.stringify(output_obj, function(key, value) {{
// Ensure numbers are properly serialized
if (typeof value === 'number') {{
// Handle very small numbers that might cause precision issues
if (Math.abs(value) < 1e-1 && Math.abs(value) > 0) {{
// Convert to string to preserve precision
return value.toString();
}}
}}
return value;
}})
var result = `<<RESULT>>${{output_json}}<<RESULT>>`
console.log(result)
}} catch (error) {{
console.error('JavaScript execution error:', error.message)
// Provide more detailed error information
var errorResult = `<<RESULT>>{{"error": "JavaScript execution failed: " + error.message}}<<RESULT>>`
console.log(errorResult)
}}
""" """
) )
return runner_script return runner_script

@ -38,6 +38,7 @@ class TemplateTransformer(ABC):
:param response: response :param response: response
:return: :return:
""" """
try: try:
result_str = cls.extract_result_str_from_response(response) result_str = cls.extract_result_str_from_response(response)
result = json.loads(result_str) result = json.loads(result_str)
@ -48,17 +49,42 @@ class TemplateTransformer(ABC):
raise e raise e
except Exception as e: except Exception as e:
raise ValueError(f"Unexpected error during response transformation: {str(e)}") raise ValueError(f"Unexpected error during response transformation: {str(e)}")
# Check if the result contains an error # Check if the result contains an error
if isinstance(result, dict) and "error" in result: if isinstance(result, dict) and "error" in result:
raise ValueError(f"JavaScript execution error: {result['error']}") raise ValueError(f"JavaScript execution error: {result['error']}")
if not isinstance(result, dict): if not isinstance(result, dict):
raise ValueError(f"Result must be a dict, got {type(result).__name__}") raise ValueError(f"Result must be a dict, got {type(result).__name__}")
if not all(isinstance(k, str) for k in result): if not all(isinstance(k, str) for k in result):
raise ValueError("Result keys must be strings") raise ValueError("Result keys must be strings")
# Post-process the result to convert scientific notation strings back to numbers
result = cls._post_process_result(result)
return result return result
@classmethod
def _post_process_result(cls, result: dict[Any, Any]) -> dict[Any, Any]:
"""
Post-process the result to convert scientific notation strings back to numbers
"""
def convert_scientific_notation(value):
if isinstance(value, str):
# Check if the string looks like scientific notation
if re.match(r"^-?\d+\.?\d*e[+-]\d+$", value, re.IGNORECASE):
try:
return float(value)
except ValueError:
pass
elif isinstance(value, dict):
return {k: convert_scientific_notation(v) for k, v in value.items()}
elif isinstance(value, list):
return [convert_scientific_notation(v) for v in value]
return value
return convert_scientific_notation(result) # type: ignore[no-any-return]
@classmethod @classmethod
@abstractmethod @abstractmethod
def get_runner_script(cls) -> str: def get_runner_script(cls) -> str:

Loading…
Cancel
Save