@donotdev/crud 0.0.4 → 0.0.6

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 (150) hide show
  1. package/dist/CrudService.d.ts +7 -3
  2. package/dist/CrudService.d.ts.map +1 -1
  3. package/dist/CrudService.js +1 -1
  4. package/dist/CrudStore.d.ts +6 -1
  5. package/dist/CrudStore.d.ts.map +1 -1
  6. package/dist/CrudStore.js +1 -1
  7. package/dist/FieldRegistry.d.ts +126 -0
  8. package/dist/FieldRegistry.d.ts.map +1 -0
  9. package/dist/FieldRegistry.js +1 -0
  10. package/dist/adapters/FirestoreAdapter.d.ts.map +1 -1
  11. package/dist/adapters/FirestoreAdapter.js +1 -1
  12. package/dist/builtinFieldTypes.d.ts +5 -0
  13. package/dist/builtinFieldTypes.d.ts.map +1 -0
  14. package/dist/builtinFieldTypes.js +1 -0
  15. package/dist/components/ControlledFields.d.ts +42 -24
  16. package/dist/components/ControlledFields.d.ts.map +1 -1
  17. package/dist/components/ControlledFields.js +1 -1
  18. package/dist/components/DisplayFieldRenderer.d.ts +36 -0
  19. package/dist/components/DisplayFieldRenderer.d.ts.map +1 -0
  20. package/dist/components/DisplayFieldRenderer.js +1 -0
  21. package/dist/components/EntityFormRenderer.d.ts +36 -8
  22. package/dist/components/EntityFormRenderer.d.ts.map +1 -1
  23. package/dist/components/EntityFormRenderer.js +5 -1
  24. package/dist/components/FormFieldRenderer.d.ts +3 -16
  25. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  26. package/dist/components/FormFieldRenderer.js +1 -1
  27. package/dist/components/form/fields/AddressFieldComponent.d.ts +3 -1
  28. package/dist/components/form/fields/AddressFieldComponent.d.ts.map +1 -1
  29. package/dist/components/form/fields/AddressFieldComponent.js +1 -1
  30. package/dist/components/form/fields/CheckboxFieldComponent.d.ts +2 -0
  31. package/dist/components/form/fields/CheckboxFieldComponent.d.ts.map +1 -1
  32. package/dist/components/form/fields/CheckboxFieldComponent.js +1 -1
  33. package/dist/components/form/fields/ComboboxComponent.d.ts +43 -0
  34. package/dist/components/form/fields/ComboboxComponent.d.ts.map +1 -0
  35. package/dist/components/form/fields/ComboboxComponent.js +1 -0
  36. package/dist/components/form/fields/CurrencyFieldComponent.d.ts +41 -0
  37. package/dist/components/form/fields/CurrencyFieldComponent.d.ts.map +1 -0
  38. package/dist/components/form/fields/CurrencyFieldComponent.js +1 -0
  39. package/dist/components/form/fields/DateFieldComponent.d.ts +2 -0
  40. package/dist/components/form/fields/DateFieldComponent.d.ts.map +1 -1
  41. package/dist/components/form/fields/DateFieldComponent.js +1 -1
  42. package/dist/components/form/fields/DropdownComponent.d.ts.map +1 -1
  43. package/dist/components/form/fields/DropdownComponent.js +1 -1
  44. package/dist/components/form/fields/FileFieldComponent.d.ts +2 -0
  45. package/dist/components/form/fields/FileFieldComponent.d.ts.map +1 -1
  46. package/dist/components/form/fields/FileFieldComponent.js +1 -1
  47. package/dist/components/form/fields/GeoPointFieldComponent.d.ts +2 -0
  48. package/dist/components/form/fields/GeoPointFieldComponent.d.ts.map +1 -1
  49. package/dist/components/form/fields/GeoPointFieldComponent.js +1 -1
  50. package/dist/components/form/fields/ImageFieldComponent.d.ts +32 -17
  51. package/dist/components/form/fields/ImageFieldComponent.d.ts.map +1 -1
  52. package/dist/components/form/fields/ImageFieldComponent.js +1 -1
  53. package/dist/components/form/fields/MapFieldComponent.d.ts +2 -0
  54. package/dist/components/form/fields/MapFieldComponent.d.ts.map +1 -1
  55. package/dist/components/form/fields/MapFieldComponent.js +1 -1
  56. package/dist/components/form/fields/MultiDropdownComponent.d.ts +2 -2
  57. package/dist/components/form/fields/MultiDropdownComponent.d.ts.map +1 -1
  58. package/dist/components/form/fields/MultiDropdownComponent.js +1 -1
  59. package/dist/components/form/fields/MultiInputTextFieldComponent.d.ts +2 -0
  60. package/dist/components/form/fields/MultiInputTextFieldComponent.d.ts.map +1 -1
  61. package/dist/components/form/fields/MultiInputTextFieldComponent.js +1 -1
  62. package/dist/components/form/fields/NumberFieldComponent.d.ts.map +1 -1
  63. package/dist/components/form/fields/NumberFieldComponent.js +1 -1
  64. package/dist/components/form/fields/PasswordFieldComponent.d.ts.map +1 -1
  65. package/dist/components/form/fields/PasswordFieldComponent.js +1 -1
  66. package/dist/components/form/fields/PhoneNumberComponent.d.ts +31 -17
  67. package/dist/components/form/fields/PhoneNumberComponent.d.ts.map +1 -1
  68. package/dist/components/form/fields/PhoneNumberComponent.js +1 -1
  69. package/dist/components/form/fields/RadioFieldComponent.d.ts.map +1 -1
  70. package/dist/components/form/fields/RadioFieldComponent.js +1 -1
  71. package/dist/components/form/fields/RangeFieldComponent.d.ts.map +1 -1
  72. package/dist/components/form/fields/RangeFieldComponent.js +1 -1
  73. package/dist/components/form/fields/ReferenceFieldComponent.d.ts +7 -2
  74. package/dist/components/form/fields/ReferenceFieldComponent.d.ts.map +1 -1
  75. package/dist/components/form/fields/ReferenceFieldComponent.js +1 -1
  76. package/dist/components/form/fields/SwitchFieldComponent.d.ts +28 -0
  77. package/dist/components/form/fields/SwitchFieldComponent.d.ts.map +1 -0
  78. package/dist/components/form/fields/SwitchFieldComponent.js +1 -0
  79. package/dist/components/form/fields/TextAreaComponent.d.ts.map +1 -1
  80. package/dist/components/form/fields/TextAreaComponent.js +1 -1
  81. package/dist/components/form/fields/TextFieldComponent.d.ts.map +1 -1
  82. package/dist/components/form/fields/TextFieldComponent.js +1 -1
  83. package/dist/components/form/fields/TimestampFieldComponent.d.ts +2 -0
  84. package/dist/components/form/fields/TimestampFieldComponent.d.ts.map +1 -1
  85. package/dist/components/form/fields/TimestampFieldComponent.js +1 -1
  86. package/dist/components/form/fields/index.d.ts +7 -1
  87. package/dist/components/form/fields/index.d.ts.map +1 -1
  88. package/dist/components/form/fields/index.js +1 -1
  89. package/dist/components/form/internal/ImageViewerDialog.d.ts +25 -0
  90. package/dist/components/form/internal/ImageViewerDialog.d.ts.map +1 -0
  91. package/dist/components/form/internal/ImageViewerDialog.js +1 -0
  92. package/dist/components/index.d.ts +2 -0
  93. package/dist/components/index.d.ts.map +1 -1
  94. package/dist/components/index.js +1 -1
  95. package/dist/context/FormUploadContext.d.ts +36 -0
  96. package/dist/context/FormUploadContext.d.ts.map +1 -0
  97. package/dist/context/FormUploadContext.js +1 -0
  98. package/dist/context/index.d.ts +2 -0
  99. package/dist/context/index.d.ts.map +1 -0
  100. package/dist/context/index.js +1 -0
  101. package/dist/forms/hooks/index.d.ts +11 -0
  102. package/dist/forms/hooks/index.d.ts.map +1 -0
  103. package/dist/forms/hooks/index.js +1 -0
  104. package/dist/forms/hooks/useEntityField.d.ts +67 -0
  105. package/dist/forms/hooks/useEntityField.d.ts.map +1 -0
  106. package/dist/forms/hooks/useEntityField.js +1 -0
  107. package/dist/forms/hooks/useEntityForm.d.ts +89 -0
  108. package/dist/forms/hooks/useEntityForm.d.ts.map +1 -0
  109. package/dist/forms/hooks/useEntityForm.js +1 -0
  110. package/dist/forms/index.d.ts +37 -0
  111. package/dist/forms/index.d.ts.map +1 -0
  112. package/dist/forms/index.js +1 -0
  113. package/dist/forms/types.d.ts +185 -0
  114. package/dist/forms/types.d.ts.map +1 -0
  115. package/dist/forms/types.js +0 -0
  116. package/dist/forms/utils/createEntitySchema.d.ts +53 -0
  117. package/dist/forms/utils/createEntitySchema.d.ts.map +1 -0
  118. package/dist/forms/utils/createEntitySchema.js +1 -0
  119. package/dist/forms/utils/getFieldsForOperation.d.ts +87 -0
  120. package/dist/forms/utils/getFieldsForOperation.d.ts.map +1 -0
  121. package/dist/forms/utils/getFieldsForOperation.js +1 -0
  122. package/dist/forms/utils/index.d.ts +14 -0
  123. package/dist/forms/utils/index.d.ts.map +1 -0
  124. package/dist/forms/utils/index.js +1 -0
  125. package/dist/forms/utils/isFieldEditable.d.ts +43 -0
  126. package/dist/forms/utils/isFieldEditable.d.ts.map +1 -0
  127. package/dist/forms/utils/isFieldEditable.js +1 -0
  128. package/dist/forms/utils/normalizeToFieldConfig.d.ts +47 -0
  129. package/dist/forms/utils/normalizeToFieldConfig.d.ts.map +1 -0
  130. package/dist/forms/utils/normalizeToFieldConfig.js +1 -0
  131. package/dist/forms/utils/validateEntity.d.ts +77 -0
  132. package/dist/forms/utils/validateEntity.d.ts.map +1 -0
  133. package/dist/forms/utils/validateEntity.js +1 -0
  134. package/dist/index.d.ts +4 -1
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.js +1 -1
  137. package/dist/tsconfig.tsbuildinfo +1 -1
  138. package/dist/useCrud.d.ts +67 -15
  139. package/dist/useCrud.d.ts.map +1 -1
  140. package/dist/useCrud.js +1 -1
  141. package/dist/utils/imageProcessing.d.ts +49 -0
  142. package/dist/utils/imageProcessing.d.ts.map +1 -0
  143. package/dist/utils/imageProcessing.js +1 -0
  144. package/dist/utils/imageStorage.d.ts +35 -0
  145. package/dist/utils/imageStorage.d.ts.map +1 -0
  146. package/dist/utils/imageStorage.js +1 -0
  147. package/dist/utils/imageUtils.d.ts +86 -0
  148. package/dist/utils/imageUtils.d.ts.map +1 -0
  149. package/dist/utils/imageUtils.js +1 -0
  150. package/package.json +10 -7
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @fileoverview Field filtering utility
3
+ * @description Filters entity fields based on operation type, visibility, and viewer role.
4
+ *
5
+ * @version 0.0.1
6
+ * @since 0.0.1
7
+ * @author AMBROISE PARK Consulting
8
+ */
9
+ import type { Entity, EntityField, FieldConfig, FieldType } from '@donotdev/core';
10
+ /** Entity fields input - supports Entity, Entity['fields'], or plain Record */
11
+ export type EntityFieldsInput = Entity | Entity['fields'] | Record<string, EntityField<FieldType> | FieldConfig<FieldType>>;
12
+ import { type ViewerRole } from './isFieldEditable';
13
+ /** Field with computed editability for rendering */
14
+ export interface RenderableField<T extends FieldType = FieldType> {
15
+ /** Field name/key */
16
+ name: string;
17
+ /** Normalized field configuration */
18
+ config: FieldConfig<T>;
19
+ /** Whether field is editable (input vs read-only) */
20
+ editable: boolean;
21
+ }
22
+ /** Options for field filtering */
23
+ export interface GetFieldsForOperationOptions {
24
+ /** Form operation type */
25
+ operation: 'create' | 'edit';
26
+ /** Viewer role for editability checks */
27
+ viewerRole?: ViewerRole;
28
+ /**
29
+ * Available field names (for edit mode).
30
+ * When provided, only fields in this list are returned.
31
+ * Typically comes from Object.keys(defaultValues) - backend-filtered data.
32
+ */
33
+ availableFields?: string[];
34
+ }
35
+ /**
36
+ * Filters entity fields based on operation type and viewer role.
37
+ *
38
+ * Pure function, no React dependencies. Use for building custom form layouts.
39
+ *
40
+ * **Create operation:**
41
+ * - Excludes `visibility: 'technical'` fields (auto-added by backend)
42
+ * - Excludes `visibility: 'hidden'` fields (never shown)
43
+ *
44
+ * **Edit operation:**
45
+ * - Excludes `visibility: 'hidden'` fields (never shown)
46
+ * - Technical fields are marked as `editable: false` (read-only)
47
+ * - If `availableFields` provided, only returns fields in that list (backend-filtered)
48
+ *
49
+ * @param entity - Entity definition from defineEntity()
50
+ * @param options - Filtering options
51
+ * @returns Array of renderable fields with computed editability
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * import { getFieldsForOperation } from '@donotdev/crud/forms';
56
+ * import { productEntity } from './entities/product';
57
+ *
58
+ * // Create form - excludes technical and hidden
59
+ * const createFields = getFieldsForOperation(productEntity, {
60
+ * operation: 'create',
61
+ * viewerRole: 'user'
62
+ * });
63
+ *
64
+ * // Edit form - uses backend-filtered fields
65
+ * const editFields = getFieldsForOperation(productEntity, {
66
+ * operation: 'edit',
67
+ * viewerRole: 'admin',
68
+ * availableFields: Object.keys(existingData)
69
+ * });
70
+ *
71
+ * // Render custom form
72
+ * editFields.map(({ name, config, editable }) => (
73
+ * editable
74
+ * ? <Input key={name} {...config} />
75
+ * : <ReadOnlyDisplay key={name} {...config} />
76
+ * ));
77
+ * ```
78
+ *
79
+ * @see {@link Entity} for entity definition structure
80
+ * @see {@link RenderableField} for return type
81
+ *
82
+ * @version 0.0.1
83
+ * @since 0.0.1
84
+ * @author AMBROISE PARK Consulting
85
+ */
86
+ export declare function getFieldsForOperation(entity: EntityFieldsInput, options: GetFieldsForOperationOptions): RenderableField[];
87
+ //# sourceMappingURL=getFieldsForOperation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFieldsForOperation.d.ts","sourceRoot":"","sources":["../../../src/forms/utils/getFieldsForOperation.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,MAAM,EACN,WAAW,EACX,WAAW,EACX,SAAS,EACV,MAAM,gBAAgB,CAAC;AAExB,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,MAAM,CAAC,QAAQ,CAAC,GAChB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;AAGpE,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAErE,oDAAoD;AACpD,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IAC9D,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACvB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,kCAAkC;AAClC,MAAM,WAAW,4BAA4B;IAC3C,0BAA0B;IAC1B,SAAS,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC7B,yCAAyC;IACzC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,4BAA4B,GACpC,eAAe,EAAE,CAyDnB"}
@@ -0,0 +1 @@
1
+ import{normalizeToFieldConfig as f}from"./normalizeToFieldConfig";import{isFieldEditable as u}from"./isFieldEditable";function F(e,s){const{operation:r,viewerRole:d="admin",availableFields:t}=s,a=e&&typeof e=="object"&&"fields"in e&&"name"in e?e.fields:e;return Object.entries(a).map(([i,c])=>{const n=f(i,c),l=n.visibility||"user";if(r==="create"){if(l==="technical"||l==="hidden")return null}else if(l==="hidden"||t&&!t.includes(i))return null;let o=u(n.editable,d,r);return r==="edit"&&l==="technical"&&n.editable===void 0&&(o=!1),{name:i,config:n,editable:o}}).filter(i=>i!==null)}export{F as getFieldsForOperation};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Form utilities barrel export
3
+ * @description Exports all form utility functions for custom form building.
4
+ *
5
+ * @version 0.0.1
6
+ * @since 0.0.1
7
+ * @author AMBROISE PARK Consulting
8
+ */
9
+ export { isFieldEditable, type ViewerRole } from './isFieldEditable';
10
+ export { normalizeToFieldConfig } from './normalizeToFieldConfig';
11
+ export { getFieldsForOperation, type RenderableField, type GetFieldsForOperationOptions, type EntityFieldsInput, } from './getFieldsForOperation';
12
+ export { createEntitySchema, type SchemaOperation } from './createEntitySchema';
13
+ export { validateEntity, type ValidationIssue, type ValidationResult, } from './validateEntity';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/forms/utils/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ import{isFieldEditable as r}from"./isFieldEditable";import{normalizeToFieldConfig as i}from"./normalizeToFieldConfig";import{getFieldsForOperation as m}from"./getFieldsForOperation";import{createEntitySchema as l}from"./createEntitySchema";import{validateEntity as d}from"./validateEntity";export{l as createEntitySchema,m as getFieldsForOperation,r as isFieldEditable,i as normalizeToFieldConfig,d as validateEntity};
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @fileoverview Field editability utility
3
+ * @description Determines if a field is editable based on editable config, viewer role, and operation.
4
+ *
5
+ * @version 0.0.1
6
+ * @since 0.0.1
7
+ * @author AMBROISE PARK Consulting
8
+ */
9
+ import type { Editable } from '@donotdev/core';
10
+ /** Viewer role type - used for editability checks */
11
+ export type ViewerRole = 'public' | 'guest' | 'user' | 'admin' | 'super';
12
+ /**
13
+ * Determines if a field is editable by the current viewer.
14
+ *
15
+ * NOTE: Visibility is handled by backend - this function only handles editability (UI concern).
16
+ *
17
+ * @param editable - Field's editable configuration
18
+ * @param viewerRole - Current viewer's role
19
+ * @param operation - Form operation type
20
+ * @returns Whether the field should be rendered as an input (true) or read-only (false)
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Default editable
25
+ * isFieldEditable(undefined, 'user', 'create'); // true
26
+ *
27
+ * // Admin-only field
28
+ * isFieldEditable('admin', 'user', 'edit'); // false
29
+ * isFieldEditable('admin', 'admin', 'edit'); // true
30
+ *
31
+ * // Create-only field
32
+ * isFieldEditable('create-only', 'user', 'create'); // true
33
+ * isFieldEditable('create-only', 'user', 'edit'); // false
34
+ * ```
35
+ *
36
+ * @see {@link Editable} for editable configuration options
37
+ *
38
+ * @version 0.0.1
39
+ * @since 0.0.1
40
+ * @author AMBROISE PARK Consulting
41
+ */
42
+ export declare function isFieldEditable(editable: Editable | undefined, viewerRole: ViewerRole, operation: 'create' | 'edit'): boolean;
43
+ //# sourceMappingURL=isFieldEditable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isFieldEditable.d.ts","sourceRoot":"","sources":["../../../src/forms/utils/isFieldEditable.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,qDAAqD;AACrD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,QAAQ,GAAG,MAAM,GAC3B,OAAO,CAcT"}
@@ -0,0 +1 @@
1
+ import{hasRoleAccess as t,USER_ROLES as u}from"@donotdev/core";function i(r,e,n){return r===void 0||r===!0?!0:r===!1?!1:r==="admin"?t(e,u.ADMIN):r==="create-only"?n==="create":!0}export{i as isFieldEditable};
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @fileoverview Field config normalization utility
3
+ * @description Converts EntityField (from defineEntity) to FieldConfig format used by form components.
4
+ * Preserves generic type parameter for type-safe form handling.
5
+ *
6
+ * @version 0.0.2
7
+ * @since 0.0.1
8
+ * @author AMBROISE PARK Consulting
9
+ */
10
+ import type { FieldConfig, EntityField, FieldType } from '@donotdev/core';
11
+ /**
12
+ * Normalizes EntityField to FieldConfig format, preserving type parameter.
13
+ *
14
+ * Handles conversion from entity definitions (defineEntity) to form-compatible format.
15
+ * If the field already has a `name` property (is already a FieldConfig), returns as-is.
16
+ *
17
+ * @template T - The field type, preserved from input for type-safe validation
18
+ * @param name - Field name/key from the entity definition
19
+ * @param field - Field definition (EntityField or FieldConfig)
20
+ * @returns Normalized FieldConfig ready for form rendering
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // From EntityField (defineEntity output) - type is preserved
25
+ * const entityField: EntityField<'email'> = {
26
+ * type: 'email',
27
+ * visibility: 'user',
28
+ * validation: { required: true }
29
+ * };
30
+ * const config = normalizeToFieldConfig('email', entityField);
31
+ * // FieldConfig<'email'> - TypeScript knows value type is string
32
+ *
33
+ * // Already a FieldConfig (passes through)
34
+ * const fieldConfig: FieldConfig<'text'> = { name: 'email', type: 'text', label: 'Email' };
35
+ * const config2 = normalizeToFieldConfig('email', fieldConfig);
36
+ * // Same as input, type preserved
37
+ * ```
38
+ *
39
+ * @see {@link EntityField} for entity field definition
40
+ * @see {@link FieldConfig} for form field configuration
41
+ *
42
+ * @version 0.0.2
43
+ * @since 0.0.1
44
+ * @author AMBROISE PARK Consulting
45
+ */
46
+ export declare function normalizeToFieldConfig<T extends FieldType>(name: string, field: FieldConfig<T> | EntityField<T>): FieldConfig<T>;
47
+ //# sourceMappingURL=normalizeToFieldConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeToFieldConfig.d.ts","sourceRoot":"","sources":["../../../src/forms/utils/normalizeToFieldConfig.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,SAAS,EACxD,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GACrC,WAAW,CAAC,CAAC,CAAC,CA2BhB"}
@@ -0,0 +1 @@
1
+ function n(t,e){if("name"in e&&typeof e.name=="string")return e;const i=e;return{name:t,type:i.type,label:i.label||t.charAt(0).toUpperCase()+t.slice(1).replace(/([A-Z])/g," $1"),required:i.validation?.required??!1,visibility:i.visibility,editable:i.editable,validation:i.validation,options:i.options,dependsOn:i.dependsOn,hint:i.hint,i18n:i.i18n,group:i.group}}export{n as normalizeToFieldConfig};
@@ -0,0 +1,77 @@
1
+ import type { Entity } from '@donotdev/core';
2
+ import { type SchemaOperation } from './createEntitySchema';
3
+ /**
4
+ * Validation issue structure
5
+ */
6
+ export interface ValidationIssue {
7
+ /** Field path (e.g., 'name' or 'address.street') */
8
+ path: string;
9
+ /** Error message */
10
+ message: string;
11
+ }
12
+ /**
13
+ * Validation result structure
14
+ * @template T - Data type
15
+ */
16
+ export interface ValidationResult<T> {
17
+ /** Whether validation succeeded */
18
+ success: boolean;
19
+ /** Validated data (if success) */
20
+ data?: T;
21
+ /** Validation issues (if failed) */
22
+ issues?: ValidationIssue[];
23
+ }
24
+ /**
25
+ * Validates data against an entity definition.
26
+ *
27
+ * Uses Valibot under the hood with entity-derived schemas.
28
+ * Pure function, no React dependencies.
29
+ *
30
+ * @template E - Entity type from defineEntity()
31
+ * @param entity - Entity definition from defineEntity()
32
+ * @param data - Data to validate
33
+ * @param operation - Validation context ('create' or 'update')
34
+ * @returns Validation result with typed issues
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { validateEntity } from '@donotdev/crud/forms';
39
+ * import { productEntity } from './entities/product';
40
+ *
41
+ * // Validate create data
42
+ * const result = validateEntity(productEntity, formData, 'create');
43
+ *
44
+ * if (result.success) {
45
+ * await saveProduct(result.data);
46
+ * } else {
47
+ * console.error('Validation failed:', result.issues);
48
+ * // [{ path: 'name', message: 'Required' }, ...]
49
+ * }
50
+ * ```
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * // Use in form submission
55
+ * const onSubmit = async (data: unknown) => {
56
+ * const validation = validateEntity(productEntity, data, 'create');
57
+ *
58
+ * if (!validation.success) {
59
+ * validation.issues?.forEach(issue => {
60
+ * form.setError(issue.path, { message: issue.message });
61
+ * });
62
+ * return;
63
+ * }
64
+ *
65
+ * await api.createProduct(validation.data);
66
+ * };
67
+ * ```
68
+ *
69
+ * @see {@link Entity} for entity definition structure
70
+ * @see {@link ValidationResult} for return type
71
+ *
72
+ * @version 0.0.1
73
+ * @since 0.0.1
74
+ * @author AMBROISE PARK Consulting
75
+ */
76
+ export declare function validateEntity<E extends Entity>(entity: E, data: unknown, operation?: SchemaOperation): ValidationResult<Record<string, unknown>>;
77
+ //# sourceMappingURL=validateEntity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateEntity.d.ts","sourceRoot":"","sources":["../../../src/forms/utils/validateEntity.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,kCAAkC;IAClC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,oCAAoC;IACpC,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,OAAO,EACb,SAAS,GAAE,eAA0B,GACpC,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAsB3C"}
@@ -0,0 +1 @@
1
+ import*as o from"valibot";import{createEntitySchema as i}from"./createEntitySchema";function p(t,a,c="create"){const r=i(t,c),s=o.safeParse(r,a);return s.success?{success:!0,data:s.output}:{success:!1,issues:s.issues.map(e=>({path:e.path?.map(u=>u.key).join(".")||"",message:e.message}))}}export{p as validateEntity};
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * @fileoverview CRUD package
3
3
  * @description CRUD operations and form components for DoNotDev framework
