@resistdesign/voltra 3.0.0-alpha.32 → 3.0.0-alpha.34

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 (54) hide show
  1. package/README.md +72 -2
  2. package/api/Indexing/fulltext/FullTextDdbBackend.d.ts +5 -3
  3. package/api/Indexing/index.d.ts +3 -3
  4. package/api/Indexing/rel/Handlers.d.ts +3 -2
  5. package/api/ORM/drivers/index.d.ts +1 -1
  6. package/api/ORM/index.d.ts +2 -11
  7. package/api/index.js +114 -99
  8. package/app/forms/Engine.d.ts +3 -0
  9. package/app/forms/UI.d.ts +7 -1
  10. package/app/forms/core/createAutoField.d.ts +11 -3
  11. package/app/forms/core/createFormRenderer.d.ts +3 -2
  12. package/app/forms/core/mergeSuites.d.ts +3 -2
  13. package/app/forms/core/resolveSuite.d.ts +2 -1
  14. package/app/forms/core/types.d.ts +20 -9
  15. package/app/forms/index.d.ts +1 -2
  16. package/app/forms/types.d.ts +36 -55
  17. package/app/index.js +22 -14
  18. package/app/utils/ApplicationState.d.ts +1 -1
  19. package/app/utils/Route.d.ts +3 -3
  20. package/build/index.js +4 -4
  21. package/chunk-4PV5LPTT.js +1144 -0
  22. package/chunk-7AMEFPPP.js +78 -0
  23. package/{chunk-FQMZMCXU.js → chunk-RUVFOXCR.js} +1 -1
  24. package/chunk-TJFTWPXQ.js +39 -0
  25. package/{chunk-LGM75I6P.js → chunk-WTD5BBJP.js} +223 -38
  26. package/common/ItemRelationships/ItemRelationshipValidation.d.ts +1 -1
  27. package/common/ItemRelationships/index.d.ts +1 -5
  28. package/common/Logging/Utils.d.ts +0 -9
  29. package/common/TypeInfoORM/index.d.ts +2 -10
  30. package/common/TypeParsing/TypeInfo.d.ts +20 -0
  31. package/common/TypeParsing/Validation.d.ts +152 -22
  32. package/common/index.d.ts +2 -12
  33. package/common/index.js +21 -9
  34. package/iac/packs/auth.d.ts +10 -4
  35. package/iac-packs/index.d.ts +1 -0
  36. package/native/forms/UI.d.ts +8 -2
  37. package/native/forms/createNativeFormRenderer.d.ts +1 -1
  38. package/native/forms/index.d.ts +16 -0
  39. package/native/forms/suite.d.ts +1 -1
  40. package/native/index.js +71 -40
  41. package/native/testing/react-native.d.ts +33 -15
  42. package/native/utils/index.d.ts +13 -1
  43. package/package.json +1 -1
  44. package/web/forms/UI.d.ts +8 -2
  45. package/web/forms/createWebFormRenderer.d.ts +1 -1
  46. package/web/forms/suite.d.ts +1 -1
  47. package/web/index.js +234 -113
  48. package/web/utils/Route.d.ts +9 -3
  49. package/web/utils/index.d.ts +1 -0
  50. package/chunk-G5CLUK4Y.js +0 -621
  51. package/chunk-HVY7POTD.js +0 -22
  52. package/chunk-IWRHGGGH.js +0 -10
  53. package/chunk-MUCSL3UR.js +0 -1
  54. package/chunk-WELZGQDJ.js +0 -456
