@reformer/renderer-json 5.0.2 → 6.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,81 @@
1
+ declare const _default: {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://reformer.dev/schemas/form-schema.schema.json",
4
+ "title": "ReFormer JSON form schema (M1, string-operator DSL)",
5
+ "description": "Base meta-schema: validates node structure + operator string syntax ($model/$component/$dataSource). Component-name enum is tightened per-app via buildFormSchemaMetaSchema; $dataSource names and $model paths are checked outside this schema.",
6
+ "type": "object",
7
+ "required": ["root"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "$schema": { "type": "string" },
11
+ "version": { "type": "string" },
12
+ "root": { "$ref": "#/definitions/node" }
13
+ },
14
+ "definitions": {
15
+ "modelOp": {
16
+ "type": "string",
17
+ "pattern": "^\\$model\\(.+\\)$",
18
+ "description": "Model binding: \"$model(path)\" — path resolved at runtime (not validated here)."
19
+ },
20
+ "componentOp": {
21
+ "type": "string",
22
+ "pattern": "^\\$component\\(.+\\)$",
23
+ "description": "Registry component: \"$component(Name)\". Name is tightened to a registry enum by buildFormSchemaMetaSchema."
24
+ },
25
+ "node": {
26
+ "oneOf": [
27
+ { "$ref": "#/definitions/fieldNode" },
28
+ { "$ref": "#/definitions/arrayNode" },
29
+ { "$ref": "#/definitions/containerNode" }
30
+ ]
31
+ },
32
+ "fieldNode": {
33
+ "type": "object",
34
+ "required": ["value"],
35
+ "additionalProperties": false,
36
+ "properties": {
37
+ "selector": { "type": "string" },
38
+ "value": { "$ref": "#/definitions/modelOp" },
39
+ "component": { "$ref": "#/definitions/componentOp" },
40
+ "componentProps": { "type": "object" },
41
+ "wrapper": { "$ref": "#/definitions/node" }
42
+ }
43
+ },
44
+ "arrayNode": {
45
+ "type": "object",
46
+ "required": ["array", "item"],
47
+ "additionalProperties": false,
48
+ "properties": {
49
+ "selector": { "type": "string" },
50
+ "array": { "$ref": "#/definitions/modelOp" },
51
+ "item": {
52
+ "type": "object",
53
+ "required": ["$template"],
54
+ "additionalProperties": false,
55
+ "properties": {
56
+ "$template": { "$ref": "#/definitions/node" }
57
+ }
58
+ },
59
+ "initialValue": { "type": "object" },
60
+ "componentProps": { "type": "object" }
61
+ }
62
+ },
63
+ "containerNode": {
64
+ "type": "object",
65
+ "required": ["component"],
66
+ "additionalProperties": false,
67
+ "properties": {
68
+ "selector": { "type": "string" },
69
+ "component": { "$ref": "#/definitions/componentOp" },
70
+ "componentProps": { "type": "object" },
71
+ "children": {
72
+ "type": "array",
73
+ "items": { "$ref": "#/definitions/node" }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ ;
80
+
81
+ export default _default;
@@ -0,0 +1,20 @@
1
+ import { ComponentRegistry } from '../registry/types';
2
+ /** Базовая мета-схема form-DSL (draft-07): структура + синтаксис операторов, имена не ограничены. */
3
+ export declare const formSchemaMetaSchema: Record<string, unknown>;
4
+ /** Имена компонентов реестра (`reg.field`/`reg.container`). */
5
+ export declare function getComponentNames(registry: ComponentRegistry): string[];
6
+ /** Имена registry-source (`reg.source`): options/itemLabel/константы/loading-компоненты. */
7
+ export declare function getSourceNames(registry: ComponentRegistry): string[];
8
+ /**
9
+ * Конкретная мета-схема: базовая + (если заданы `componentNames`) сужение паттерна `$component(...)`
10
+ * до enum имён (`^\$component\((Input|Select|…)\)$`). `$dataSource`-имена JSON Schema'й не покрыть
11
+ * (вложены в произвольный componentProps) — их проверяет рекурсивный обход в `validateFormSchema`.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const schema = buildFormSchemaMetaSchema({ componentNames: getComponentNames(registry) });
16
+ * ```
17
+ */
18
+ export declare function buildFormSchemaMetaSchema(opts?: {
19
+ componentNames?: string[];
20
+ }): Record<string, unknown>;
@@ -1,125 +1,76 @@
1
- /**
2
- * Типы для JSON-схемы формы
3
- *
4
- * @module reformer/renderer-json/types
5
- */
6
- /**
7
- * Унифицированный узел JSON-схемы
8
- *
9
- * Может представлять:
10
- * - Поле формы (если указан `model`)
11
- * - Контейнер/компонент (если указан только `component`)
12
- * - Поле с кастомным компонентом (если указаны оба)
13
- *
14
- * @example
15
- * ```json
16
- * // Поле формы с дефолтным компонентом
17
- * { "model": "email" }
18
- *
19
- * // Поле с кастомным компонентом
20
- * { "model": "password", "component": "InputPassword" }
21
- *
22
- * // Контейнер
23
- * { "component": "Box", "children": [...] }
24
- * ```
25
- */
26
- export interface JsonNode {
27
- /**
28
- * Идентификатор узла для renderBehavior (hideWhen, patchProps).
29
- * Необязателен — нужен только если к узлу привязано поведение.
30
- */
1
+ import { ModelOp, ComponentOp } from '../operators';
2
+ /** Лист формы: значение из модели (`$model`) + опциональный компонент (`$component`, дефолт — Input). */
3
+ export interface JsonFieldNode {
4
+ /** Id для render-behavior (hideWhen/patchProps). Опционален. */
31
5
  selector?: string;
32
- /**
33
- * Имя компонента из реестра: "Input", "Box", "Section", "Select"
34
- *
35
- * - Для полей: компонент для рендеринга значения (опционально, по умолчанию Input)
36
- * - Для контейнеров: React-компонент контейнера (обязательно)
37
- */
38
- component?: string;
39
- /**
40
- * Путь к полю формы (модели): "email", "personalData.firstName", "addresses[0].city"
41
- *
42
- * Если указан — узел представляет поле формы.
43
- */
44
- model?: string;
45
- /**
46
- * Props для компонента (className, title и т.д.)
47
- */
6
+ /** Привязка к сигналу модели: `'$model(personalData.lastName)'`. */
7
+ value: ModelOp;
8
+ /** Компонент поля из реестра: `'$component(Select)'`. Опционален. */
9
+ component?: ComponentOp;
10
+ /** Props компонента; значения могут содержать строки-операторы (`'$dataSource(NAME)'`) или вложенные узлы. */
48
11
  componentProps?: Record<string, unknown>;
12
+ /** Обёртка поля (например, FormField). */
13
+ wrapper?: JsonNode;
14
+ }
15
+ /** Массив форм: данные из модели (`$model`) + шаблон элемента (`$template`). */
16
+ export interface JsonArrayNode {
17
+ /** Id для render-behavior. */
18
+ selector?: string;
19
+ /** Привязка к массиву модели: `'$model(coBorrowers)'`. */
20
+ array: ModelOp;
21
+ /** Шаблон под-схемы элемента. */
22
+ item: {
23
+ $template: JsonNode;
24
+ };
49
25
  /**
50
- * Дочерние узлы (для контейнеров)
26
+ * «Пустой» элемент для кнопки «Добавить» (литерал-объект по форме элемента).
27
+ * Нужен, т.к. листья шаблона несут `value: '$model(...)'`, а не литерал-дефолт.
51
28
  */
29
+ initialValue?: Record<string, unknown>;
30
+ /** Оформление секции массива (title/addButtonLabel/itemLabel/emptyMessage/…). */
31
+ componentProps?: Record<string, unknown>;
32
+ }
33
+ /** Контейнер (Box/Section/Wizard/Step/…) с дочерними узлами. */
34
+ export interface JsonContainerNode {
35
+ /** Id для render-behavior. */
36
+ selector?: string;
37
+ /** Компонент-контейнер из реестра: `'$component(Section)'`. */
38
+ component: ComponentOp;
39
+ /** Props компонента; значения могут содержать строки-операторы или вложенные узлы. */
40
+ componentProps?: Record<string, unknown>;
41
+ /** Дочерние узлы. */
52
42
  children?: JsonNode[];
53
- /**
54
- * Обёртка для узла (например, fieldWrapper)
55
- *
56
- * @example
57
- * ```json
58
- * {
59
- * "model": "email",
60
- * "wrapper": {
61
- * "component": "FormField",
62
- * "componentProps": { "className": "col-span-2" }
63
- * }
64
- * }
65
- * ```
66
- */
67
- wrapper?: JsonNode;
68
43
  }
44
+ /** Узел JSON-схемы (M1). */
45
+ export type JsonNode = JsonFieldNode | JsonArrayNode | JsonContainerNode;
69
46
  /**
70
- * Корневая JSON-схема формы
47
+ * Корневая JSON-схема формы.
71
48
  *
72
49
  * @example
73
- * ```json
74
- * {
75
- * "version": "1.0",
76
- * "root": {
77
- * "component": "Box",
78
- * "componentProps": { "className": "space-y-4" },
79
- * "children": [
80
- * { "model": "email" },
81
- * { "model": "password", "component": "InputPassword" }
82
- * ]
83
- * }
84
- * }
50
+ * ```ts
51
+ * const schema: JsonFormSchema = {
52
+ * version: '1.0',
53
+ * root: {
54
+ * component: '$component(Box)',
55
+ * children: [{ value: '$model(email)', component: '$component(Input)' }],
56
+ * },
57
+ * };
85
58
  * ```
86
59
  */
87
60
  export interface JsonFormSchema {
88
61
  /**
89
- * Версия схемы (для миграций)
62
+ * Путь к мета-схеме для IDE (VSCode подсветит структуру/синтаксис/имена `$component`).
63
+ * Игнорируется конвертером. Сгенерировать конкретную мета-схему: `gen-form-json-schema.ts`.
90
64
  */
65
+ $schema?: string;
66
+ /** Версия схемы (для миграций). */
91
67
  version?: string;
92
- /**
93
- * Корневой узел схемы
94
- */
68
+ /** Корневой узел. */
95
69
  root: JsonNode;
96
70
  }
97
- /**
98
- * Type guard: проверяет, является ли узел полем формы (имеет `model`).
99
- *
100
- * @param node - Узел JSON-схемы.
101
- * @returns `true`, если у узла есть непустое `model`.
102
- *
103
- * @example
104
- * ```typescript
105
- * if (isFieldNode(node)) {
106
- * // node.model гарантированно строка
107
- * readField(node.model);
108
- * }
109
- * ```
110
- */
111
- export declare function isFieldNode(node: JsonNode): boolean;
112
- /**
113
- * Type guard: проверяет, является ли узел контейнером (только `component`, без `model`).
114
- *
115
- * @param node - Узел JSON-схемы.
116
- * @returns `true`, если у узла есть `component`, но нет `model`.
117
- *
118
- * @example
119
- * ```typescript
120
- * if (isContainerNode(node)) {
121
- * node.children?.forEach(walk);
122
- * }
123
- * ```
124
- */
125
- export declare function isContainerNode(node: JsonNode): boolean;
71
+ /** Type-guard: узел — массив (`array: '$model(...)'` + `item.$template`). Проверять ПЕРВЫМ. */
72
+ export declare function isArrayNode(node: JsonNode): node is JsonArrayNode;
73
+ /** Type-guard: узел — лист (`value: '$model(...)'`). */
74
+ export declare function isFieldNode(node: JsonNode): node is JsonFieldNode;
75
+ /** Type-guard: узел контейнер (`component: '$component(...)'`, без `value`/`array`). */
76
+ export declare function isContainerNode(node: JsonNode): node is JsonContainerNode;
@@ -0,0 +1,23 @@
1
+ import { ComponentRegistry } from './registry/types';
2
+ /** Результат валидации схемы. */
3
+ export interface FormSchemaValidationResult {
4
+ valid: boolean;
5
+ /** Человекочитаемые ошибки (путь + сообщение). Пусто, если валидно. */
6
+ errors: string[];
7
+ }
8
+ /** Опции: реестр (имена извлекаются автоматически) либо явные списки имён. */
9
+ export interface ValidateFormSchemaOptions {
10
+ registry?: ComponentRegistry;
11
+ componentNames?: string[];
12
+ sourceNames?: string[];
13
+ }
14
+ /**
15
+ * Валидирует form-DSL JSON-схему. Если передан `registry`, имена компонентов/source берутся из него.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const { valid, errors } = validateFormSchema(jsonSchema, { registry });
20
+ * if (!valid) console.error(errors);
21
+ * ```
22
+ */
23
+ export declare function validateFormSchema(schema: unknown, opts?: ValidateFormSchemaOptions): FormSchemaValidationResult;