@donotdev/crud 0.0.3 → 0.0.5
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.
- package/dist/CrudService.d.ts +7 -3
- package/dist/CrudService.d.ts.map +1 -1
- package/dist/CrudService.js +1 -1
- package/dist/CrudStore.d.ts +5 -0
- package/dist/CrudStore.d.ts.map +1 -1
- package/dist/CrudStore.js +1 -1
- package/dist/FieldRegistry.d.ts +126 -0
- package/dist/FieldRegistry.d.ts.map +1 -0
- package/dist/FieldRegistry.js +1 -0
- package/dist/adapters/FirestoreAdapter.d.ts.map +1 -1
- package/dist/adapters/FirestoreAdapter.js +1 -1
- package/dist/adapters/FunctionsAdapter.js +1 -1
- package/dist/adapters/index.js +1 -1
- package/dist/builtinFieldTypes.d.ts +5 -0
- package/dist/builtinFieldTypes.d.ts.map +1 -0
- package/dist/builtinFieldTypes.js +1 -0
- package/dist/components/ControlledFields.d.ts +42 -24
- package/dist/components/ControlledFields.d.ts.map +1 -1
- package/dist/components/ControlledFields.js +1 -1
- package/dist/components/CrudButton.js +1 -1
- package/dist/components/DisplayFieldRenderer.d.ts +36 -0
- package/dist/components/DisplayFieldRenderer.d.ts.map +1 -0
- package/dist/components/DisplayFieldRenderer.js +1 -0
- package/dist/components/EntityFormRenderer.d.ts +36 -8
- package/dist/components/EntityFormRenderer.d.ts.map +1 -1
- package/dist/components/EntityFormRenderer.js +5 -1
- package/dist/components/FormFieldRenderer.d.ts +3 -16
- package/dist/components/FormFieldRenderer.d.ts.map +1 -1
- package/dist/components/FormFieldRenderer.js +1 -1
- package/dist/components/FormLayout.js +1 -1
- package/dist/components/form/fields/AddressFieldComponent.d.ts +3 -1
- package/dist/components/form/fields/AddressFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/AddressFieldComponent.js +1 -1
- package/dist/components/form/fields/AvatarFieldComponent.js +1 -1
- package/dist/components/form/fields/BadgeFieldComponent.js +1 -1
- package/dist/components/form/fields/ButtonFieldComponent.js +1 -1
- package/dist/components/form/fields/CheckboxFieldComponent.d.ts +2 -0
- package/dist/components/form/fields/CheckboxFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/CheckboxFieldComponent.js +1 -1
- package/dist/components/form/fields/ComboboxComponent.d.ts +43 -0
- package/dist/components/form/fields/ComboboxComponent.d.ts.map +1 -0
- package/dist/components/form/fields/ComboboxComponent.js +1 -0
- package/dist/components/form/fields/CurrencyFieldComponent.d.ts +41 -0
- package/dist/components/form/fields/CurrencyFieldComponent.d.ts.map +1 -0
- package/dist/components/form/fields/CurrencyFieldComponent.js +1 -0
- package/dist/components/form/fields/DateFieldComponent.d.ts +2 -0
- package/dist/components/form/fields/DateFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/DateFieldComponent.js +1 -1
- package/dist/components/form/fields/DropdownComponent.d.ts.map +1 -1
- package/dist/components/form/fields/DropdownComponent.js +1 -1
- package/dist/components/form/fields/FileFieldComponent.d.ts +2 -0
- package/dist/components/form/fields/FileFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/FileFieldComponent.js +1 -1
- package/dist/components/form/fields/GeoPointFieldComponent.d.ts +2 -0
- package/dist/components/form/fields/GeoPointFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/GeoPointFieldComponent.js +1 -1
- package/dist/components/form/fields/HiddenFieldComponent.js +1 -1
- package/dist/components/form/fields/ImageFieldComponent.d.ts +32 -17
- package/dist/components/form/fields/ImageFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/ImageFieldComponent.js +1 -1
- package/dist/components/form/fields/MapFieldComponent.d.ts +2 -0
- package/dist/components/form/fields/MapFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/MapFieldComponent.js +1 -1
- package/dist/components/form/fields/MultiDropdownComponent.d.ts +2 -2
- package/dist/components/form/fields/MultiDropdownComponent.d.ts.map +1 -1
- package/dist/components/form/fields/MultiDropdownComponent.js +1 -1
- package/dist/components/form/fields/MultiInputTextFieldComponent.d.ts +2 -0
- package/dist/components/form/fields/MultiInputTextFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/MultiInputTextFieldComponent.js +1 -1
- package/dist/components/form/fields/NumberFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/NumberFieldComponent.js +1 -1
- package/dist/components/form/fields/PasswordFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/PasswordFieldComponent.js +1 -1
- package/dist/components/form/fields/PhoneNumberComponent.d.ts +31 -17
- package/dist/components/form/fields/PhoneNumberComponent.d.ts.map +1 -1
- package/dist/components/form/fields/PhoneNumberComponent.js +1 -1
- package/dist/components/form/fields/RadioFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/RadioFieldComponent.js +1 -1
- package/dist/components/form/fields/RangeFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/RangeFieldComponent.js +1 -1
- package/dist/components/form/fields/ReferenceFieldComponent.d.ts +7 -2
- package/dist/components/form/fields/ReferenceFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/ReferenceFieldComponent.js +1 -1
- package/dist/components/form/fields/SwitchFieldComponent.d.ts +28 -0
- package/dist/components/form/fields/SwitchFieldComponent.d.ts.map +1 -0
- package/dist/components/form/fields/SwitchFieldComponent.js +1 -0
- package/dist/components/form/fields/TextAreaComponent.d.ts.map +1 -1
- package/dist/components/form/fields/TextAreaComponent.js +1 -1
- package/dist/components/form/fields/TextFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/TextFieldComponent.js +1 -1
- package/dist/components/form/fields/TimestampFieldComponent.d.ts +2 -0
- package/dist/components/form/fields/TimestampFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/TimestampFieldComponent.js +1 -1
- package/dist/components/form/fields/index.d.ts +7 -1
- package/dist/components/form/fields/index.d.ts.map +1 -1
- package/dist/components/form/fields/index.js +1 -1
- package/dist/components/form/internal/ImageViewerDialog.d.ts +25 -0
- package/dist/components/form/internal/ImageViewerDialog.d.ts.map +1 -0
- package/dist/components/form/internal/ImageViewerDialog.js +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/context/FormUploadContext.d.ts +36 -0
- package/dist/context/FormUploadContext.d.ts.map +1 -0
- package/dist/context/FormUploadContext.js +1 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +1 -0
- package/dist/forms/hooks/index.d.ts +11 -0
- package/dist/forms/hooks/index.d.ts.map +1 -0
- package/dist/forms/hooks/index.js +1 -0
- package/dist/forms/hooks/useEntityField.d.ts +67 -0
- package/dist/forms/hooks/useEntityField.d.ts.map +1 -0
- package/dist/forms/hooks/useEntityField.js +1 -0
- package/dist/forms/hooks/useEntityForm.d.ts +89 -0
- package/dist/forms/hooks/useEntityForm.d.ts.map +1 -0
- package/dist/forms/hooks/useEntityForm.js +1 -0
- package/dist/forms/index.d.ts +37 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/index.js +1 -0
- package/dist/forms/types.d.ts +185 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/types.js +0 -0
- package/dist/forms/utils/createEntitySchema.d.ts +53 -0
- package/dist/forms/utils/createEntitySchema.d.ts.map +1 -0
- package/dist/forms/utils/createEntitySchema.js +1 -0
- package/dist/forms/utils/getFieldsForOperation.d.ts +87 -0
- package/dist/forms/utils/getFieldsForOperation.d.ts.map +1 -0
- package/dist/forms/utils/getFieldsForOperation.js +1 -0
- package/dist/forms/utils/index.d.ts +14 -0
- package/dist/forms/utils/index.d.ts.map +1 -0
- package/dist/forms/utils/index.js +1 -0
- package/dist/forms/utils/isFieldEditable.d.ts +43 -0
- package/dist/forms/utils/isFieldEditable.d.ts.map +1 -0
- package/dist/forms/utils/isFieldEditable.js +1 -0
- package/dist/forms/utils/normalizeToFieldConfig.d.ts +47 -0
- package/dist/forms/utils/normalizeToFieldConfig.d.ts.map +1 -0
- package/dist/forms/utils/normalizeToFieldConfig.js +1 -0
- package/dist/forms/utils/validateEntity.d.ts +77 -0
- package/dist/forms/utils/validateEntity.d.ts.map +1 -0
- package/dist/forms/utils/validateEntity.js +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/useCrud.d.ts +67 -15
- package/dist/useCrud.d.ts.map +1 -1
- package/dist/useCrud.js +1 -1
- package/dist/utils/collections.js +1 -1
- package/dist/utils/imageProcessing.d.ts +49 -0
- package/dist/utils/imageProcessing.d.ts.map +1 -0
- package/dist/utils/imageProcessing.js +1 -0
- package/dist/utils/imageStorage.d.ts +35 -0
- package/dist/utils/imageStorage.d.ts.map +1 -0
- package/dist/utils/imageStorage.js +1 -0
- package/dist/utils/imageUtils.d.ts +86 -0
- package/dist/utils/imageUtils.d.ts.map +1 -0
- package/dist/utils/imageUtils.js +1 -0
- package/package.json +10 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createEntitySchema.d.ts","sourceRoot":"","sources":["../../../src/forms/utils/createEntitySchema.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,MAAM,EAAe,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAyIvE;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,MAAM,EAAE,CAAC,EACT,SAAS,GAAE,eAA0B,GACpC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAkDtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as e from"valibot";import{TECHNICAL_FIELD_NAMES as m}from"@donotdev/schemas";function f(n,t={}){const{type:l,validation:a}=n,{isDraft:s=!1}=t;let i;switch(l){case"number":case"range":i=e.number(),a?.min!==void 0&&(i=e.pipe(i,e.minValue(a.min))),a?.max!==void 0&&(i=e.pipe(i,e.maxValue(a.max)));break;case"boolean":case"checkbox":i=e.boolean();break;case"email":i=e.pipe(e.string(),e.email());break;case"url":i=e.pipe(e.string(),e.url());break;case"multiselect":case"array":i=e.array(e.string());break;case"select":case"radio":if(a?.options&&Array.isArray(a.options)){const c=a.options.map(o=>o.value);i=e.picklist(c)}else i=e.string();break;case"date":case"datetime-local":case"time":case"month":case"week":case"timestamp":i=e.string();break;case"image":i=e.object({fullUrl:e.string(),thumbUrl:e.optional(e.string())});break;case"images":i=e.array(e.object({fullUrl:e.string(),thumbUrl:e.optional(e.string())}));break;default:i=e.string(),a?.minLength!==void 0&&(i=e.pipe(i,e.minLength(a.minLength))),a?.maxLength!==void 0&&(i=e.pipe(i,e.maxLength(a.maxLength))),a?.pattern&&(i=e.pipe(i,e.regex(new RegExp(a.pattern))));break}return(!a?.required||s)&&(i=e.optional(i)),i}function d(n,t="create"){const l=t==="draft",a={};for(const[i,c]of Object.entries(n.fields)){if(c.visibility==="hidden")continue;const o=m.includes(i);let r=f(c,{isDraft:l});(t==="create"||t==="draft")&&o&&(r=e.optional(r)),t==="update"&&i!=="id"&&(r=e.optional(r)),a[i]=r}t==="update"&&(a.id=e.pipe(e.string(),e.minLength(1,"ID is required")));const s=e.object(a);return s.metadata={collection:n.collection,entity:n.name},s}export{d as createEntitySchema};
|
|
@@ -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.
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;
|
|
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
|
|
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};
|