import { autoFormatString, omitKeys } from "core/utils"; import { type Draft, Draft2019, type JsonSchema } from "json-schema-library"; import type { JSONSchema } from "json-schema-to-ts"; import type { JSONSchemaType } from "json-schema-to-ts/lib/types/definitions/jsonSchema"; export { isEqual, getPath } from "core/utils/objects"; //export { isEqual } from "lodash-es"; export function coerce(value: any, schema: JsonSchema, opts?: { required?: boolean }) { if (!value && typeof opts?.required === "boolean" && !opts.required) { return undefined; } switch (schema.type) { case "string": return String(value); case "integer": case "number": return Number(value); case "boolean": return ["true", "1", 1, "on", true].includes(value); case "null": return null; } return value; } export function pathToPointer(path: string) { return "#/" + (path.includes(".") ? path.split(".").join("/") : path); } export function prefixPointer(pointer: string, prefix: string) { return pointer.replace("#/", `#/${prefix.length > 0 ? prefix + "/" : ""}`).replace(/\/\//g, "/"); } const PathFilter = (value: any) => typeof value !== "undefined" && value !== null && value !== ""; export function prefixPath(path: string = "", prefix: string | number = "") { const p = path.includes(".") ? path.split(".") : [path]; return [prefix, ...p].filter(PathFilter).join("."); } export function suffixPath(path: string = "", suffix: string | number = "") { const p = path.includes(".") ? path.split(".") : [path]; return [...p, suffix].filter(PathFilter).join("."); } export function getParentPointer(pointer: string) { return pointer.substring(0, pointer.lastIndexOf("/")); } export function isRequired(lib: Draft, pointer: string, schema: JsonSchema, data?: any) { if (pointer === "#/" || !schema) { return false; } const childSchema = lib.getSchema({ pointer, data, schema }); if (typeof childSchema === "object" && "const" in childSchema) { return true; } const parentPointer = getParentPointer(pointer); const parentSchema = lib.getSchema({ pointer: parentPointer, data }); const required = parentSchema?.required?.includes(pointer.split("/").pop()!); return !!required; } export type IsTypeType = | JSONSchemaType | JSONSchemaType[] | readonly JSONSchemaType[] | string | undefined; export function isType(type: IsTypeType, compare: IsTypeType) { if (!type || !compare) return false; const _type = Array.isArray(type) ? type : [type]; const _compare = Array.isArray(compare) ? compare : [compare]; return _compare.some((t) => _type.includes(t)); } export function getLabel(name: string, schema: JsonSchema) { if (typeof schema === "object" && "title" in schema) return schema.title; if (!name) return ""; const label = name.includes(".") ? (name.split(".").pop() ?? "") : name; return autoFormatString(label); } export function getMultiSchema(schema: JsonSchema): JsonSchema[] | undefined { if (!schema || typeof schema !== "object") return; return (schema.anyOf ?? schema.oneOf) as any; } export function getMultiSchemaMatched( schema: JsonSchema, data: any ): [number, JsonSchema[], JsonSchema | undefined] { const multiSchema = getMultiSchema(schema); //console.log("getMultiSchemaMatched", schema, data, multiSchema); if (!multiSchema) return [-1, [], undefined]; const index = multiSchema.findIndex((subschema) => { const lib = new Draft2019(subschema as any); return lib.validate(data, subschema).length === 0; }); if (index === -1) return [-1, multiSchema, undefined]; return [index, multiSchema, multiSchema[index]]; } export function omitSchema(_schema: Given, keys: string[], _data?: any) { if (typeof _schema !== "object" || !("properties" in _schema) || keys.length === 0) return [_schema, _data]; const schema = JSON.parse(JSON.stringify(_schema)); const data = _data ? JSON.parse(JSON.stringify(_data)) : undefined; const updated = { ...schema, properties: omitKeys(schema.properties, keys) }; if (updated.required) { updated.required = updated.required.filter((key) => !keys.includes(key as any)); } const reducedConfig = omitKeys(data, keys) as any; return [updated, reducedConfig]; } export function isTypeSchema(schema?: JsonSchema): schema is JsonSchema { return typeof schema === "object" && "type" in schema && !isType(schema.type, "error"); }