@gravity-ui/dynamic-forms 5.26.0 → 5.27.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.
Files changed (55) hide show
  1. package/build/cjs/lib/unstable/core/SchemaRendererNode/SchemaRendererNode.js +67 -14
  2. package/build/cjs/lib/unstable/core/SchemaRendererNode/utils.d.ts +6 -3
  3. package/build/cjs/lib/unstable/core/SchemaRendererNode/utils.js +63 -14
  4. package/build/cjs/lib/unstable/core/index.d.ts +1 -1
  5. package/build/cjs/lib/unstable/core/index.js +4 -1
  6. package/build/cjs/lib/unstable/core/useSchemaRenderer/types/state.d.ts +1 -0
  7. package/build/cjs/lib/unstable/core/useSchemaRenderer/useSchemaRenderer.d.ts +2 -1
  8. package/build/cjs/lib/unstable/core/useSchemaRenderer/useSchemaRenderer.js +39 -22
  9. package/build/cjs/lib/unstable/core/useSchemaRenderer/utils/get-validate.js +6 -1
  10. package/build/cjs/lib/unstable/core/useSchemaRendererState/useSchemaRendererState.js +14 -0
  11. package/build/cjs/lib/unstable/core/utils/common.d.ts +3 -0
  12. package/build/cjs/lib/unstable/core/utils/common.js +7 -1
  13. package/build/cjs/lib/unstable/core/utils/index.d.ts +1 -0
  14. package/build/cjs/lib/unstable/core/utils/index.js +1 -0
  15. package/build/cjs/lib/unstable/core/utils/strict-mode.d.ts +6 -0
  16. package/build/cjs/lib/unstable/core/utils/strict-mode.js +30 -0
  17. package/build/cjs/lib/unstable/kit/components/EntityError/EntityError.js +1 -1
  18. package/build/cjs/lib/unstable/kit/entities/OneOfNested/OneOfNested.js +9 -1
  19. package/build/cjs/lib/unstable/kit/form-entities/StringNumberWithScaleInput/StringNumberWithScaleInput.d.ts +1 -1
  20. package/build/cjs/lib/unstable/kit/form-entities/StringNumberWithScaleInput/StringNumberWithScaleInput.js +8 -7
  21. package/build/cjs/lib/unstable/kit/overview-entities/StringNumberWithScaleValue/StringNumberWithScaleValue.d.ts +1 -1
  22. package/build/cjs/lib/unstable/kit/overview-entities/StringNumberWithScaleValue/StringNumberWithScaleValue.js +5 -5
  23. package/build/cjs/lib/unstable/kit/utils/common.d.ts +0 -3
  24. package/build/cjs/lib/unstable/kit/utils/common.js +1 -7
  25. package/build/cjs/lib/unstable/kit/utils/index.d.ts +1 -1
  26. package/build/cjs/lib/unstable/kit/utils/index.js +1 -4
  27. package/build/cjs/lib/unstable/kit/utils/transformer.js +10 -2
  28. package/build/esm/lib/unstable/core/SchemaRendererNode/SchemaRendererNode.js +70 -17
  29. package/build/esm/lib/unstable/core/SchemaRendererNode/utils.d.ts +6 -3
  30. package/build/esm/lib/unstable/core/SchemaRendererNode/utils.js +63 -14
  31. package/build/esm/lib/unstable/core/index.d.ts +1 -1
  32. package/build/esm/lib/unstable/core/index.js +1 -1
  33. package/build/esm/lib/unstable/core/useSchemaRenderer/types/state.d.ts +1 -0
  34. package/build/esm/lib/unstable/core/useSchemaRenderer/useSchemaRenderer.d.ts +2 -1
  35. package/build/esm/lib/unstable/core/useSchemaRenderer/useSchemaRenderer.js +40 -23
  36. package/build/esm/lib/unstable/core/useSchemaRenderer/utils/get-validate.js +6 -1
  37. package/build/esm/lib/unstable/core/useSchemaRendererState/useSchemaRendererState.js +15 -1
  38. package/build/esm/lib/unstable/core/utils/common.d.ts +3 -0
  39. package/build/esm/lib/unstable/core/utils/common.js +3 -0
  40. package/build/esm/lib/unstable/core/utils/index.d.ts +1 -0
  41. package/build/esm/lib/unstable/core/utils/index.js +1 -0
  42. package/build/esm/lib/unstable/core/utils/strict-mode.d.ts +6 -0
  43. package/build/esm/lib/unstable/core/utils/strict-mode.js +26 -0
  44. package/build/esm/lib/unstable/kit/components/EntityError/EntityError.js +1 -1
  45. package/build/esm/lib/unstable/kit/entities/OneOfNested/OneOfNested.js +9 -1
  46. package/build/esm/lib/unstable/kit/form-entities/StringNumberWithScaleInput/StringNumberWithScaleInput.d.ts +1 -1
  47. package/build/esm/lib/unstable/kit/form-entities/StringNumberWithScaleInput/StringNumberWithScaleInput.js +2 -1
  48. package/build/esm/lib/unstable/kit/overview-entities/StringNumberWithScaleValue/StringNumberWithScaleValue.d.ts +1 -1
  49. package/build/esm/lib/unstable/kit/overview-entities/StringNumberWithScaleValue/StringNumberWithScaleValue.js +1 -1
  50. package/build/esm/lib/unstable/kit/utils/common.d.ts +0 -3
  51. package/build/esm/lib/unstable/kit/utils/common.js +0 -3
  52. package/build/esm/lib/unstable/kit/utils/index.d.ts +1 -1
  53. package/build/esm/lib/unstable/kit/utils/index.js +1 -1
  54. package/build/esm/lib/unstable/kit/utils/transformer.js +10 -2
  55. package/package.json +1 -1
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaRendererNode = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
+ const get_1 = tslib_1.__importDefault(require("lodash/get"));
6
7
  const noop_1 = tslib_1.__importDefault(require("lodash/noop"));