package/chunk-WELZGQDJ.js DELETED
@@ -1,456 +0,0 @@
1
- import { useState, useCallback, useMemo, useEffect } from 'react';
2
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
-
4
- // src/app/utils/easy-layout/parseTemplate.ts
5
- var parseTrackSpec = (token) => {
6
- const trimmed = token.trim();
7
- const numericMatch = trimmed.match(/^([0-9]*\.?[0-9]+)(fr|px|%)$/);
8
- if (!numericMatch) {
9
- throw new Error(
10
- `Invalid track token "${trimmed}". Supported units are fr, px, and %.`
11
- );
12
- }
13
- const value = Number(numericMatch[1]);
14
- const suffix = numericMatch[2];
15
- if (!Number.isFinite(value) || value < 0) {
16
- throw new Error(`Track value must be a non-negative number. Received "${trimmed}".`);
17
- }
18
- if (suffix === "fr") {
19
- return { kind: "fr", value };
20
- }
21
- if (suffix === "px") {
22
- return { kind: "px", value };
23
- }
24
- return { kind: "pct", value };
25
- };
26
- var normalizeAreas = (areaPart) => {
27
- return areaPart.trim().split(/\s+/g).map((token) => token.trim()).filter(Boolean);
28
- };
29
- var parseTemplate = (template = "") => {
30
- const lines = template.split("\n").map((line) => line.trim()).filter(Boolean);
31
- const areaGrid = [];
32
- const rowTracks = [];
33
- let colTracks = null;
34
- for (const line of lines) {
35
- if (line.startsWith("\\")) {
36
- if (colTracks) {
37
- throw new Error("Template can include only one column-track line.");
38
- }
39
- const colTokens = line.replace(/\\/g, " ").trim().split(/\s+/g).filter(Boolean);
40
- colTracks = colTokens.map(parseTrackSpec);
41
- continue;
42
- }
43
- const parts = line.split(",").map((part) => part.trim());
44
- const areaPart = parts[0] || "";
45
- if (!areaPart) {
46
- continue;
47
- }
48
- if (parts.length > 2) {
49
- throw new Error(
50
- `Invalid row definition "${line}". Expected "<areas>, <row-track>".`
51
- );
52
- }
53
- const areas = normalizeAreas(areaPart);
54
- if (!areas.length) {
55
- continue;
56
- }
57
- areaGrid.push(areas);
58
- const rowTrack = parts[1];
59
- if (rowTrack) {
60
- rowTracks.push(parseTrackSpec(rowTrack));
61
- }
62
- }
63
- if (!areaGrid.length) {
64
- throw new Error("Template must include at least one area row.");
65
- }
66
- const expectedWidth = areaGrid[0].length;
67
- for (let rowIndex = 0; rowIndex < areaGrid.length; rowIndex++) {
68
- const width = areaGrid[rowIndex].length;
69
- if (width !== expectedWidth) {
70
- throw new Error(
71
- `All area rows must have the same width. Expected ${expectedWidth}, received ${width} at row ${rowIndex + 1}.`
72
- );
73
- }
74
- }
75
- if (colTracks && colTracks.length !== expectedWidth) {
76
- throw new Error(
77
- `Column track count must match area width. Expected ${expectedWidth}, received ${colTracks.length}.`
78
- );
79
- }
80
- const areaNames = Array.from(
81
- new Set(
82
- areaGrid.flat().map((name) => name.trim()).filter((name) => !!name && name !== ".")
83
- )
84
- );
85
- return {
86
- areaGrid,
87
- rowTracks,
88
- colTracks: colTracks || [],
89
- areaNames
90
- };
91
- };
92
-
93
- // src/app/utils/easy-layout/computeAreaBounds.ts
94
- var computeAreaBounds = (parsed) => {
95
- const result = {};
96
- for (let rowIndex = 0; rowIndex < parsed.areaGrid.length; rowIndex++) {
97
- const row = parsed.areaGrid[rowIndex];
98
- for (let colIndex = 0; colIndex < row.length; colIndex++) {
99
- const name = row[colIndex];
100
- if (!name || name === ".") {
101
- continue;
102
- }
103
- const row1 = rowIndex + 1;
104
- const col1 = colIndex + 1;
105
- const existing = result[name];
106
- if (!existing) {
107
- result[name] = {
108
- name,
109
- rowStart: row1,
110
- rowEnd: row1,
111
- colStart: col1,
112
- colEnd: col1
113
- };
114
- continue;
115
- }
116
- existing.rowStart = Math.min(existing.rowStart, row1);
117
- existing.rowEnd = Math.max(existing.rowEnd, row1);
118
- existing.colStart = Math.min(existing.colStart, col1);
119
- existing.colEnd = Math.max(existing.colEnd, col1);
120
- }
121
- }
122
- return result;
123
- };
124
-
125
- // src/app/utils/easy-layout/validateAreas.ts
126
- var validateAreas = (parsed) => {
127
- const bounds = computeAreaBounds(parsed);
128
- for (const areaName of parsed.areaNames) {
129
- const bound = bounds[areaName];
130
- if (!bound) {
131
- continue;
132
- }
133
- for (let row = bound.rowStart; row <= bound.rowEnd; row++) {
134
- for (let col = bound.colStart; col <= bound.colEnd; col++) {
135
- const token = parsed.areaGrid[row - 1]?.[col - 1];
136
- if (token !== areaName) {
137
- throw new Error(
138
- `Area "${areaName}" must be a rectangle. Missing "${areaName}" at row ${row}, col ${col}.`
139
- );
140
- }
141
- }
142
- }
143
- }
144
- };
145
-
146
- // src/app/forms/core/getFieldKind.ts
147
- var hasSelectableValues = (field) => {
148
- const possibleValues = field.possibleValues ?? [];
149
- return possibleValues.some(
150
- (value) => typeof value === "string" || typeof value === "number"
151
- );
152
- };
153
- var getFieldKind = (field) => {
154
- if (field.typeReference) {
155
- return field.array ? "relation_array" : "relation_single";
156
- }
157
- if (field.tags?.customType) {
158
- return field.array ? "custom_array" : "custom_single";
159
- }
160
- if (field.array) {
161
- return "array";
162
- }
163
- if (hasSelectableValues(field)) {
164
- return "enum_select";
165
- }
166
- if (field.type === "boolean") {
167
- return "boolean";
168
- }
169
- if (field.type === "number") {
170
- return "number";
171
- }
172
- return "string";
173
- };
174
-
175
- // src/app/forms/core/resolveSuite.ts
176
- var fieldKinds = [
177
- "string",
178
- "number",
179
- "boolean",
180
- "enum_select",
181
- "array",
182
- "relation_single",
183
- "relation_array",
184
- "custom_single",
185
- "custom_array"
186
- ];
187
- var getMissingKinds = (renderers) => {
188
- return fieldKinds.filter((kind) => !renderers[kind]);
189
- };
190
- var resolveSuite = (overrides, fallback) => {
191
- const mergedRenderers = {
192
- ...fallback.renderers ?? {},
193
- ...overrides?.renderers ?? {}
194
- };
195
- const missingKinds = getMissingKinds(mergedRenderers);
196
- if (missingKinds.length) {
197
- throw new Error(
198
- `Missing renderers for field kinds: ${missingKinds.join(", ")}`
199
- );
200
- }
201
- const mergedPrimitives = {
202
- ...fallback.primitives ?? {},
203
- ...overrides?.primitives ?? {}
204
- };
205
- return {
206
- renderers: mergedRenderers,
207
- primitives: Object.keys(mergedPrimitives).length ? mergedPrimitives : void 0
208
- };
209
- };
210
-
211
- // src/app/forms/core/createAutoField.ts
212
- var createAutoField = (suite) => {
213
- const renderField = (props) => {
214
- const { field, fieldKey, value, onChange, error, disabled } = props;
215
- const { tags } = field;
216
- const context = {
217
- field,
218
- fieldKey,
219
- label: tags?.label ?? fieldKey,
220
- required: !field.optional,
221
- disabled: !!disabled,
222
- error,
223
- value,
224
- onChange,
225
- constraints: tags?.constraints,
226
- format: tags?.format,
227
- possibleValues: field.possibleValues,
228
- allowCustomSelection: tags?.allowCustomSelection,
229
- customType: tags?.customType,
230
- onRelationAction: props.onRelationAction,
231
- onCustomTypeAction: props.onCustomTypeAction,
232
- renderField
233
- };
234
- const kind = getFieldKind(field);
235
- return suite.renderers[kind](context);
236
- };
237
- return renderField;
238
- };
239
-
240
- // src/app/forms/core/createFormRenderer.ts
241
- var createFormRenderer = (options) => {
242
- const resolvedSuite = resolveSuite(
243
- options.suite,
244
- options.fallbackSuite
245
- );
246
- const AutoField = createAutoField(resolvedSuite);
247
- return {
248
- AutoField,
249
- suite: resolvedSuite
250
- };
251
- };
252
- var getDeniedOperation = (deniedOperations, operation) => {
253
- if (!deniedOperations) {
254
- return false;
255
- }
256
- const denied = deniedOperations[operation];
257
- if (typeof denied === "boolean") {
258
- return denied;
259
- }
260
- return deniedOperations[operation.toLowerCase()] ?? false;
261
- };
262
- var buildInitialValues = (initialValues, typeInfo) => {
263
- const values = { ...initialValues };
264
- for (const [key, field] of Object.entries(typeInfo.fields ?? {})) {
265
- if (values[key] !== void 0) {
266
- continue;
267
- }
268
- const defaultValue = field.tags?.constraints?.defaultValue;
269
- if (defaultValue !== void 0) {
270
- let parsedDefaultValue = defaultValue;
271
- try {
272
- parsedDefaultValue = JSON.parse(defaultValue);
273
- } catch (error) {
274
- }
275
- values[key] = parsedDefaultValue;
276
- continue;
277
- }
278
- if (field.array && !field.typeReference && !field.optional) {
279
- values[key] = [];
280
- continue;
281
- }
282
- if (field.type === "boolean" && !field.optional) {
283
- values[key] = false;
284
- }
285
- }
286
- return values;
287
- };
288
- var useFormEngine = (initialValues = {}, typeInfo, options) => {
289
- const operation = options?.operation ?? "CREATE" /* CREATE */;
290
- const [values, setValues] = useState(
291
- buildInitialValues(initialValues, typeInfo)
292
- );
293
- const [errors, setErrors] = useState({});
294
- const setFieldValue = useCallback((path, value) => {
295
- setValues((prev) => {
296
- return {
297
- ...prev,
298
- [path]: value
299
- };
300
- });
301
- }, []);
302
- const validate = useCallback(() => {
303
- const newErrors = {};
304
- for (const [key, field] of Object.entries(typeInfo.fields ?? {})) {
305
- if (field.tags?.hidden) {
306
- continue;
307
- }
308
- const val = values[key];
309
- if (field.readonly && (val === void 0 || val === null || val === "")) {
310
- continue;
311
- }
312
- const isMissing = val === void 0 || val === null || val === "" || field.array && (!Array.isArray(val) || val.length === 0);
313
- if (!field.optional && isMissing) {
314
- newErrors[key] = "This field is required";
315
- continue;
316
- }
317
- if (isMissing) {
318
- continue;
319
- }
320
- const constraints = field.tags?.constraints;
321
- if (constraints?.pattern && typeof val === "string") {
322
- const pattern = new RegExp(constraints.pattern);
323
- if (!pattern.test(val)) {
324
- newErrors[key] = "Value does not match required pattern";
325
- continue;
326
- }
327
- }
328
- if (field.type === "number" && typeof val === "number") {
329
- if (constraints?.min !== void 0 && val < constraints.min) {
330
- newErrors[key] = `Value must be at least ${constraints.min}`;
331
- continue;
332
- }
333
- if (constraints?.max !== void 0 && val > constraints.max) {
334
- newErrors[key] = `Value must be at most ${constraints.max}`;
335
- continue;
336
- }
337
- }
338
- }
339
- setErrors(newErrors);
340
- return Object.keys(newErrors).length === 0;
341
- }, [typeInfo, values]);
342
- const fields = useMemo(() => {
343
- return Object.entries(typeInfo.fields ?? {}).map(([key, field]) => {
344
- const { tags } = field;
345
- const isPrimary = tags?.primaryField || typeInfo.primaryField === key;
346
- return {
347
- key,
348
- field,
349
- label: tags?.label ?? key,
350
- required: !field.optional,
351
- disabled: field.readonly || getDeniedOperation(typeInfo.tags?.deniedOperations, operation) || getDeniedOperation(tags?.deniedOperations, operation) || operation === "UPDATE" /* UPDATE */ && isPrimary,
352
- hidden: !!tags?.hidden,
353
- primary: isPrimary,
354
- format: tags?.format,
355
- constraints: tags?.constraints,
356
- value: values[key],
357
- onChange: (value) => setFieldValue(key, value),
358
- error: errors[key]
359
- };
360
- });
361
- }, [typeInfo, values, errors, setFieldValue, operation]);
362
- return {
363
- typeInfo,
364
- typeTags: typeInfo.tags,
365
- operation,
366
- values,
367
- errors,
368
- fields,
369
- setFieldValue,
370
- validate,
371
- setErrors
372
- };
373
- };
374
- var fallbackFormRoot = ({
375
- children,
376
- onSubmit
377
- }) => {
378
- const handleSubmit = (event) => {
379
- event.preventDefault();
380
- onSubmit?.();
381
- };
382
- return /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, children });
383
- };
384
- var fallbackButton = ({
385
- children,
386
- disabled,
387
- type,
388
- onClick
389
- }) => {
390
- return /* @__PURE__ */ jsx("button", { type: type ?? "button", disabled, onClick, children });
391
- };
392
- var AutoFormView = ({
393
- controller,
394
- onSubmit,
395
- renderer,
396
- submitDisabled,
397
- onRelationAction,
398
- onCustomTypeAction
399
- }) => {
400
- const FormRoot = renderer.suite.primitives?.FormRoot ?? fallbackFormRoot;
401
- const Button = renderer.suite.primitives?.Button ?? fallbackButton;
402
- const AutoField = renderer.AutoField;
403
- const submit = () => {
404
- if (controller.validate()) {
405
- onSubmit(controller.values);
406
- }
407
- };
408
- return /* @__PURE__ */ jsx(FormRoot, { onSubmit: submit, children: /* @__PURE__ */ jsxs(Fragment, { children: [
409
- controller.fields.filter((fieldController) => !fieldController.hidden).map((fieldController) => /* @__PURE__ */ jsx(
410
- AutoField,
411
- {
412
- field: fieldController.field,
413
- fieldKey: fieldController.key,
414
- value: fieldController.value,
415
- onChange: fieldController.onChange,
416
- error: fieldController.error,
417
- onRelationAction,
418
- disabled: fieldController.disabled,
419
- onCustomTypeAction
420
- },
421
- fieldController.key
422
- )),
423
- /* @__PURE__ */ jsx(Button, { type: "submit", onClick: submit, disabled: submitDisabled, children: /* @__PURE__ */ jsx(Fragment, { children: "Submit" }) })
424
- ] }) });
425
- };
426
- var AutoForm = ({
427
- typeInfo,
428
- onSubmit,
429
- renderer,
430
- initialValues,
431
- onValuesChange,
432
- onRelationAction,
433
- onCustomTypeAction,
434
- operation,
435
- submitDisabled
436
- }) => {
437
- const controller = useFormEngine(initialValues, typeInfo, { operation });
438
- useEffect(() => {
439
- if (onValuesChange) {
440
- onValuesChange(controller.values);
441
- }
442
- }, [controller.values, onValuesChange]);
443
- return /* @__PURE__ */ jsx(
444
- AutoFormView,
445
- {
446
- controller,
447
- onSubmit,
448
- renderer,
449
- onRelationAction,
450
- onCustomTypeAction,
451
- submitDisabled
452
- }
453
- );
454
- };
455
-
456
- export { AutoForm, AutoFormView, computeAreaBounds, createAutoField, createFormRenderer, getFieldKind, parseTemplate, resolveSuite, useFormEngine, validateAreas };