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

View File

@@ -1,57 +0,0 @@
#!/usr/bin/env node
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = join(__dirname, '..');
// exec helper
const exec = (command, options = {}) => {
const defaultOptions = {
stdio: 'inherit',
cwd: rootDir,
shell: true,
...options,
};
return execSync(command, defaultOptions);
};
try {
const schemaPath = join(rootDir, 'source/parser/xo-template.schema.json');
const validatorPath = join(rootDir, 'source/parser/ajv/validate-xo-template.js');
const tsconfigPath = join(rootDir, 'tsconfig.json');
// Point directly to the dist file - the type is exported at the end via barrel export
const templatePath = join(rootDir, 'node_modules/@xo-cash/types/dist/index.d.ts');
// Generate schema JSON (write to file directly instead of shell redirection)
// Using --no-type-check to skip type checking and --expose all to find types exported via barrel exports
const schemaContent = execSync(
`ts-json-schema-generator --no-ref-encode --no-type-check --expose all --tsconfig "${tsconfigPath}" --path "${templatePath}" --type "XOTemplate"`,
{ encoding: 'utf8', cwd: rootDir },
);
writeFileSync(schemaPath, schemaContent, 'utf8');
// Compile validator with AJV
exec(`ajv compile -s "${schemaPath}" --allowUnionTypes --all-errors -o "${validatorPath}"`);
// Transform the generated validator code
let code = readFileSync(validatorPath, 'utf8');
code = code
.replace(/"use strict";module\.exports = [^;]+;module\.exports\.default = [^;]+;/, 'export default validate20;')
.replace(/;const /g, ';\nconst ')
.replace(/;function /g, ';\nfunction ')
.replace(/\}function /g, '}\nfunction ');
writeFileSync(validatorPath, code, 'utf8');
console.log('Schema generation complete!');
} catch (error) {
console.error('Error generating schema:', error.message);
process.exit(1);
}

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env node
/**
* Generates a JSON Schema file from the template schema, see source/template/schemas.ts for the schema definition.
*
* To provide support for types that JSON Schema cannot natively represent (e.g. bigint, Uint8Array), this script uses
* Zod's override functionality.
*
* The generated schema file (source/template/xo-template.schema.json) is not directly used anywhere in the xo project, but can be consumed by other JSON Schema validators
* to perform validations and help development of xo templates but it is important to note that they do not guarantee the support for bigint and
* other types support in the future. Hence, for XO compatible templates, it's a requirement that the provided template (json or typescript) is validated against
* the current template schema (source/template/schemas.ts) and validator.
*/
import { writeFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { ZodBigInt } from 'zod';
import { xoTemplateSchema, uint8ArraySchema } from '../source/template/schemas.ts';
// Gets the directory of this script file.
const scriptDirectory = dirname(fileURLToPath(import.meta.url));
// Gets the root directory of the package.
const rootDirectory = join(scriptDirectory, '..');
// The output path for the generated JSON Schema file, placed alongside the template schemas.
const schemaOutputPath = join(rootDirectory, 'source/template/xo-template.schema.json');
/**
* Generates the JSON Schema from the zod's template validation schema.
*
* - Bigint fields are mapped to `{ "type": "integer", "format": "bigint" }` because JSON Schema has no native bigint type.
* - Uint8Array fields are mapped to `{ "type": "string", "format": "uint8array" }` because JSON Schema has no byte array type.
*
* @returns The generated JSON Schema object.
*/
const generateSchema = (): Record<string, unknown> => {
return xoTemplateSchema.toJSONSchema({
// With "throw", Zod throws for any type it cannot represent in JSON Schema natively, unless the
// override below handles it first. This ensures new unrepresentable types added to the schema are
// caught immediately rather than silently producing an empty schema node.
unrepresentable: 'throw',
override: ({ zodSchema, jsonSchema: schemaNode }): void => {
// Override for bigint
if (zodSchema instanceof ZodBigInt) {
Object.assign(schemaNode, { type: 'integer', format: 'bigint' });
}
// Override for Uint8Array
if (zodSchema === uint8ArraySchema) {
Object.assign(schemaNode, { type: 'string', format: 'uint8array' });
}
},
});
};
try {
const schema = generateSchema();
writeFileSync(schemaOutputPath, JSON.stringify(schema, null, 4) + '\n', 'utf8');
console.log('Schema generated:', schemaOutputPath);
} catch (thrownValue) {
const errorMessage = thrownValue instanceof Error ? thrownValue.message : String(thrownValue);
console.error('Schema generation failed:', errorMessage);
process.exit(1);
}