7
8
  const react_final_form_1 = require("react-final-form");
8
9
  const constants_1 = require("../constants");
@@ -11,9 +12,9 @@ const useSchemaRendererState_1 = require("../useSchemaRendererState");
11
12
  const utils_1 = require("../utils");
12
13
  const utils_2 = require("./utils");
13
14
  const SchemaRendererNodeComponent = ({ headName, modeOverride, name, schemaOverride, schemaPath, }) => {
14
- var _a;
15
+ var _a, _b, _c, _d, _e, _f;
15
16
  const form = (0, react_final_form_1.useForm)();
16
- const compareValuesRef = react_1.default.useRef((0, utils_2.getCompareValues)());
17
+ const strictCheckerRef = react_1.default.useRef((0, utils_1.getStrictModeChecker)());
17
18
  const fieldRef = react_1.default.useRef(null);
18
19
  const unsubscribeRef = react_1.default.useRef(null);
19
20
  const [ticks, setTicks] = react_1.default.useState({ input: 0, meta: 0 });
@@ -34,13 +35,15 @@ const SchemaRendererNodeComponent = ({ headName, modeOverride, name, schemaOverr
34
35
  const schema = react_1.default.useMemo(() => (0, utils_2.getAccumulatedSchema)(schemaPath, srState === null || srState === void 0 ? void 0 : srState.schema, schemaOverride), [schemaOverride, schemaPath, srState === null || srState === void 0 ? void 0 : srState.schema]);
35
36
  const error = srState === null || srState === void 0 ? void 0 : srState.errors[name];
36
37
  const mode = modeOverride || (srState === null || srState === void 0 ? void 0 : srState.mode);
37
- const jsonDefaultValues = ((_a = srState === null || srState === void 0 ? void 0 : srState.settings) === null || _a === void 0 ? void 0 : _a.jsonDefaultValues) || false;
38
+ // todo: check parent
39
+ const required = (_b = (_a = schema === null || schema === void 0 ? void 0 : schema.nodeParameters) === null || _a === void 0 ? void 0 : _a.flags) === null || _b === void 0 ? void 0 : _b.required;
40
+ const coerceInitialValues = (_d = (_c = srState === null || srState === void 0 ? void 0 : srState.settings) === null || _c === void 0 ? void 0 : _c.coerceInitialValues) !== null && _d !== void 0 ? _d : true;
41
+ const jsonDefaultValues = (_f = (_e = srState === null || srState === void 0 ? void 0 : srState.settings) === null || _e === void 0 ? void 0 : _e.jsonDefaultValues) !== null && _f !== void 0 ? _f : false;
38
42
  const kit = react_1.default.useMemo(() => (0, utils_2.getRenderKit)({ config: srState === null || srState === void 0 ? void 0 : srState.config, schema }), [schema, srState === null || srState === void 0 ? void 0 : srState.config]);
39
43
  react_1.default.useMemo(() => {
40
44
  var _a;
41
- if (compareValuesRef.current({
45
+ if (!strictCheckerRef.current.checkDiff({
42
46
  form,
43
- jsonDefaultValues,
44
47
  headName,
45
48
  name,
46
49
  default: schema === null || schema === void 0 ? void 0 : schema.default,
@@ -51,13 +54,35 @@ const SchemaRendererNodeComponent = ({ headName, modeOverride, name, schemaOverr
51
54
  }
52
55
  (_a = unsubscribeRef.current) === null || _a === void 0 ? void 0 : _a.call(unsubscribeRef);
53
56
  const initialState = { schemaPath };
54
- let defaultValue = schema === null || schema === void 0 ? void 0 : schema.default;
55
- if (jsonDefaultValues && typeof defaultValue === 'string') {
56
- try {
57
- defaultValue = JSON.parse(defaultValue);
57
+ const defaultValue = (() => {
58
+ let result = schema === null || schema === void 0 ? void 0 : schema.default;
59
+ if (jsonDefaultValues) {
60
+ try {
61
+ result = JSON.parse(result);
62
+ }
63
+ catch (_a) {
64
+ result = undefined;
65
+ }
58
66
  }
59
- catch (_b) { }
60
- }
67
+ if (result === undefined && required) {
68
+ if ((Array.isArray(schema.type) &&
69
+ schema.type.length &&
70
+ !schema.type.filter((t) => t !== constants_1.JsonSchemaType.Array).length) ||
71
+ schema.type === constants_1.JsonSchemaType.Array) {
72
+ result = [];
73
+ }
74
+ else if ((Array.isArray(schema.type) &&
75
+ schema.type.length &&
76
+ !schema.type.filter((t) => t !== constants_1.JsonSchemaType.Object).length) ||
77
+ schema.type === constants_1.JsonSchemaType.Object) {
78
+ result = {};
79
+ }
80
+ }
81
+ if (coerceInitialValues) {
82
+ result = (0, utils_2.coerceToJsonSchemaType)(result, schema === null || schema === void 0 ? void 0 : schema.type);
83
+ }
84
+ return result;
85
+ })();
61
86
  const unsubscribe = form.registerField(name, (f) => {
62
87
  const prevF = fieldRef.current;
63
88
  if (prevF) {
@@ -85,12 +110,36 @@ const SchemaRendererNodeComponent = ({ headName, modeOverride, name, schemaOverr
85
110
  silent: true,
86
111
  validateFields: [(0, utils_1.getServiceFieldName)(useSchemaRenderer_1.SCHEMA_RENDERER_SERVICE_FIELD, headName)],
87
112
  });
88
- (0, utils_2.scheduleFlush)(form);
113
+ const castParams = (() => {
114
+ if (!coerceInitialValues) {
115
+ return undefined;
116
+ }
117
+ const formValues = form.getState().values;
118
+ const currentValue = name ? (0, get_1.default)(formValues, name) : formValues;
119
+ if (currentValue === undefined) {
120
+ return undefined;
121
+ }
122
+ const coercedCurrentValue = (0, utils_2.coerceToJsonSchemaType)(currentValue, schema === null || schema === void 0 ? void 0 : schema.type);
123
+ if (coercedCurrentValue !== undefined) {
124
+ if (coercedCurrentValue === currentValue) {
125
+ return undefined;
126
+ }
127
+ return { name, value: coercedCurrentValue };
128
+ }
129
+ if (defaultValue !== undefined) {
130
+ if (defaultValue === currentValue) {
131
+ return undefined;
132
+ }
133
+ return { name, value: defaultValue };
134
+ }
135
+ return undefined;
136
+ })();
137
+ (0, utils_2.scheduleFlush)(form, headName, castParams);
89
138
  unsubscribeRef.current = () => {
90
139
  unsubscribe();
91
- (0, utils_2.scheduleFlush)(form);
140
+ (0, utils_2.scheduleFlush)(form, headName);
92
141
  };
93
- }, [form, jsonDefaultValues, headName, name, schema === null || schema === void 0 ? void 0 : schema.default, schema === null || schema === void 0 ? void 0 : schema.type, schemaPath]);
142
+ }, [form, headName, name, schema === null || schema === void 0 ? void 0 : schema.default, schema === null || schema === void 0 ? void 0 : schema.type, schemaPath]);
94
143
  const input = react_1.default.useMemo(() => {
95
144
  var _a;
96
145
  const fieldState = form.getFieldState(name);
@@ -114,8 +163,12 @@ const SchemaRendererNodeComponent = ({ headName, modeOverride, name, schemaOverr
114
163
  };
115
164
  }, [error, form, name, ticks.meta]);
116
165
  react_1.default.useEffect(() => {
166
+ const strictChecker = strictCheckerRef.current;
117
167
  return () => {
118
168
  var _a;
169
+ if (strictChecker.isStrict()) {
170
+ return;
171
+ }
119
172
  (_a = unsubscribeRef.current) === null || _a === void 0 ? void 0 : _a.call(unsubscribeRef);
120
173
  };
121
174
  }, []);
@@ -1,6 +1,6 @@
1
1
  import type { FormApi } from 'final-form';
2
2
  import { SchemaRendererMode } from '../constants';
3
- import type { JsonSchema, NodeEntity, NodeLayout, NodesConfig } from '../types';
3
+ import type { FieldValue, JsonSchema, NodeEntity, NodeLayout, NodesConfig } from '../types';
4
4
  type GetRenderKitParams<Schema extends JsonSchema> = {
5
5
  config?: NodesConfig;
6
6
  schema?: Schema;
@@ -23,6 +23,9 @@ type GetRenderKitReturn<Schema extends JsonSchema> = {
23
23
  };
24
24
  export declare const getRenderKit: <Schema extends JsonSchema>({ config, schema, }: GetRenderKitParams<Schema>) => GetRenderKitReturn<Schema>;
25
25
  export declare const getAccumulatedSchema: (schemaPath: string, rootSchema?: JsonSchema, override?: JsonSchema, collectedPaths?: Set<string>) => JsonSchema;
26
- export declare const scheduleFlush: (form: FormApi) => void;
27
- export declare const getCompareValues: () => (currentValues: Record<string, unknown>) => boolean;
26
+ export declare const scheduleFlush: (form: FormApi, headName: string, change?: {
27
+ name: string;
28
+ value: FieldValue;
29
+ }) => void;
30
+ export declare const coerceToJsonSchemaType: (value: FieldValue, type?: JsonSchema["type"]) => FieldValue;
28
31
  export {};
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCompareValues = exports.scheduleFlush = exports.getAccumulatedSchema = exports.getRenderKit = void 0;
3
+ exports.coerceToJsonSchemaType = exports.scheduleFlush = exports.getAccumulatedSchema = exports.getRenderKit = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const get_1 = tslib_1.__importDefault(require("lodash/get"));
6
+ const isObjectLike_1 = tslib_1.__importDefault(require("lodash/isObjectLike"));
6
7
  const isString_1 = tslib_1.__importDefault(require("lodash/isString"));
7
8
  const set_1 = tslib_1.__importDefault(require("lodash/set"));
8
9
  const constants_1 = require("../constants");
10
+ const useSchemaRenderer_1 = require("../useSchemaRenderer");
9
11
  const utils_1 = require("../utils");
10
12
  const fixType = (value) => value;
11
13
  const mergeValues = (first, second) => {
@@ -161,26 +163,73 @@ const getAccumulatedSchema = (schemaPath, rootSchema, override, collectedPaths =
161
163
  };
162
164
  exports.getAccumulatedSchema = getAccumulatedSchema;
163
165
  const flushes = new WeakMap();
164
- const scheduleFlush = (form) => {
165
- if (flushes.get(form)) {
166
+ const scheduleFlush = (form, headName, change) => {
167
+ const scheduled = flushes.get(form);
168
+ if (scheduled) {
169
+ scheduled.headNames.add(headName);
170
+ if (change) {
171
+ scheduled.changes.set(change.name, change.value);
172
+ }
166
173
  return;
167
174
  }
168
- flushes.set(form, true);
175
+ const changes = new Map();
176
+ const headNames = new Set([headName]);
177
+ if (change) {
178
+ changes.set(change.name, change.value);
179
+ }
180
+ flushes.set(form, { changes, headNames });
169
181
  queueMicrotask(() => {
170
182
  flushes.delete(form);
171
- form.batch(() => { });
183
+ form.batch(() => {
184
+ changes.forEach((value, name) => {
185
+ form.change(name, value);
186
+ });
187
+ });
188
+ headNames.forEach((name) => {
189
+ var _a;
190
+ const srName = (0, utils_1.getServiceFieldName)(useSchemaRenderer_1.SCHEMA_RENDERER_SERVICE_FIELD, name);
191
+ const srField = form.getFieldState(srName);
192
+ const srState = (_a = srField === null || srField === void 0 ? void 0 : srField.data) === null || _a === void 0 ? void 0 : _a.state;
193
+ srState === null || srState === void 0 ? void 0 : srState.runValidate();
194
+ });
172
195
  });
173
196
  };
174
197
  exports.scheduleFlush = scheduleFlush;
175
- const getCompareValues = () => {
176
- let cachedValues;
177
- return (currentValues) => {
178
- if (!cachedValues ||
179
- [...Object.keys(cachedValues), ...Object.keys(currentValues)].some((key) => cachedValues[key] !== currentValues[key])) {
180
- cachedValues = Object.assign({}, currentValues);
198
+ // eslint-disable-next-line complexity
199
+ const coerceToJsonSchemaType = (value, type) => {
200
+ if (value === undefined || value === null || !type) {
201
+ return value;
202
+ }
203
+ const typeArray = Array.isArray(type) ? type : [type];
204
+ if (typeArray.length &&
205
+ typeArray.some((t) => t === constants_1.JsonSchemaType.Number || t === constants_1.JsonSchemaType.Integer) &&
206
+ !typeArray.filter((t) => t !== constants_1.JsonSchemaType.Number &&
207
+ t !== constants_1.JsonSchemaType.Integer &&
208
+ t !== constants_1.JsonSchemaType.Null).length) {
209
+ if ((0, utils_1.isStringNumber)(value)) {
210
+ return Number(value);
211
+ }
212
+ return value;
213
+ }
214
+ if (typeArray.length &&
215
+ typeArray.some((t) => t === constants_1.JsonSchemaType.Boolean) &&
216
+ !typeArray.filter((t) => t !== constants_1.JsonSchemaType.Boolean && t !== constants_1.JsonSchemaType.Null).length) {
217
+ if (value === 'true' || value === 1) {
218
+ return true;
219
+ }
220
+ if (value === 'false' || value === 0) {
181
221
  return false;
182
222
  }
183
- return true;
184
- };
223
+ return value;
224
+ }
225
+ if (typeArray.length &&
226
+ typeArray.some((t) => t === constants_1.JsonSchemaType.String) &&
227
+ !typeArray.filter((t) => t !== constants_1.JsonSchemaType.String && t !== constants_1.JsonSchemaType.Null).length) {
228
+ if (!(typeof value === 'string' || (0, isObjectLike_1.default)(value))) {
229
+ return String(value);
230
+ }
231
+ return value;
232
+ }
233
+ return value;
185
234
  };
186
- exports.getCompareValues = getCompareValues;
235
+ exports.coerceToJsonSchemaType = coerceToJsonSchemaType;
@@ -5,4 +5,4 @@ export type * from './types';
5
5
  export { SCHEMA_RENDERER_SERVICE_FIELD, type SchemaRendererState, type SchemaPatch, type SchemaPatchRemover, type UseSchemaRendererParams, useSchemaRenderer, } from './useSchemaRenderer';
6
6
  export { type UseSchemaRendererStateParams, useSchemaRendererState } from './useSchemaRendererState';
7
7
  export { useSchemaRendererTools } from './useSchemaRendererTools';
8
- export { createNodeParametersDefiner, defineNodeEntityConfig, defineNodeLayoutConfig, getServiceFieldName, getSchemaByPointer, } from './utils';
8
+ export { createNodeParametersDefiner, defineNodeEntityConfig, defineNodeLayoutConfig, getServiceFieldName, getSchemaByPointer, isStringFloat, isStringInt, isStringNumber, } from './utils';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSchemaByPointer = exports.getServiceFieldName = exports.defineNodeLayoutConfig = exports.defineNodeEntityConfig = exports.createNodeParametersDefiner = exports.useSchemaRendererTools = exports.useSchemaRendererState = exports.useSchemaRenderer = exports.SCHEMA_RENDERER_SERVICE_FIELD = exports.SchemaRendererMode = exports.SchemaRendererEventType = exports.JsonSchemaType = exports.NodeType = exports.SchemaRenderer = exports.getRenderKit = exports.getAccumulatedSchema = exports.SchemaRendererNode = void 0;
3
+ exports.isStringNumber = exports.isStringInt = exports.isStringFloat = exports.getSchemaByPointer = exports.getServiceFieldName = exports.defineNodeLayoutConfig = exports.defineNodeEntityConfig = exports.createNodeParametersDefiner = exports.useSchemaRendererTools = exports.useSchemaRendererState = exports.useSchemaRenderer = exports.SCHEMA_RENDERER_SERVICE_FIELD = exports.SchemaRendererMode = exports.SchemaRendererEventType = exports.JsonSchemaType = exports.NodeType = exports.SchemaRenderer = exports.getRenderKit = exports.getAccumulatedSchema = exports.SchemaRendererNode = void 0;
4
4
  var SchemaRendererNode_1 = require("./SchemaRendererNode");
5
5
  Object.defineProperty(exports, "SchemaRendererNode", { enumerable: true, get: function () { return SchemaRendererNode_1.SchemaRendererNode; } });
6
6
  Object.defineProperty(exports, "getAccumulatedSchema", { enumerable: true, get: function () { return SchemaRendererNode_1.getAccumulatedSchema; } });
@@ -25,3 +25,6 @@ Object.defineProperty(exports, "defineNodeEntityConfig", { enumerable: true, get
25
25
  Object.defineProperty(exports, "defineNodeLayoutConfig", { enumerable: true, get: function () { return utils_1.defineNodeLayoutConfig; } });
26
26
  Object.defineProperty(exports, "getServiceFieldName", { enumerable: true, get: function () { return utils_1.getServiceFieldName; } });
27
27
  Object.defineProperty(exports, "getSchemaByPointer", { enumerable: true, get: function () { return utils_1.getSchemaByPointer; } });
28
+ Object.defineProperty(exports, "isStringFloat", { enumerable: true, get: function () { return utils_1.isStringFloat; } });
29
+ Object.defineProperty(exports, "isStringInt", { enumerable: true, get: function () { return utils_1.isStringInt; } });
30
+ Object.defineProperty(exports, "isStringNumber", { enumerable: true, get: function () { return utils_1.isStringNumber; } });
@@ -18,6 +18,7 @@ export interface SchemaRendererState<UserContext extends Record<string, unknown>
18
18
  runValidate: () => void;
19
19
  schema: JsonSchema;
20
20
  settings: {
21
+ coerceInitialValues: boolean;
21
22
  jsonDefaultValues: boolean;
22
23
  };
23
24
  subscribe: (subscriber: SchemaRendererSubscriber) => string;
@@ -3,6 +3,7 @@ import { type SchemaRendererMode } from '../constants';
3
3
  import type { ErrorMessages, FieldValue, JsonSchema, NodesConfig } from '../types';
4
4
  import type { SchemaRendererState } from './types';
5
5
  export interface UseSchemaRendererParams {
6
+ coerceInitialValues?: boolean;
6
7
  config?: NodesConfig;
7
8
  connectValidate?: boolean;
8
9
  errorMessages?: ErrorMessages;
@@ -13,4 +14,4 @@ export interface UseSchemaRendererParams {
13
14
  validateOnBlur: boolean;
14
15
  userContext?: SchemaRendererState['userContext'];
15
16
  }
16
- export declare const useSchemaRenderer: ({ config, connectValidate, errorMessages, jsonDefaultValues, mode, name: headName, schema: originalSchema, validateOnBlur, userContext, }: UseSchemaRendererParams) => FieldValidator<FieldValue>;
17
+ export declare const useSchemaRenderer: ({ coerceInitialValues, config, connectValidate, errorMessages, jsonDefaultValues, mode, name: headName, schema: originalSchema, validateOnBlur, userContext, }: UseSchemaRendererParams) => FieldValidator<FieldValue>;
@@ -10,8 +10,9 @@ const constants_1 = require("../constants");
10
10
  const utils_1 = require("../utils");
11
11
  const constants_2 = require("./constants");
12
12
  const utils_2 = require("./utils");
13
- const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, jsonDefaultValues = false, mode, name: headName, schema: originalSchema, validateOnBlur, userContext, }) => {
13
+ const useSchemaRenderer = ({ coerceInitialValues = true, config, connectValidate = true, errorMessages, jsonDefaultValues = false, mode, name: headName, schema: originalSchema, validateOnBlur, userContext, }) => {
14
14
  const form = (0, react_final_form_1.useForm)();
15
+ const strictCheckerRef = react_1.default.useRef((0, utils_1.getStrictModeChecker)());
15
16
  const stateRef = react_1.default.useRef(null);
16
17
  const prevParamsRef = react_1.default.useRef(null);
17
18
  const unsubscribeRef = react_1.default.useRef(null);
@@ -19,9 +20,7 @@ const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, json
19
20
  const dispatchEvent = react_1.default.useMemo(() => (0, utils_2.getDispatch)(form, headName), [form, headName]);
20
21
  const runValidate = react_1.default.useMemo(() => (0, utils_2.getRunValidate)(form, headName, validateOnBlur), [form, headName, validateOnBlur]);
21
22
  const validate = react_1.default.useMemo(() => (0, utils_2.getValidate)(form, headName), [form, headName]);
22
- const unsubscribeField = react_1.default.useMemo(() => {
23
- var _a;
24
- (_a = unsubscribeRef.current) === null || _a === void 0 ? void 0 : _a.call(unsubscribeRef);
23
+ const { initialEvents, initialState } = react_1.default.useMemo(() => {
25
24
  const prevParams = prevParamsRef.current;
26
25
  const prevState = stateRef.current;
27
26
  const configUpdated = config !== (prevParams === null || prevParams === void 0 ? void 0 : prevParams.config);
@@ -30,7 +29,8 @@ const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, json
30
29
  const modeUpdated = mode !== (prevParams === null || prevParams === void 0 ? void 0 : prevParams.mode);
31
30
  const schemaUpdated = originalSchema !== (prevParams === null || prevParams === void 0 ? void 0 : prevParams.schema);
32
31
  const userContextUpdated = userContext !== (prevParams === null || prevParams === void 0 ? void 0 : prevParams.userContext);
33
- const settingsUpdated = jsonDefaultValues !== (prevParams === null || prevParams === void 0 ? void 0 : prevParams.jsonDefaultValues);
32
+ const settingsUpdated = coerceInitialValues !== (prevParams === null || prevParams === void 0 ? void 0 : prevParams.coerceInitialValues) ||
33
+ jsonDefaultValues !== (prevParams === null || prevParams === void 0 ? void 0 : prevParams.jsonDefaultValues);
34
34
  const initialState = {
35
35
  cache: nameUpdated || schemaUpdated || !(prevState === null || prevState === void 0 ? void 0 : prevState.cache) ? {} : prevState.cache,
36
36
  config: config || {},
@@ -47,7 +47,7 @@ const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, json
47
47
  ? {}
48
48
  : prevState.regularErrors,
49
49
  runValidate,
50
- settings: { jsonDefaultValues },
50
+ settings: { coerceInitialValues, jsonDefaultValues },
51
51
  schema: nameUpdated || schemaUpdated ? (0, cloneDeep_1.default)(originalSchema) : (prevState === null || prevState === void 0 ? void 0 : prevState.schema) || {},
52
52
  subscribe,
53
53
  subscribers: (prevState === null || prevState === void 0 ? void 0 : prevState.subscribers) || { byId: {}, byName: new Map(), byPath: new Map() },
@@ -55,8 +55,7 @@ const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, json
55
55
  userContext: userContextUpdated ? userContext || {} : (prevState === null || prevState === void 0 ? void 0 : prevState.userContext) || {},
56
56
  waiters: nameUpdated || schemaUpdated || !(prevState === null || prevState === void 0 ? void 0 : prevState.waiters) ? {} : prevState.waiters,
57
57
  };
58
- const getValidator = connectValidate ? () => validate : undefined;
59
- let initialEvents = [
58
+ const initialEvents = [
60
59
  ...(configUpdated ? [constants_1.SchemaRendererEventType.Config] : []),
61
60
  ...(errorMessagesUpdated ? [constants_1.SchemaRendererEventType.ErrorMessages] : []),
62
61
  ...(nameUpdated ? [constants_1.SchemaRendererEventType.Name] : []),
@@ -65,15 +64,8 @@ const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, json
65
64
  ...(userContextUpdated ? [constants_1.SchemaRendererEventType.UserContext] : []),
66
65
  ...(settingsUpdated ? [constants_1.SchemaRendererEventType.Settings] : []),
67
66
  ].map((type) => ({ type, all: true }));
68
- unsubscribeRef.current = form.registerField((0, utils_1.getServiceFieldName)(constants_2.SCHEMA_RENDERER_SERVICE_FIELD, headName), (f) => {
69
- var _a;
70
- const state = (_a = f.data) === null || _a === void 0 ? void 0 : _a.state;
71
- if (state && initialEvents.length) {
72
- state.dispatchEvent(initialEvents);
73
- initialEvents = [];
74
- }
75
- }, { data: true }, { data: { state: initialState }, getValidator, silent: true, validateFields: [headName] });
76
67
  prevParamsRef.current = {
68
+ coerceInitialValues,
77
69
  config,
78
70
  errorMessages,
79
71
  jsonDefaultValues,
@@ -84,13 +76,12 @@ const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, json
84
76
  validateOnBlur,
85
77
  };
86
78
  stateRef.current = initialState;
87
- return unsubscribeRef.current;
79
+ return { initialEvents, initialState };
88
80
  }, [
81
+ coerceInitialValues,
89
82
  config,
90
- connectValidate,
91
83
  dispatchEvent,
92
84
  errorMessages,
93
- form,
94
85
  jsonDefaultValues,
95
86
  headName,
96
87
  mode,
@@ -98,16 +89,42 @@ const useSchemaRenderer = ({ config, connectValidate = true, errorMessages, json
98
89
  runValidate,
99
90
  subscribe,
100
91
  unsubscribe,
101
- validate,
102
92
  validateOnBlur,
103
93
  userContext,
104
94
  ]);
95
+ react_1.default.useMemo(() => {
96
+ var _a;
97
+ if (!strictCheckerRef.current.checkDiff({
98
+ connectValidate,
99
+ form,
100
+ headName,
101
+ validate,
102
+ })) {
103
+ return;
104
+ }
105
+ const getValidator = connectValidate ? () => validate : undefined;
106
+ (_a = unsubscribeRef.current) === null || _a === void 0 ? void 0 : _a.call(unsubscribeRef);
107
+ unsubscribeRef.current = form.registerField((0, utils_1.getServiceFieldName)(constants_2.SCHEMA_RENDERER_SERVICE_FIELD, headName), () => { }, { data: true }, {
108
+ data: { state: stateRef.current },
109
+ getValidator,
110
+ silent: true,
111
+ validateFields: [headName],
112
+ });
113
+ }, [connectValidate, form, headName, validate]);
105
114
  react_1.default.useEffect(() => {
106
- runValidate();
107
- }, [unsubscribeField]);
115
+ const srField = form.getFieldState((0, utils_1.getServiceFieldName)(constants_2.SCHEMA_RENDERER_SERVICE_FIELD, headName));
116
+ if (srField === null || srField === void 0 ? void 0 : srField.data) {
117
+ srField.data.state = initialState;
118
+ initialState.dispatchEvent(initialEvents);
119
+ }
120
+ }, [initialEvents, initialState]);
108
121
  react_1.default.useEffect(() => {
122
+ const strictChecker = strictCheckerRef.current;
109
123
  return () => {
110
124
  var _a;
125
+ if (strictChecker.isStrict()) {
126
+ return;
127
+ }
111
128
  (_a = unsubscribeRef.current) === null || _a === void 0 ? void 0 : _a.call(unsubscribeRef);
112
129
  };
113
130
  }, []);
@@ -70,7 +70,12 @@ const getValidate = (form, headName) => {
70
70
  Object.keys(Object.assign(Object.assign({}, srState.errors), allErrors)).forEach((key) => {
71
71
  if (srState.errors[key] !== allErrors[key]) {
72
72
  newErrors[key] = allErrors[key];
73
- srState.errors[key] = allErrors[key];
73
+ if (allErrors[key] === undefined) {
74
+ delete srState.errors[key];
75
+ }
76
+ else {
77
+ srState.errors[key] = allErrors[key];
78
+ }
74
79
  }
75
80
  });
76
81
  srState.waiters = Object.assign(Object.assign({}, srState.waiters), waiters);
@@ -9,11 +9,21 @@ const useSchemaRenderer_1 = require("../useSchemaRenderer");
9
9
  const utils_1 = require("../utils");
10
10
  const useSchemaRendererState = ({ headName, name, schemaPath, subscriptions = Object.values(constants_1.SchemaRendererEventType), }) => {
11
11
  const form = (0, react_final_form_1.useForm)();
12
+ const strictCheckerRef = react_1.default.useRef((0, utils_1.getStrictModeChecker)());
12
13
  const uuidRef = react_1.default.useRef(null);
13
14
  const [tick, setTick] = react_1.default.useState(0);
14
15
  const srName = react_1.default.useMemo(() => (0, utils_1.getServiceFieldName)(useSchemaRenderer_1.SCHEMA_RENDERER_SERVICE_FIELD, headName), [headName]);
15
16
  react_1.default.useMemo(() => {
16
17
  var _a;
18
+ if (!strictCheckerRef.current.checkDiff({
19
+ form,
20
+ headName,
21
+ name,
22
+ schemaPath,
23
+ subscriptions: subscriptions.join(','),
24
+ })) {
25
+ return;
26
+ }
17
27
  const srField = form.getFieldState(srName);
18
28
  const srState = (_a = srField === null || srField === void 0 ? void 0 : srField.data) === null || _a === void 0 ? void 0 : _a.state;
19
29
  if (srState) {
@@ -48,8 +58,12 @@ const useSchemaRendererState = ({ headName, name, schemaPath, subscriptions = Ob
48
58
  return undefined;
49
59
  }, [form, srName, tick]);
50
60
  react_1.default.useEffect(() => {
61
+ const strictChecker = strictCheckerRef.current;
51
62
  return () => {
52
63
  var _a;
64
+ if (strictChecker.isStrict()) {
65
+ return;
66
+ }
53
67
  const srField = form.getFieldState(srName);
54
68
  const srState = (_a = srField === null || srField === void 0 ? void 0 : srField.data) === null || _a === void 0 ? void 0 : _a.state;
55
69
  if (srState && uuidRef.current) {
@@ -58,3 +58,6 @@ export declare const arrayPathToDotBracket: (arrayPath: string[]) => string;
58
58
  export declare const getSchemaByPointer: (schema: JsonSchema, pointer: string | string[]) => JsonSchema | undefined;
59
59
  export declare const getValuePaths: (value: unknown, path?: string[]) => string[][];
60
60
  export declare const getServiceFieldName: (serviceFieldName: string, headName: string) => string;
61
+ export declare const isStringInt: (v: unknown) => v is string;
62
+ export declare const isStringFloat: (v: unknown) => v is string;
63
+ export declare const isStringNumber: (v: unknown) => v is string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getServiceFieldName = exports.getValuePaths = exports.getSchemaByPointer = exports.arrayPathToDotBracket = exports.dotBracketToArrayPath = exports.pointerToArrayPath = void 0;
3
+ exports.isStringNumber = exports.isStringFloat = exports.isStringInt = exports.getServiceFieldName = exports.getValuePaths = exports.getSchemaByPointer = exports.arrayPathToDotBracket = exports.dotBracketToArrayPath = exports.pointerToArrayPath = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const get_1 = tslib_1.__importDefault(require("lodash/get"));
6
6
  /**
@@ -116,3 +116,9 @@ const getValuePaths = (value, path = []) => {
116
116
  exports.getValuePaths = getValuePaths;
117
117
  const getServiceFieldName = (serviceFieldName, headName) => headName ? `${serviceFieldName}.${headName}` : serviceFieldName;
118
118
  exports.getServiceFieldName = getServiceFieldName;
119
+ const isStringInt = (v) => /^-?(0|[1-9][0-9]*)$/.test(`${v}`);
120
+ exports.isStringInt = isStringInt;
121
+ const isStringFloat = (v) => /^-?(0|[1-9][0-9]*)(\.[0-9]+)?$/.test(`${v}`);
122
+ exports.isStringFloat = isStringFloat;
123
+ const isStringNumber = (v) => (0, exports.isStringInt)(v) || (0, exports.isStringFloat)(v);
124
+ exports.isStringNumber = isStringNumber;
@@ -1,2 +1,3 @@
1
1
  export * from './common';
2
2
  export * from './definers';
3
+ export * from './strict-mode';
@@ -3,3 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./common"), exports);
5
5
  tslib_1.__exportStar(require("./definers"), exports);
6
+ tslib_1.__exportStar(require("./strict-mode"), exports);
@@ -0,0 +1,6 @@
1
+ export declare const getStrictModeChecker: () => {
2
+ cachedValues: Record<string, unknown> | undefined;
3
+ hasDiff: boolean | undefined;
4
+ checkDiff: (currentValues: Record<string, unknown>) => boolean;
5
+ isStrict: () => boolean | undefined;
6
+ };
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStrictModeChecker = void 0;
4
+ const getStrictModeChecker = () => {
5
+ const checker = {
6
+ cachedValues: undefined,
7
+ hasDiff: undefined,
8
+ checkDiff: (currentValues) => {
9
+ const cachedValues = checker.cachedValues;
10
+ if (!cachedValues ||
11
+ [...Object.keys(cachedValues), ...Object.keys(currentValues)].some((key) => cachedValues[key] !== currentValues[key])) {
12
+ checker.cachedValues = Object.assign({}, currentValues);
13
+ checker.hasDiff = true;
14
+ return true;
15
+ }
16
+ checker.hasDiff = false;
17
+ return false;
18
+ },
19
+ isStrict: () => {
20
+ if (checker.hasDiff === undefined) {
21
+ return undefined;
22
+ }
23
+ const hasDiff = checker.hasDiff;
24
+ checker.hasDiff = undefined;
25
+ return !hasDiff;
26
+ },
27
+ };
28
+ return checker;
29
+ };
30
+ exports.getStrictModeChecker = getStrictModeChecker;
@@ -8,7 +8,7 @@ const utils_1 = require("../../utils");
8
8
  const b = (0, utils_1.block)('entity-error');
9
9
  const EntityError = ({ errorMessage, validationState }) => {
10
10
  if (validationState === 'invalid' && errorMessage) {
11
- return (react_1.default.createElement(uikit_1.Text, { className: b(), color: "danger", "data-sr-error": "true" }, errorMessage));
11
+ return (react_1.default.createElement(uikit_1.Text, { className: b(), color: "danger", wordBreak: "break-word", "data-sr-error": "true" }, errorMessage));
12
12
  }
13
13
  return null;
14
14
  };
@@ -15,7 +15,15 @@ const OneOfNested = ({ Layout, headName, input, layoutProps, meta, mode, props,
15
15
  headName,
16
16
  subscriptions: [core_1.SchemaRendererEventType.Config],
17
17
  });
18
- const [togglerValue, setTogglerValue] = react_1.default.useState(Object.keys(value || (overviewFlag ? undefined : schema.properties) || {})[0]);
18
+ const [togglerValue, setTogglerValue] = react_1.default.useState(() => {
19
+ if (value && Object.keys(value).length) {
20
+ return Object.keys(value)[0];
21
+ }
22
+ if (!overviewFlag && schema.properties) {
23
+ return Object.keys(schema.properties)[0];
24
+ }
25
+ return undefined;
26
+ });
19
27
  const toggler = react_1.default.useMemo(() => {
20
28
  var _a;
21
29
  let result = null;
@@ -1,5 +1,5 @@
1
1
  import { type TextInputProps } from '@gravity-ui/uikit';
2
- import type { JsonSchemaString, NodeEntity } from '../../../core';
2
+ import { type JsonSchemaString, type NodeEntity } from '../../../core';
3
3
  export interface StringNumberWithScaleInputProps extends Omit<TextInputProps, 'defaultValue' | 'value' | 'onFocus' | 'onBlur' | 'onChange' | 'onUpdate' | 'errorMessage' | 'validationState' | 'qa'> {
4
4
  defaultType?: string;
5
5
  viewType?: string;