From c404e613f5e98deedaae2c04a6dfdf21adeee107 Mon Sep 17 00:00:00 2001 From: babayaga Date: Thu, 20 Feb 2025 18:14:32 +0100 Subject: [PATCH] zod --- packages/commons/dist/schemas/index.d.ts | 23 ++ packages/commons/dist/schemas/index.js | 204 +++++++++++++++++ packages/commons/dist/schemas/openapi.d.ts | 1 + packages/commons/dist/schemas/openapi.js | 22 ++ packages/commons/dist/schemas/path.d.ts | 30 +++ packages/commons/dist/schemas/path.js | 237 +++++++++++++++++++ packages/commons/dist/schemas/types.d.ts | 194 ++++++++++++++++ packages/commons/dist/schemas/types.js | 140 ++++++++++++ packages/commons/dist/schemas/vfs.d.ts | 1 + packages/commons/dist/schemas/vfs.js | 3 + packages/commons/dist/schemas/zod_map.d.ts | 46 ++++ packages/commons/dist/schemas/zod_map.js | 99 ++++++++ packages/commons/src/schemas/index.ts | 211 +++++++++++++++++ packages/commons/src/schemas/openapi.ts | 20 ++ packages/commons/src/schemas/path.ts | 253 +++++++++++++++++++++ packages/commons/src/schemas/types.ts | 187 +++++++++++++++ packages/commons/src/schemas/vfs.ts | 1 + packages/commons/src/schemas/zod_map.ts | 109 +++++++++ 18 files changed, 1781 insertions(+) create mode 100644 packages/commons/dist/schemas/index.d.ts create mode 100644 packages/commons/dist/schemas/index.js create mode 100644 packages/commons/dist/schemas/openapi.d.ts create mode 100644 packages/commons/dist/schemas/openapi.js create mode 100644 packages/commons/dist/schemas/path.d.ts create mode 100644 packages/commons/dist/schemas/path.js create mode 100644 packages/commons/dist/schemas/types.d.ts create mode 100644 packages/commons/dist/schemas/types.js create mode 100644 packages/commons/dist/schemas/vfs.d.ts create mode 100644 packages/commons/dist/schemas/vfs.js create mode 100644 packages/commons/dist/schemas/zod_map.d.ts create mode 100644 packages/commons/dist/schemas/zod_map.js create mode 100644 packages/commons/src/schemas/index.ts create mode 100644 packages/commons/src/schemas/openapi.ts create mode 100644 packages/commons/src/schemas/path.ts create mode 100644 packages/commons/src/schemas/types.ts create mode 100644 packages/commons/src/schemas/vfs.ts create mode 100644 packages/commons/src/schemas/zod_map.ts diff --git a/packages/commons/dist/schemas/index.d.ts b/packages/commons/dist/schemas/index.d.ts new file mode 100644 index 00000000..6775674b --- /dev/null +++ b/packages/commons/dist/schemas/index.d.ts @@ -0,0 +1,23 @@ +import * as CLI from 'yargs'; +import { z, ZodTypeAny, ZodObject } from 'zod'; +export * from './path.js'; +export * from './zod_map.js'; +export declare const generate_interfaces: (schemas: ZodObject[], dst: string) => void; +export declare const enumerateHelpStrings: (schema: ZodTypeAny, path: string[], logger: any) => void; +export declare const yargsDefaults: (yargs: CLI.Argv) => any; +export declare const getInnerSchema: (schema: ZodTypeAny) => ZodTypeAny; +export declare const getInnerType: (type: ZodTypeAny) => any; +export declare const getDefaultValue: (schema: ZodTypeAny) => any; +export declare const getFieldDefaultValue: (schema: ZodTypeAny) => any | undefined; +export declare const getDescription: (schema: ZodTypeAny) => string | undefined; +export declare const toYargs: (yargs: CLI.Argv, zodSchema: ZodObject, options?: { + onKey?: (yargs: CLI.Argv, key: string, options: any) => any; +}) => CLI.Argv; +export declare const WRITERS: { + '.json': (data: any, file: string, name: string, options: {}) => void; +}; +export declare const writer: (file: string) => any; +export declare const write: (schemas: ZodObject[], file: string, name: string, options: {}) => void; +export declare const combineValidatorsOr: (validators: z.ZodTypeAny[]) => z.ZodEffects; +export declare const combineValidatorsOrUsingZod: (validators: z.ZodTypeAny[]) => z.ZodTypeAny; +export declare const combineValidatorsOrUsingZod2: (validators: z.ZodTypeAny[]) => z.ZodTypeAny; diff --git a/packages/commons/dist/schemas/index.js b/packages/commons/dist/schemas/index.js new file mode 100644 index 00000000..c59d02a4 --- /dev/null +++ b/packages/commons/dist/schemas/index.js @@ -0,0 +1,204 @@ +import * as path from 'path'; +import { z, ZodObject, ZodEffects, ZodOptional, ZodDefault } from 'zod'; +import { sync as writeFS } from '@polymech/fs/write'; +import { zodToTs, printNode } from 'zod-to-ts'; +import { zodToJsonSchema } from "zod-to-json-schema"; +import { logger } from '@/logger.js'; +export * from './path.js'; +export * from './zod_map.js'; +export const generate_interfaces = (schemas, dst) => { + const types = schemas.map(schema => `export interface ${schema.description || 'IOptions'} ${printNode(zodToTs(schema).node)}`); + writeFS(dst, types.join('\n')); +}; +export const enumerateHelpStrings = (schema, path = [], logger) => { + if (schema instanceof ZodObject) { + for (const key in schema.shape) { + const nestedSchema = schema.shape[key]; + enumerateHelpStrings(nestedSchema, [...path, key], logger); + } + } + else { + const description = schema._def.description; + if (description) { + logger.debug(`\t ${path.join('.')}: ${description}`); + } + } +}; +export const yargsDefaults = (yargs) => yargs.parserConfiguration({ "camel-case-expansion": false }); +export const getInnerSchema = (schema) => { + while (schema instanceof ZodEffects) { + schema = schema._def.schema; + } + return schema; +}; +export const getInnerType = (type) => { + while (type instanceof ZodOptional) { + type = type._def.innerType; + } + while (type._def.typeName === 'ZodDefault' || type._def.typeName === 'ZodOptional') { + type = type._def.innerType; + } + return type._def.typeName; +}; +export const getDefaultValue = (schema) => { + if (schema instanceof ZodDefault) { + return schema._def.defaultValue(); + } + return undefined; +}; +export const getFieldDefaultValue = (schema) => { + if (!schema) { + return undefined; + } + if (schema._def.typeName === 'ZodDefault') { + return schema._def.defaultValue(); + } + if (schema instanceof ZodOptional) { + return getFieldDefaultValue(schema.unwrap()); + } + if (schema instanceof ZodEffects) { + return getFieldDefaultValue(schema._def.schema); + } + if (typeof schema._def) { + return getFieldDefaultValue(schema._def.schema); + } + return undefined; +}; +export const getDescription = (schema) => { + if (!schema) { + return undefined; + } + if (schema._def.description) { + return schema._def.description; + } + if (schema instanceof ZodOptional) { + return getDescription(schema.unwrap()); + } + if (schema instanceof ZodEffects) { + return getDescription(schema._def.schema); + } + if (typeof schema._def) { + return getDescription(schema._def.schema); + } + return undefined; +}; +export const toYargs = (yargs, zodSchema, options) => { + yargsDefaults(yargs); + try { + const shape = zodSchema.shape; + for (const key in shape) { + const zodField = shape[key]; + const innerDef = getInnerSchema(zodField); + if (!innerDef) { + continue; + } + let type; + const inner_type = getInnerType(innerDef); + let descriptionExtra = ''; + switch (inner_type) { + case 'ZodString': + type = 'string'; + break; + case 'ZodBoolean': + type = 'boolean'; + break; + case 'ZodNumber': + type = 'number'; + break; + case 'ZodOptional': + case 'ZodEnum': + type = getInnerType(innerDef); + if (innerDef._def.typeName === 'ZodEnum') { + descriptionExtra = `\n\t ${innerDef._def.values.join(' \n\t ')}`; + } + break; + } + const defaultValue = getFieldDefaultValue(zodField); + let handled = false; + const args = { + type, + default: defaultValue, + describe: `${zodField._def.description || ''} ${descriptionExtra}`.trim() + }; + if (options?.onKey) { + handled = options.onKey(yargs, key, args); + } + if (!handled) { + yargs.option(key, args); + } + } + return yargs; + } + catch (error) { + logger.error('Error processing schema:', error); + return yargs; + } +}; +///////////////////////////////////////////////////////// +// +// Schema Writers +// +const extension = (file) => path.parse(file).ext; +const json = (data, file, name, options) => writeFS(file, data.map((s) => zodToJsonSchema(s, name))); +export const WRITERS = { + '.json': json +}; +export const writer = (file) => WRITERS[extension(file)]; +export const write = (schemas, file, name, options) => { + if (!WRITERS[extension(file)]) { + logger.error(`No writer found for file extension: ${extension(file)} : file: ${file}`); + return; + } + logger.debug(`Writing schema to ${file} : ${name}`); + try { + writer(file)(schemas, file, name, options); + } + catch (e) { + logger.trace(`Error writing schema to ${file} : ${name}`, e, e.stack, e.message); + } +}; +//////////////////////////////////////////////////////////////////// +// +// Schema Combinators +export const combineValidatorsOr = (validators) => { + return z.string().refine((value) => { + const errors = []; + const isValid = validators.some((validator) => { + try { + validator.parse(value); + return true; + } + catch (err) { + errors.push(err.errors); + return false; + } + }); + if (!isValid) { + throw new z.ZodError(errors.flat()); + } + return true; + }, 'Invalid value for all provided validators'); +}; +export const combineValidatorsOrUsingZod = (validators) => { + return validators.reduce((acc, validator) => acc.or(validator)); +}; +export const combineValidatorsOrUsingZod2 = (validators) => { + return validators.reduce((acc, validator) => { + return acc.or(validator).refine((value) => { + try { + acc.parse(value); + return true; + } + catch (errAcc) { + try { + validator.parse(value); + return true; + } + catch (errValidator) { + throw new z.ZodError([...errAcc.errors, ...errValidator.errors]); + } + } + }); + }); +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NoZW1hcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUU1QixPQUFPLEVBQUUsQ0FBQyxFQUFjLFNBQVMsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUNuRixPQUFPLEVBQUUsSUFBSSxJQUFJLE9BQU8sRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRXBDLGNBQWMsV0FBVyxDQUFBO0FBQ3pCLGNBQWMsY0FBYyxDQUFBO0FBRTVCLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsT0FBeUIsRUFBRSxHQUFXLEVBQUUsRUFBRTtJQUMxRSxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsb0JBQW9CLE1BQU0sQ0FBQyxXQUFXLElBQUksVUFBVSxJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQzlILE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0FBQ2xDLENBQUMsQ0FBQTtBQUNELE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsTUFBa0IsRUFBRSxPQUFpQixFQUFFLEVBQUUsTUFBVyxFQUFRLEVBQUU7SUFDL0YsSUFBSSxNQUFNLFlBQVksU0FBUyxFQUFFLENBQUM7UUFDOUIsS0FBSyxNQUFNLEdBQUcsSUFB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 \ No newline at end of file diff --git a/packages/commons/dist/schemas/openapi.d.ts b/packages/commons/dist/schemas/openapi.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/commons/dist/schemas/openapi.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/commons/dist/schemas/openapi.js b/packages/commons/dist/schemas/openapi.js new file mode 100644 index 00000000..b2b9dc1d --- /dev/null +++ b/packages/commons/dist/schemas/openapi.js @@ -0,0 +1,22 @@ +export {}; +/* +export const openapi = (data: ZodObject[], file: string, name: string, options: {}) => { + const registry = new OpenAPIRegistry() + data.forEach((s) => registry.register(s.description, s)) + const generator = new OpenApiGeneratorV3(registry.definitions) + const component = generator.generateComponents() + // const content = stringifyYAML(component) + return component +} +*/ +/* +const yaml = (data: ZodObject[], file: string, name: string, options: {}) => { + const registry = new OpenAPIRegistry() + data.forEach((s) => registry.register(s.description, s)) + const generator = new OpenApiGeneratorV3(registry.definitions) + const component = generator.generateComponents() + logger.debug(`Writing schema to ${file} : ${name}`,component) + writeFS(file,stringifyYAML(component)) +} +*/ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY2hlbWFzL29wZW5hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7RUFTRTtBQUNGOzs7Ozs7Ozs7RUFTRSJ9 \ No newline at end of file diff --git a/packages/commons/dist/schemas/path.d.ts b/packages/commons/dist/schemas/path.d.ts new file mode 100644 index 00000000..2092e35a --- /dev/null +++ b/packages/commons/dist/schemas/path.d.ts @@ -0,0 +1,30 @@ +import { z, ZodTypeAny } from 'zod'; +export declare enum E_PATH { + ENSURE_PATH_EXISTS = 1, + INVALID_INPUT = 2, + ENSURE_DIRECTORY_WRITABLE = 3, + ENSURE_FILE_IS_JSON = 4, + ENSURE_PATH_IS_ABSOLUTE = 5, + ENSURE_PATH_IS_RELATIVE = 6, + GET_PATH_INFO = 7 +} +export declare const Transformers: Record; +export declare const TransformersDescription: { + description: string; + fn: any; +}[]; +export declare const extendSchema: (baseSchema: z.ZodObject, extend: Record) => z.ZodObject, "strip", z.ZodTypeAny, { + [x: string]: any; +}, { + [x: string]: any; +}>; +export declare const ENSURE_DIRECTORY_WRITABLE: (inputPath: string, ctx: any, variables: Record) => string; +export declare const IS_VALID_STRING: (inputPath: string) => boolean; +export declare const ENSURE_PATH_EXISTS: (inputPath: string, ctx: any, variables: Record) => string; +export declare const test: () => z.ZodObject, "strip", z.ZodTypeAny, { + [x: string]: any; +}, { + [x: string]: any; +}>; +export declare const Templates: Record; +export declare const extend: (baseSchema: ZodTypeAny, template: any, variables?: Record) => z.ZodTypeAny; diff --git a/packages/commons/dist/schemas/path.js b/packages/commons/dist/schemas/path.js new file mode 100644 index 00000000..1d4e61de --- /dev/null +++ b/packages/commons/dist/schemas/path.js @@ -0,0 +1,237 @@ +import { z } from 'zod'; +import * as path from 'path'; +import { accessSync, constants, lstatSync, existsSync } from 'fs'; +import { isString } from '@polymech/core/primitives'; +import { sync as exists } from '@polymech/fs/exists'; +import { sync as read } from '@polymech/fs/read'; +import { logger } from '@/logger.js'; +import { DEFAULT_VARS, resolve, template } from '@/variables.js'; +import { getDescription } from '@/schemas/index.js'; +import { isFile } from '@/lib/fs.js'; +const DefaultPathSchemaBase = z.string().describe('Path to a file or directory'); +const PathErrorMessages = { + INVALID_INPUT: 'INVALID_INPUT: ${inputPath}', + PATH_DOES_NOT_EXIST: 'Path does not exist ${inputPath} = ${resolvedPath}', + DIRECTORY_NOT_WRITABLE: 'Directory is not writable ${inputPath} = ${resolvedPath}', + NOT_A_DIRECTORY: 'Path is not a directory or does not exist ${inputPath} = ${resolvedPath}', + NOT_A_JSON_FILE: 'File is not a JSON file or does not exist ${inputPath} = ${resolvedPath}', + PATH_NOT_ABSOLUTE: 'Path is not absolute ${inputPath} = ${resolvedPath}', + PATH_NOT_RELATIVE: 'Path is not relative ${inputPath} = ${resolvedPath}', +}; +export var E_PATH; +(function (E_PATH) { + E_PATH[E_PATH["ENSURE_PATH_EXISTS"] = 1] = "ENSURE_PATH_EXISTS"; + E_PATH[E_PATH["INVALID_INPUT"] = 2] = "INVALID_INPUT"; + E_PATH[E_PATH["ENSURE_DIRECTORY_WRITABLE"] = 3] = "ENSURE_DIRECTORY_WRITABLE"; + E_PATH[E_PATH["ENSURE_FILE_IS_JSON"] = 4] = "ENSURE_FILE_IS_JSON"; + E_PATH[E_PATH["ENSURE_PATH_IS_ABSOLUTE"] = 5] = "ENSURE_PATH_IS_ABSOLUTE"; + E_PATH[E_PATH["ENSURE_PATH_IS_RELATIVE"] = 6] = "ENSURE_PATH_IS_RELATIVE"; + E_PATH[E_PATH["GET_PATH_INFO"] = 7] = "GET_PATH_INFO"; +})(E_PATH || (E_PATH = {})); +export const Transformers = { + resolve: (val, variables = {}) => { + if (!val) { + return null; + } + return { + resolved: path.resolve(resolve(val, false, variables)), + source: val + }; + }, + json: (val, variables = {}) => { + if (!val) { + return null; + } + const resolved = path.resolve(resolve(isString(val) ? val : val.source, false, variables)); + return { + resolved, + source: val, + value: read(resolved, 'json') + }; + }, + string: (val, variables = {}) => { + if (!val) { + return null; + } + let src = isString(val) ? val : val.source; + src = resolve(src, false, variables); + const resolved = path.resolve(src); + if (!exists(resolved) || !isFile(resolved)) { + return { + resolved, + source: val, + value: null + }; + } + else { + let value = null; + try { + value = read(resolved, 'string'); + } + catch (e) { + logger.error('Failed to read file', { resolved, source: val, error: e.message }); + } + return { + resolved, + source: val, + value + }; + } + } +}; +export const TransformersDescription = [ + { + description: 'RESOLVE_PATH', + fn: Transformers.resolve + }, + { + description: 'READ_JSON', + fn: Transformers.json + }, + { + description: 'READ_STRING', + fn: Transformers.string + } +]; +const extendType = (type, extend, variables = {}) => { + if (Array.isArray(extend.refine)) { + for (const refine of extend.refine) { + type = type.refine(refine); + } + } + else { + type = type.refine(extend.refine); + } + if (Array.isArray(extend.transform)) { + for (const transform of extend.transform) { + type = type.transform((val) => transform(val, variables)); + } + } + else { + type = type.transform(extend.transform); + } + return type; +}; +const extendTypeDescription = (type, extension, variables = {}) => { + const description = getDescription(type) || ''; + let transformerDescriptions = 'Transformers:\n'; + if (Array.isArray(extension.transform)) { + for (const transform of extension.transform) { + transformerDescriptions += transformerDescription(transform) + '\n'; + } + } + else { + transformerDescriptions += transformerDescription(extension.transform) + '\n'; + } + type = type.describe(description + '\n' + transformerDescriptions); + return type; +}; +const transformerDescription = (fn) => { + const description = TransformersDescription.find((t) => t.fn === fn); + return description ? description.description : 'Unknown'; +}; +export const extendSchema = (baseSchema, extend) => { + const baseShape = baseSchema.shape; + const extendedShape = { ...baseShape }; + for (const [key, refines] of Object.entries(extend)) { + if (!baseShape[key]) + continue; + let fieldSchema = baseShape[key]; + if (Array.isArray(refines.refine)) { + for (const refine of refines.refine) { + fieldSchema = fieldSchema.superRefine(refine); + } + } + else { + fieldSchema = fieldSchema.superRefine(refines); + } + if (Array.isArray(refines.transform)) { + for (const transform of refines.transform) { + fieldSchema = fieldSchema.transform((val) => transform(val)); + } + } + else { + fieldSchema = fieldSchema.transform(refines.transform); + } + extendedShape[key] = fieldSchema; + } + return z.object(extendedShape); +}; +export const ENSURE_DIRECTORY_WRITABLE = (inputPath, ctx, variables) => { + const resolvedPath = path.resolve(resolve(inputPath, false, variables)); + const parts = path.parse(resolvedPath); + if (resolvedPath && existsSync(parts.dir) && lstatSync(parts.dir).isDirectory()) { + try { + accessSync(resolvedPath, constants.W_OK); + return resolvedPath; + } + catch (e) { + ctx.addIssue({ + code: E_PATH.ENSURE_DIRECTORY_WRITABLE, + message: template(PathErrorMessages.DIRECTORY_NOT_WRITABLE, { inputPath, resolvedPath }) + }); + return z.NEVER; + } + } + else { + ctx.addIssue({ + code: E_PATH.ENSURE_DIRECTORY_WRITABLE, + message: template(PathErrorMessages.NOT_A_DIRECTORY, { inputPath, resolvedPath }) + }); + return z.NEVER; + } +}; +export const IS_VALID_STRING = (inputPath) => isString(inputPath); +export const ENSURE_PATH_EXISTS = (inputPath, ctx, variables) => { + if (!inputPath || !ctx) { + return z.NEVER; + } + if (!isString(inputPath)) { + ctx.addIssue({ + code: E_PATH.INVALID_INPUT, + message: template(PathErrorMessages.INVALID_INPUT, {}) + }); + return z.NEVER; + } + const resolvedPath = path.resolve(resolve(inputPath, false, variables)); + if (!exists(resolvedPath)) { + ctx.addIssue({ + code: E_PATH.ENSURE_PATH_EXISTS, + message: template(PathErrorMessages.PATH_DOES_NOT_EXIST, { inputPath, resolvedPath }) + }); + return z.NEVER; + } + return resolvedPath; +}; +export const test = () => { + const BaseCompilerOptions = () => z.object({ + root: DefaultPathSchemaBase.default(`${process.cwd()}`) + }); + const ret = extendSchema(BaseCompilerOptions(), { + root: { + refine: [ + (val, ctx) => ENSURE_DIRECTORY_WRITABLE(val, ctx, DEFAULT_VARS({ exampleVar: 'exampleValue' })), + (val, ctx) => ENSURE_PATH_EXISTS(val, ctx, DEFAULT_VARS({ exampleVar: 'exampleValue' })) + ], + transform: [ + (val) => path.resolve(resolve(val, false, DEFAULT_VARS({ exampleVar: 'exampleValue' }))) + ] + } + }); + return ret; +}; +export const Templates = { + json: { + refine: [IS_VALID_STRING, ENSURE_PATH_EXISTS], + transform: [Transformers.resolve, Transformers.json] + }, + string: { + refine: [ENSURE_PATH_EXISTS], + transform: [Transformers.resolve, Transformers.string] + } +}; +export const extend = (baseSchema, template, variables = {}) => { + const type = extendType(baseSchema, template, variables); + return extendTypeDescription(type, template, variables); +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY2hlbWFzL3BhdGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLENBQUMsRUFBYyxNQUFNLEtBQUssQ0FBQTtBQUNuQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUM1QixPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sSUFBSSxDQUFBO0FBRWpFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsSUFBSSxJQUFJLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUNoRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQU9wQyxNQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtBQUVoRixNQUFNLGlCQUFpQixHQUFHO0lBQ3RCLGFBQWEsRUFBRSw2QkFBNkI7SUFDNUMsbUJBQW1CLEVBQUUsb0RBQW9EO0lBQ3pFLHNCQUFzQixFQUFFLDBEQUEwRDtJQUNsRixlQUFlLEVBQUUsMEVBQTBFO0lBQzNGLGVBQWUsRUFBRSwwRUFBMEU7SUFDM0YsaUJBQWlCLEVBQUUscURBQXFEO0lBQ3hFLGlCQUFpQixFQUFFLHFEQUFxRDtDQUNsRSxDQUFBO0FBRVYsTUFBTSxDQUFOLElBQVksTUFRWDtBQVJE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 \ No newline at end of file diff --git a/packages/commons/dist/schemas/types.d.ts b/packages/commons/dist/schemas/types.d.ts new file mode 100644 index 00000000..7126d7e8 --- /dev/null +++ b/packages/commons/dist/schemas/types.d.ts @@ -0,0 +1,194 @@ +export declare enum FLAG { + /** + * Instruct for no additional extra processing + * @constant + * @type int + */ + NONE = 0, + /** + * Will instruct the pre/post processor to base-64 decode or encode + * @constant + * @type int + */ + BASE_64 = 1, + /** + * Post/Pre process the value with a user function + * @constant + * @type int + */ + USE_FUNCTION = 2, + /** + * Replace variables with local scope's variables during the post/pre process + * @constant + * @type int + */ + REPLACE_VARIABLES = 4, + /** + * Replace variables with local scope's variables during the post/pre process but evaluate the whole string + * as Javascript + * @constant + * @type int + */ + REPLACE_VARIABLES_EVALUATED = 8, + /** + * Will instruct the pre/post processor to escpape evaluated or replaced variables or expressions + * @constant + * @type int + */ + ESCAPE = 16, + /** + * Will instruct the pre/post processor to replace block calls with oridinary vanilla script + * @constant + * @type int + */ + REPLACE_BLOCK_CALLS = 32, + /** + * Will instruct the pre/post processor to remove variable delimitters/placeholders from the final string + * @constant + * @type int + */ + REMOVE_DELIMTTERS = 64, + /** + * Will instruct the pre/post processor to remove "[" ,"]" , "(" , ")" , "{", "}" , "*" , "+" , "." + * @constant + * @type int + */ + ESCAPE_SPECIAL_CHARS = 128, + /** + * Will instruct the pre/post processor to use regular expressions over string substitution + * @constant + * @type int + */ + USE_REGEX = 256, + /** + * Will instruct the pre/post processor to use Filtrex (custom bison parser, needs xexpression) over string substitution + * @constant + * @type int + */ + USE_FILTREX = 512, + /** + * Cascade entry. There are cases where #USE_FUNCTION is not enough or we'd like to avoid further type checking. + * @constant + * @type int + */ + CASCADE = 1024, + /** + * Cascade entry. There are cases where #USE_FUNCTION is not enough or we'd like to avoid further type checking. + * @constant + * @type int + */ + EXPRESSION = 2048, + /** + * Dont parse anything + * @constant + * @type int + */ + DONT_PARSE = 4096, + /** + * Convert to hex + * @constant + * @type int + */ + TO_HEX = 8192, + /** + * Convert to hex + * @constant + * @type int + */ + REPLACE_HEX = 16384, + /** + * Wait for finish + * @constant + * @type int + */ + WAIT = 32768, + /** + * Wait for finish + * @constant + * @type int + */ + DONT_ESCAPE = 65536, + /** + * Flag to mark the maximum core bit mask, after here its user land + * @constant + * @type int + */ + END = 131072 +} +export declare enum EType { + Number = "Number", + String = "String", + Boolean = "Boolean", + Date = "Date", + TimeStamp = "TimeStamp", + Duration = "Duration", + Url = "Url", + UrlScheme = "Url-Scheme", + Asset = "Asset", + Symbol = "Symbol", + Value = "Value", + Values = "Values", + Attribute = "Attribute", + Parameter = "Parameter", + Operation = "Operation", + ParameterOperation = "ParameterOperation", + Template = "Template", + Arguments = "Arguments" +} +export type TVector2D = [number, number]; +export type TVector3D = [number, number, number]; +export type TBBox = [TVector3D, TVector3D]; +export type TQuaternion = [number, number, number, number]; +export type TFlags = Record; +export type TExpression = string | [string | RegExp, { + [key: string]: any; +}]; +export type TOptions = { + flags?: TFlags | { + [key: string]: any; + }; +}; +export interface IUrlScheme { + url: string; + options?: { + [key: string]: any; + }; +} +export interface IAsset { + urlScheme: IUrlScheme; + options?: { + [key: string]: any; + }; +} +export type TSelector = TExpression | [TExpression, { + [key: string]: any; +}]; +export interface ITypeInfo { + type: string; + symbol: bigint; +} +export interface IRef { + key: string | string; + struct: { + [key: string]: any; + }; +} +export interface IAttribute { + type: ITypeInfo; + value: bigint; +} +export interface IParameter { + type: ITypeInfo; + value: bigint; +} +export interface IParameterOperation { + param1: bigint; + param2: bigint; + operation: bigint; +} +export type TTemplate = string | [ITypeInfo | TSelector, { + [key: string]: any; +}]; +export type TArguments = { + [key: string]: any; +} | any[]; diff --git a/packages/commons/dist/schemas/types.js b/packages/commons/dist/schemas/types.js new file mode 100644 index 00000000..22bc28e5 --- /dev/null +++ b/packages/commons/dist/schemas/types.js @@ -0,0 +1,140 @@ +export var FLAG; +(function (FLAG) { + /** + * Instruct for no additional extra processing + * @constant + * @type int + */ + FLAG[FLAG["NONE"] = 0] = "NONE"; + /** + * Will instruct the pre/post processor to base-64 decode or encode + * @constant + * @type int + */ + FLAG[FLAG["BASE_64"] = 1] = "BASE_64"; + /** + * Post/Pre process the value with a user function + * @constant + * @type int + */ + FLAG[FLAG["USE_FUNCTION"] = 2] = "USE_FUNCTION"; + /** + * Replace variables with local scope's variables during the post/pre process + * @constant + * @type int + */ + FLAG[FLAG["REPLACE_VARIABLES"] = 4] = "REPLACE_VARIABLES"; + /** + * Replace variables with local scope's variables during the post/pre process but evaluate the whole string + * as Javascript + * @constant + * @type int + */ + FLAG[FLAG["REPLACE_VARIABLES_EVALUATED"] = 8] = "REPLACE_VARIABLES_EVALUATED"; + /** + * Will instruct the pre/post processor to escpape evaluated or replaced variables or expressions + * @constant + * @type int + */ + FLAG[FLAG["ESCAPE"] = 16] = "ESCAPE"; + /** + * Will instruct the pre/post processor to replace block calls with oridinary vanilla script + * @constant + * @type int + */ + FLAG[FLAG["REPLACE_BLOCK_CALLS"] = 32] = "REPLACE_BLOCK_CALLS"; + /** + * Will instruct the pre/post processor to remove variable delimitters/placeholders from the final string + * @constant + * @type int + */ + FLAG[FLAG["REMOVE_DELIMTTERS"] = 64] = "REMOVE_DELIMTTERS"; + /** + * Will instruct the pre/post processor to remove "[" ,"]" , "(" , ")" , "{", "}" , "*" , "+" , "." + * @constant + * @type int + */ + FLAG[FLAG["ESCAPE_SPECIAL_CHARS"] = 128] = "ESCAPE_SPECIAL_CHARS"; + /** + * Will instruct the pre/post processor to use regular expressions over string substitution + * @constant + * @type int + */ + FLAG[FLAG["USE_REGEX"] = 256] = "USE_REGEX"; + /** + * Will instruct the pre/post processor to use Filtrex (custom bison parser, needs xexpression) over string substitution + * @constant + * @type int + */ + FLAG[FLAG["USE_FILTREX"] = 512] = "USE_FILTREX"; + /** + * Cascade entry. There are cases where #USE_FUNCTION is not enough or we'd like to avoid further type checking. + * @constant + * @type int + */ + FLAG[FLAG["CASCADE"] = 1024] = "CASCADE"; + /** + * Cascade entry. There are cases where #USE_FUNCTION is not enough or we'd like to avoid further type checking. + * @constant + * @type int + */ + FLAG[FLAG["EXPRESSION"] = 2048] = "EXPRESSION"; + /** + * Dont parse anything + * @constant + * @type int + */ + FLAG[FLAG["DONT_PARSE"] = 4096] = "DONT_PARSE"; + /** + * Convert to hex + * @constant + * @type int + */ + FLAG[FLAG["TO_HEX"] = 8192] = "TO_HEX"; + /** + * Convert to hex + * @constant + * @type int + */ + FLAG[FLAG["REPLACE_HEX"] = 16384] = "REPLACE_HEX"; + /** + * Wait for finish + * @constant + * @type int + */ + FLAG[FLAG["WAIT"] = 32768] = "WAIT"; + /** + * Wait for finish + * @constant + * @type int + */ + FLAG[FLAG["DONT_ESCAPE"] = 65536] = "DONT_ESCAPE"; + /** + * Flag to mark the maximum core bit mask, after here its user land + * @constant + * @type int + */ + FLAG[FLAG["END"] = 131072] = "END"; +})(FLAG || (FLAG = {})); +export var EType; +(function (EType) { + EType["Number"] = "Number"; + EType["String"] = "String"; + EType["Boolean"] = "Boolean"; + EType["Date"] = "Date"; + EType["TimeStamp"] = "TimeStamp"; + EType["Duration"] = "Duration"; + EType["Url"] = "Url"; + EType["UrlScheme"] = "Url-Scheme"; + EType["Asset"] = "Asset"; + EType["Symbol"] = "Symbol"; + EType["Value"] = "Value"; + EType["Values"] = "Values"; + EType["Attribute"] = "Attribute"; + EType["Parameter"] = "Parameter"; + EType["Operation"] = "Operation"; + EType["ParameterOperation"] = "ParameterOperation"; + EType["Template"] = "Template"; + EType["Arguments"] = "Arguments"; +})(EType || (EType = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NoZW1hcy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSxJQW9IWDtBQXBIRCxXQUFZLElBQUk7SUFDZjs7OztPQUlHO0lBQ0gsK0JBQWlCLENBQUE7SUFDakI7Ozs7T0FJRztJQUNILHFDQUFvQixDQUFBO0lBQ3BCOzs7O09BSUc7SUFDSCwrQ0FBeUIsQ0FBQTtJQUN6Qjs7OztPQUlHO0lBQ0gseURBQThCLENBQUE7SUFDOUI7Ozs7O09BS0c7SUFDSCw2RUFBd0MsQ0FBQTtJQUN4Qzs7OztPQUlHO0lBQ0gsb0NBQW1CLENBQUE7SUFDbkI7Ozs7T0FJRztJQUNILDhEQUFnQyxDQUFBO0lBQ2hDOzs7O09BSUc7SUFDSCwwREFBOEIsQ0FBQTtJQUM5Qjs7OztPQUlHO0lBQ0gsaUVBQWlDLENBQUE7SUFDakM7Ozs7T0FJRztJQUNILDJDQUFzQixDQUFBO0lBQ3RCOzs7O09BSUc7SUFDSCwrQ0FBd0IsQ0FBQTtJQUN4Qjs7OztPQUlHO0lBQ0gsd0NBQW9CLENBQUE7SUFDcEI7Ozs7T0FJRztJQUNILDhDQUF1QixDQUFBO0lBQ3ZCOzs7O09BSUc7SUFDSCw4Q0FBd0IsQ0FBQTtJQUN4Qjs7OztPQUlHO0lBQ0gsc0NBQW9CLENBQUE7SUFDcEI7Ozs7T0FJRztJQUNILGlEQUF5QixDQUFBO0lBQ3pCOzs7O09BSUc7SUFDSCxtQ0FBa0IsQ0FBQTtJQUNsQjs7OztPQUlHO0lBQ0gsaURBQXlCLENBQUE7SUFDekI7Ozs7T0FJRztJQUNILGtDQUFpQixDQUFBO0FBQ2xCLENBQUMsRUFwSFcsSUFBSSxLQUFKLElBQUksUUFvSGY7QUFFRCxNQUFNLENBQU4sSUFBWSxLQW9CWDtBQXBCRCxXQUFZLEtBQUs7SUFFYiwwQkFBaUIsQ0FBQTtJQUNqQiwwQkFBaUIsQ0FBQTtJQUNqQiw0QkFBbUIsQ0FBQTtJQUNuQixzQkFBYSxDQUFBO0lBQ2IsZ0NBQXVCLENBQUE7SUFDdkIsOEJBQXFCLENBQUE7SUFDckIsb0JBQVcsQ0FBQTtJQUNYLGlDQUF3QixDQUFBO0lBQ3hCLHdCQUFlLENBQUE7SUFDZiwwQkFBaUIsQ0FBQTtJQUNqQix3QkFBZSxDQUFBO0lBQ2YsMEJBQWlCLENBQUE7SUFDakIsZ0NBQXVCLENBQUE7SUFDdkIsZ0NBQXVCLENBQUE7SUFDdkIsZ0NBQXVCLENBQUE7SUFDdkIsa0RBQXlDLENBQUE7SUFDekMsOEJBQXFCLENBQUE7SUFDckIsZ0NBQXVCLENBQUE7QUFDM0IsQ0FBQyxFQXBCVyxLQUFLLEtBQUwsS0FBSyxRQW9CaEIifQ== \ No newline at end of file diff --git a/packages/commons/dist/schemas/vfs.d.ts b/packages/commons/dist/schemas/vfs.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/commons/dist/schemas/vfs.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/commons/dist/schemas/vfs.js b/packages/commons/dist/schemas/vfs.js new file mode 100644 index 00000000..9adece09 --- /dev/null +++ b/packages/commons/dist/schemas/vfs.js @@ -0,0 +1,3 @@ +export {}; +//import { zodToJsonSchema } from "zod-to-json-schema" +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmZzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjaGVtYXMvdmZzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxzREFBc0QifQ== \ No newline at end of file diff --git a/packages/commons/dist/schemas/zod_map.d.ts b/packages/commons/dist/schemas/zod_map.d.ts new file mode 100644 index 00000000..d6b6127a --- /dev/null +++ b/packages/commons/dist/schemas/zod_map.d.ts @@ -0,0 +1,46 @@ +import { ZodObject, ZodTypeAny } from 'zod'; +/** + * Manages a collection of Zod schema properties + * and combines them into a single Zod object schema. + * + * @template MetaType The type of metadata you want to store for each field. + * Defaults to Record if not provided. + */ +export declare class ZodMetaMap> { + private fieldMap; + /** + * Adds a Zod schema under a specific key (property name), + * optionally attaching typed metadata. + * + * @param key - The name of the property in the root object. + * @param schema - The Zod schema for that property. + * @param metadata - Optional metadata object (type MetaType). + */ + add(key: string, schema: T, metadata?: MetaType): this; + /** + * Builds and returns a root Zod object + * that combines all properties which were added. + */ + root(): ZodObject>; + /** + * Retrieves the metadata for a specific key, if any. + */ + getMetadata(key: string): MetaType | undefined; + /** + * Static factory method: creates a SchemaMetaManager + * while letting you optionally specify the MetaType. + * + * Usage: + * const manager = SchemaMetaManager.create(); + */ + static create>(): ZodMetaMap; + /** + * Returns a basic UiSchema object that RJSF can use to render form controls. + * + * - Adds a top-level "ui:submitButtonOptions" (example). + * - For each field, we set `ui:title` (uppercase key), + * `ui:description` (from Zod's .describe() if available), + * and a naive placeholder from the default value (if parse(undefined) succeeds). + */ + getUISchema(): Record; +} diff --git a/packages/commons/dist/schemas/zod_map.js b/packages/commons/dist/schemas/zod_map.js new file mode 100644 index 00000000..ee3f66d9 --- /dev/null +++ b/packages/commons/dist/schemas/zod_map.js @@ -0,0 +1,99 @@ +import { z } from 'zod'; +/** + * Manages a collection of Zod schema properties + * and combines them into a single Zod object schema. + * + * @template MetaType The type of metadata you want to store for each field. + * Defaults to Record if not provided. + */ +export class ZodMetaMap { + fieldMap = new Map(); + /** + * Adds a Zod schema under a specific key (property name), + * optionally attaching typed metadata. + * + * @param key - The name of the property in the root object. + * @param schema - The Zod schema for that property. + * @param metadata - Optional metadata object (type MetaType). + */ + add(key, schema, metadata) { + this.fieldMap.set(key, { schema, metadata }); + return this; + } + /** + * Builds and returns a root Zod object + * that combines all properties which were added. + */ + root() { + const shape = {}; + for (const [key, { schema }] of this.fieldMap.entries()) { + shape[key] = schema; + } + return z.object(shape); + } + /** + * Retrieves the metadata for a specific key, if any. + */ + getMetadata(key) { + return this.fieldMap.get(key)?.metadata; + } + /** + * Static factory method: creates a SchemaMetaManager + * while letting you optionally specify the MetaType. + * + * Usage: + * const manager = SchemaMetaManager.create(); + */ + static create() { + return new ZodMetaMap(); + } + /** + * Returns a basic UiSchema object that RJSF can use to render form controls. + * + * - Adds a top-level "ui:submitButtonOptions" (example). + * - For each field, we set `ui:title` (uppercase key), + * `ui:description` (from Zod's .describe() if available), + * and a naive placeholder from the default value (if parse(undefined) succeeds). + */ + getUISchema() { + // Start with some top-level UI schema config (optional) + const uiSchema = { + 'ui:submitButtonOptions': { + props: { + disabled: false, + className: 'btn btn-info', + }, + norender: false, + submitText: 'Submit', + }, + }; + for (const [key, { schema }] of this.fieldMap.entries()) { + let fieldUi = {}; + // Use the Zod description if available + // (Accessing `._def.description` is private/hacky, but commonly done.) + const sAny = schema; + if (sAny?._def?.description) { + fieldUi['ui:description'] = sAny._def.description; + } + // RJSF usually reads 'title' from JSON schema. But if you want + // to override it in UI schema, you can do so: + fieldUi['ui:title'] = key[0].toUpperCase() + key.substr(1).toLowerCase(); + // If the Zod schema allows a default, we can parse(undefined) to get it. + try { + const defaultVal = schema.parse(undefined); + // There's no official 'ui:default' in RJSF, but you could do a placeholder: + fieldUi['ui:placeholder'] = defaultVal; + } + catch { + // no default + } + fieldUi = { + ...fieldUi, + ...this.getMetadata(key), + }; + uiSchema[key] = fieldUi; + } + return uiSchema; + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9kX21hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY2hlbWFzL3pvZF9tYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLENBQUMsRUFBeUIsTUFBTSxLQUFLLENBQUM7QUFFL0M7Ozs7OztHQU1HO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFDWCxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBR3ZCLENBQUM7SUFFSjs7Ozs7OztPQU9HO0lBQ0gsR0FBRyxDQUF1QixHQUFXLEVBQUUsTUFBUyxFQUFFLFFBQW1CO1FBQ2pFLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJO1FBQ0EsTUFBTSxLQUFLLEdBQStCLEVBQUUsQ0FBQztRQUM3QyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUN0RCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ3hCLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVyxDQUFDLEdBQVc7UUFDbkIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxNQUFNO1FBQ1QsT0FBTyxJQUFJLFVBQVUsRUFBTSxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsV0FBVztRQUNQLHdEQUF3RDtRQUN4RCxNQUFNLFFBQVEsR0FBNEI7WUFDdEMsd0JBQXdCLEVBQUU7Z0JBQ3RCLEtBQUssRUFBRTtvQkFDSCxRQUFRLEVBQUUsS0FBSztvQkFDZixTQUFTLEVBQUUsY0FBYztpQkFDNUI7Z0JBQ0QsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsVUFBVSxFQUFFLFFBQVE7YUFDdkI7U0FDSixDQUFDO1FBRUYsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDdEQsSUFBSSxPQUFPLEdBQTRCLEVBQUcsQ0FBQztZQUMzQyx1Q0FBdUM7WUFDdkMsdUVBQXVFO1lBQ3ZFLE1BQU0sSUFBSSxHQUFHLE1BQWEsQ0FBQztZQUMzQixJQUFJLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7Z0JBQzFCLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQ3RELENBQUM7WUFFRCwrREFBK0Q7WUFDL0QsOENBQThDO1lBQzlDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtZQUV4RSx5RUFBeUU7WUFDekUsSUFBSSxDQUFDO2dCQUNELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQzNDLDRFQUE0RTtnQkFDNUUsT0FBTyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsVUFBVSxDQUFDO1lBQzNDLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ0wsYUFBYTtZQUNqQixDQUFDO1lBQ0QsT0FBTyxHQUFHO2dCQUNOLEdBQUcsT0FBTztnQkFDVixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDO2FBQzNCLENBQUE7WUFDRCxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDO1FBQzVCLENBQUM7UUFDRCxPQUFPLFFBQVEsQ0FBQztJQUNwQixDQUFDO0NBQ0oifQ== \ No newline at end of file diff --git a/packages/commons/src/schemas/index.ts b/packages/commons/src/schemas/index.ts new file mode 100644 index 00000000..e3873519 --- /dev/null +++ b/packages/commons/src/schemas/index.ts @@ -0,0 +1,211 @@ +import * as path from 'path' +import * as CLI from 'yargs' +import { z, ZodTypeAny, ZodObject, ZodEffects, ZodOptional, ZodDefault } from 'zod' +import { sync as writeFS } from '@polymech/fs/write' +import { zodToTs, printNode } from 'zod-to-ts' +import { zodToJsonSchema } from "zod-to-json-schema" +import { logger } from '@/logger.js' + +export * from './path.js' +export * from './zod_map.js' + +export const generate_interfaces = (schemas: ZodObject[], dst: string) => { + const types = schemas.map(schema => `export interface ${schema.description || 'IOptions'} ${printNode(zodToTs(schema).node)}`) + writeFS(dst, types.join('\n')) +} +export const enumerateHelpStrings = (schema: ZodTypeAny, path: string[] = [], logger: any): void => { + if (schema instanceof ZodObject) { + for (const key in schema.shape) { + const nestedSchema = schema.shape[key]; + enumerateHelpStrings(nestedSchema, [...path, key], logger) + } + } else { + const description = schema._def.description; + if (description) { + logger.debug(`\t ${path.join('.')}: ${description}`) + } + } +} +export const yargsDefaults = (yargs: CLI.Argv) => yargs.parserConfiguration({ "camel-case-expansion": false }) + +export const getInnerSchema = (schema: ZodTypeAny): ZodTypeAny => { + while (schema instanceof ZodEffects) { + schema = schema._def.schema + } + return schema +} +export const getInnerType = (type: ZodTypeAny) => { + while (type instanceof ZodOptional) { + type = type._def.innerType + } + while (type._def.typeName === 'ZodDefault' || type._def.typeName === 'ZodOptional') { + type = type._def.innerType; + } + return type._def.typeName +} +export const getDefaultValue = (schema: ZodTypeAny) => { + if (schema instanceof ZodDefault) { + return schema._def.defaultValue(); + } + return undefined; +} +export const getFieldDefaultValue = (schema: ZodTypeAny): any | undefined => { + if(!schema){ + return undefined + } + if (schema._def.typeName === 'ZodDefault') { + return schema._def.defaultValue(); + } + if (schema instanceof ZodOptional) { + return getFieldDefaultValue(schema.unwrap()); + } + if (schema instanceof ZodEffects) { + return getFieldDefaultValue(schema._def.schema); + } + if(typeof schema._def){ + return getFieldDefaultValue(schema._def.schema) + } + return undefined; + } +export const getDescription = (schema: ZodTypeAny): string | undefined =>{ + if(!schema){ + return undefined + } + if (schema._def.description) { + return schema._def.description; + } + if (schema instanceof ZodOptional) { + return getDescription(schema.unwrap()); + } + + if (schema instanceof ZodEffects) { + return getDescription(schema._def.schema); + } + + if(typeof schema._def){ + return getDescription(schema._def.schema) + } + return undefined; + } +export const toYargs = (yargs: CLI.Argv, zodSchema: ZodObject, options?: { + onKey?: (yargs: CLI.Argv, key: string, options:any) => any +}) => { + yargsDefaults(yargs) + try { + const shape = zodSchema.shape + for (const key in shape) { + const zodField = shape[key] as ZodTypeAny + const innerDef = getInnerSchema(zodField) + if (!innerDef) { + continue + } + let type: 'string' | 'boolean' | 'number' | undefined; + const inner_type = getInnerType(innerDef) + let descriptionExtra = '' + switch (inner_type) { + case 'ZodString': + type = 'string' + break + case 'ZodBoolean': + type = 'boolean' + break + case 'ZodNumber': + type = 'number' + break + case 'ZodOptional': + case 'ZodEnum': + type = getInnerType(innerDef) + if (innerDef._def.typeName === 'ZodEnum') { + descriptionExtra = `\n\t ${innerDef._def.values.join(' \n\t ')}` + } + break + } + const defaultValue = getFieldDefaultValue(zodField) + let handled = false + const args = { + type, + default: defaultValue, + describe: `${zodField._def.description || ''} ${descriptionExtra}`.trim() + } + if(options?.onKey){ + handled = options.onKey(yargs, key, args) + } + if(!handled){ + yargs.option(key,args) + } + } + return yargs + } catch (error) { + logger.error('Error processing schema:', error) + return yargs + } +} +///////////////////////////////////////////////////////// +// +// Schema Writers +// +const extension = (file: string) => path.parse(file).ext +const json = (data: any, file: string, name: string, options: {}) => writeFS(file, data.map((s) => zodToJsonSchema(s, name))) + +export const WRITERS = +{ + '.json': json +} + +export const writer = (file: string) => WRITERS[extension(file)] + +export const write = (schemas: ZodObject[], file: string, name: string, options: {}) => { + if (!WRITERS[extension(file)]) { + logger.error(`No writer found for file extension: ${extension(file)} : file: ${file}`) + return + } + logger.debug(`Writing schema to ${file} : ${name}`) + try { + writer(file)(schemas, file, name, options) + } catch (e) { + logger.trace(`Error writing schema to ${file} : ${name}`, e, e.stack, e.message) + } +} +//////////////////////////////////////////////////////////////////// +// +// Schema Combinators +export const combineValidatorsOr = (validators: z.ZodTypeAny[]) => { + return z.string().refine((value) => { + const errors = []; + const isValid = validators.some((validator) => { + try { + validator.parse(value) + return true; + } catch (err) { + errors.push(err.errors) + return false; + } + }); + if (!isValid) { + throw new z.ZodError(errors.flat()) + } + return true; + }, 'Invalid value for all provided validators') +} + +export const combineValidatorsOrUsingZod = (validators: z.ZodTypeAny[]) => { + return validators.reduce((acc, validator) => acc.or(validator)); +}; +export const combineValidatorsOrUsingZod2 = (validators: z.ZodTypeAny[]) => { + return validators.reduce((acc, validator) => { + return acc.or(validator).refine((value) => { + try { + acc.parse(value); + return true; + } catch (errAcc) { + try { + validator.parse(value); + return true; + } catch (errValidator) { + throw new z.ZodError([...errAcc.errors, ...errValidator.errors]); + } + } + }) + }) +} + diff --git a/packages/commons/src/schemas/openapi.ts b/packages/commons/src/schemas/openapi.ts new file mode 100644 index 00000000..64bb4de0 --- /dev/null +++ b/packages/commons/src/schemas/openapi.ts @@ -0,0 +1,20 @@ +/* +export const openapi = (data: ZodObject[], file: string, name: string, options: {}) => { + const registry = new OpenAPIRegistry() + data.forEach((s) => registry.register(s.description, s)) + const generator = new OpenApiGeneratorV3(registry.definitions) + const component = generator.generateComponents() + // const content = stringifyYAML(component) + return component +} +*/ +/* +const yaml = (data: ZodObject[], file: string, name: string, options: {}) => { + const registry = new OpenAPIRegistry() + data.forEach((s) => registry.register(s.description, s)) + const generator = new OpenApiGeneratorV3(registry.definitions) + const component = generator.generateComponents() + logger.debug(`Writing schema to ${file} : ${name}`,component) + writeFS(file,stringifyYAML(component)) +} +*/ \ No newline at end of file diff --git a/packages/commons/src/schemas/path.ts b/packages/commons/src/schemas/path.ts new file mode 100644 index 00000000..c7e73d14 --- /dev/null +++ b/packages/commons/src/schemas/path.ts @@ -0,0 +1,253 @@ +import { z, ZodTypeAny } from 'zod' +import * as path from 'path' +import { accessSync, constants, lstatSync, existsSync } from 'fs' + +import { isString } from '@polymech/core/primitives' +import { sync as exists } from '@polymech/fs/exists' +import { sync as read } from '@polymech/fs/read' + +import { logger } from '@/logger.js' +import { DEFAULT_VARS, resolve, template } from '@/variables.js' +import { getDescription } from '@/schemas/index.js' +import { isFile } from '@/lib/fs.js' + +type TResult = { resolved: string, source: string, value: unknown } +type TRefine = (src: string, ctx: any, variables: Record) => string | z.ZodNever +type TTransform = (src: string, variables?: Record) => string | TResult +type TExtend = { refine: Array, transform: Array } + +const DefaultPathSchemaBase = z.string().describe('Path to a file or directory') + +const PathErrorMessages = { + INVALID_INPUT: 'INVALID_INPUT: ${inputPath}', + PATH_DOES_NOT_EXIST: 'Path does not exist ${inputPath} = ${resolvedPath}', + DIRECTORY_NOT_WRITABLE: 'Directory is not writable ${inputPath} = ${resolvedPath}', + NOT_A_DIRECTORY: 'Path is not a directory or does not exist ${inputPath} = ${resolvedPath}', + NOT_A_JSON_FILE: 'File is not a JSON file or does not exist ${inputPath} = ${resolvedPath}', + PATH_NOT_ABSOLUTE: 'Path is not absolute ${inputPath} = ${resolvedPath}', + PATH_NOT_RELATIVE: 'Path is not relative ${inputPath} = ${resolvedPath}', +} as const + +export enum E_PATH { + ENSURE_PATH_EXISTS = 1, + INVALID_INPUT, + ENSURE_DIRECTORY_WRITABLE, + ENSURE_FILE_IS_JSON, + ENSURE_PATH_IS_ABSOLUTE, + ENSURE_PATH_IS_RELATIVE, + GET_PATH_INFO +} + +export const Transformers:Record = { + resolve: (val: string, variables: Record = {}) => { + if (!val) { + return null + } + return { + resolved: path.resolve(resolve(val, false, variables)), + source: val + } + }, + json: (val: string | { resolved: string, source: string }, variables: Record = {}) => { + if (!val) { + return null + } + const resolved = path.resolve(resolve(isString(val) ? val : val.source, false, variables)) + return { + resolved, + source: val, + value: read(resolved, 'json') + } + }, + string: (val: string | { resolved: string, source: string }, variables: Record = {}) => { + if (!val) { + return null + } + let src = isString(val) ? val : val.source + src = resolve(src, false, variables) + const resolved = path.resolve(src) + if (!exists(resolved) || !isFile(resolved)) { + return { + resolved, + source: val, + value: null + } + } + else { + let value = null + try { + value = read(resolved, 'string') + } catch (e) { + logger.error('Failed to read file', { resolved, source: val, error: e.message }) + } + return { + resolved, + source: val, + value + } + } + } +} + +export const TransformersDescription = [ + { + description: 'RESOLVE_PATH', + fn: Transformers.resolve + }, + { + description: 'READ_JSON', + fn: Transformers.json + }, + { + description: 'READ_STRING', + fn: Transformers.string + } +] +const extendType = (type: ZodTypeAny, extend: TExtend, variables: Record = {}) => { + if (Array.isArray(extend.refine)) { + for (const refine of extend.refine) { + type = type.refine(refine as any) + } + } else { + type = type.refine(extend.refine) + } + if (Array.isArray(extend.transform)) { + for (const transform of extend.transform) { + type = type.transform((val) => transform(val, variables)) + } + } else { + type = type.transform(extend.transform) + } + return type +} + +const extendTypeDescription = (type: ZodTypeAny, extension: TExtend, variables: Record = {}) => { + const description = getDescription(type) || '' + let transformerDescriptions = 'Transformers:\n' + if (Array.isArray(extension.transform)) { + for (const transform of extension.transform) { + transformerDescriptions += transformerDescription(transform) + '\n' + } + } else { + transformerDescriptions += transformerDescription(extension.transform) + '\n' + } + type = type.describe(description + '\n' + transformerDescriptions) + return type +} + +const transformerDescription = (fn: TTransform) => { + const description = TransformersDescription.find((t) => t.fn === fn) + return description ? description.description : 'Unknown' +} + +export const extendSchema = (baseSchema: z.ZodObject, extend: Record) => { + const baseShape = baseSchema.shape + const extendedShape: Record = { ...baseShape } + for (const [key, refines] of Object.entries(extend)) { + if (!baseShape[key]) + continue + + let fieldSchema = baseShape[key] + if (Array.isArray(refines.refine)) { + for (const refine of refines.refine) { + fieldSchema = fieldSchema.superRefine(refine) + } + } else { + fieldSchema = fieldSchema.superRefine(refines) + } + if (Array.isArray(refines.transform)) { + for (const transform of refines.transform) { + fieldSchema = fieldSchema.transform((val) => transform(val)) + } + } else { + fieldSchema = fieldSchema.transform(refines.transform) + } + extendedShape[key] = fieldSchema + + } + return z.object(extendedShape) +} + +export const ENSURE_DIRECTORY_WRITABLE = (inputPath: string, ctx: any, variables: Record) => { + const resolvedPath = path.resolve(resolve(inputPath, false, variables)) + const parts = path.parse(resolvedPath) + if (resolvedPath && existsSync(parts.dir) && lstatSync(parts.dir).isDirectory()) { + try { + accessSync(resolvedPath, constants.W_OK) + return resolvedPath + } catch (e) { + ctx.addIssue({ + code: E_PATH.ENSURE_DIRECTORY_WRITABLE, + message: template(PathErrorMessages.DIRECTORY_NOT_WRITABLE, { inputPath, resolvedPath }) + }) + return z.NEVER + } + } else { + ctx.addIssue({ + code: E_PATH.ENSURE_DIRECTORY_WRITABLE, + message: template(PathErrorMessages.NOT_A_DIRECTORY, { inputPath, resolvedPath }) + }) + return z.NEVER + } + +} + +export const IS_VALID_STRING = (inputPath: string) => isString(inputPath) + +export const ENSURE_PATH_EXISTS = (inputPath: string, ctx: any, variables: Record) => { + if (!inputPath || !ctx) { + return z.NEVER + } + if (!isString(inputPath)) { + ctx.addIssue({ + code: E_PATH.INVALID_INPUT, + message: template(PathErrorMessages.INVALID_INPUT, {}) + }) + return z.NEVER + } + const resolvedPath = path.resolve(resolve(inputPath, false, variables)) + if (!exists(resolvedPath)) { + ctx.addIssue({ + code: E_PATH.ENSURE_PATH_EXISTS, + message: template(PathErrorMessages.PATH_DOES_NOT_EXIST, { inputPath, resolvedPath }) + }) + + return z.NEVER + } + return resolvedPath +} + +export const test = () => { + const BaseCompilerOptions = () => z.object({ + root: DefaultPathSchemaBase.default(`${process.cwd()}`) + }) + const ret = extendSchema(BaseCompilerOptions(), { + root: { + refine: [ + (val, ctx) => ENSURE_DIRECTORY_WRITABLE(val, ctx, DEFAULT_VARS({ exampleVar: 'exampleValue' })), + (val, ctx) => ENSURE_PATH_EXISTS(val, ctx, DEFAULT_VARS({ exampleVar: 'exampleValue' })) + ], + transform: [ + (val) => path.resolve(resolve(val, false, DEFAULT_VARS({ exampleVar: 'exampleValue' }))) + ] + } + }) + return ret +} + +export const Templates:Record = +{ + json: { + refine: [IS_VALID_STRING, ENSURE_PATH_EXISTS], + transform: [Transformers.resolve, Transformers.json] + }, + string: { + refine: [ENSURE_PATH_EXISTS], + transform: [Transformers.resolve, Transformers.string] + } +} + +export const extend = (baseSchema: ZodTypeAny, template: any, variables: Record = {}) => { + const type = extendType(baseSchema, template, variables) + return extendTypeDescription(type, template, variables) +} diff --git a/packages/commons/src/schemas/types.ts b/packages/commons/src/schemas/types.ts new file mode 100644 index 00000000..25d974b3 --- /dev/null +++ b/packages/commons/src/schemas/types.ts @@ -0,0 +1,187 @@ +export enum FLAG { + /** + * Instruct for no additional extra processing + * @constant + * @type int + */ + NONE = 0x00000000, + /** + * Will instruct the pre/post processor to base-64 decode or encode + * @constant + * @type int + */ + BASE_64 = 0x00000001, + /** + * Post/Pre process the value with a user function + * @constant + * @type int + */ + USE_FUNCTION = 0x00000002, + /** + * Replace variables with local scope's variables during the post/pre process + * @constant + * @type int + */ + REPLACE_VARIABLES = 0x00000004, + /** + * Replace variables with local scope's variables during the post/pre process but evaluate the whole string + * as Javascript + * @constant + * @type int + */ + REPLACE_VARIABLES_EVALUATED = 0x00000008, + /** + * Will instruct the pre/post processor to escpape evaluated or replaced variables or expressions + * @constant + * @type int + */ + ESCAPE = 0x00000010, + /** + * Will instruct the pre/post processor to replace block calls with oridinary vanilla script + * @constant + * @type int + */ + REPLACE_BLOCK_CALLS = 0x00000020, + /** + * Will instruct the pre/post processor to remove variable delimitters/placeholders from the final string + * @constant + * @type int + */ + REMOVE_DELIMTTERS = 0x00000040, + /** + * Will instruct the pre/post processor to remove "[" ,"]" , "(" , ")" , "{", "}" , "*" , "+" , "." + * @constant + * @type int + */ + ESCAPE_SPECIAL_CHARS = 0x00000080, + /** + * Will instruct the pre/post processor to use regular expressions over string substitution + * @constant + * @type int + */ + USE_REGEX = 0x00000100, + /** + * Will instruct the pre/post processor to use Filtrex (custom bison parser, needs xexpression) over string substitution + * @constant + * @type int + */ + USE_FILTREX = 0x00000200, + /** + * Cascade entry. There are cases where #USE_FUNCTION is not enough or we'd like to avoid further type checking. + * @constant + * @type int + */ + CASCADE = 0x00000400, + /** + * Cascade entry. There are cases where #USE_FUNCTION is not enough or we'd like to avoid further type checking. + * @constant + * @type int + */ + EXPRESSION = 0x00000800, + /** + * Dont parse anything + * @constant + * @type int + */ + DONT_PARSE = 0x000001000, + /** + * Convert to hex + * @constant + * @type int + */ + TO_HEX = 0x000002000, + /** + * Convert to hex + * @constant + * @type int + */ + REPLACE_HEX = 0x000004000, + /** + * Wait for finish + * @constant + * @type int + */ + WAIT = 0x000008000, + /** + * Wait for finish + * @constant + * @type int + */ + DONT_ESCAPE = 0x000010000, + /** + * Flag to mark the maximum core bit mask, after here its user land + * @constant + * @type int + */ + END = 0x000020000 +} + +export enum EType +{ + Number = 'Number', + String = 'String', + Boolean = 'Boolean', + Date = 'Date', + TimeStamp = 'TimeStamp', + Duration = 'Duration', + Url = 'Url', + UrlScheme = 'Url-Scheme', + Asset = 'Asset', + Symbol = 'Symbol', + Value = 'Value', + Values = 'Values', + Attribute = 'Attribute', + Parameter = 'Parameter', + Operation = 'Operation', + ParameterOperation = 'ParameterOperation', + Template = 'Template', + Arguments = 'Arguments' +} +export type TVector2D = [number, number]; +export type TVector3D = [number, number, number]; +export type TBBox = [TVector3D, TVector3D]; +export type TQuaternion = [number, number, number, number]; +export type TFlags = Record; +export type TExpression = string | [string | RegExp, { [key: string]: any }]; +export type TOptions = { flags?: TFlags | { [key: string]: any } }; + +export interface IUrlScheme { + url: string; + options?: { [key: string]: any }; +} + +export interface IAsset { + urlScheme: IUrlScheme; + options?: { [key: string]: any }; +} + +export type TSelector = TExpression | [TExpression, { [key: string]: any }]; + +export interface ITypeInfo { + type: string; + symbol: bigint; +} + +export interface IRef { + key: string | string; + struct: { [key: string]: any }; +} + +export interface IAttribute { + type: ITypeInfo; + value: bigint; +} + +export interface IParameter { + type: ITypeInfo; + value: bigint; +} + +export interface IParameterOperation { + param1: bigint; + param2: bigint; + operation: bigint; +} + +export type TTemplate = string | [ITypeInfo | TSelector, { [key: string]: any }]; +export type TArguments = { [key: string]: any } | any[]; diff --git a/packages/commons/src/schemas/vfs.ts b/packages/commons/src/schemas/vfs.ts new file mode 100644 index 00000000..b644c02f --- /dev/null +++ b/packages/commons/src/schemas/vfs.ts @@ -0,0 +1 @@ +//import { zodToJsonSchema } from "zod-to-json-schema" diff --git a/packages/commons/src/schemas/zod_map.ts b/packages/commons/src/schemas/zod_map.ts new file mode 100644 index 00000000..a152d2e1 --- /dev/null +++ b/packages/commons/src/schemas/zod_map.ts @@ -0,0 +1,109 @@ +import { z, ZodObject, ZodTypeAny } from 'zod'; + +/** + * Manages a collection of Zod schema properties + * and combines them into a single Zod object schema. + * + * @template MetaType The type of metadata you want to store for each field. + * Defaults to Record if not provided. + */ +export class ZodMetaMap> { + private fieldMap = new Map< + string, + { schema: ZodTypeAny; metadata?: MetaType } + >(); + + /** + * Adds a Zod schema under a specific key (property name), + * optionally attaching typed metadata. + * + * @param key - The name of the property in the root object. + * @param schema - The Zod schema for that property. + * @param metadata - Optional metadata object (type MetaType). + */ + add(key: string, schema: T, metadata?: MetaType): this { + this.fieldMap.set(key, { schema, metadata }); + return this; + } + + /** + * Builds and returns a root Zod object + * that combines all properties which were added. + */ + root(): ZodObject> { + const shape: Record = {}; + for (const [key, { schema }] of this.fieldMap.entries()) { + shape[key] = schema; + } + return z.object(shape); + } + + /** + * Retrieves the metadata for a specific key, if any. + */ + getMetadata(key: string): MetaType | undefined { + return this.fieldMap.get(key)?.metadata; + } + + /** + * Static factory method: creates a SchemaMetaManager + * while letting you optionally specify the MetaType. + * + * Usage: + * const manager = SchemaMetaManager.create(); + */ + static create>(): ZodMetaMap { + return new ZodMetaMap(); + } + + /** + * Returns a basic UiSchema object that RJSF can use to render form controls. + * + * - Adds a top-level "ui:submitButtonOptions" (example). + * - For each field, we set `ui:title` (uppercase key), + * `ui:description` (from Zod's .describe() if available), + * and a naive placeholder from the default value (if parse(undefined) succeeds). + */ + getUISchema(): Record { + // Start with some top-level UI schema config (optional) + const uiSchema: Record = { + 'ui:submitButtonOptions': { + props: { + disabled: false, + className: 'btn btn-info', + }, + norender: false, + submitText: 'Submit', + }, + }; + + for (const [key, { schema }] of this.fieldMap.entries()) { + let fieldUi: Record = { }; + // Use the Zod description if available + // (Accessing `._def.description` is private/hacky, but commonly done.) + const sAny = schema as any; + if (sAny?._def?.description) { + fieldUi['ui:description'] = sAny._def.description; + } + + // RJSF usually reads 'title' from JSON schema. But if you want + // to override it in UI schema, you can do so: + fieldUi['ui:title'] = key[0].toUpperCase() + key.substr(1).toLowerCase() + + // If the Zod schema allows a default, we can parse(undefined) to get it. + try { + const defaultVal = schema.parse(undefined); + // There's no official 'ui:default' in RJSF, but you could do a placeholder: + fieldUi['ui:placeholder'] = defaultVal; + } catch { + // no default + } + fieldUi = { + ...fieldUi, + ...this.getMetadata(key), + } + uiSchema[key] = fieldUi; + } + return uiSchema; + } +} \ No newline at end of file