4
4
  *
5
- * @version 0.0.1
5
+ * @version 0.0.2
6
6
  * @since 0.0.1
7
7
  * @author AMBROISE PARK Consulting
8
8
  */
@@ -10,4 +10,7 @@ export * from './useCrud';
10
10
  export * from './components';
11
11
  export { getCrudService } from './CrudService';
12
12
  export { loadDeterministicRange, upsertDeterministic, appendToCollection, } from './utils/collections';
13
+ export { getFieldRegistry, registerFieldType, isFieldTypeRegistered, type FieldTypeRegistration, type SchemaGenerator, type ControlledFieldProps, type UncontrolledFieldProps, } from './FieldRegistry';
14
+ export { useEntityForm, useEntityField, isFieldEditable, normalizeToFieldConfig, getFieldsForOperation, createEntitySchema, validateEntity, } from './forms';
15
+ export type { ViewerRole, RenderableField, GetFieldsForOperationOptions, EntityFieldsInput, SchemaOperation, ValidationIssue, ValidationResult, InferEntityData, InferEntityInput, InferEntityOutput, UseEntityFormOptions, EntityFormReturn, EntityFieldReturn, } from './forms';
13
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAGH,cAAc,WAAW,CAAC;AAG1B,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,aAAa,EACb,cAAc,EAEd,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,GACf,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,UAAU,EACV,eAAe,EACf,4BAA4B,EAC5B,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./useCrud";export*from"./components";import{getCrudService as i}from"./CrudService";import{loadDeterministicRange as m,upsertDeterministic as n,appendToCollection as c}from"./utils/collections";export{c as appendToCollection,i as getCrudService,m as loadDeterministicRange,n as upsertDeterministic};
1
+ export*from"./useCrud";export*from"./components";import{getCrudService as d}from"./CrudService";import{loadDeterministicRange as m,upsertDeterministic as n,appendToCollection as s}from"./utils/collections";import{getFieldRegistry as F,registerFieldType as g,isFieldTypeRegistered as f}from"./FieldRegistry";import{useEntityForm as c,useEntityField as x,isFieldEditable as u,normalizeToFieldConfig as E,getFieldsForOperation as T,createEntitySchema as C,validateEntity as R}from"./forms";import{registerBuiltinFieldTypes as e}from"./builtinFieldTypes";e();export{s as appendToCollection,C as createEntitySchema,d as getCrudService,F as getFieldRegistry,T as getFieldsForOperation,u as isFieldEditable,f as isFieldTypeRegistered,m as loadDeterministicRange,E as normalizeToFieldConfig,g as registerFieldType,n as upsertDeterministic,x as useEntityField,c as useEntityForm,R as validateEntity};