UNPKG

zod-to-x

Version:

Multi language types generation from Zod schemas.

385 lines (384 loc) 16.2 kB
import { ASTAliasedTypes, ASTEnum, ASTIntersection, ASTNode, ASTObject, ASTUnion, Zod2X } from "../../core"; import { IZod2CppOpt } from "./options"; /** * @description Transpiler for Zod schemas to C++11 code. */ export declare class Zod2Cpp extends Zod2X<IZod2CppOpt> { protected readonly commentKey = "//"; protected serializers: string[]; protected useBoost: boolean; protected lib: { exceptions: string; integers: string; map: string; nlohmann: string; set: string; string: string; tuple: string; vector: string; optional: string; variant: string; }; constructor(opt?: IZod2CppOpt); protected getIntersectionType: () => string; protected runBefore(): void; protected addImportFromFile(filename: string, _: string): string; protected getTypeFromExternalNamespace(namespace: string, typeName: string): string; protected addExtendedType(name: string, parentNamespace: string, aliasOf: string, opt?: { type?: "union" | "alias"; isInternal?: boolean; templates?: string; templateDefinition?: string; templateList?: string; }): void; protected getGenericTemplatesTranslation(data: ASTNode): string | undefined; /** * Emits an alias/extension declaration early for layered references. * It keeps concrete template translations and falls back to declared templates (e.g. <T>) * for aliases of generic templates. */ protected checkExtendedTypeInclusion(data: ASTNode, type?: "union" | "alias"): boolean; protected runAfter(): void; protected getDateType: () => string; protected getBooleanType: () => string; protected getStringType: () => string; /** Ex: std::tuple<TypeA, TypeB, ...> */ protected getTupleType: (itemsType: string[]) => string; protected getAnyType: () => string; /** Ex: std::set<TypeA> */ protected getSetType: (itemType: string) => string; /** Ex: boost::variant<TypeA, TypeB> */ protected getUnionType: (itemsType: string[]) => string; /** Ex: depends on number range (if any). One of: * - std::uint32_t * - std::uint64_t * - std::int32_t * - std::int64_t * - double */ protected getNumberType: (isInt: boolean, range: { min?: number; max?: number; }) => string; /** Ex: std::vector<std::vector<TypeA>> */ protected getArrayType(arrayType: string, arrayDeep: number): string; protected getLiteralStringType(value: string | number | boolean, parentEnumNameKey?: [string, string]): string; /** Ex: std::unordered_map<TypeA> */ protected getMapType(keyType: string, valueType: string): string; protected getRecordType(keyType: string, valueType: string): string; protected _getOptional(type: string): string; protected _addExtendedTypeSerializer(typeName: string, parentNamespace: string, opt?: { templateDefinition?: string; templateList?: string; }): void; protected _addExtendedTypeDeserializer(typeName: string, parentNamespace: string, opt?: { templateDefinition?: string; templateList?: string; }): void; protected transpileAliasedType(data: ASTAliasedTypes): void; /** Ex: * enum class EnumA: int { * Item1, * Item2 * } */ protected transpileEnum(data: ASTEnum): void; /** Ex: * - Case of using classes: * class MyClassC: public MyClassA, public MyClassB { * public: * MyClassC() = default; * virtual ~MyClass() = default; * } * * - Case of using structs * struct MyStructC: public MyStructA, public MyStructB { * * } */ protected transpileIntersection(data: ASTIntersection): void; /** Ex: using TypeC = boost::variant<TypeA, TypeB> */ protected transpileUnion(data: ASTUnion): void; protected transpileStruct(data: ASTObject): void; private _getTemplates; /** Ex: * struct MyStruct { * TypeA attribute1; * TypeB attribute2; * } */ private _transpileStructAsStruct; /** Ex: * class MyClass { * private: * TypeA attribute1; * TypeB attribute2; * * public: * MyClass() = default; * virtual ~MyClass() = default; * * const TypeA& get_attribute1() const { return this->attribute1; } * TypeA& get_mut attribute1() { return this->attribute1; } * void set_attribute1(TypeA& value) { this->attribute1 = value; } * [...] * } */ private _transpileStructAsClass; /** * @description Transpiles an individual member of a C++ class based on the provided ASTNode. * * @param memberName - The name of the member variable to transpile. * @param memberNode - The ASTNode defining the member's type, description, and other * attributes. * * @returns - The original C++ type of the member, without optional modifier. */ private _transpileMember; /** * @description Creates getter and setter enumHelpers for a C++ class member variable. * * @param memberName - The name of the member variable. * @param memberType - The C++ type of the member variable. * @param [required] - Whether the member is required (default is `false`). * * @returns - An array of strings representing the C++ getter and setter enumHelpers. */ private _createSetterGetter; /** * @description Generates a JSON serializer for a struct. Each required field is serialized * directly, and optional fields are checked for existence before serialization. * Ex: * inline void to_json(nlohmann::json& j, const MyStruct& x) { * j["requiredField"] = x.required_field; * if (x.optional_field) { * j["optionalField"] = x.optional_field; * } * } * @param parent - Name of the serialized structure * @param childs - Structure attributes data. * @param templates - Generic templates string (if any) */ private _createStructSerializer; /** * @description Generates a JSON deserializer for a struct. Each required field is deserialized * using at, while optional fields are handled with get_opt. * Ex: * inline void from_json(const nlohmann::json& j, MyStruct& x) { * x.required_field(j.at("requiredField").get<int>()); * x.optional_field(get_opt<std::string>(j, "optionalField")); * } * @param parent - Name of the deserialized structure * @param childs - Structure attributes data. * @param templates - Generic templates string (if any) */ private _createStructDeserializer; /** * @description Generates a JSON serializer for a class. The serializer uses getter methods to * access class attributes. Optional fields are checked for existence before * serialization. * Ex: * inline void to_json(nlohmann::json& j, const MyClass& x) { * j["requiredField"] = x.get_required_field(); * if (x.get_optional_field()) { * j["optionalField"] = x.get_optional_field(); * } * } * @param parent - Name of the serialized structure * @param childs - Structure attributes data. * @param templates - Generic templates string (if any) */ private _createClassSerializer; /** * @description Generates a JSON deserializer for a class. The deserializer uses setter methods * to populate class attributes. * Ex: * inline void from_json(const nlohmann::json& j, MyClass& x) { * x.set_required_field(j.at("requiredField").get<int>()); * x.set_optional_field(get_opt<std::string>(j, "optionalField")); * } * @param parent - Name of the deserialized structure * @param childs - Structure attributes data. * @param templates - Generic templates string (if any) */ private _createClassDeserializer; /** * @description Generates a JSON serializer for an enum. Maps enum values to strings for * serialization, with a default case for unexpected values. * Ex: * inline void to_json(nlohmann::json& j, const MyEnum& x) { * switch (x) { * case MyEnum::Value1: j = "VALUE_1"; break; * case MyEnum::Value2: j = "VALUE_2"; break; * default: throw std::runtime_error("Unexpected value serializing enum MyEnum: " + * std::to_string(static_cast<int>(x))); * } * } * @param parent - Name of the serialized enumerate * @param childs - Enumerate values data. */ private _createEnumSerializer; /** * @description Generates a JSON deserializer for an enum. Maps strings to enum values, with an * error for unexpected strings. * Ex: * inline void from_json(const nlohmann::json& j, MyEnum& x) { * if (j == "VALUE_1") x = MyEnum::Value1; * else if (j == "VALUE_2") x = MyEnum::Value2; * else { * throw std::runtime_error("Unexpected value deserializing enum MyEnum."); * } * } * @param parent - Name of the deserialized enumerate * @param childs - Enumerate values data. */ private _createEnumDeserializer; /** * @description Creates a JSON serializer for a class or struct that is the intersection of * multiple types. * * @example * // inline void to_json(nlohmann::json& j, const DerivedType& x) { * // to_json(j, static_cast<const BaseType1&>(x)); * // to_json(j, static_cast<const BaseType2&>(x)); * // } * * @param intersectName - The name of the intersected class or struct. * @param itemsType - An array of strings representing the names of the base types to serialize. */ private _createIntersectionSerializer; /** * @description Creates a JSON deserializer for a class or struct that is the intersection of * multiple types. * * @example * // inline void from_json(const nlohmann::json& j, DerivedType& x) { * // from_json(j, static_cast<BaseType1&>(x)); * // from_json(j, static_cast<BaseType2&>(x)); * // } * * @param intersectName - The name of the intersected class or struct. * @param itemsType - An array of strings representing the names of the base types to deserialize. */ private _createIntersectionDeserializer; /** * @description Generates a `to_json` function for a specified union type, allowing the JSON * library to correctly serialize any variant within the union. * * @param unionName The name of the union type. * @param itemsType A list of all variant types contained in the union. * * @example * // Given: unionName = "MyUnion", itemsType = {"int", "std::string"} * // The generated output might look like: * // * // inline void to_json(nlohmann::json& j, const MyUnion& x) { * // if (x.type() == typeid(int)) { * // j = boost::get<int>(x); * // } else if (x.type() == typeid(std::string)) { * // j = boost::get<std::string>(x); * // } else { * // throw std::runtime_error("Unknown MyUnion type."); * // } * // } */ protected _createUnionSerializer(unionName: string, itemsType: string[]): void; /** * @description Generates a `from_json` function for a specified union type, attempting to * deserialize the provided JSON into one of the known variant types. If no match * is found, it throws an error. * * @param unionName The name of the union type. * @param items A list of possible variant types. Each item includes: * - `type`: The C++ type for deserialization (e.g., `int`, `std::string`). * - `discriminantValue` (optional): The value in the discriminator field * that maps to the respective type. * @param discriminator (optional) The JSON field name that acts as a type discriminator. * Required for discriminator-based deserialization. * * @example * // Discriminator-based deserialization: * // Given: unionName = "MyUnion", discriminator = "type" * // items = { {"type": "EmailContact", "discriminantValue": "email"}, * // {"type": "PhoneContact", "discriminantValue": "phone"} } * // * // The generated output might look like: * // inline void from_json(const nlohmann::json& j, MyUnion& x) { * // const auto& k = j.at("type").get<std::string>(); * // if (k == "email") { * // x = j.get<EmailContact>(); * // } else if (k == "phone") { * // x = j.get<PhoneContact>(); * // } else { * // throw std::runtime_error("Failed to deserialize MyUnion: unknown type"); * // } * // } * * @example * // Fallback matching without a discriminator: * // Given: unionName = "MyUnion", items = { {"type": "int"}, {"type": "std::string"} } * // * // The generated output might look like: * // inline void from_json(const nlohmann::json& j, MyUnion& x) { * // try { * // // Try to deserialize as int * // x = j.get<int>(); * // return; * // } catch (const std::exception&) { * // // Fall through to try the next type * // } * // * // try { * // // Try to deserialize as std::string * // x = j.get<std::string>(); * // return; * // } catch (const std::exception&) { * // // None of the types matched. Error * // throw std::runtime_error("Failed to deserialize MyUnion: unknown format"); * // } * // } */ private _createUnionDeserializer; protected _push0: (item: string[], data: string) => number; protected _push1: (item: string[], data: string) => number; protected _push2: (item: string[], data: string) => number; protected _push3: (item: string[], data: string) => number; protected _push4: (item: string[], data: string) => number; } /** * @description Transpiler for Zod schemas to C++17 code. */ export declare class Zod2Cpp17 extends Zod2Cpp { constructor(opt?: IZod2CppOpt); /** Ex: std::variant<TypeA, TypeB> */ protected getUnionType: (itemsType: string[]) => string; protected _getOptional(type: string): string; /** * @description Generates a `to_json` function for a specified union type, allowing the JSON * library to correctly serialize any variant within the union. * * @param unionName The name of the union type. * @param itemsType A list of all variant types contained in the union. * * @example * // Given: unionName = "MyUnion", itemsType = {"int", "std::string"} * // The generated output might look like: * // * // inline void to_json(nlohmann::json& j, const MyUnion& x) { * // std::visit( * // [&j](auto&& arg) { * // using T = std::decay_t<decltype(arg)>; * // if constexpr (std::is_same_v<T, int>) { * // j = arg; * // } else if constexpr (std::is_same_v<T, std::string>) { * // j = arg; * // } else { * // throw std::runtime_error("Unknown MyUnion type."); * // } * // }, * // x * // ); * // } */ protected _createUnionSerializer(unionName: string, itemsType: string[]): void; }