@donotdev/crud 0.0.31 → 0.1.0
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/LICENSE.md +3 -3
- package/dist/CrudService.d.ts +4 -4
- package/dist/CrudService.js +2 -2
- package/dist/CrudStore.d.ts +1 -1
- package/dist/CrudStore.js +1 -1
- package/dist/FieldRegistry.d.ts +1 -1
- package/dist/FieldRegistry.d.ts.map +1 -1
- package/dist/FieldRegistry.js +1 -1
- package/dist/adapters/FunctionsAdapter.d.ts +3 -3
- package/dist/adapters/FunctionsAdapter.d.ts.map +1 -1
- package/dist/adapters/FunctionsAdapter.js +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/builtinFieldTypes.d.ts +1 -1
- package/dist/components/CrudButton.js +1 -1
- package/dist/components/DateFilter.js +1 -1
- package/dist/components/DisplayFieldRenderer.d.ts +1 -1
- package/dist/components/DisplayFieldRenderer.js +1 -1
- package/dist/components/DisplayThumbnail.d.ts +1 -1
- package/dist/components/DisplayThumbnail.js +1 -1
- package/dist/components/EntityFilters.js +1 -1
- package/dist/components/FormFieldRenderer.js +1 -1
- package/dist/components/FormLayout.d.ts +1 -1
- package/dist/components/FormLayout.js +1 -1
- package/dist/components/controlled/complex/ControlledAddressField.js +1 -1
- package/dist/components/controlled/complex/ControlledDateField.js +1 -1
- package/dist/components/controlled/complex/ControlledFieldArrayField.js +1 -1
- package/dist/components/controlled/complex/ControlledGeoPointField.js +1 -1
- package/dist/components/controlled/complex/ControlledMapField.js +1 -1
- package/dist/components/controlled/complex/ControlledMultiInputField.js +1 -1
- package/dist/components/controlled/complex/ControlledRichTextField.js +1 -1
- package/dist/components/controlled/complex/ControlledTimestampField.js +1 -1
- package/dist/components/controlled/complex/index.js +1 -1
- package/dist/components/controlled/file/ControlledDocumentField.js +1 -1
- package/dist/components/controlled/file/ControlledFileField.js +1 -1
- package/dist/components/controlled/file/ControlledImageField.js +1 -1
- package/dist/components/controlled/file/ControlledMultiDocumentField.js +1 -1
- package/dist/components/controlled/file/ControlledMultiFileField.js +1 -1
- package/dist/components/controlled/file/ControlledMultiImageField.js +1 -1
- package/dist/components/controlled/file/index.js +1 -1
- package/dist/components/controlled/index.js +1 -1
- package/dist/components/controlled/input/ControlledCheckboxField.js +1 -1
- package/dist/components/controlled/input/ControlledCurrencyField.js +1 -1
- package/dist/components/controlled/input/ControlledDurationField.js +1 -1
- package/dist/components/controlled/input/ControlledGdprConsentField.js +1 -1
- package/dist/components/controlled/input/ControlledNumberField.js +1 -1
- package/dist/components/controlled/input/ControlledPasswordField.js +1 -1
- package/dist/components/controlled/input/ControlledPhoneField.js +1 -1
- package/dist/components/controlled/input/ControlledPriceField.js +1 -1
- package/dist/components/controlled/input/ControlledRangeField.js +1 -1
- package/dist/components/controlled/input/ControlledRatingField.js +1 -1
- package/dist/components/controlled/input/ControlledSwitchField.js +1 -1
- package/dist/components/controlled/input/ControlledTextField.js +1 -1
- package/dist/components/controlled/input/ControlledTextareaField.js +1 -1
- package/dist/components/controlled/input/index.js +1 -1
- package/dist/components/controlled/select/ControlledComboboxField.js +1 -1
- package/dist/components/controlled/select/ControlledDropdownField.js +1 -1
- package/dist/components/controlled/select/ControlledMultiDropdownField.js +1 -1
- package/dist/components/controlled/select/ControlledRadioField.js +1 -1
- package/dist/components/controlled/select/ControlledReferenceField.js +1 -1
- package/dist/components/controlled/select/ControlledYearField.js +1 -1
- package/dist/components/controlled/select/index.js +1 -1
- package/dist/components/controlled/types.js +1 -1
- package/dist/components/fields/display/AvatarFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/AvatarFieldDisplay.js +1 -1
- package/dist/components/fields/display/BadgeFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/BadgeFieldDisplay.js +1 -1
- package/dist/components/fields/display/ButtonFieldDisplay.d.ts +2 -2
- package/dist/components/fields/display/ButtonFieldDisplay.js +1 -1
- package/dist/components/fields/display/CheckboxFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/CheckboxFieldDisplay.js +1 -1
- package/dist/components/fields/display/DateFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/DateFieldDisplay.js +1 -1
- package/dist/components/fields/display/DropdownDisplay.d.ts +1 -1
- package/dist/components/fields/display/DropdownDisplay.js +1 -1
- package/dist/components/fields/display/FileFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/FileFieldDisplay.js +1 -1
- package/dist/components/fields/display/GeoPointFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/GeoPointFieldDisplay.js +1 -1
- package/dist/components/fields/display/HiddenFieldDisplay.d.ts +2 -2
- package/dist/components/fields/display/HiddenFieldDisplay.js +1 -1
- package/dist/components/fields/display/ImageFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/ImageFieldDisplay.js +1 -1
- package/dist/components/fields/display/LinkFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/LinkFieldDisplay.js +1 -1
- package/dist/components/fields/display/MapFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/MapFieldDisplay.js +1 -1
- package/dist/components/fields/display/MultiDropdownDisplay.d.ts +1 -1
- package/dist/components/fields/display/MultiDropdownDisplay.js +1 -1
- package/dist/components/fields/display/MultiInputTextFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/MultiInputTextFieldDisplay.js +1 -1
- package/dist/components/fields/display/NumberFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/NumberFieldDisplay.js +1 -1
- package/dist/components/fields/display/PasswordFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/PasswordFieldDisplay.js +1 -1
- package/dist/components/fields/display/PhoneNumberDisplay.d.ts +1 -1
- package/dist/components/fields/display/PhoneNumberDisplay.js +1 -1
- package/dist/components/fields/display/RadioFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/RadioFieldDisplay.js +1 -1
- package/dist/components/fields/display/RangeFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/RangeFieldDisplay.js +1 -1
- package/dist/components/fields/display/ReferenceFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/ReferenceFieldDisplay.js +1 -1
- package/dist/components/fields/display/RichTextDisplay.d.ts +1 -1
- package/dist/components/fields/display/RichTextDisplay.js +2 -2
- package/dist/components/fields/display/TextAreaDisplay.d.ts +1 -1
- package/dist/components/fields/display/TextAreaDisplay.js +1 -1
- package/dist/components/fields/display/TextFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/TextFieldDisplay.js +1 -1
- package/dist/components/fields/display/TimestampFieldDisplay.d.ts +1 -1
- package/dist/components/fields/display/TimestampFieldDisplay.js +1 -1
- package/dist/components/fields/display/index.d.ts +1 -1
- package/dist/components/fields/display/index.js +1 -1
- package/dist/components/form/fields/AddressFieldComponent.js +1 -1
- package/dist/components/form/fields/AvatarFieldComponent.d.ts +2 -2
- package/dist/components/form/fields/AvatarFieldComponent.js +1 -1
- package/dist/components/form/fields/BadgeFieldComponent.d.ts +2 -2
- 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 +1 -1
- package/dist/components/form/fields/CheckboxFieldComponent.js +1 -1
- package/dist/components/form/fields/ComboboxComponent.d.ts +1 -1
- package/dist/components/form/fields/ComboboxComponent.js +1 -1
- package/dist/components/form/fields/CurrencyFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/CurrencyFieldComponent.js +1 -1
- package/dist/components/form/fields/DateFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/DateFieldComponent.js +1 -1
- package/dist/components/form/fields/DocumentFieldComponent.js +1 -1
- package/dist/components/form/fields/DropdownComponent.d.ts +1 -1
- package/dist/components/form/fields/DropdownComponent.js +1 -1
- package/dist/components/form/fields/DurationFieldComponent.js +1 -1
- package/dist/components/form/fields/FileFieldComponent.js +1 -1
- package/dist/components/form/fields/GdprConsentFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/GdprConsentFieldComponent.js +1 -1
- package/dist/components/form/fields/GeoPointFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/GeoPointFieldComponent.js +1 -1
- package/dist/components/form/fields/HiddenFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/HiddenFieldComponent.js +1 -1
- package/dist/components/form/fields/ImageFieldComponent.js +1 -1
- package/dist/components/form/fields/MapFieldComponent.js +1 -1
- package/dist/components/form/fields/MultiDropdownComponent.d.ts +1 -1
- package/dist/components/form/fields/MultiDropdownComponent.js +1 -1
- package/dist/components/form/fields/MultiInputTextFieldComponent.js +1 -1
- package/dist/components/form/fields/NumberFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/NumberFieldComponent.js +1 -1
- package/dist/components/form/fields/PasswordFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/PasswordFieldComponent.js +1 -1
- package/dist/components/form/fields/PhoneNumberComponent.d.ts +1 -1
- package/dist/components/form/fields/PhoneNumberComponent.js +1 -1
- package/dist/components/form/fields/PriceFieldComponent.js +1 -1
- package/dist/components/form/fields/RadioFieldComponent.js +1 -1
- package/dist/components/form/fields/RangeFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/RangeFieldComponent.js +1 -1
- package/dist/components/form/fields/RatingFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/RatingFieldComponent.js +1 -1
- package/dist/components/form/fields/ReferenceFieldComponent.js +1 -1
- package/dist/components/form/fields/RichTextComponent.d.ts +1 -1
- package/dist/components/form/fields/RichTextComponent.js +1 -1
- package/dist/components/form/fields/SwitchFieldComponent.d.ts +1 -1
- package/dist/components/form/fields/SwitchFieldComponent.js +1 -1
- package/dist/components/form/fields/TextAreaComponent.d.ts +1 -1
- package/dist/components/form/fields/TextAreaComponent.js +1 -1
- package/dist/components/form/fields/TextFieldComponent.d.ts +2 -2
- package/dist/components/form/fields/TextFieldComponent.js +1 -1
- package/dist/components/form/fields/TimestampFieldComponent.js +1 -1
- package/dist/components/form/fields/index.d.ts +1 -1
- package/dist/components/form/fields/index.js +1 -1
- package/dist/components/form/fields/internal/TiptapEditor.d.ts +1 -1
- package/dist/components/form/fields/internal/TiptapEditor.js +2 -2
- package/dist/components/form/fields/types.d.ts +1 -1
- package/dist/components/form/index.d.ts +1 -1
- package/dist/components/form/internal/ImageViewerDialog.js +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/contexts/UploadContext.js +1 -1
- package/dist/contexts/index.js +1 -1
- package/dist/fieldTypeRegistry.d.ts.map +1 -1
- package/dist/fieldTypeRegistry.js +1 -1
- package/dist/fieldTypeRegistry.store.js +1 -1
- package/dist/fieldTypeRegistry.types.d.ts.map +1 -1
- package/dist/forms/hooks/index.d.ts +1 -1
- package/dist/forms/hooks/index.js +1 -1
- package/dist/forms/hooks/useController.js +1 -1
- package/dist/forms/hooks/useEntityField.d.ts +1 -1
- package/dist/forms/hooks/useEntityField.js +1 -1
- package/dist/forms/hooks/useEntityForm.d.ts.map +1 -1
- package/dist/forms/hooks/useEntityForm.js +1 -1
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.js +1 -1
- package/dist/forms/types.d.ts +7 -7
- package/dist/forms/utils/buildInitialValues.js +1 -1
- package/dist/forms/utils/getFieldsForOperation.d.ts +2 -2
- package/dist/forms/utils/getFieldsForOperation.js +1 -1
- package/dist/forms/utils/index.d.ts +1 -1
- package/dist/forms/utils/index.js +1 -1
- package/dist/forms/utils/isFieldEditable.d.ts +1 -1
- package/dist/forms/utils/isFieldEditable.js +1 -1
- package/dist/forms/utils/translateFieldLabel.d.ts +3 -3
- package/dist/forms/utils/translateFieldLabel.js +1 -1
- package/dist/forms/utils/validateEntity.d.ts +1 -1
- package/dist/forms/utils/validateEntity.js +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useCrudFilters.js +1 -1
- package/dist/hooks/useEntityFavorites.js +1 -1
- package/dist/hooks/useFieldConditions.js +1 -1
- package/dist/hooks/useFileUpload.js +1 -1
- package/dist/hooks/useReferenceResolver.js +1 -1
- package/dist/hooks/useRelatedItems.js +1 -1
- package/dist/hooks/useUnsavedChangesWarning.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/registerBuiltinFieldTypes.js +1 -1
- package/dist/stores/FormStore.js +1 -1
- package/dist/stores/UploadStore.js +1 -1
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.js +1 -1
- package/dist/useBaseCrudList.js +1 -1
- package/dist/useCrud.js +1 -1
- package/dist/useCrudCardList.js +1 -1
- package/dist/useCrudList.js +1 -1
- package/dist/utils/clientListProcessing.d.ts +1 -1
- package/dist/utils/clientListProcessing.js +1 -1
- package/dist/utils/collections.d.ts +6 -6
- package/dist/utils/collections.js +1 -1
- package/dist/utils/fileStorage.js +1 -1
- package/dist/utils/imageProcessing.d.ts +1 -1
- package/dist/utils/imageProcessing.js +1 -1
- package/dist/utils/imageStorage.js +1 -1
- package/dist/utils/imageUtils.d.ts +1 -1
- package/dist/utils/imageUtils.js +1 -1
- package/dist/utils/matchesFilter.d.ts.map +1 -1
- package/dist/utils/matchesFilter.js +1 -1
- package/dist/utils/mergeWithOptimistic.js +1 -1
- package/dist/utils/sanitizeHtml.d.ts +0 -5
- package/dist/utils/sanitizeHtml.d.ts.map +1 -1
- package/dist/utils/sanitizeHtml.js +1 -1
- package/dist/utils/scopeUtils.js +1 -1
- package/dist/utils/uploadValidation.d.ts +1 -1
- package/dist/utils/uploadValidation.js +1 -1
- package/dist/workflows/WorkflowPersistence.d.ts +1 -1
- package/dist/workflows/WorkflowPersistence.js +1 -1
- package/dist/workflows/defineWorkflow.d.ts +1 -1
- package/dist/workflows/index.d.ts +1 -1
- package/dist/workflows/index.js +1 -1
- package/dist/workflows/useEntityWorkflow.js +1 -1
- package/package.json +3 -3
package/dist/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - CrudStore = only tracks optimistic metadata (optimisticData + originalData)
|
|
8
8
|
* - mergeWithOptimistic merges TanStack cache with optimistic data for display
|
|
9
9
|
*
|
|
10
|
-
* @version 0.0
|
|
10
|
+
* @version 0.1.0
|
|
11
11
|
* @since 0.0.1
|
|
12
12
|
* @author AMBROISE PARK Consulting
|
|
13
13
|
*/
|
|
@@ -65,7 +65,7 @@ export interface CollectionUIState {
|
|
|
65
65
|
* CRUD store state interface
|
|
66
66
|
* Note: No data field - TanStack Query owns data, CrudStore only tracks optimistic ops
|
|
67
67
|
*
|
|
68
|
-
* @version 0.0
|
|
68
|
+
* @version 0.1.0
|
|
69
69
|
* @since 0.0.1
|
|
70
70
|
* @author AMBROISE PARK Consulting
|
|
71
71
|
*/
|
|
@@ -87,7 +87,7 @@ export interface CrudState {
|
|
|
87
87
|
* CRUD store actions interface
|
|
88
88
|
* Note: No setData/getData - TanStack Query owns data, CrudStore only tracks optimistic ops
|
|
89
89
|
*
|
|
90
|
-
* @version 0.0
|
|
90
|
+
* @version 0.1.0
|
|
91
91
|
* @since 0.0.1
|
|
92
92
|
* @author AMBROISE PARK Consulting
|
|
93
93
|
*/
|
|
@@ -162,7 +162,7 @@ export interface MutationOptions {
|
|
|
162
162
|
* CRUD Service Interface
|
|
163
163
|
* Complete interface for CRUD operations with caching and optimistic updates
|
|
164
164
|
*
|
|
165
|
-
* @version 0.0
|
|
165
|
+
* @version 0.1.0
|
|
166
166
|
* @since 0.0.1
|
|
167
167
|
* @author AMBROISE PARK Consulting
|
|
168
168
|
*/
|
package/dist/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const e={PENDING:"pending",CONFIRMED:"confirmed",FAILED:"failed"},E={ADD:"add",UPDATE:"update",SET:"set",DELETE:"delete"};export{E as CRUD_OPERATION,e as OPTIMISTIC_STATUSES};
|
package/dist/useBaseCrudList.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useMemo as
|
|
1
|
+
import{useMemo as Q,useCallback as Z,useRef as R,useState as $,useEffect as ee}from"react";import{useQuery as te}from"@donotdev/core";import{useCrudStore as se}from"./CrudStore";import{CRUD_OPERATION as z}from"./types";import{useCrud as V,getCrudServiceInstance as re,EMPTY_OPTIMISTIC as oe}from"./useCrud";import{mergeWithOptimistic as ce}from"./utils/mergeWithOptimistic";import{injectScopeFilter as ie,getCurrentScopeValue as ne}from"./utils/scopeUtils";const ae=1e3;function Oe(j,f,s,g={}){const K=g.enabled??!0,b=V("status"),a=b==="ready",N=V(j,g),{error:E,invalidate:L,_collection:d,_schemas:O,_cacheOptions:S,_scope:T}=N,F=se(e=>e.collections[d]?.optimistic||oe),q=R(new Map([[1,null]])),y=R(0),[A,U]=$(!1),i=s?.mode==="auto"?A?"server":"client":s?.mode??"client",k=ne(T),I=Q(()=>{if(!a||!O)return null;const e=re();if(!e)return null;const h=f==="listCard"?O.listCard:O.list,n=ie(g.queryOptions,T);if(!s)return e.getListQueryOptions(d,n,h,S,f);if(i==="client"){const o=s.mode==="auto"&&!n?.limit?{...n,limit:ae}:n;return e.getListQueryOptions(d,o,h,S,f)}const l=q.current,u=y.current,{page:m,pageSize:p}=s;let t,r;if(l.has(m))t=l.get(m)??void 0,r=p;else if(m>u&&l.has(u)){const o=m-u;t=l.get(u)??void 0,r=o*p}else t=void 0,r=m*p;return e.getListQueryOptions(d,{...n,limit:r,startAfter:t},h,S,f)},[a,d,S,O?"hasSchema":"noSchema",f,i,s?.page,s?.pageSize,g.queryOptions,T?.provider,k]),{data:c,isLoading:B,isFetching:W,error:Y,refetch:M}=te({queryKey:I?.queryKey??["crud",d,"disabled"],queryFn:I?.queryFn??(()=>Promise.resolve({items:[]})),staleTime:I?.staleTime,enabled:K&&!!I});ee(()=>{s?.mode==="auto"&&!A&&c&&c.total!=null&&c.total>c.items.length&&U(!0)},[c,s?.mode,A]);const P=Q(()=>{if(!c||!a)return{items:[],total:void 0};let e=c.items;if(i==="server"&&s&&e.length>0){const t=q.current,r=y.current,{page:o,pageSize:v}=s,H=e.length;if(Math.ceil(H/v)>1||o>r){const w=t.has(o)?o:r+1;for(let C=w;C<=o;C++){const x=(C-w+1)*v-1;if(x<e.length){const X=e[x];t.set(C+1,X.id)}}}c.lastVisible&&t.set(o+1,c.lastVisible),y.current=Math.max(r,o);const _=t.has(o)?0:(o-r-1)*v,J=_+v;e=e.slice(_,J)}const h=ce(e,F),n=new Set(e.map(t=>t.id));let l=0,u=0;for(const[t,r]of Object.entries(F))r.operation===z.ADD&&!n.has(t)?l++:r.operation===z.DELETE&&n.has(t)&&u++;const p=(c.total??e.length)+l-u;return{items:h,total:p}},[c,F,a,i,s?.page,s?.pageSize]),D=Z(async()=>{a&&(i==="server"&&(q.current=new Map([[1,null]]),y.current=0),await L(),await M())},[L,M,a,i]);if(!a){const e=async()=>{};return{status:b,data:{items:[],total:void 0},items:[],loading:!0,fetching:!1,error:E,mutate:e,refresh:e,isAvailable:!1,effectiveMode:i}}const G=P?.items??[];return{status:b,data:P,items:G,loading:B,fetching:W,error:Y??E,mutate:D,refresh:D,isAvailable:!0,effectiveMode:i}}export{Oe as useBaseCrudList};
|
package/dist/useCrud.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useEffect as
|
|
1
|
+
"use client";import{useEffect as V,useMemo as F,useCallback as a}from"react";import{useFeatureConsent as W,FRAMEWORK_FEATURES as Z,FEATURE_STATUS as h,handleError as $,isClient as B,createSchemas as H,DEGRADED_CRUD_API as J}from"@donotdev/core";import{getCrudService as X}from"./CrudService";import{useCrudStore as u}from"./CrudStore";import{injectScope as P,injectScopeFilter as O}from"./utils/scopeUtils";const re={},ne={};let v=null,_=null,g=!1;function i(){return v}function ae(l,d={}){const S=W(Z.CRUD),x=u(e=>e.crudService),C=S&&!x,D=S?C?h.INITIALIZING:h.READY:h.DEGRADED,m=l==="status",p=!m&&typeof l=="object"?l:d.entity,s=m?"__status__":typeof l=="string"?l:l.collection,o=p?.scope,T=d.noCache??!1,A=d.staleTime,f=F(()=>({noCache:T,staleTime:A}),[T,A]),t=F(()=>{if(!m){if(d.schema){const e=d.schema;return{create:e,draft:e,update:e,get:e,list:e,listCard:e,delete:e}}if(p)return H(p)}},[m,d.schema,p?.name,s]),M=u(e=>e.collections[s]?.loading||!1),b=u(e=>e.collections[s]?.error||null),N=null;V(()=>{if(!B()||!S||!t)return;const{crudService:e}=u.getState();e||v||_||(_=(async()=>{try{if(v||u.getState().crudService)return;const c=X();v=c,c.setStore(u),await c.initialize(),g=!1,u.getState().setCrudService(c)}catch(c){g||($(c,{userMessage:"Failed to initialize CRUD service.",context:{collection:s},severity:"error"}),g=!0)}finally{_=null}})())},[S,s,t?"hasSchema":"noSchema"]);const I=C||M,z=D===h.READY,Y=a(async e=>{const c=i();return!c||!t?null:c.get(s,e,t.get,f)},[s,t?"hasSchema":"noSchema",f]),j=a(async(e,c,r)=>{const n=i();if(!n||!t)return;const E=P(c,o),Q=E?.status==="draft"?t.draft:t.create;await n.set(s,e,E,Q,r)},[s,t?"hasSchema":"noSchema",o?.provider]),k=a(async(e,c,r)=>{const n=i();n&&await n.update(s,e,c,t?.update,r)},[s,t]),q=a(async(e,c)=>{const r=i();r&&await r.delete(s,e,c)},[s]),G=a(async(e,c)=>{const r=i();if(!r||!t)return"";const n=P(e,o),w=n?.status==="draft"?t.draft:t.create;return r.add(s,n,w,c)},[s,t?"hasSchema":"noSchema",o?.provider]),L=a(async e=>{const c=i();if(!c||!t)return[];const r=O(e,o);return(await c.query(s,r,t.list,f)).items},[s,t?"hasSchema":"noSchema",f,o?.provider]),R=a((e,c)=>{const r=i();return!r||!t?()=>{}:r.subscribe(s,e,c,t.get)},[s,t?"hasSchema":"noSchema"]),y=a((e,c)=>{const r=i();return!r||!t?()=>{}:r.subscribeToCollection(s,e,c,t.list)},[s,t?"hasSchema":"noSchema"]),U=a(async()=>{const e=i();e&&await e.invalidateCollection(s)},[s]);return m?D:z?{status:h.READY,data:N,loading:I,error:b,get:Y,set:j,update:k,delete:q,add:G,query:L,subscribe:R,subscribeToCollection:y,invalidate:U,isAvailable:!0,_collection:s,_schemas:t,_cacheOptions:f,_scope:o}:{...J,status:D,loading:I,error:b,subscribe:R,subscribeToCollection:y,invalidate:U,_collection:s,_schemas:t,_cacheOptions:f,_scope:o}}export{re as EMPTY_DATA,ne as EMPTY_OPTIMISTIC,i as getCrudServiceInstance,ae as useCrud};
|
package/dist/useCrudCardList.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useMemo as
|
|
1
|
+
import{useMemo as o}from"react";import{useCrudFilters as f}from"./hooks/useCrudFilters";import{useBaseCrudList as h}from"./useBaseCrudList";import{applyFilters as y,applySearch as g,applySort as p}from"./utils/clientListProcessing";function v(l,t={}){const u={enabled:t.enabled,queryOptions:t.queryOptions,schema:t.schema,entity:t.entity,staleTime:t.staleTime,noCache:t.noCache},e=h(l,"listCard",null,u),s=typeof l=="string"?null:l,c=s?.collection??l,{filters:a}=f({collection:c}),i=t.clientSort===null?null:t.clientSort??s?.defaultSort??null,{processed:n,filteredTotal:m}=o(()=>{let r=e.items;s&&Object.keys(a).length>0&&(r=y(r,a,s)),s&&t.searchQuery&&(r=g(r,t.searchQuery,s));const d=r.length;return i&&(r=p(r,i)),{processed:r,filteredTotal:d}},[e.items,a,t.searchQuery,i,s]);return{status:e.status,data:e.data?{items:e.data.items}:null,items:e.items,processed:n,filteredTotal:m,loading:e.loading,fetching:e.fetching,error:e.error,mutate:e.mutate,refresh:e.refresh,isAvailable:e.isAvailable}}export{v as useCrudCardList};
|
package/dist/useCrudList.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useMemo as h}from"react";import{useCrudFilters as
|
|
1
|
+
import{useMemo as h}from"react";import{useCrudFilters as y}from"./hooks/useCrudFilters";import{useBaseCrudList as S}from"./useBaseCrudList";import{applyFilters as b,applySearch as T,applySort as Q}from"./utils/clientListProcessing";function L(a,e={}){const n=e.pagination??"auto",u=e.page??1,i=e.pageSize??10,o={mode:n,page:u,pageSize:i},m={enabled:e.enabled,queryOptions:e.queryOptions,schema:e.schema,entity:e.entity,staleTime:e.staleTime,noCache:e.noCache},s=S(a,"list",o,m),r=typeof a=="string"?null:a,d=r?.collection??a,{filters:l}=y({collection:d}),c=e.clientSort===null?null:e.clientSort??r?.defaultSort??null,{processed:f,filteredTotal:p}=h(()=>{let t=s.items;r&&Object.keys(l).length>0&&(t=b(t,l,r)),r&&e.searchQuery&&(t=T(t,e.searchQuery,r));const g=t.length;return c&&(t=Q(t,c)),{processed:t,filteredTotal:g}},[s.items,l,e.searchQuery,c,r]);return{...s,processed:f,filteredTotal:p}}export{L as useCrudList};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{matchesFilter as u}from"./matchesFilter";import{getValueType as
|
|
1
|
+
import{matchesFilter as u}from"./matchesFilter";import{getValueType as c}from"../fieldTypeRegistry.store";function g(t,l,s){const o=Object.entries(l);return o.length===0?t:t.filter(r=>o.every(([i,f])=>{const n=s.fields[i]?.type||"text";return u(r[i],f,n)}))}function a(t){if(t.search?.fields&&t.search.fields.length>0)return t.search.fields;const l=new Set(["string"]),s=[];for(const[o,r]of Object.entries(t.fields)){if(r.visibility==="hidden"||r.visibility==="technical")continue;const i=c(r.type);i&&l.has(i)&&s.push(o)}return s}function h(t,l,s){if(!l||l.trim()==="")return t;const o=l.toLowerCase(),r=a(s);return r.length===0?t.filter(i=>Object.values(i).some(f=>f==null?!1:String(f).toLowerCase().includes(o))):t.filter(i=>r.some(f=>{const e=i[f];return e==null?!1:typeof e=="object"&&"formatted_address"in e?String(e.formatted_address).toLowerCase().includes(o):String(e).toLowerCase().includes(o)}))}function b(t,l){const{field:s,direction:o="asc"}=l,r=o==="desc"?-1:1;return[...t].sort((i,f)=>{const e=i[s],n=f[s];return e==null&&n==null?0:e==null?1:n==null?-1:typeof e=="number"&&typeof n=="number"?(e-n)*r:typeof e=="object"&&"amount"in e&&typeof n=="object"&&"amount"in n?(e.amount-n.amount)*r:e instanceof Date&&n instanceof Date?(e.getTime()-n.getTime())*r:String(e).localeCompare(String(n))*r})}export{g as applyFilters,h as applySearch,b as applySort,a as getSearchableFields};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Collection utilities
|
|
3
3
|
* @description Utilities for working with collections and subcollections
|
|
4
4
|
*
|
|
5
|
-
* @version 0.0
|
|
5
|
+
* @version 0.1.0
|
|
6
6
|
* @since 0.0.1
|
|
7
7
|
* @author AMBROISE PARK Consulting
|
|
8
8
|
*/
|
|
@@ -10,7 +10,7 @@ import type { dndevSchema } from '@donotdev/core';
|
|
|
10
10
|
/**
|
|
11
11
|
* Deterministic subcollection configuration
|
|
12
12
|
*
|
|
13
|
-
* @version 0.0
|
|
13
|
+
* @version 0.1.0
|
|
14
14
|
* @since 0.0.1
|
|
15
15
|
* @author AMBROISE PARK Consulting
|
|
16
16
|
*/
|
|
@@ -26,7 +26,7 @@ export interface DeterministicSubcollectionConfig<T> {
|
|
|
26
26
|
/**
|
|
27
27
|
* Append subcollection configuration
|
|
28
28
|
*
|
|
29
|
-
* @version 0.0
|
|
29
|
+
* @version 0.1.0
|
|
30
30
|
* @since 0.0.1
|
|
31
31
|
* @author AMBROISE PARK Consulting
|
|
32
32
|
*/
|
|
@@ -38,7 +38,7 @@ export interface AppendSubcollectionConfig<T> {
|
|
|
38
38
|
/**
|
|
39
39
|
* Load a deterministic range of items from a subcollection
|
|
40
40
|
*
|
|
41
|
-
* @version 0.0
|
|
41
|
+
* @version 0.1.0
|
|
42
42
|
* @since 0.0.1
|
|
43
43
|
* @author AMBROISE PARK Consulting
|
|
44
44
|
*/
|
|
@@ -46,7 +46,7 @@ export declare function loadDeterministicRange<T>(userId: string, config: Determ
|
|
|
46
46
|
/**
|
|
47
47
|
* Upsert a deterministic range of items in a subcollection
|
|
48
48
|
*
|
|
49
|
-
* @version 0.0
|
|
49
|
+
* @version 0.1.0
|
|
50
50
|
* @since 0.0.1
|
|
51
51
|
* @author AMBROISE PARK Consulting
|
|
52
52
|
*/
|
|
@@ -54,7 +54,7 @@ export declare function upsertDeterministic<T>(userId: string, config: Determini
|
|
|
54
54
|
/**
|
|
55
55
|
* Append an item to a subcollection
|
|
56
56
|
*
|
|
57
|
-
* @version 0.0
|
|
57
|
+
* @version 0.1.0
|
|
58
58
|
* @since 0.0.1
|
|
59
59
|
* @author AMBROISE PARK Consulting
|
|
60
60
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getCrudService as
|
|
1
|
+
import{getCrudService as o}from"../CrudService";async function u(s,t){const e=o(),r=[],a=t.range?.start??1,n=t.range?.end??28;for(let c=a;c<=n;c++){const i=String(c),d=await e.get(t.path(s),i,t.schema);d&&r.push(d)}return r}async function m(s,t,e){const r=o();for(const a of e){const n=t.idOf(a);await r.set(t.path(s),n,a,t.schema)}}async function h(s,t,e){const r=o();if(t.idFrom){const a=t.idFrom(e);return r.set(t.path(s),a,e,t.schema)}return r.add(t.path(s),e,t.schema)}export{h as appendToCollection,u as loadDeterministicRange,m as upsertDeterministic};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{handleError as
|
|
1
|
+
"use client";import{handleError as u,getProvider as d}from"@donotdev/core";function f(e){return e.replace(/[^a-zA-Z0-9.-]/g,"_").replace(/_{2,}/g,"_").toLowerCase()}async function x(e,t={}){const{storagePath:r="uploads/files",filename:n,onProgress:s}=t,o=Date.now(),a=f(e.name),c=n||`${o}_${a}`,l=`${r}/${c}`;try{return{url:(await d("storage").upload(e,{storagePath:r,filename:c,onProgress:s?p=>s({bytesTransferred:0,totalBytes:0,progress:p}):void 0})).url,filename:e.name,size:e.size,mimeType:e.type,uploadedAt:new Date().toISOString()}}catch(i){throw u(i,{userMessage:"Failed to upload file",severity:"error",context:{filename:e.name,fileSize:e.size}})}}async function v(e,t={}){const r=[],n=e.reduce((o,a)=>o+a.size,0);let s=0;for(const o of e){const a=t.onProgress?l=>{const i=l.bytesTransferred/l.totalBytes*o.size;t.onProgress({bytesTransferred:s+i,totalBytes:n,progress:(s+i)/n*100})}:void 0,c=await x(o,{...t,onProgress:a});r.push(c),s+=o.size}return r}async function F(e){try{await d("storage").delete(e.url)}catch(t){throw u(t,{userMessage:"Failed to delete file",severity:"error",context:{url:e.url,filename:e.filename}}),t}}function M(){return`${Date.now()}-${Math.random().toString(36).slice(2,9)}`}function g(e){const t=e.split(".");return t.length>1?t.pop().toLowerCase():""}function P(e,t){const r=t?g(t):"";if(e){if(e.startsWith("image/"))return"image";if(e.startsWith("video/"))return"video";if(e.startsWith("audio/"))return"audio";if(e==="application/pdf")return"pdf";if(e.includes("word")||e.includes("document"))return"doc";if(e.includes("excel")||e.includes("spreadsheet"))return"xls";if(e.includes("powerpoint")||e.includes("presentation"))return"ppt"}switch(r){case"pdf":return"pdf";case"doc":case"docx":return"doc";case"xls":case"xlsx":case"csv":return"xls";case"ppt":case"pptx":return"ppt";case"md":case"txt":return"text";case"html":case"htm":return"html";case"zip":case"rar":case"7z":return"archive";default:return"file"}}function S(e){if(e===0)return"0 B";const t=1024,r=["B","KB","MB","GB"],n=Math.floor(Math.log(e)/Math.log(t));return`${parseFloat((e/Math.pow(t,n)).toFixed(1))} ${r[n]}`}const h=["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-powerpoint","application/vnd.openxmlformats-officedocument.presentationml.presentation","text/plain","text/markdown","text/html","text/csv"],m=[".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".txt",".md",".html",".csv"];function B(){return[...h,...m].join(",")}export{m as DOCUMENT_EXTENSIONS,h as DOCUMENT_MIME_TYPES,F as deleteFile,S as formatFileSize,M as generateFileId,B as getDocumentAcceptString,g as getFileExtension,P as getFileIcon,x as uploadFile,v as uploadFiles};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function
|
|
1
|
+
async function v(i,r={}){const{maxWidth:h=1920,maxHeight:l=1440,thumbWidth:d=300,thumbHeight:t=225,aspectRatio:e=4/3,quality:a=.85,crop:o}=r;return new Promise((w,s)=>{const n=new Image,c=new FileReader;c.onload=u=>{n.src=u.target?.result},c.onerror=()=>s(new Error("Failed to read file")),n.onload=async()=>{try{const{width:u,height:f}=m(o?o.width:n.width,o?o.height:n.height,h,l,e),b=await F(n,u,f,e,a,o),g=await F(n,d,t,e,.65,o);w({fullBlob:b,thumbBlob:g,width:u,height:f})}catch(u){s(u)}},n.onerror=()=>s(new Error("Failed to load image")),c.readAsDataURL(i)})}function m(i,r,h,l,d){let t=i,e=r;t>h&&(e=h/t*e,t=h),e>l&&(t=l/e*t,e=l);const a=t/e;return Math.abs(a-d)>.01&&(a>d?e=t/d:t=e*d),{width:Math.round(t),height:Math.round(e)}}async function F(i,r,h,l,d,t){const e=document.createElement("canvas"),a=e.getContext("2d");if(!a)throw new Error("Failed to get canvas context");e.width=r,e.height=h,a.fillStyle="#FFFFFF",a.fillRect(0,0,r,h);let o,w,s,n;if(t)o=t.x,w=t.y,s=t.width,n=t.height;else{const c=i.width/i.height;s=i.width,n=i.height,o=0,w=0,c>l?(s=i.height*l,o=(i.width-s)/2):c<l&&(n=i.width/l,w=(i.height-n)/2)}return a.drawImage(i,o,w,s,n,0,0,r,h),new Promise((c,u)=>{e.toBlob(f=>{f?c(f):u(new Error("Failed to convert canvas to blob"))},"image/webp",d)})}function x(i,r){return i.type.startsWith("image/")?r&&i.size>r?{valid:!1,error:`File size exceeds ${(r/1048576).toFixed(1)}MB limit`}:{valid:!0}:{valid:!1,error:"File must be an image"}}export{v as processImage,x as validateImageFile};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{handleError as
|
|
1
|
+
import{handleError as w,getProvider as m}from"@donotdev/core";function y(e){return e.replace(/[^a-zA-Z0-9.-]/g,"_").replace(/_{2,}/g,"_").toLowerCase()}async function F(e,t,r,h={}){const{storagePath:a="uploads/images",filename:f,onProgress:s}=h,g=Date.now(),l=(f||`${g}_${y(r)}`).replace(/\.[^/.]+$/,""),d=`${a}/${l}_full.webp`,p=`${a}/${l}_thumb.webp`;try{const n=new File([e],`${l}_full.webp`,{type:"image/webp"}),o=new File([t],`${l}_thumb.webp`,{type:"image/webp"});let c,i;const b=m("storage");return c=(await b.upload(n,{storagePath:a,filename:`${l}_full.webp`,onProgress:s?u=>s({bytesTransferred:0,totalBytes:0,progress:u*.5}):void 0})).url,i=(await b.upload(o,{storagePath:a,filename:`${l}_thumb.webp`,onProgress:s?u=>s({bytesTransferred:0,totalBytes:0,progress:50+u*.5}):void 0})).url,{fullUrl:c,thumbUrl:i}}catch(n){try{const o=m("storage");await o.delete(d).catch(()=>{}),await o.delete(p).catch(()=>{})}catch{}throw n}}async function x(e){try{const t=m("storage"),r=[t.delete(e.fullUrl)];e.thumbUrl&&r.push(t.delete(e.thumbUrl)),await Promise.all(r)}catch(t){throw w(t,{userMessage:"Failed to delete image",severity:"error",context:{fullUrl:e.fullUrl,thumbUrl:e.thumbUrl}}),t}}export{x as deleteImage,F as uploadImage};
|
package/dist/utils/imageUtils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
async function d(e){const t=await e.arrayBuffer(),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(
|
|
1
|
+
async function d(e){const t=await e.arrayBuffer(),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(o=>o.toString(16).padStart(2,"0")).join("")}function h(e){return URL.createObjectURL(e)}function u(e){e.startsWith("blob:")&&URL.revokeObjectURL(e)}async function l(e){return new Promise((t,r)=>{const a=new Image,o=new FileReader;o.onload=n=>{if(!n.target?.result){r(new Error("Failed to read file"));return}a.src=n.target.result},o.onerror=()=>r(new Error("Failed to read file")),a.onload=()=>{const n=document.createElement("canvas"),i=n.getContext("2d");if(!i){r(new Error("Failed to get canvas context"));return}n.width=a.height,n.height=a.width,i.translate(n.width/2,n.height/2),i.rotate(Math.PI/2),i.drawImage(a,-a.width/2,-a.height/2),n.toBlob(s=>{if(s){const c=new File([s],e.name,{type:e.type,lastModified:Date.now()});t(c)}else r(new Error("Failed to create blob from canvas"))},e.type,.95)},a.onerror=()=>r(new Error("Failed to load image")),o.readAsDataURL(e)})}class f{undoStack=[];redoStack=[];maxStackSize=50;push(t){this.undoStack.push(t),this.undoStack.length>this.maxStackSize&&this.undoStack.shift(),this.redoStack=[]}undo(){const t=this.undoStack.pop();return t?(this.redoStack.push(t),t):null}redo(){const t=this.redoStack.pop();return t?(this.undoStack.push(t),t):null}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}clear(){this.undoStack=[],this.redoStack=[]}}function g(e,t){return e.filter(r=>r.hash===t)}function p(){return`img_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}export{f as UndoRedoManager,h as createPreviewURL,g as findDuplicatesByHash,d as generateFileHash,p as generateImageId,u as revokePreviewURL,l as rotateImage90};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchesFilter.d.ts","sourceRoot":"","sources":["../../src/utils/matchesFilter.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,GAAG,EAEd,WAAW,EACP,MAAM,GACN;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,MAAM,EAAE,GACR;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B;IACE,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EAErC,SAAS,EAAE,MAAM,GAChB,OAAO,
|
|
1
|
+
{"version":3,"file":"matchesFilter.d.ts","sourceRoot":"","sources":["../../src/utils/matchesFilter.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,GAAG,EAEd,WAAW,EACP,MAAM,GACN;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,MAAM,EAAE,GACR;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B;IACE,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EAErC,SAAS,EAAE,MAAM,GAChB,OAAO,CA8VT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getFilterType as
|
|
1
|
+
import{getFilterType as w}from"../fieldTypeRegistry.store";function T(n,t,s){if(!t)return!0;if(Array.isArray(t)){if(t.length===0)return!0;if(!(w(s)==="range"&&(s==="date"||s==="datetime-local"||s==="timestamp")))return t.some(r=>{if(typeof r=="object"&&"date"in r){const e=r.date;if(n==null)return!1;const f=n instanceof Date?n:new Date(n);return isNaN(f.getTime())?!1:f.toISOString().split("T")[0]===e}return String(n)===String(r)});if(n==null)return!1;const d=n instanceof Date?n:new Date(n);if(isNaN(d.getTime()))return!1;const D=d.toISOString().split("T")[0];return t.some(r=>typeof r=="string"?D===r:typeof r=="object"&&"date"in r?D===r.date:!1)}if(typeof t=="object"&&"date"in t&&!("min"in t)&&!Array.isArray(t)){if(!(w(s)==="range"&&(s==="date"||s==="datetime-local"||s==="timestamp")))return!1;const d=t.date;if(!d)return!0;if(n==null)return!1;const D=n instanceof Date?n.toISOString().split("T")[0]:new Date(n).toISOString().split("T")[0];if((s==="datetime-local"||s==="timestamp")&&t.time){const r=n instanceof Date?n.toISOString().slice(11,16):new Date(n).toISOString().slice(11,16);return D===d&&r===t.time}return D===d}if(typeof t=="object"&&"min"in t){const i=w(s);if(!i)return!0;const c=i==="range"&&(s==="date"||s==="datetime-local"||s==="timestamp"),d=i==="range"&&!c,D=s==="price",r=D&&n!=null&&typeof n=="object"?Number(n.amount):d&&n!=null?typeof n=="number"?n:Number(n):NaN;if(d||D){if(typeof t.min=="object"&&t.min!==null&&"date"in t.min)return!1;const e=t,f=typeof e.min=="string"&&e.min!=="",p=typeof e.max=="string"&&e.max!=="";return f&&!p?n==null||isNaN(r)?!1:r>=Number(e.min):!f&&p?n==null?!0:isNaN(r)?!1:r<=Number(e.max):f&&p?n==null||isNaN(r)?!1:r>=Number(e.min)&&r<=Number(e.max):!0}if(c){if(typeof t.min=="object"&&t.min!==null&&"date"in t.min&&!("min"in t.min)){const o=t,N=o.min,a=o.max,m=N?.date&&N.date!=="",b=a?.date&&a.date!=="";if(m&&!b){if(n==null)return!1;const g=n instanceof Date?n:new Date(n);if(isNaN(g.getTime()))return!1;const u=new Date(N.date+(N.time?`T${N.time}:00`:"T00:00:00"));return g>=u}if(!m&&b&&a){if(n==null)return!0;const g=n instanceof Date?n:new Date(n);if(isNaN(g.getTime()))return!1;const u=new Date(a.date+(a.time?`T${a.time}:00`:"T23:59:59"));return g<=u}if(m&&b&&a){if(n==null)return!1;const g=n instanceof Date?n:new Date(n);if(isNaN(g.getTime()))return!1;const u=new Date(N.date+(N.time?`T${N.time}:00`:"T00:00:00")),y=new Date(a.date+(a.time?`T${a.time}:00`:"T23:59:59"));return g>=u&&g<=y}return!0}const e=t,f=typeof e.min=="string"&&e.min!=="",p=typeof e.max=="string"&&e.max!=="";if(f&&!p){if(n==null)return!1;const o=n instanceof Date?n:new Date(n);return isNaN(o.getTime())?!1:o>=new Date(e.min)}if(!f&&p){if(n==null)return!0;const o=n instanceof Date?n:new Date(n);return isNaN(o.getTime())?!1:o<=new Date(e.max)}if(f&&p){if(n==null)return!1;const o=n instanceof Date?n:new Date(n);return isNaN(o.getTime())?!1:o>=new Date(e.min)&&o<=new Date(e.max)}return!0}}if(typeof t=="string"&&w(s)==="rating"){if(n==null)return!1;const i=Number(t),c=typeof n=="number"?n:Number(n);return isNaN(i)||isNaN(c)?!1:c>=i}const S=w(s);if(!S)return!0;if(S==="address")return n==null?!1:typeof n=="object"&&"formatted_address"in n?String(n.formatted_address).toLowerCase().includes(String(t).toLowerCase()):!1;if(S==="multiselect"){if(!Array.isArray(n)||n.length===0)return!1;const i=String(t).toLowerCase();return n.some(c=>String(c).toLowerCase().includes(i))}return n==null?!1:String(n).toLowerCase().includes(String(t).toLowerCase())}export{T as matchesFilter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CRUD_OPERATION as
|
|
1
|
+
import{CRUD_OPERATION as e}from"../types";function r(a,s){const o=[],n=new Set;for(const i of a){const t=s[i.id];t?.operation!==e.DELETE&&(t?.operation===e.UPDATE&&t.optimisticData?o.push(t.optimisticData):o.push(i),n.add(i.id))}for(const[i,t]of Object.entries(s))t.operation===e.ADD&&!n.has(i)&&t.optimisticData&&o.push(t.optimisticData);return o}export{r as mergeWithOptimistic};
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sanitize HTML using DOMPurify — handles all known XSS vectors including
|
|
3
|
-
* malformed tags, event handlers, javascript: URIs, data: URIs, SVG payloads,
|
|
4
|
-
* CSS injection, and HTML entity encoding bypasses.
|
|
5
|
-
*/
|
|
6
1
|
export declare function sanitizeHtml(html: string): string;
|
|
7
2
|
//# sourceMappingURL=sanitizeHtml.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeHtml.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizeHtml.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sanitizeHtml.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizeHtml.ts"],"names":[],"mappings":"AA6DA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"dompurify";const r=["p","h1","h2","h3","h4","h5","h6","blockquote","pre","hr","ul","ol","li","a","strong","b","em","i","u","s","code","br","span","sub","sup","mark","table","thead","tbody","tr","th","td","img","div","figure","figcaption","details","summary"],i=["href","target","rel","src","alt","width","height","class","colspan","rowspan"],a=/<\/?(?:embed|source|track|area|wbr)[^>]*>/gi;function n(t){return e.sanitize(t,{ALLOWED_TAGS:r,ALLOWED_ATTR:i}).replace(a,"")}export{n as sanitizeHtml};
|
package/dist/utils/scopeUtils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getScopeValue as
|
|
1
|
+
import{getScopeValue as o,CRUD_OPERATORS as p}from"@donotdev/core";function c(t,e){if(!e)return t;const r=o(e.provider);if(!r)throw new Error(`[CRUD] Scope provider "${e.provider}" returned null. Cannot write scoped entity without a scope value. Ensure a scope is selected before creating scoped entities.`);return{...t,[e.field]:r}}function l(t,e){const r=t??{};if(!e||typeof e.field!="string")return r;const i=o(e.provider);if(!i)throw new Error(`[CRUD] Scope provider "${e.provider}" returned null. Cannot query scoped entity without a scope value. Ensure a scope is selected before querying scoped entities.`);const n={field:e.field,operator:p.EQ,value:i};return{...r,where:r.where?[...r.where,n]:[n]}}function s(t){return t?o(t.provider):null}export{s as getCurrentScopeValue,c as injectScope,l as injectScopeFilter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";function
|
|
1
|
+
"use client";function s(r){return!r||typeof r!="string"?!1:r.startsWith("https://")&&!r.startsWith("blob:")}function c(r){return!(!r||typeof r!="object"||!s(r.fullUrl)||r.thumbUrl&&!s(r.thumbUrl))}function u(r,o=""){const t=[];if(r==null)return t;if(typeof r=="string")return r.startsWith("blob:")&&t.push(o||"root"),t;if(typeof r!="object")return t;if(Array.isArray(r))r.forEach((e,n)=>{const l=o?`${o}[${n}]`:`[${n}]`;t.push(...u(e,l))});else{const e=r;if(e.fullUrl!==void 0&&e.thumbUrl!==void 0){const n=e.fullUrl,l=e.thumbUrl,f=typeof n=="string"&&!s(n),b=l&&typeof l=="string"&&!s(l);if(f||b){const i=o||"root";t.push(`${i}.fullUrl or ${i}.thumbUrl contains blob URL`)}}else Object.entries(e).forEach(([n,l])=>{const f=o?`${o}.${n}`:n;t.push(...u(l,f))})}return t}function h(r){return u(r).length>0}export{u as checkForBlobUrls,h as hasBlobUrls,s as isStorageUrl,c as validatePicture};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const r="dndev-workflow-";function c(t,o){try{const e=`${r}${t}`;localStorage.setItem(e,JSON.stringify(o))}catch{}}function n(t){try{const o=`${r}${t}`,e=localStorage.getItem(o);return e?JSON.parse(e):null}catch{return null}}function a(t){try{const o=`${r}${t}`;localStorage.removeItem(o)}catch{}}export{a as clearWorkflowState,n as loadWorkflowState,c as saveWorkflowState};
|
package/dist/workflows/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as
|
|
1
|
+
import{defineWorkflow as e}from"./defineWorkflow";import{useEntityWorkflow as f}from"./useEntityWorkflow";import{saveWorkflowState as a,loadWorkflowState as k,clearWorkflowState as w}from"./WorkflowPersistence";export{w as clearWorkflowState,e as defineWorkflow,k as loadWorkflowState,a as saveWorkflowState,f as useEntityWorkflow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useState as
|
|
1
|
+
"use client";import{useState as b,useCallback as p,useMemo as I,useEffect as G,useRef as L}from"react";import{evaluateCondition as M}from"@donotdev/core";import{saveWorkflowState as K,loadWorkflowState as j,clearWorkflowState as O}from"./WorkflowPersistence";function B(e,D={}){const{onComplete:k,onStepChange:u,defaultValues:y}=D,w=L(k);w.current=k;const[l,v]=b(()=>{if(e.persist){const t=j(e.persistKey??e.id);if(t)return t.stepData}if(y){const t={};for(const r of e.steps)if(r.entity&&r.fields){const o={};for(const i of r.fields)i in y&&(o[i]=y[i]);Object.keys(o).length>0&&(t[r.id]=o)}return t}return{}}),[s,m]=b(()=>{if(e.persist){const t=j(e.persistKey??e.id);if(t)return t.currentStepIndex}return 0}),[x,h]=b(!1),d=I(()=>{const t={};for(const[r,o]of Object.entries(l))for(const[i,a]of Object.entries(o))t[i]=a,t[`${r}.${i}`]=a;return t},[l]),n=I(()=>e.steps.filter(t=>t.conditions?.visible?M(t.conditions.visible,d):!0),[e.steps,d]),W=n[s]??n[0],S=s===0,c=s===n.length-1;G(()=>{e.persist&&K(e.persistKey??e.id,{currentStepIndex:s,stepData:l,savedAt:Date.now()})},[e.persist,e.persistKey,e.id,s,l]);const F=p(async t=>{const r=n[s];if(!r)return!1;if(t&&v(i=>({...i,[r.id]:{...i[r.id],...t}})),r.validation?.validate){const i={...d,...t??{}};if(r.validation.validate(i)!==!0)return!1}if(r.after){const i={};await r.after({data:t??l[r.id]??{},allData:{...d,...t??{}},next:{prefill:a=>{const f=n[s+1];f&&(i[f.id]=a)}}}),Object.keys(i).length>0&&v(a=>{const f={...a};for(const[C,$]of Object.entries(i))f[C]={...f[C],...$};return f})}if(c){h(!0);try{const i={...d,...t??{}},a=w.current??e.onComplete;return a&&await a(i),e.persist&&O(e.persistKey??e.id),!0}catch{return!1}finally{h(!1)}}const o=s+1;return m(o),u?.(s,o),!0},[n,s,d,l,c,e,u]),N=p(()=>{if(S)return;const t=s-1;m(t),u?.(s,t)},[s,S,u]),A=p(()=>{if(!n[s]?.allowSkip||c)return;const r=s+1;m(r),u?.(s,r)},[n,s,c,u]),E=p(t=>{t>=0&&t<n.length&&(u?.(s,t),m(t))},[n.length,s,u]),P=p(()=>{e.persist&&K(e.persistKey??e.id,{currentStepIndex:s,stepData:l,savedAt:Date.now()})},[e,s,l]),R=p(()=>{O(e.persistKey??e.id)},[e]),V=p((t,r)=>{v(o=>({...o,[t]:{...o[t],...r}}))},[]);return{currentStep:W,currentStepIndex:s,visibleSteps:n,stepData:l,allData:d,goNext:F,goPrevious:N,skipStep:A,goToStep:E,isFirst:S,isLast:c,isSubmitting:x,canGoNext:!x,persistNow:P,clearPersisted:R,prefillStep:V}}export{B as useEntityWorkflow};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@donotdev/crud",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"@dnd-kit/core": "^6.3.1",
|
|
54
54
|
"@dnd-kit/sortable": "^10.0.0",
|
|
55
55
|
"@dnd-kit/utilities": "^3.2.2",
|
|
56
|
-
"@donotdev/components": "^0.0
|
|
57
|
-
"@donotdev/core": "^0.0
|
|
56
|
+
"@donotdev/components": "^0.1.0",
|
|
57
|
+
"@donotdev/core": "^0.1.0",
|
|
58
58
|
"@hookform/resolvers": "^5.2.2",
|
|
59
59
|
"dompurify": "^3.3.2",
|
|
60
60
|
"react-easy-crop": "^5.5.6"
|