zod-to-fields
Version:
Turn your Zod schemas into configurable field arrays for easy integration with HTML, React, Vue, and more.
85 lines • 3.5 kB
JavaScript
import { z } from 'zod';
import { handleNativeZodEnum, handleZodBoolean, handleZodEnum, handleZodNumber, handleZodString, } from '../utils/fieldHandlers';
import { setDefaultOptions } from '../utils/formHelpers';
import { isZodBoolean, isZodEnum, isZodNativeEnum, isZodNumber, isZodString, } from '../utils/typeGuards/zodTypeGuards';
import { unwrapZodType } from '../utils/zodHelpers';
/**
* Handles the conversion of Zod types to appropriate field options.
* @param {z.ZodTypeAny} fieldValue - The Zod schema type.
* @param {unknown} fieldOptions - Additional field options.
* @param {string} fieldKey - Additional field options.
* @throws Will throw an error if the Zod type is unsupported.
* @returns {GenericFieldOptions} - Returns the corresponding field element.
*/
function handleFieldValue(fieldKey, fieldValue, fieldOptions) {
const defaultOptions = setDefaultOptions(fieldKey, fieldValue);
const options = { ...defaultOptions, ...fieldOptions };
const baseType = unwrapZodType(fieldValue);
if (isZodString(baseType)) {
return handleZodString(options);
}
else if (isZodNumber(baseType)) {
return handleZodNumber(options);
}
else if (isZodBoolean(baseType)) {
return handleZodBoolean(options);
}
else if (isZodEnum(baseType)) {
return handleZodEnum(options, fieldValue);
}
else if (isZodNativeEnum(baseType)) {
return handleNativeZodEnum(options, fieldValue);
}
throw new Error(`Unsupported Zod type`);
}
/**
* Creates and manages field options based on a Zod schema.
* @param initialSchema The initial Zod schema.
* @returns An object containing methods for manipulating field options.
*/
const createOptions = (initialSchema) => {
let options = {};
/**
* Merges the provided field options with existing options.
* @param fieldOptions The field options to merge.
* @returns An object containing methods for further manipulation or to build the options. Chainable.
*/
const withFieldOptions = (fieldOptions) => {
options = { ...options, ...fieldOptions };
return { withFieldOptions, build };
};
/**
* Builds the final options object.
* @returns The built options object.
*/
const build = () => {
return options;
};
return { withFieldOptions, build };
};
/**
* Generates an array of form elements based on the given Zod schema and options.
* @param {ZodObject<T>} schema - The Zod schema.
* @param {MappedFieldOptions<K>} [options] - Additional field options.
* @returns {FormFieldsArray} - Returns an array of form fields.
* @template T, K
*/
const generateFields = (schema, options) => {
const finalResult = [];
for (const [fieldKey, fieldValue] of Object.entries(schema.shape)) {
if (fieldValue instanceof z.ZodObject) {
const description = fieldValue.description;
const nestedSchema = fieldValue;
const nestedOptions = options?.[fieldKey];
const generatedForm = generateFields(nestedSchema, nestedOptions);
finalResult.push({ [fieldKey]: { fields: generatedForm, description } });
continue;
}
const fieldOptions = options?.[fieldKey];
const element = handleFieldValue(fieldKey, fieldValue, fieldOptions);
finalResult.push(element);
}
return finalResult;
};
export { createOptions, generateFields, handleFieldValue };
//# sourceMappingURL=formGenerator.js.map