vira
Version:
A simple and highly versatile design system using element-vir.
207 lines (206 loc) • 8.76 kB
TypeScript
import { type JsonValue } from '@augment-vir/common';
import { type JSONSchema } from 'json-schema-to-ts';
/**
* The JSON Schema type used by `ViraJsonForm`. Re-exported from `json-schema-to-ts` so that callers
* can pass standard JSON Schema objects.
*
* @category Internal
*/
export type ViraJsonSchema = JSONSchema;
/**
* A non-boolean JSON Schema object. Boolean schemas (`true` / `false`) are valid JSON Schemas but
* don't constrain the editor in useful ways, so we normalize them away during traversal.
*
* @category Internal
*/
export type ViraJsonSchemaObject = Exclude<ViraJsonSchema, boolean>;
/**
* The JSON types supported by `ViraJsonForm`.
*
* @category Internal
*/
export declare enum ViraJsonType {
String = "string",
Number = "number",
Integer = "integer",
Boolean = "boolean",
Null = "null",
Object = "object",
Array = "array"
}
/**
* Human-friendly labels for each {@link ViraJsonType}.
*
* @category Internal
*/
export declare const viraJsonTypeLabels: Readonly<Record<ViraJsonType, string>>;
/**
* Classifies a JSON value's runtime type. Note that {@link ViraJsonType.Integer} is never returned;
* it only appears in schemas. All numbers (whole or fractional) classify as
* {@link ViraJsonType.Number}, since JSON has no separate integer type at runtime.
*
* @category Internal
*/
export declare function getJsonType(value: JsonValue | undefined): ViraJsonType;
/**
* Normalizes a schema to a non-boolean object form. `true` becomes an unconstrained schema (`{}`),
* `false` becomes `undefined` (nothing is allowed; treated as "no schema available").
*
* @category Internal
*/
export declare function normalizeSchema(schema: ViraJsonSchema | undefined): ViraJsonSchemaObject | undefined;
/**
* Context used while resolving `$ref` entries against a root schema's `$defs` (or `definitions`)
* map. A stack of seen refs prevents infinite recursion from cyclical schemas.
*
* @category Internal
*/
export type SchemaResolveContext = {
root: ViraJsonSchemaObject | undefined;
seenRefs: ReadonlySet<string>;
};
/** @category Internal */
export declare function createResolveContext(schema: ViraJsonSchema | undefined): SchemaResolveContext;
/**
* Resolves a schema through `$ref` (via its root's `$defs`/`definitions`), returning the resolved
* schema and an updated resolve context. Non-ref schemas are returned as-is.
*
* @category Internal
*/
export declare function resolveSchema(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): {
resolved: ViraJsonSchemaObject | undefined;
context: SchemaResolveContext;
};
/**
* Flattens `anyOf` / `oneOf` branches into a single list of non-union schemas so that the editor
* can treat them uniformly.
*
* @category Internal
*/
export declare function expandSchemaBranches(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): ReadonlyArray<ViraJsonSchemaObject>;
/**
* Computes the set of JSON types that a given schema allows.
*
* @category Internal
*/
export declare function getAllowedJsonTypes(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): ReadonlyArray<ViraJsonType>;
/** @category Internal */
export declare function createDefaultForJsonType(type: ViraJsonType): JsonValue;
/**
* Picks the first schema branch whose `type` contains (or is) the given JSON type. Used to narrow
* the schema when traversing into a concrete value.
*
* @category Internal
*/
export declare function pickBranchForType(schema: ViraJsonSchema | undefined, valueType: ViraJsonType, context: SchemaResolveContext): ViraJsonSchemaObject | undefined;
/**
* Finds the sub-schema for a given object property key, considering `properties`,
* `patternProperties`, and `additionalProperties`.
*
* @category Internal
*/
export declare function getPropertySchema(parentSchema: ViraJsonSchema | undefined, key: string, context: SchemaResolveContext): ViraJsonSchema | undefined;
/**
* Finds the sub-schema for an array item at a given index, considering tuple `items` arrays and
* `additionalItems` fallbacks.
*
* @category Internal
*/
export declare function getItemSchema(parentSchema: ViraJsonSchema | undefined, index: number, context: SchemaResolveContext): ViraJsonSchema | undefined;
/**
* Returns the schema used when appending a new item to an array. Falls back to `additionalItems`
* when `items` is a tuple array and the new index is beyond the tuple's length.
*
* @category Internal
*/
export declare function getNewItemSchema(parentSchema: ViraJsonSchema | undefined, currentLength: number, context: SchemaResolveContext): ViraJsonSchema | undefined;
/**
* Returns the schema used when adding an arbitrary new field to an object. When no schema is
* provided at all the editor is unconstrained, so additions are allowed; once a schema is provided,
* additions are only allowed when the schema explicitly opts in via `additionalProperties: true` or
* an `additionalProperties` sub-schema. This is stricter than JSON Schema's `true` default — UI
* authors must opt in.
*
* @category Internal
*/
export declare function getAdditionalPropertiesSchema(parentSchema: ViraJsonSchema | undefined, context: SchemaResolveContext): {
allowed: boolean;
schema: ViraJsonSchema | undefined;
};
/**
* Returns the `enum` values defined by any resolved branch of a schema. Aggregates across
* `anyOf`/`oneOf` branches and includes `const` values so the editor can offer them as a select.
*
* @category Internal
*/
export declare function getSchemaEnumValues(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): ReadonlyArray<JsonValue> | undefined;
/**
* Collects the string `enum`/`const` values declared by any branch of a schema, ignoring branches
* that declare no enum/const. Unlike {@link getSchemaEnumValues}, a schema that mixes an enum branch
* with a free-form branch still yields the enum values (rather than bailing out). Non-string enum
* entries are excluded.
*
* @category Internal
*/
export declare function getStringEnumValues(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): ReadonlyArray<string>;
/**
* Returns whether the schema permits an arbitrary (non-enum, non-const) string in any of its
* branches. Used alongside {@link getStringEnumValues} to detect fields that accept both a fixed set
* of enum options and free-form text.
*
* @category Internal
*/
export declare function allowsFreeformString(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): boolean;
/**
* Returns the list of required property names declared by the object branch of a schema.
*
* @category Internal
*/
export declare function getRequiredProperties(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): ReadonlyArray<string>;
/**
* Returns the `properties` map declared by the object branch of a schema, or an empty record when
* none is defined.
*
* @category Internal
*/
export declare function getDefinedProperties(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): Readonly<Record<string, ViraJsonSchema>>;
/**
* Reads the title of a schema's first resolved branch (for display purposes).
*
* @category Internal
*/
export declare function getSchemaTitle(schema: ViraJsonSchema | undefined, context: SchemaResolveContext): string | undefined;
/**
* Validates a JSON value against the (loose) JSON Schema subset supported by `ViraJsonForm`.
* Returns a list of human-readable error messages; an empty array means the value is valid. Only
* the constraints understood by the editor (`type`, `required`, `properties`, `additionalProperties
* = false`, `items`, `enum`, `const`, `anyOf`, `oneOf`, `$ref`) are checked.
*
* @category Internal
*/
export declare function validateAgainstSchema(value: JsonValue, schema: ViraJsonSchema | undefined): ReadonlyArray<string>;
/**
* Type of a JSON path element. `string` selects an object key; `number` selects an array index.
*
* @category Internal
*/
export type ViraJsonPath = ReadonlyArray<string | number>;
/** @category Internal */
export declare function pathToKey(path: ViraJsonPath): string;
/**
* Returns a new JSON value where the value at `path` has been replaced with `newValue`.
*
* @category Internal
*/
export declare function setValueAtPath({ root, path, newValue, }: Readonly<{
root: JsonValue;
path: ViraJsonPath;
newValue: JsonValue;
}>): JsonValue;
/**
* Returns a new JSON value where the value at `path` has been removed. If `path` targets an object
* key, the key is deleted; if it targets an array index, the item is spliced out.
*
* @category Internal
*/
export declare function deleteValueAtPath(root: JsonValue, path: ViraJsonPath): JsonValue;