Refactor, Added documentation, moved from avj-cli to avj, update script and added tests

This commit is contained in:
Kuldeep
2026-04-19 09:33:48 +00:00
parent cfd4c6a43b
commit 013583e7f8
26 changed files with 4216 additions and 9970 deletions

37
source/template/parser.ts Normal file
View File

@@ -0,0 +1,37 @@
import type { XOTemplate } from '@xo-cash/types';
import { xoTemplateSchema } from './schemas.ts';
import { TemplateInvalidError, buildErrorDescription } from './errors.ts';
import { deserializeTemplate, serializeTemplate } from './serialization.ts';
/**
* Accepts a template value and returns a validated XOTemplate object. The input may be
* either an Extended JSON string or a pre-parsed object. Both are validated
* against the XOTemplate schema.
*
* @param inputTemplate - The value to validate. May be an Extended JSON string or a pre-parsed object.
* @returns The validated template object
* @throws {TemplateSerializationFailedError} If a pre-parsed object input cannot be serialized to JSON for normalization.
* @throws {TemplateJsonMalformedError} If the string input is not valid JSON.
* @throws {TemplateInvalidError} If the value does not conform to the XOTemplate schema.
*/
export const parseTemplate = (inputTemplate: string | XOTemplate): XOTemplate => {
// Regardless of whether the inputTemplate is a string, an imported template or an in-memory object, serialize and then
// deserialize it to ensure the output shape is consistent. For example, optional fields explicitly set to 'undefined' would be passed through
// and then dropped on the string path, resulting in structurally different results for the same template.
const serializedTemplate = typeof inputTemplate === 'string' ? inputTemplate : serializeTemplate(inputTemplate);
const templateObject = deserializeTemplate(serializedTemplate);
// Validate the template against the schema.
const parseResult = xoTemplateSchema.safeParse(templateObject);
if (parseResult.success) {
// Return the validated template object
return parseResult.data as XOTemplate;
}
// Build a human-readable description of every validation failure
const errorDescription = buildErrorDescription(parseResult.error.issues);
// Throw a typed error with the description
throw new TemplateInvalidError(errorDescription);
};