zod
This commit is contained in:
parent
734879e8f0
commit
c404e613f5
23
packages/commons/dist/schemas/index.d.ts
vendored
Normal file
23
packages/commons/dist/schemas/index.d.ts
vendored
Normal file
@ -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<any>[], 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<any>, 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<any>[], file: string, name: string, options: {}) => void;
|
||||
export declare const combineValidatorsOr: (validators: z.ZodTypeAny[]) => z.ZodEffects<z.ZodString, string, string>;
|
||||
export declare const combineValidatorsOrUsingZod: (validators: z.ZodTypeAny[]) => z.ZodTypeAny;
|
||||
export declare const combineValidatorsOrUsingZod2: (validators: z.ZodTypeAny[]) => z.ZodTypeAny;
|
||||
204
packages/commons/dist/schemas/index.js
vendored
Normal file
204
packages/commons/dist/schemas/index.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
packages/commons/dist/schemas/openapi.d.ts
vendored
Normal file
1
packages/commons/dist/schemas/openapi.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export {};
|
||||
22
packages/commons/dist/schemas/openapi.js
vendored
Normal file
22
packages/commons/dist/schemas/openapi.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
export {};
|
||||
/*
|
||||
export const openapi = (data: ZodObject<any>[], 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<any>[], 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
|
||||
30
packages/commons/dist/schemas/path.d.ts
vendored
Normal file
30
packages/commons/dist/schemas/path.d.ts
vendored
Normal file
@ -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<string, any>;
|
||||
export declare const TransformersDescription: {
|
||||
description: string;
|
||||
fn: any;
|
||||
}[];
|
||||
export declare const extendSchema: (baseSchema: z.ZodObject<any>, extend: Record<string, any>) => z.ZodObject<Record<string, z.ZodTypeAny>, "strip", z.ZodTypeAny, {
|
||||
[x: string]: any;
|
||||
}, {
|
||||
[x: string]: any;
|
||||
}>;
|
||||
export declare const ENSURE_DIRECTORY_WRITABLE: (inputPath: string, ctx: any, variables: Record<string, string>) => string;
|
||||
export declare const IS_VALID_STRING: (inputPath: string) => boolean;
|
||||
export declare const ENSURE_PATH_EXISTS: (inputPath: string, ctx: any, variables: Record<string, string>) => string;
|
||||
export declare const test: () => z.ZodObject<Record<string, z.ZodTypeAny>, "strip", z.ZodTypeAny, {
|
||||
[x: string]: any;
|
||||
}, {
|
||||
[x: string]: any;
|
||||
}>;
|
||||
export declare const Templates: Record<string, any>;
|
||||
export declare const extend: (baseSchema: ZodTypeAny, template: any, variables?: Record<string, string>) => z.ZodTypeAny;
|
||||
237
packages/commons/dist/schemas/path.js
vendored
Normal file
237
packages/commons/dist/schemas/path.js
vendored
Normal file
File diff suppressed because one or more lines are too long
194
packages/commons/dist/schemas/types.d.ts
vendored
Normal file
194
packages/commons/dist/schemas/types.d.ts
vendored
Normal file
@ -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<string, bigint>;
|
||||
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[];
|
||||
140
packages/commons/dist/schemas/types.js
vendored
Normal file
140
packages/commons/dist/schemas/types.js
vendored
Normal file
@ -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==
|
||||
1
packages/commons/dist/schemas/vfs.d.ts
vendored
Normal file
1
packages/commons/dist/schemas/vfs.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export {};
|
||||
3
packages/commons/dist/schemas/vfs.js
vendored
Normal file
3
packages/commons/dist/schemas/vfs.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export {};
|
||||
//import { zodToJsonSchema } from "zod-to-json-schema"
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmZzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjaGVtYXMvdmZzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxzREFBc0QifQ==
|
||||
46
packages/commons/dist/schemas/zod_map.d.ts
vendored
Normal file
46
packages/commons/dist/schemas/zod_map.d.ts
vendored
Normal file
@ -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<string, unknown> if not provided.
|
||||
*/
|
||||
export declare class ZodMetaMap<MetaType = Record<string, unknown>> {
|
||||
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<T extends ZodTypeAny>(key: string, schema: T, metadata?: MetaType): this;
|
||||
/**
|
||||
* Builds and returns a root Zod object
|
||||
* that combines all properties which were added.
|
||||
*/
|
||||
root(): ZodObject<Record<string, ZodTypeAny>>;
|
||||
/**
|
||||
* 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<MyFieldMeta>();
|
||||
*/
|
||||
static create<MT = Record<string, unknown>>(): ZodMetaMap<MT>;
|
||||
/**
|
||||
* 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<string, unknown>;
|
||||
}
|
||||
99
packages/commons/dist/schemas/zod_map.js
vendored
Normal file
99
packages/commons/dist/schemas/zod_map.js
vendored
Normal file
@ -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<string, unknown> 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<MyFieldMeta>();
|
||||
*/
|
||||
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==
|
||||
211
packages/commons/src/schemas/index.ts
Normal file
211
packages/commons/src/schemas/index.ts
Normal file
@ -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<any>[], 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<any>, 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<any>[], 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]);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
20
packages/commons/src/schemas/openapi.ts
Normal file
20
packages/commons/src/schemas/openapi.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
export const openapi = (data: ZodObject<any>[], 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<any>[], 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))
|
||||
}
|
||||
*/
|
||||
253
packages/commons/src/schemas/path.ts
Normal file
253
packages/commons/src/schemas/path.ts
Normal file
@ -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, string>) => string | z.ZodNever
|
||||
type TTransform = (src: string, variables?: Record<string, string>) => string | TResult
|
||||
type TExtend = { refine: Array<TRefine>, transform: Array<TTransform> }
|
||||
|
||||
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<string,any> = {
|
||||
resolve: (val: string, variables: Record<string, string> = {}) => {
|
||||
if (!val) {
|
||||
return null
|
||||
}
|
||||
return {
|
||||
resolved: path.resolve(resolve(val, false, variables)),
|
||||
source: val
|
||||
}
|
||||
},
|
||||
json: (val: string | { resolved: string, source: string }, variables: Record<string, string> = {}) => {
|
||||
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<string, string> = {}) => {
|
||||
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<string, string> = {}) => {
|
||||
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<string, string> = {}) => {
|
||||
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<any>, extend: Record<string, any>) => {
|
||||
const baseShape = baseSchema.shape
|
||||
const extendedShape: Record<string, ZodTypeAny> = { ...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<string, string>) => {
|
||||
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<string, string>) => {
|
||||
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<string,any> =
|
||||
{
|
||||
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<string, string> = {}) => {
|
||||
const type = extendType(baseSchema, template, variables)
|
||||
return extendTypeDescription(type, template, variables)
|
||||
}
|
||||
187
packages/commons/src/schemas/types.ts
Normal file
187
packages/commons/src/schemas/types.ts
Normal file
@ -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<string, bigint>;
|
||||
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[];
|
||||
1
packages/commons/src/schemas/vfs.ts
Normal file
1
packages/commons/src/schemas/vfs.ts
Normal file
@ -0,0 +1 @@
|
||||
//import { zodToJsonSchema } from "zod-to-json-schema"
|
||||
109
packages/commons/src/schemas/zod_map.ts
Normal file
109
packages/commons/src/schemas/zod_map.ts
Normal file
@ -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<string, unknown> if not provided.
|
||||
*/
|
||||
export class ZodMetaMap<MetaType = Record<string, unknown>> {
|
||||
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<T extends ZodTypeAny>(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<Record<string, ZodTypeAny>> {
|
||||
const shape: Record<string, ZodTypeAny> = {};
|
||||
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<MyFieldMeta>();
|
||||
*/
|
||||
static create<MT = Record<string, unknown>>(): ZodMetaMap<MT> {
|
||||
return new ZodMetaMap<MT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<string, unknown> {
|
||||
// Start with some top-level UI schema config (optional)
|
||||
const uiSchema: Record<string, unknown> = {
|
||||
'ui:submitButtonOptions': {
|
||||
props: {
|
||||
disabled: false,
|
||||
className: 'btn btn-info',
|
||||
},
|
||||
norender: false,
|
||||
submitText: 'Submit',
|
||||
},
|
||||
};
|
||||
|
||||
for (const [key, { schema }] of this.fieldMap.entries()) {
|
||||
let fieldUi: Record<string, unknown> = { };
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user