Closed loynoir closed 1 year ago
@loynoir Hi.
Generating specific code files for AOT is considered out of scope for the TypeBox project. While the TypeCompiler does support the generation of assertion routines, the arrangement of these routines into a output file format is a task left for users.
The reason for this is there are a many different module systems, naming preferences, and various code organization preferences. Rather than trying to make all possible outputs preferences configurable, TypeBox instead just tries to provide a small API to generate the assertion routine, leaving the output / configuration / and general preferences to the users (or package authors who may want to write a CLI interface to generate)
The API for code generation is quite simple. The following generates a JavaScript ESM module to assert multiple types.
import { TypeCompiler } from '@sinclair/typebox/compiler'
import { Type, TSchema } from '@sinclair/typebox'
function CompileFunction(name: string, schema: TSchema) {
return `export const ${name} = (() => { ${TypeCompiler.Code(schema)} })();`
}
function CompileModule(schemas: Record<string, TSchema>): string {
return Object.entries(schemas).reduce((acc, [name, value]) => {
return [...acc, CompileFunction(name, value)]
}, [] as string[]).join('\n')
}
const Code = CompileModule({
A: Type.Object({
x: Type.Number(),
y: Type.Number(),
z: Type.Number()
}),
B: Type.Object({
a: Type.String(),
b: Type.String(),
c: Type.String()
})
})
console.log(Code)
Which produces the following output
export const A = (() => {
return function check(value) {
return (
(typeof value === 'object' && value !== null && !Array.isArray(value)) &&
(typeof value.x === 'number' && Number.isFinite(value.x)) &&
(typeof value.y === 'number' && Number.isFinite(value.y)) &&
(typeof value.z === 'number' && Number.isFinite(value.z))
)
} })();
export const B = (() => {
return function check(value) {
return (
(typeof value === 'object' && value !== null && !Array.isArray(value)) &&
(typeof value.a === 'string') &&
(typeof value.b === 'string') &&
(typeof value.c === 'string')
)
} })();
This should be enough functionality to implement a variety of code generation outputs external to TypeBox.
But what about error details?
@loynoir Heya,
But what about error details?
Compiler supported error generation is planned, but currently pending until there's been some formalization of error reporting established alongside the JSON Schema specification. See https://github.com/json-schema-org/json-schema-spec/issues/1396 for an issue I've submitted recently regarding this.
For now, TypeBox uses dynamic error generation, but will move to compiled once there's been some formal guidelines established with the spec (and until i18n mapping has been fully worked out in the dynamic error reporter).
So, planned, but probably not for several months.
@loynoir Going to close this issue off as code generation is out of scope for TypeBox (as a library)
However, there are some efforts happening elsewhere to offer code generation functionality in some capacity. There is a private package currently under development which is being worked on to provide a variety of code generation cases, as well as two initial projects utilizing some of the work there. You can find these at the links below.
CLI code generation for TypeBox
https://github.com/xddq/ts2typebox
https://sinclairzx81.github.io/typebox-workbench/
https://github.com/sinclairzx81/typebox-workbench
Will close off this issue for now, but for suggestions on code generation features (with may be inclusive of error generation), the best place to submit issues is on the typebox workbench project until some of the codegen work is made formally public.
Cheers S
feat
ajv
https://ajv.js.org/standalone.html#generating-functions-s-for-multiple-schemas-using-the-js-library-es6-and-cjs-exports
Generating functions(s) for multiple schemas using the JS library - ES6 and CJS exports
typia
https://typia.io/docs/validators/is/