@blueprint-ts/core 4.1.0-beta.2 → 4.1.0-beta.3
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/bulkRequests/BulkRequestEvent.enum.d.ts +4 -0
- package/dist/bulkRequests/BulkRequestEvent.enum.js +5 -0
- package/dist/bulkRequests/BulkRequestSender.d.ts +31 -0
- package/dist/bulkRequests/BulkRequestSender.js +161 -0
- package/dist/bulkRequests/BulkRequestWrapper.d.ts +15 -0
- package/dist/bulkRequests/BulkRequestWrapper.js +50 -0
- package/dist/bulkRequests/index.d.ts +5 -0
- package/dist/bulkRequests/index.js +5 -0
- package/{src/laravel/pagination/contracts/PaginationResponseBodyContract.ts → dist/laravel/pagination/contracts/PaginationResponseBodyContract.d.ts} +4 -4
- package/dist/laravel/pagination/contracts/PaginationResponseBodyContract.js +1 -0
- package/dist/laravel/pagination/dataDrivers/RequestDriver.d.ts +10 -0
- package/dist/laravel/pagination/dataDrivers/RequestDriver.js +18 -0
- package/dist/laravel/pagination/index.d.ts +4 -0
- package/dist/laravel/pagination/index.js +2 -0
- package/dist/laravel/requests/JsonBaseRequest.d.ts +14 -0
- package/dist/laravel/requests/JsonBaseRequest.js +15 -0
- package/dist/laravel/requests/PaginationJsonBaseRequest.d.ts +8 -0
- package/dist/laravel/requests/PaginationJsonBaseRequest.js +13 -0
- package/dist/laravel/requests/index.d.ts +7 -0
- package/dist/laravel/requests/index.js +5 -0
- package/dist/laravel/requests/responses/JsonResponse.d.ts +5 -0
- package/dist/laravel/requests/responses/JsonResponse.js +6 -0
- package/dist/laravel/requests/responses/PaginationResponse.d.ts +7 -0
- package/dist/laravel/requests/responses/PaginationResponse.js +9 -0
- package/dist/pagination/BasePaginator.d.ts +19 -0
- package/dist/pagination/BasePaginator.js +65 -0
- package/dist/pagination/InfiniteScroller.d.ts +6 -0
- package/dist/pagination/InfiniteScroller.js +17 -0
- package/dist/pagination/PageAwarePaginator.d.ts +32 -0
- package/dist/pagination/PageAwarePaginator.js +86 -0
- package/dist/pagination/StatePaginator.d.ts +25 -0
- package/dist/pagination/StatePaginator.js +55 -0
- package/dist/pagination/contracts/BaseViewDriverContract.d.ts +6 -0
- package/dist/pagination/contracts/BaseViewDriverContract.js +1 -0
- package/{src/pagination/contracts/BaseViewDriverFactoryContract.ts → dist/pagination/contracts/BaseViewDriverFactoryContract.d.ts} +2 -3
- package/dist/pagination/contracts/BaseViewDriverFactoryContract.js +1 -0
- package/dist/pagination/contracts/PaginateableRequestContract.d.ts +4 -0
- package/dist/pagination/contracts/PaginateableRequestContract.js +1 -0
- package/dist/pagination/contracts/PaginationDataDriverContract.d.ts +4 -0
- package/dist/pagination/contracts/PaginationDataDriverContract.js +1 -0
- package/{src/pagination/contracts/PaginationResponseContract.ts → dist/pagination/contracts/PaginationResponseContract.d.ts} +3 -5
- package/dist/pagination/contracts/PaginationResponseContract.js +1 -0
- package/{src/pagination/contracts/PaginatorLoadDataOptions.ts → dist/pagination/contracts/PaginatorLoadDataOptions.d.ts} +2 -2
- package/dist/pagination/contracts/PaginatorLoadDataOptions.js +1 -0
- package/{src/pagination/contracts/StatePaginationDataDriverContract.ts → dist/pagination/contracts/StatePaginationDataDriverContract.d.ts} +2 -3
- package/dist/pagination/contracts/StatePaginationDataDriverContract.js +1 -0
- package/dist/pagination/contracts/ViewDriverContract.d.ts +9 -0
- package/dist/pagination/contracts/ViewDriverContract.js +1 -0
- package/dist/pagination/contracts/ViewDriverFactoryContract.d.ts +4 -0
- package/dist/pagination/contracts/ViewDriverFactoryContract.js +1 -0
- package/dist/pagination/dataDrivers/ArrayDriver.d.ts +9 -0
- package/dist/pagination/dataDrivers/ArrayDriver.js +20 -0
- package/dist/pagination/dtos/PaginationDataDto.d.ts +7 -0
- package/dist/pagination/dtos/PaginationDataDto.js +12 -0
- package/dist/pagination/dtos/StatePaginationDataDto.d.ts +7 -0
- package/dist/pagination/dtos/StatePaginationDataDto.js +13 -0
- package/dist/pagination/factories/VueBaseViewDriverFactory.d.ts +5 -0
- package/dist/pagination/factories/VueBaseViewDriverFactory.js +6 -0
- package/dist/pagination/factories/VuePaginationDriverFactory.d.ts +5 -0
- package/dist/pagination/factories/VuePaginationDriverFactory.js +6 -0
- package/dist/pagination/frontendDrivers/VueBaseViewDriver.d.ts +11 -0
- package/dist/pagination/frontendDrivers/VueBaseViewDriver.js +19 -0
- package/dist/pagination/frontendDrivers/VuePaginationDriver.d.ts +21 -0
- package/dist/pagination/frontendDrivers/VuePaginationDriver.js +41 -0
- package/dist/pagination/index.d.ts +22 -0
- package/dist/pagination/index.js +13 -0
- package/dist/persistenceDrivers/LocalStorageDriver.d.ts +9 -0
- package/dist/persistenceDrivers/LocalStorageDriver.js +18 -0
- package/dist/persistenceDrivers/NonPersistentDriver.d.ts +7 -0
- package/dist/persistenceDrivers/NonPersistentDriver.js +8 -0
- package/dist/persistenceDrivers/SessionStorageDriver.d.ts +9 -0
- package/dist/persistenceDrivers/SessionStorageDriver.js +18 -0
- package/dist/persistenceDrivers/index.d.ts +6 -0
- package/dist/persistenceDrivers/index.js +4 -0
- package/dist/persistenceDrivers/types/PersistenceDriver.d.ts +5 -0
- package/dist/persistenceDrivers/types/PersistenceDriver.js +1 -0
- package/dist/requests/BaseRequest.d.ts +62 -0
- package/dist/requests/BaseRequest.js +224 -0
- package/dist/requests/ErrorHandler.d.ts +11 -0
- package/dist/requests/ErrorHandler.js +127 -0
- package/dist/requests/RequestConcurrencyMode.enum.d.ts +6 -0
- package/dist/requests/RequestConcurrencyMode.enum.js +7 -0
- package/dist/requests/RequestErrorRouter.d.ts +38 -0
- package/dist/requests/RequestErrorRouter.js +38 -0
- package/dist/requests/RequestEvents.enum.d.ts +4 -0
- package/dist/requests/RequestEvents.enum.js +5 -0
- package/dist/requests/RequestMethod.enum.d.ts +8 -0
- package/dist/requests/RequestMethod.enum.js +9 -0
- package/dist/requests/bodies/BinaryBody.d.ts +10 -0
- package/dist/requests/bodies/BinaryBody.js +22 -0
- package/dist/requests/bodies/FormDataBody.d.ts +14 -0
- package/dist/requests/bodies/FormDataBody.js +60 -0
- package/dist/requests/bodies/JsonBody.d.ts +8 -0
- package/dist/requests/bodies/JsonBody.js +13 -0
- package/{src/requests/contracts/AbortableRequestContract.ts → dist/requests/contracts/AbortableRequestContract.d.ts} +1 -1
- package/dist/requests/contracts/AbortableRequestContract.js +1 -0
- package/dist/requests/contracts/BaseRequestContract.d.ts +23 -0
- package/dist/requests/contracts/BaseRequestContract.js +1 -0
- package/dist/requests/contracts/BodyContract.d.ts +6 -0
- package/dist/requests/contracts/BodyContract.js +1 -0
- package/dist/requests/contracts/BodyFactoryContract.d.ts +4 -0
- package/dist/requests/contracts/BodyFactoryContract.js +1 -0
- package/dist/requests/contracts/DriverConfigContract.d.ts +8 -0
- package/dist/requests/contracts/DriverConfigContract.js +1 -0
- package/dist/requests/contracts/HeadersContract.d.ts +7 -0
- package/dist/requests/contracts/HeadersContract.js +1 -0
- package/dist/requests/contracts/RequestDriverContract.d.ts +8 -0
- package/dist/requests/contracts/RequestDriverContract.js +1 -0
- package/dist/requests/contracts/RequestLoaderContract.d.ts +4 -0
- package/dist/requests/contracts/RequestLoaderContract.js +1 -0
- package/{src/requests/contracts/RequestLoaderFactoryContract.ts → dist/requests/contracts/RequestLoaderFactoryContract.d.ts} +2 -3
- package/dist/requests/contracts/RequestLoaderFactoryContract.js +1 -0
- package/dist/requests/contracts/ResponseContract.d.ts +5 -0
- package/dist/requests/contracts/ResponseContract.js +1 -0
- package/dist/requests/drivers/contracts/ResponseHandlerContract.d.ts +9 -0
- package/dist/requests/drivers/contracts/ResponseHandlerContract.js +1 -0
- package/dist/requests/drivers/fetch/FetchDriver.d.ts +26 -0
- package/dist/requests/drivers/fetch/FetchDriver.js +73 -0
- package/dist/requests/drivers/fetch/FetchResponse.d.ts +12 -0
- package/dist/requests/drivers/fetch/FetchResponse.js +38 -0
- package/dist/requests/drivers/xhr/XMLHttpRequestDriver.d.ts +13 -0
- package/dist/requests/drivers/xhr/XMLHttpRequestDriver.js +107 -0
- package/dist/requests/drivers/xhr/XMLHttpRequestResponse.d.ts +17 -0
- package/dist/requests/drivers/xhr/XMLHttpRequestResponse.js +84 -0
- package/dist/requests/exceptions/BadGatewayException.d.ts +3 -0
- package/dist/requests/exceptions/BadGatewayException.js +3 -0
- package/dist/requests/exceptions/BadRequestException.d.ts +3 -0
- package/dist/requests/exceptions/BadRequestException.js +3 -0
- package/dist/requests/exceptions/ConflictException.d.ts +3 -0
- package/dist/requests/exceptions/ConflictException.js +3 -0
- package/dist/requests/exceptions/ForbiddenException.d.ts +3 -0
- package/dist/requests/exceptions/ForbiddenException.js +3 -0
- package/dist/requests/exceptions/GatewayTimeoutException.d.ts +3 -0
- package/dist/requests/exceptions/GatewayTimeoutException.js +3 -0
- package/dist/requests/exceptions/GoneException.d.ts +3 -0
- package/dist/requests/exceptions/GoneException.js +3 -0
- package/dist/requests/exceptions/InvalidJsonException.d.ts +7 -0
- package/dist/requests/exceptions/InvalidJsonException.js +10 -0
- package/dist/requests/exceptions/LockedException.d.ts +3 -0
- package/dist/requests/exceptions/LockedException.js +3 -0
- package/dist/requests/exceptions/MethodNotAllowedException.d.ts +3 -0
- package/dist/requests/exceptions/MethodNotAllowedException.js +3 -0
- package/dist/requests/exceptions/NoResponseReceivedException.d.ts +3 -0
- package/{src/requests/exceptions/NoResponseReceivedException.ts → dist/requests/exceptions/NoResponseReceivedException.js} +3 -3
- package/dist/requests/exceptions/NotFoundException.d.ts +3 -0
- package/dist/requests/exceptions/NotFoundException.js +3 -0
- package/dist/requests/exceptions/NotImplementedException.d.ts +3 -0
- package/dist/requests/exceptions/NotImplementedException.js +3 -0
- package/dist/requests/exceptions/PageExpiredException.d.ts +3 -0
- package/dist/requests/exceptions/PageExpiredException.js +3 -0
- package/dist/requests/exceptions/PayloadTooLargeException.d.ts +3 -0
- package/dist/requests/exceptions/PayloadTooLargeException.js +3 -0
- package/dist/requests/exceptions/PreconditionFailedException.d.ts +3 -0
- package/dist/requests/exceptions/PreconditionFailedException.js +3 -0
- package/dist/requests/exceptions/RequestTimeoutException.d.ts +3 -0
- package/dist/requests/exceptions/RequestTimeoutException.js +3 -0
- package/dist/requests/exceptions/ResponseBodyException.d.ts +7 -0
- package/dist/requests/exceptions/ResponseBodyException.js +10 -0
- package/dist/requests/exceptions/ResponseException.d.ts +6 -0
- package/dist/requests/exceptions/ResponseException.js +9 -0
- package/dist/requests/exceptions/ServerErrorException.d.ts +3 -0
- package/dist/requests/exceptions/ServerErrorException.js +3 -0
- package/dist/requests/exceptions/ServiceUnavailableException.d.ts +3 -0
- package/dist/requests/exceptions/ServiceUnavailableException.js +3 -0
- package/dist/requests/exceptions/StaleResponseException.d.ts +5 -0
- package/dist/requests/exceptions/StaleResponseException.js +10 -0
- package/dist/requests/exceptions/TooManyRequestsException.d.ts +3 -0
- package/dist/requests/exceptions/TooManyRequestsException.js +3 -0
- package/dist/requests/exceptions/UnauthorizedException.d.ts +3 -0
- package/dist/requests/exceptions/UnauthorizedException.js +3 -0
- package/dist/requests/exceptions/UnsupportedMediaTypeException.d.ts +3 -0
- package/dist/requests/exceptions/UnsupportedMediaTypeException.js +3 -0
- package/dist/requests/exceptions/ValidationException.d.ts +3 -0
- package/dist/requests/exceptions/ValidationException.js +3 -0
- package/dist/requests/exceptions/index.d.ts +25 -0
- package/dist/requests/exceptions/index.js +25 -0
- package/dist/requests/factories/BinaryBodyFactory.d.ts +8 -0
- package/dist/requests/factories/BinaryBodyFactory.js +9 -0
- package/dist/requests/factories/FormDataFactory.d.ts +12 -0
- package/dist/requests/factories/FormDataFactory.js +6 -0
- package/dist/requests/factories/JsonBodyFactory.d.ts +5 -0
- package/dist/requests/factories/JsonBodyFactory.js +6 -0
- package/dist/requests/index.d.ts +31 -0
- package/dist/requests/index.js +19 -0
- package/dist/requests/responses/BaseResponse.d.ts +14 -0
- package/dist/requests/responses/BaseResponse.js +36 -0
- package/dist/requests/responses/BlobResponse.d.ts +7 -0
- package/dist/requests/responses/BlobResponse.js +16 -0
- package/dist/requests/responses/JsonResponse.d.ts +5 -0
- package/dist/requests/responses/JsonResponse.js +12 -0
- package/dist/requests/responses/PlainTextResponse.d.ts +5 -0
- package/dist/requests/responses/PlainTextResponse.js +12 -0
- package/{src/requests/types/RequestConcurrencyOptions.ts → dist/requests/types/RequestConcurrencyOptions.d.ts} +4 -5
- package/dist/requests/types/RequestConcurrencyOptions.js +1 -0
- package/dist/requests/types/RequestUploadProgress.d.ts +6 -0
- package/dist/requests/types/RequestUploadProgress.js +1 -0
- package/dist/support/DeferredPromise.d.ts +37 -0
- package/dist/support/DeferredPromise.js +55 -0
- package/dist/support/helpers.d.ts +5 -0
- package/dist/support/helpers.js +69 -0
- package/{src/support/index.ts → dist/support/index.d.ts} +3 -4
- package/dist/support/index.js +3 -0
- package/dist/vue/composables/useConfirmDialog.d.ts +20 -0
- package/dist/vue/composables/useConfirmDialog.js +52 -0
- package/dist/vue/composables/useGlobalCheckbox.d.ts +13 -0
- package/dist/vue/composables/useGlobalCheckbox.js +123 -0
- package/dist/vue/composables/useIsEmpty.d.ts +4 -0
- package/dist/vue/composables/useIsEmpty.js +27 -0
- package/dist/vue/composables/useIsOpen.d.ts +5 -0
- package/dist/vue/composables/useIsOpen.js +25 -0
- package/dist/vue/composables/useIsOpenFromVar.d.ts +6 -0
- package/dist/vue/composables/useIsOpenFromVar.js +45 -0
- package/dist/vue/composables/useModelWrapper.d.ts +9 -0
- package/dist/vue/composables/useModelWrapper.js +18 -0
- package/dist/vue/composables/useOnOpen.d.ts +7 -0
- package/dist/vue/composables/useOnOpen.js +25 -0
- package/{src/vue/contracts/ModelValueOptions.ts → dist/vue/contracts/ModelValueOptions.d.ts} +1 -1
- package/dist/vue/contracts/ModelValueOptions.js +1 -0
- package/dist/vue/contracts/ModelValueProps.d.ts +3 -0
- package/dist/vue/contracts/ModelValueProps.js +1 -0
- package/dist/vue/forms/BaseForm.d.ts +162 -0
- package/dist/vue/forms/BaseForm.js +997 -0
- package/dist/vue/forms/PropertyAwareArray.d.ts +53 -0
- package/dist/vue/forms/PropertyAwareArray.js +54 -0
- package/{src/vue/forms/index.ts → dist/vue/forms/index.d.ts} +9 -11
- package/dist/vue/forms/index.js +6 -0
- package/dist/vue/forms/types/PersistedForm.d.ts +6 -0
- package/dist/vue/forms/types/PersistedForm.js +1 -0
- package/dist/vue/forms/validation/ValidationMode.enum.d.ts +11 -0
- package/dist/vue/forms/validation/ValidationMode.enum.js +14 -0
- package/dist/vue/forms/validation/index.d.ts +12 -0
- package/dist/vue/forms/validation/index.js +9 -0
- package/dist/vue/forms/validation/rules/BaseRule.d.ts +5 -0
- package/dist/vue/forms/validation/rules/BaseRule.js +5 -0
- package/dist/vue/forms/validation/rules/ConfirmedRule.d.ts +10 -0
- package/dist/vue/forms/validation/rules/ConfirmedRule.js +26 -0
- package/dist/vue/forms/validation/rules/EmailRule.d.ts +7 -0
- package/dist/vue/forms/validation/rules/EmailRule.js +19 -0
- package/dist/vue/forms/validation/rules/JsonRule.d.ts +7 -0
- package/dist/vue/forms/validation/rules/JsonRule.js +25 -0
- package/dist/vue/forms/validation/rules/MinRule.d.ts +26 -0
- package/dist/vue/forms/validation/rules/MinRule.js +52 -0
- package/dist/vue/forms/validation/rules/RequiredRule.d.ts +7 -0
- package/dist/vue/forms/validation/rules/RequiredRule.js +16 -0
- package/dist/vue/forms/validation/rules/UrlRule.d.ts +7 -0
- package/dist/vue/forms/validation/rules/UrlRule.js +22 -0
- package/{src/vue/forms/validation/types/BidirectionalRule.ts → dist/vue/forms/validation/types/BidirectionalRule.d.ts} +4 -4
- package/dist/vue/forms/validation/types/BidirectionalRule.js +1 -0
- package/dist/vue/forms/validation/types/ValidationRules.d.ts +11 -0
- package/dist/vue/forms/validation/types/ValidationRules.js +1 -0
- package/dist/vue/index.d.ts +11 -0
- package/dist/vue/index.js +10 -0
- package/dist/vue/requests/factories/VueRequestLoaderFactory.d.ts +6 -0
- package/dist/vue/requests/factories/VueRequestLoaderFactory.js +6 -0
- package/{src/vue/requests/index.ts → dist/vue/requests/index.d.ts} +4 -5
- package/dist/vue/requests/index.js +4 -0
- package/dist/vue/requests/loaders/VueRequestBatchLoader.d.ts +12 -0
- package/dist/vue/requests/loaders/VueRequestBatchLoader.js +29 -0
- package/dist/vue/requests/loaders/VueRequestLoader.d.ts +8 -0
- package/dist/vue/requests/loaders/VueRequestLoader.js +12 -0
- package/dist/vue/router/routeResourceBinding/RouteResourceBoundView.d.ts +57 -0
- package/dist/vue/router/routeResourceBinding/RouteResourceBoundView.js +135 -0
- package/dist/vue/router/routeResourceBinding/RouteResourceRequestResolver.d.ts +6 -0
- package/dist/vue/router/routeResourceBinding/RouteResourceRequestResolver.js +20 -0
- package/dist/vue/router/routeResourceBinding/defineRoute.d.ts +23 -0
- package/dist/vue/router/routeResourceBinding/defineRoute.js +42 -0
- package/dist/vue/router/routeResourceBinding/index.d.ts +8 -0
- package/dist/vue/router/routeResourceBinding/index.js +6 -0
- package/dist/vue/router/routeResourceBinding/installRouteInjection.d.ts +14 -0
- package/dist/vue/router/routeResourceBinding/installRouteInjection.js +133 -0
- package/dist/vue/router/routeResourceBinding/types.d.ts +55 -0
- package/dist/vue/router/routeResourceBinding/types.js +1 -0
- package/dist/vue/router/routeResourceBinding/useRouteResource.d.ts +8 -0
- package/dist/vue/router/routeResourceBinding/useRouteResource.js +29 -0
- package/dist/vue/state/State.d.ts +75 -0
- package/dist/vue/state/State.js +267 -0
- package/dist/vue/state/index.d.ts +2 -0
- package/dist/vue/state/index.js +2 -0
- package/package.json +81 -23
- package/.editorconfig +0 -508
- package/.eslintrc.cjs +0 -15
- package/.prettierrc.json +0 -8
- package/CHANGELOG.md +0 -226
- package/docker-compose.yaml +0 -8
- package/docs/.vitepress/config.ts +0 -124
- package/docs/index.md +0 -13
- package/docs/laravel/pagination.md +0 -67
- package/docs/laravel/requests.md +0 -62
- package/docs/services/pagination/index.md +0 -46
- package/docs/services/pagination/infinite-scroller.md +0 -20
- package/docs/services/pagination/page-aware.md +0 -51
- package/docs/services/pagination/state-pagination.md +0 -77
- package/docs/services/pagination/updating-rows.md +0 -52
- package/docs/services/persistence/index.md +0 -46
- package/docs/services/requests/abort-requests.md +0 -29
- package/docs/services/requests/bulk-requests.md +0 -70
- package/docs/services/requests/concurrency.md +0 -58
- package/docs/services/requests/drivers.md +0 -115
- package/docs/services/requests/error-handling.md +0 -153
- package/docs/services/requests/events.md +0 -53
- package/docs/services/requests/file-uploads.md +0 -168
- package/docs/services/requests/getting-started.md +0 -201
- package/docs/services/requests/headers.md +0 -40
- package/docs/services/requests/loading.md +0 -63
- package/docs/services/requests/request-bodies.md +0 -89
- package/docs/services/requests/responses.md +0 -34
- package/docs/services/support/deferred-promise.md +0 -63
- package/docs/services/support/helpers.md +0 -77
- package/docs/services/support/index.md +0 -6
- package/docs/upgrading/v1-to-v2.md +0 -64
- package/docs/upgrading/v2-to-v3.md +0 -52
- package/docs/upgrading/v3-to-v4.md +0 -214
- package/docs/upgrading.md +0 -0
- package/docs/vue/composables/use-confirm-dialog.md +0 -96
- package/docs/vue/composables/use-global-checkbox.md +0 -73
- package/docs/vue/composables/use-is-empty.md +0 -26
- package/docs/vue/composables/use-is-open-from-var.md +0 -32
- package/docs/vue/composables/use-is-open.md +0 -28
- package/docs/vue/composables/use-model-wrapper.md +0 -29
- package/docs/vue/composables/use-on-open.md +0 -26
- package/docs/vue/forms/arrays.md +0 -102
- package/docs/vue/forms/errors.md +0 -52
- package/docs/vue/forms/index.md +0 -99
- package/docs/vue/forms/payloads.md +0 -99
- package/docs/vue/forms/persistence.md +0 -19
- package/docs/vue/forms/state-and-properties.md +0 -26
- package/docs/vue/forms/utilities.md +0 -27
- package/docs/vue/forms/validation.md +0 -189
- package/docs/vue/requests/loading.md +0 -51
- package/docs/vue/router/route-resource-binding.md +0 -240
- package/docs/vue/state.md +0 -309
- package/env.d.ts +0 -1
- package/eslint.config.js +0 -15
- package/release-tool.json +0 -26
- package/src/bulkRequests/BulkRequestEvent.enum.ts +0 -4
- package/src/bulkRequests/BulkRequestSender.ts +0 -196
- package/src/bulkRequests/BulkRequestWrapper.ts +0 -49
- package/src/bulkRequests/index.ts +0 -6
- package/src/laravel/pagination/dataDrivers/RequestDriver.ts +0 -30
- package/src/laravel/pagination/index.ts +0 -6
- package/src/laravel/requests/JsonBaseRequest.ts +0 -35
- package/src/laravel/requests/PaginationJsonBaseRequest.ts +0 -29
- package/src/laravel/requests/index.ts +0 -9
- package/src/laravel/requests/responses/JsonResponse.ts +0 -8
- package/src/laravel/requests/responses/PaginationResponse.ts +0 -16
- package/src/pagination/BasePaginator.ts +0 -94
- package/src/pagination/InfiniteScroller.ts +0 -22
- package/src/pagination/PageAwarePaginator.ts +0 -132
- package/src/pagination/StatePaginator.ts +0 -86
- package/src/pagination/contracts/BaseViewDriverContract.ts +0 -6
- package/src/pagination/contracts/PaginateableRequestContract.ts +0 -13
- package/src/pagination/contracts/PaginationDataDriverContract.ts +0 -5
- package/src/pagination/contracts/ViewDriverContract.ts +0 -10
- package/src/pagination/contracts/ViewDriverFactoryContract.ts +0 -5
- package/src/pagination/dataDrivers/ArrayDriver.ts +0 -28
- package/src/pagination/dtos/PaginationDataDto.ts +0 -14
- package/src/pagination/dtos/StatePaginationDataDto.ts +0 -19
- package/src/pagination/factories/VueBaseViewDriverFactory.ts +0 -9
- package/src/pagination/factories/VuePaginationDriverFactory.ts +0 -9
- package/src/pagination/frontendDrivers/VueBaseViewDriver.ts +0 -28
- package/src/pagination/frontendDrivers/VuePaginationDriver.ts +0 -61
- package/src/pagination/index.ts +0 -46
- package/src/persistenceDrivers/LocalStorageDriver.ts +0 -22
- package/src/persistenceDrivers/NonPersistentDriver.ts +0 -12
- package/src/persistenceDrivers/SessionStorageDriver.ts +0 -22
- package/src/persistenceDrivers/index.ts +0 -8
- package/src/persistenceDrivers/types/PersistenceDriver.ts +0 -5
- package/src/requests/BaseRequest.ts +0 -321
- package/src/requests/ErrorHandler.ts +0 -144
- package/src/requests/RequestConcurrencyMode.enum.ts +0 -6
- package/src/requests/RequestErrorRouter.ts +0 -89
- package/src/requests/RequestEvents.enum.ts +0 -4
- package/src/requests/RequestMethod.enum.ts +0 -8
- package/src/requests/bodies/BinaryBody.ts +0 -31
- package/src/requests/bodies/FormDataBody.ts +0 -81
- package/src/requests/bodies/JsonBody.ts +0 -16
- package/src/requests/contracts/BaseRequestContract.ts +0 -39
- package/src/requests/contracts/BodyContract.ts +0 -9
- package/src/requests/contracts/BodyFactoryContract.ts +0 -5
- package/src/requests/contracts/DriverConfigContract.ts +0 -9
- package/src/requests/contracts/HeadersContract.ts +0 -9
- package/src/requests/contracts/RequestDriverContract.ts +0 -15
- package/src/requests/contracts/RequestLoaderContract.ts +0 -5
- package/src/requests/contracts/ResponseContract.ts +0 -7
- package/src/requests/drivers/contracts/ResponseHandlerContract.ts +0 -10
- package/src/requests/drivers/fetch/FetchDriver.ts +0 -115
- package/src/requests/drivers/fetch/FetchResponse.ts +0 -30
- package/src/requests/drivers/xhr/XMLHttpRequestDriver.ts +0 -138
- package/src/requests/drivers/xhr/XMLHttpRequestResponse.ts +0 -95
- package/src/requests/exceptions/BadGatewayException.ts +0 -3
- package/src/requests/exceptions/BadRequestException.ts +0 -3
- package/src/requests/exceptions/ConflictException.ts +0 -3
- package/src/requests/exceptions/ForbiddenException.ts +0 -3
- package/src/requests/exceptions/GatewayTimeoutException.ts +0 -3
- package/src/requests/exceptions/GoneException.ts +0 -3
- package/src/requests/exceptions/InvalidJsonException.ts +0 -15
- package/src/requests/exceptions/LockedException.ts +0 -3
- package/src/requests/exceptions/MethodNotAllowedException.ts +0 -3
- package/src/requests/exceptions/NotFoundException.ts +0 -3
- package/src/requests/exceptions/NotImplementedException.ts +0 -3
- package/src/requests/exceptions/PageExpiredException.ts +0 -3
- package/src/requests/exceptions/PayloadTooLargeException.ts +0 -3
- package/src/requests/exceptions/PreconditionFailedException.ts +0 -3
- package/src/requests/exceptions/RequestTimeoutException.ts +0 -3
- package/src/requests/exceptions/ResponseBodyException.ts +0 -15
- package/src/requests/exceptions/ResponseException.ts +0 -11
- package/src/requests/exceptions/ServerErrorException.ts +0 -3
- package/src/requests/exceptions/ServiceUnavailableException.ts +0 -3
- package/src/requests/exceptions/StaleResponseException.ts +0 -13
- package/src/requests/exceptions/TooManyRequestsException.ts +0 -3
- package/src/requests/exceptions/UnauthorizedException.ts +0 -3
- package/src/requests/exceptions/UnsupportedMediaTypeException.ts +0 -3
- package/src/requests/exceptions/ValidationException.ts +0 -3
- package/src/requests/exceptions/index.ts +0 -51
- package/src/requests/factories/BinaryBodyFactory.ts +0 -13
- package/src/requests/factories/FormDataFactory.ts +0 -17
- package/src/requests/factories/JsonBodyFactory.ts +0 -9
- package/src/requests/index.ts +0 -68
- package/src/requests/responses/BaseResponse.ts +0 -41
- package/src/requests/responses/BlobResponse.ts +0 -19
- package/src/requests/responses/JsonResponse.ts +0 -15
- package/src/requests/responses/PlainTextResponse.ts +0 -15
- package/src/requests/types/RequestUploadProgress.ts +0 -6
- package/src/support/DeferredPromise.ts +0 -67
- package/src/support/helpers.ts +0 -78
- package/src/vue/composables/useConfirmDialog.ts +0 -63
- package/src/vue/composables/useGlobalCheckbox.ts +0 -145
- package/src/vue/composables/useIsEmpty.ts +0 -34
- package/src/vue/composables/useIsOpen.ts +0 -37
- package/src/vue/composables/useIsOpenFromVar.ts +0 -61
- package/src/vue/composables/useModelWrapper.ts +0 -27
- package/src/vue/composables/useOnOpen.ts +0 -34
- package/src/vue/contracts/ModelValueProps.ts +0 -3
- package/src/vue/forms/BaseForm.ts +0 -1192
- package/src/vue/forms/PropertyAwareArray.ts +0 -81
- package/src/vue/forms/types/PersistedForm.ts +0 -6
- package/src/vue/forms/validation/ValidationMode.enum.ts +0 -14
- package/src/vue/forms/validation/index.ts +0 -15
- package/src/vue/forms/validation/rules/BaseRule.ts +0 -7
- package/src/vue/forms/validation/rules/ConfirmedRule.ts +0 -39
- package/src/vue/forms/validation/rules/EmailRule.ts +0 -23
- package/src/vue/forms/validation/rules/JsonRule.ts +0 -28
- package/src/vue/forms/validation/rules/MinRule.ts +0 -61
- package/src/vue/forms/validation/rules/RequiredRule.ts +0 -19
- package/src/vue/forms/validation/rules/UrlRule.ts +0 -24
- package/src/vue/forms/validation/types/ValidationRules.ts +0 -15
- package/src/vue/index.ts +0 -14
- package/src/vue/requests/factories/VueRequestLoaderFactory.ts +0 -10
- package/src/vue/requests/loaders/VueRequestBatchLoader.ts +0 -35
- package/src/vue/requests/loaders/VueRequestLoader.ts +0 -18
- package/src/vue/router/routeResourceBinding/RouteResourceBoundView.ts +0 -145
- package/src/vue/router/routeResourceBinding/RouteResourceRequestResolver.ts +0 -11
- package/src/vue/router/routeResourceBinding/defineRoute.ts +0 -59
- package/src/vue/router/routeResourceBinding/index.ts +0 -11
- package/src/vue/router/routeResourceBinding/installRouteInjection.ts +0 -164
- package/src/vue/router/routeResourceBinding/types.ts +0 -53
- package/src/vue/router/routeResourceBinding/useRouteResource.ts +0 -24
- package/src/vue/state/State.ts +0 -380
- package/src/vue/state/index.ts +0 -3
- package/tests/service/bulkRequests/BulkRequestSender.test.ts +0 -76
- package/tests/service/bulkRequests/BulkRequestWrapper.test.ts +0 -51
- package/tests/service/helpers/mergeDeep.test.ts +0 -53
- package/tests/service/laravel/pagination/dataDrivers/RequestDriver.test.ts +0 -84
- package/tests/service/laravel/requests/JsonBaseRequest.test.ts +0 -43
- package/tests/service/laravel/requests/PaginationJsonBaseRequest.test.ts +0 -58
- package/tests/service/laravel/requests/responses/JsonResponse.test.ts +0 -59
- package/tests/service/laravel/requests/responses/PaginationResponse.test.ts +0 -127
- package/tests/service/pagination/BasePaginator.test.ts +0 -100
- package/tests/service/pagination/InfiniteScroller.test.ts +0 -101
- package/tests/service/pagination/PageAwarePaginator.test.ts +0 -133
- package/tests/service/pagination/StatePaginator.test.ts +0 -76
- package/tests/service/pagination/VueViewDrivers.test.ts +0 -46
- package/tests/service/pagination/dtos/PaginationDataDto.test.ts +0 -35
- package/tests/service/pagination/dtos/StatePaginationDataDto.test.ts +0 -14
- package/tests/service/pagination/factories/VuePaginationDriverFactory.test.ts +0 -32
- package/tests/service/pagination/frontendDrivers/VuePaginationDriver.test.ts +0 -66
- package/tests/service/persistenceDrivers/PersistenceDrivers.test.ts +0 -56
- package/tests/service/requests/BaseRequest.test.ts +0 -250
- package/tests/service/requests/BodiesAndFactories.test.ts +0 -52
- package/tests/service/requests/Enums.test.ts +0 -20
- package/tests/service/requests/ErrorHandler.test.ts +0 -188
- package/tests/service/requests/FormDataBody.test.ts +0 -63
- package/tests/service/requests/RequestErrorRouter.test.ts +0 -44
- package/tests/service/requests/Responses.test.ts +0 -83
- package/tests/service/requests/exceptions/Exceptions.test.ts +0 -43
- package/tests/service/requests/fetch/FetchDriver.test.ts +0 -94
- package/tests/service/requests/fetch/FetchResponse.test.ts +0 -21
- package/tests/service/requests/xhr/XMLHttpRequestDriver.test.ts +0 -197
- package/tests/service/support/DeferredPromise.test.ts +0 -40
- package/tests/service/support/helpers.test.ts +0 -37
- package/tests/vue/composables/useConfirmDialog.test.ts +0 -77
- package/tests/vue/composables/useGlobalCheckbox.test.ts +0 -126
- package/tests/vue/composables/useIsEmpty.test.ts +0 -18
- package/tests/vue/composables/useIsOpen.test.ts +0 -25
- package/tests/vue/composables/useIsOpenFromVar.test.ts +0 -22
- package/tests/vue/composables/useModelWrapper.test.ts +0 -30
- package/tests/vue/composables/useOnOpen.test.ts +0 -26
- package/tests/vue/forms/BaseForm.behavior.test.ts +0 -98
- package/tests/vue/forms/BaseForm.transformers.test.ts +0 -109
- package/tests/vue/forms/PropertyAwareArray.test.ts +0 -30
- package/tests/vue/forms/validation/ValidationRules.test.ts +0 -79
- package/tests/vue/requests/VueRequestLoaders.test.ts +0 -48
- package/tests/vue/router/routeResourceBinding/RouteResourceBoundView.test.ts +0 -344
- package/tests/vue/router/routeResourceBinding/RouteResourceUtils.test.ts +0 -70
- package/tests/vue/router/routeResourceBinding/installRouteInjection.test.ts +0 -450
- package/tests/vue/state/State.test.ts +0 -151
- package/tsconfig.json +0 -114
- package/vite.config.ts +0 -34
- package/vitest.config.ts +0 -23
|
@@ -1,1192 +0,0 @@
|
|
|
1
|
-
import { reactive, computed, toRaw, type ComputedRef, type WritableComputedRef, watch } from 'vue'
|
|
2
|
-
import { camelCase, upperFirst, cloneDeep, isEqual } from 'lodash-es'
|
|
3
|
-
import isEqualWith from 'lodash-es/isEqualWith'
|
|
4
|
-
import { type PersistedForm } from './types/PersistedForm'
|
|
5
|
-
import { NonPersistentDriver } from '../../persistenceDrivers/NonPersistentDriver'
|
|
6
|
-
import { type PersistenceDriver } from '../../persistenceDrivers/types/PersistenceDriver'
|
|
7
|
-
import { PropertyAwareArray } from './PropertyAwareArray'
|
|
8
|
-
import { ValidationMode, type ValidationRules } from './validation'
|
|
9
|
-
|
|
10
|
-
type DirtyObject = Record<string, boolean>
|
|
11
|
-
type DirtyArray = Array<boolean | DirtyObject>
|
|
12
|
-
type DirtyState = boolean | DirtyObject | DirtyArray
|
|
13
|
-
type DirtyMap<FormBody extends object> = Record<keyof FormBody, DirtyState>
|
|
14
|
-
|
|
15
|
-
type ErrorMessages = string[]
|
|
16
|
-
interface ErrorObject {
|
|
17
|
-
[key: string]: FieldErrors
|
|
18
|
-
}
|
|
19
|
-
type ErrorArray = Array<ErrorObject>
|
|
20
|
-
type FieldErrors = ErrorMessages | ErrorObject | ErrorArray
|
|
21
|
-
type ErrorBag = Record<string, FieldErrors>
|
|
22
|
-
|
|
23
|
-
type FieldProperty<T> = {
|
|
24
|
-
model: WritableComputedRef<T>
|
|
25
|
-
errors: ErrorMessages
|
|
26
|
-
dirty: boolean
|
|
27
|
-
touched: boolean
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type PropertyAwareToRaw<T> =
|
|
31
|
-
T extends Array<infer U>
|
|
32
|
-
? Array<PropertyAwareToRaw<U>>
|
|
33
|
-
: T extends { model: { value: infer V } }
|
|
34
|
-
? V
|
|
35
|
-
: T extends object
|
|
36
|
-
? { [K in keyof T]: PropertyAwareToRaw<T[K]> }
|
|
37
|
-
: T
|
|
38
|
-
|
|
39
|
-
type FormKey<FormBody extends object> = Extract<keyof FormBody, string>
|
|
40
|
-
type RequestKey<RequestBody extends object> = Extract<keyof RequestBody, string>
|
|
41
|
-
type ArrayItem<T> = T extends Array<infer Item> ? Item : never
|
|
42
|
-
type PropertyAwareInput<T> = T extends PropertyAwareArray<infer Item> ? Array<Item> | PropertyAwareArray<Item> : T
|
|
43
|
-
|
|
44
|
-
type FormProperties<FormBody extends object> = {
|
|
45
|
-
[K in keyof FormBody]: FormBody[K] extends PropertyAwareArray<infer Item>
|
|
46
|
-
? Array<Item extends object ? { [P in keyof Item]: FieldProperty<Item[P]> } : { value: FieldProperty<Item> }>
|
|
47
|
-
: FieldProperty<FormBody[K]>
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
51
|
-
return !!value && typeof value === 'object' && !Array.isArray(value)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function isErrorMessages(value: unknown): value is ErrorMessages {
|
|
55
|
-
return Array.isArray(value) && (value.length === 0 || typeof value[0] === 'string')
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function isErrorArray(value: unknown): value is ErrorArray {
|
|
59
|
-
return Array.isArray(value) && value.length > 0 && isRecord(value[0])
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function isErrorObject(value: unknown): value is ErrorObject {
|
|
63
|
-
return isRecord(value)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function propertyAwareToRaw<T>(propertyAwareObject: T): PropertyAwareToRaw<T> {
|
|
67
|
-
if (Array.isArray(propertyAwareObject)) {
|
|
68
|
-
return propertyAwareObject.map((item) => propertyAwareToRaw(item)) as PropertyAwareToRaw<T>
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!isRecord(propertyAwareObject)) {
|
|
72
|
-
return propertyAwareObject as PropertyAwareToRaw<T>
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const result: Record<string, unknown> = {}
|
|
76
|
-
const record = propertyAwareObject
|
|
77
|
-
|
|
78
|
-
for (const key in record) {
|
|
79
|
-
if (!Object.prototype.hasOwnProperty.call(record, key) || key.startsWith('_')) {
|
|
80
|
-
continue
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const value = record[key]
|
|
84
|
-
const modelValue = isRecord(value) ? (value as { model?: { value?: unknown } }).model?.value : undefined
|
|
85
|
-
|
|
86
|
-
if (modelValue !== undefined) {
|
|
87
|
-
result[key] = modelValue
|
|
88
|
-
continue
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (value && typeof value === 'object') {
|
|
92
|
-
result[key] = propertyAwareToRaw(value)
|
|
93
|
-
continue
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
result[key] = value
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return result as PropertyAwareToRaw<T>
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Helper: shallow-merge source object into target. */
|
|
103
|
-
function shallowMerge<T extends object, U extends object>(target: T, source: U): T & U {
|
|
104
|
-
Object.assign(target, source)
|
|
105
|
-
return target as T & U
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** Helper: if both values are arrays, update each element if possible, otherwise replace. */
|
|
109
|
-
function deepMergeArrays<T>(target: T[], source: T[]): T[] {
|
|
110
|
-
if (target.length !== source.length) {
|
|
111
|
-
return source
|
|
112
|
-
}
|
|
113
|
-
return target.map((t, i) => {
|
|
114
|
-
const s = source[i]
|
|
115
|
-
if (s === undefined) {
|
|
116
|
-
return t
|
|
117
|
-
}
|
|
118
|
-
if (t && typeof t === 'object' && s && typeof s === 'object') {
|
|
119
|
-
return shallowMerge({ ...t }, s)
|
|
120
|
-
}
|
|
121
|
-
return s
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Helper: Given the defaults and a state object (or original),
|
|
127
|
-
* for every key where the default is a PropertyAwareArray, rewrap the value if needed.
|
|
128
|
-
*/
|
|
129
|
-
function restorePropertyAwareArrays<FormBody>(defaults: FormBody, state: FormBody): void {
|
|
130
|
-
for (const key in defaults) {
|
|
131
|
-
const defVal = defaults[key]
|
|
132
|
-
if (defVal instanceof PropertyAwareArray) {
|
|
133
|
-
if (!(state[key] instanceof PropertyAwareArray)) {
|
|
134
|
-
const values = Array.isArray(state[key]) ? Array.from(state[key]) : []
|
|
135
|
-
state[key] = new PropertyAwareArray(values) as FormBody[typeof key]
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Compare values while treating PropertyAwareArray as its underlying array.
|
|
143
|
-
* This avoids false negatives when comparing persisted state to defaults.
|
|
144
|
-
*/
|
|
145
|
-
function propertyAwareDeepEqual<T>(a: T, b: T): boolean {
|
|
146
|
-
const getInner = (val: unknown) => {
|
|
147
|
-
if (val instanceof PropertyAwareArray) {
|
|
148
|
-
return val
|
|
149
|
-
}
|
|
150
|
-
return val
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return isEqualWith(a, b, (aValue, bValue) => {
|
|
154
|
-
const normA = getInner(aValue)
|
|
155
|
-
const normB = getInner(bValue)
|
|
156
|
-
if (normA !== aValue || normB !== bValue) {
|
|
157
|
-
return isEqual(normA, normB)
|
|
158
|
-
}
|
|
159
|
-
return undefined // use default comparison
|
|
160
|
-
})
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* A generic base class for forms.
|
|
165
|
-
*
|
|
166
|
-
* @template RequestBody - The final payload shape (what is sent to the server).
|
|
167
|
-
* @template FormBody - The raw form data shape (before mutators are applied).
|
|
168
|
-
*
|
|
169
|
-
* (We assume that for every key in RequestBody there is a corresponding key in FormBody.)
|
|
170
|
-
*/
|
|
171
|
-
export abstract class BaseForm<RequestBody extends object, FormBody extends object> {
|
|
172
|
-
protected readonly state: FormBody
|
|
173
|
-
private readonly dirty: DirtyMap<FormBody>
|
|
174
|
-
private readonly touched: Record<keyof FormBody, boolean>
|
|
175
|
-
private readonly original: FormBody
|
|
176
|
-
private readonly _model: { [K in keyof FormBody]: WritableComputedRef<FormBody[K]> }
|
|
177
|
-
private _errors: ErrorBag = reactive<ErrorBag>({})
|
|
178
|
-
private _hasErrors: ComputedRef<boolean>
|
|
179
|
-
protected append: string[] = []
|
|
180
|
-
protected ignore: string[] = []
|
|
181
|
-
protected errorMap: { [serverKey: string]: string | string[] } = {}
|
|
182
|
-
|
|
183
|
-
protected rules: ValidationRules<FormBody> = {}
|
|
184
|
-
|
|
185
|
-
private fieldDependencies: Map<keyof FormBody, Set<keyof FormBody>> = new Map()
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Returns the persistence driver to use.
|
|
189
|
-
* The default is a NonPersistentDriver.
|
|
190
|
-
* Child classes can override this method to return a different driver.
|
|
191
|
-
*/
|
|
192
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
193
|
-
protected getPersistenceDriver(_suffix: string | undefined): PersistenceDriver {
|
|
194
|
-
return new NonPersistentDriver()
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Helper: recursively computes the dirty state for a value based on the original.
|
|
199
|
-
* For plain arrays we compare the entire array (a single flag), not each element.
|
|
200
|
-
*/
|
|
201
|
-
private computeDirtyState<T>(current: T, original: T): DirtyState {
|
|
202
|
-
if (Array.isArray(current) && Array.isArray(original)) {
|
|
203
|
-
return current.length !== original.length || !isEqual(current, original)
|
|
204
|
-
} else if (current && typeof current === 'object' && original && typeof original === 'object') {
|
|
205
|
-
const dirty: Record<string, boolean> = {}
|
|
206
|
-
for (const key in current) {
|
|
207
|
-
if (Object.prototype.hasOwnProperty.call(current, key)) {
|
|
208
|
-
dirty[key] = !isEqual(current[key], original[key])
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return dirty
|
|
212
|
-
}
|
|
213
|
-
return !isEqual(current, original)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
private initDirtyTouched(defaults: FormBody): {
|
|
217
|
-
dirty: DirtyMap<FormBody>
|
|
218
|
-
touched: Record<keyof FormBody, boolean>
|
|
219
|
-
} {
|
|
220
|
-
const initDirty: Partial<DirtyMap<FormBody>> = {}
|
|
221
|
-
const initTouched: Partial<Record<keyof FormBody, boolean>> = {}
|
|
222
|
-
|
|
223
|
-
for (const key in defaults) {
|
|
224
|
-
const value = defaults[key]
|
|
225
|
-
if (value instanceof PropertyAwareArray) {
|
|
226
|
-
initDirty[key as keyof FormBody] = Array.from(value).map((item) => {
|
|
227
|
-
if (item && typeof item === 'object') {
|
|
228
|
-
const obj: Record<string, boolean> = {}
|
|
229
|
-
for (const k in item) {
|
|
230
|
-
if (Object.prototype.hasOwnProperty.call(item, k)) {
|
|
231
|
-
obj[k] = false
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return obj
|
|
235
|
-
}
|
|
236
|
-
return false
|
|
237
|
-
})
|
|
238
|
-
} else {
|
|
239
|
-
initDirty[key as keyof FormBody] = false
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
initTouched[key as keyof FormBody] = false
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return {
|
|
246
|
-
dirty: reactive(initDirty) as DirtyMap<FormBody>,
|
|
247
|
-
touched: reactive(initTouched) as Record<keyof FormBody, boolean>
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
private replacePropertyAwareArray<K extends keyof FormBody>(key: K, values: Array<ArrayItem<FormBody[K]>>): void {
|
|
252
|
-
const current = this.state[key]
|
|
253
|
-
if (current instanceof PropertyAwareArray) {
|
|
254
|
-
current.length = 0
|
|
255
|
-
values.forEach((item) => current.push(item))
|
|
256
|
-
return
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
this.state[key] = new PropertyAwareArray(values) as FormBody[K]
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
private persistState(driver?: PersistenceDriver): void {
|
|
263
|
-
if (this.options?.persist === false) {
|
|
264
|
-
return
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const persistDriver = driver ?? this.getPersistenceDriver(this.options?.persistSuffix)
|
|
268
|
-
persistDriver.set(this.constructor.name, {
|
|
269
|
-
state: toRaw(this.state),
|
|
270
|
-
original: toRaw(this.original),
|
|
271
|
-
dirty: toRaw(this.dirty),
|
|
272
|
-
touched: toRaw(this.touched)
|
|
273
|
-
} as PersistedForm<FormBody>)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
private markFieldUpdated(key: keyof FormBody, driver?: PersistenceDriver): void {
|
|
277
|
-
this.touched[key] = true
|
|
278
|
-
this.validateField(key)
|
|
279
|
-
this.validateDependentFields(key)
|
|
280
|
-
this.persistState(driver)
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
private updateField<K extends keyof FormBody>(key: K, value: FormBody[K], driver?: PersistenceDriver): void {
|
|
284
|
-
this.state[key] = value
|
|
285
|
-
this.dirty[key] = this.computeDirtyState(value, this.original[key])
|
|
286
|
-
this.markFieldUpdated(key, driver)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Build a map of field dependencies based on the rules
|
|
291
|
-
* This identifies which fields need to be revalidated when another field changes
|
|
292
|
-
*/
|
|
293
|
-
private buildFieldDependencies(): void {
|
|
294
|
-
for (const field in this.rules) {
|
|
295
|
-
if (Object.prototype.hasOwnProperty.call(this.rules, field)) {
|
|
296
|
-
const fieldRules = this.rules[field as keyof FormBody]?.rules || []
|
|
297
|
-
|
|
298
|
-
for (const rule of fieldRules) {
|
|
299
|
-
for (const dependencyField of rule.dependsOn) {
|
|
300
|
-
if (!this.fieldDependencies.has(dependencyField as keyof FormBody)) {
|
|
301
|
-
this.fieldDependencies.set(dependencyField as keyof FormBody, new Set())
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
this.fieldDependencies.get(dependencyField as keyof FormBody)?.add(field as keyof FormBody)
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const bidirectionalFields = rule.getBidirectionalFields?.()
|
|
308
|
-
if (bidirectionalFields && bidirectionalFields.length > 0) {
|
|
309
|
-
for (const bidirectionalField of bidirectionalFields) {
|
|
310
|
-
if (!this.fieldDependencies.has(field as keyof FormBody)) {
|
|
311
|
-
this.fieldDependencies.set(field as keyof FormBody, new Set())
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
this.fieldDependencies.get(field as keyof FormBody)?.add(bidirectionalField)
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Validate fields that depend on the changed field
|
|
324
|
-
*/
|
|
325
|
-
private validateDependentFields(changedField: keyof FormBody): void {
|
|
326
|
-
const dependentFields = this.fieldDependencies.get(changedField)
|
|
327
|
-
|
|
328
|
-
if (dependentFields) {
|
|
329
|
-
const fieldsToValidate = new Set<keyof FormBody>(dependentFields)
|
|
330
|
-
|
|
331
|
-
for (const field of dependentFields) {
|
|
332
|
-
const fieldDeps = this.fieldDependencies.get(field)
|
|
333
|
-
if (fieldDeps && fieldDeps.has(changedField)) {
|
|
334
|
-
fieldsToValidate.add(field)
|
|
335
|
-
fieldsToValidate.add(changedField)
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
for (const field of fieldsToValidate) {
|
|
340
|
-
this.validateField(field, {
|
|
341
|
-
isDependentChange: true,
|
|
342
|
-
isSubmitting: false
|
|
343
|
-
})
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
protected constructor(
|
|
349
|
-
defaults: FormBody,
|
|
350
|
-
protected options?: { persist?: boolean; persistSuffix?: string }
|
|
351
|
-
) {
|
|
352
|
-
const persist = options?.persist !== false
|
|
353
|
-
let initialData: FormBody
|
|
354
|
-
const driver = this.getPersistenceDriver(options?.persistSuffix)
|
|
355
|
-
|
|
356
|
-
if (persist) {
|
|
357
|
-
const persisted = driver.get<PersistedForm<FormBody>>(this.constructor.name)
|
|
358
|
-
if (persisted && propertyAwareDeepEqual(defaults, persisted.original)) {
|
|
359
|
-
initialData = persisted.state
|
|
360
|
-
this.original = cloneDeep(persisted.original)
|
|
361
|
-
this.dirty = reactive(persisted.dirty) as DirtyMap<FormBody>
|
|
362
|
-
this.touched = reactive(persisted.touched || {}) as Record<keyof FormBody, boolean>
|
|
363
|
-
restorePropertyAwareArrays(defaults, initialData)
|
|
364
|
-
restorePropertyAwareArrays(defaults, this.original)
|
|
365
|
-
} else {
|
|
366
|
-
console.log('Discarding persisted data for ' + this.constructor.name + " because it doesn't match the defaults.")
|
|
367
|
-
initialData = defaults
|
|
368
|
-
this.original = cloneDeep(defaults)
|
|
369
|
-
const init = this.initDirtyTouched(defaults)
|
|
370
|
-
this.dirty = init.dirty
|
|
371
|
-
this.touched = init.touched
|
|
372
|
-
driver.remove(this.constructor.name)
|
|
373
|
-
}
|
|
374
|
-
} else {
|
|
375
|
-
initialData = defaults
|
|
376
|
-
this.original = cloneDeep(defaults)
|
|
377
|
-
const init = this.initDirtyTouched(defaults)
|
|
378
|
-
this.dirty = init.dirty
|
|
379
|
-
this.touched = init.touched
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
this.rules = this.defineRules()
|
|
383
|
-
|
|
384
|
-
this.buildFieldDependencies()
|
|
385
|
-
|
|
386
|
-
this.state = reactive(initialData) as FormBody
|
|
387
|
-
this._model = {} as { [K in keyof FormBody]: WritableComputedRef<FormBody[K]> }
|
|
388
|
-
|
|
389
|
-
for (const key in this.state) {
|
|
390
|
-
const value = this.state[key]
|
|
391
|
-
if (value instanceof PropertyAwareArray) {
|
|
392
|
-
this._model[key as keyof FormBody] = computed({
|
|
393
|
-
get: () => this.state[key],
|
|
394
|
-
set: (newVal: PropertyAwareInput<FormBody[typeof key]>) => {
|
|
395
|
-
const next = Array.isArray(newVal) ? Array.from(newVal) : []
|
|
396
|
-
this.replacePropertyAwareArray(key as keyof FormBody, next)
|
|
397
|
-
this.dirty[key as keyof FormBody] = next.map(() => false)
|
|
398
|
-
this.markFieldUpdated(key as keyof FormBody, driver)
|
|
399
|
-
}
|
|
400
|
-
})
|
|
401
|
-
} else {
|
|
402
|
-
this._model[key as keyof FormBody] = computed({
|
|
403
|
-
get: () => this.state[key],
|
|
404
|
-
set: (value: FormBody[typeof key]) => {
|
|
405
|
-
this.updateField(key as keyof FormBody, value, driver)
|
|
406
|
-
}
|
|
407
|
-
})
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
for (const key in this.state) {
|
|
412
|
-
const value = this.state[key]
|
|
413
|
-
if (Array.isArray(value) && !(value instanceof PropertyAwareArray)) {
|
|
414
|
-
watch(
|
|
415
|
-
() => this.state[key],
|
|
416
|
-
(newVal) => {
|
|
417
|
-
this.dirty[key as keyof FormBody] = this.computeDirtyState(newVal, this.original[key])
|
|
418
|
-
this.touched[key as keyof FormBody] = true
|
|
419
|
-
},
|
|
420
|
-
{ deep: true }
|
|
421
|
-
)
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
this._hasErrors = computed(() => {
|
|
426
|
-
for (const field in this._errors) {
|
|
427
|
-
if (Object.prototype.hasOwnProperty.call(this._errors, field)) {
|
|
428
|
-
const fieldErrors = this._errors[field]
|
|
429
|
-
|
|
430
|
-
if (Array.isArray(fieldErrors) && fieldErrors.length > 0) {
|
|
431
|
-
return true
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
if (fieldErrors && typeof fieldErrors === 'object') {
|
|
435
|
-
if (Array.isArray(fieldErrors)) {
|
|
436
|
-
for (const item of fieldErrors) {
|
|
437
|
-
if (item && typeof item === 'object' && Object.keys(item).length > 0) {
|
|
438
|
-
return true
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
} else if (Object.keys(fieldErrors).length > 0) {
|
|
442
|
-
return true
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
return false
|
|
449
|
-
})
|
|
450
|
-
|
|
451
|
-
if (persist) {
|
|
452
|
-
watch(
|
|
453
|
-
() => this.state,
|
|
454
|
-
() => this.persistState(driver),
|
|
455
|
-
{ deep: true, immediate: true }
|
|
456
|
-
)
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
this.validate()
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
protected defineRules(): ValidationRules<FormBody> {
|
|
463
|
-
return {}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
private clearErrors(): void {
|
|
467
|
-
for (const key in this._errors) {
|
|
468
|
-
delete this._errors[key]
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
private getOrCreateErrorArray(key: string): ErrorArray {
|
|
473
|
-
const existing = this._errors[key]
|
|
474
|
-
if (isErrorArray(existing)) {
|
|
475
|
-
return existing
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const next: ErrorArray = []
|
|
479
|
-
this._errors[key] = next
|
|
480
|
-
return next
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
private getOrCreateErrorObject(errors: ErrorArray, index: number): ErrorObject {
|
|
484
|
-
const existing = errors[index]
|
|
485
|
-
if (isErrorObject(existing)) {
|
|
486
|
-
return existing
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
const next: ErrorObject = {}
|
|
490
|
-
errors[index] = next
|
|
491
|
-
return next
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
private getFieldErrors(field: string): ErrorMessages {
|
|
495
|
-
const errors = this._errors[field]
|
|
496
|
-
return isErrorMessages(errors) ? errors : []
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
private getOrCreateFieldErrors(field: string): ErrorMessages {
|
|
500
|
-
const existing = this._errors[field]
|
|
501
|
-
if (isErrorMessages(existing)) {
|
|
502
|
-
return existing
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
const next: ErrorMessages = []
|
|
506
|
-
this._errors[field] = next
|
|
507
|
-
return next
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
private getArrayItemErrors(field: string, index: number): ErrorObject | undefined {
|
|
511
|
-
const errors = this._errors[field]
|
|
512
|
-
if (!isErrorArray(errors)) {
|
|
513
|
-
return undefined
|
|
514
|
-
}
|
|
515
|
-
const item = errors[index]
|
|
516
|
-
return isErrorObject(item) ? item : undefined
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
private getArrayItemFieldErrors(field: string, index: number, innerKey: string): ErrorMessages {
|
|
520
|
-
const itemErrors = this.getArrayItemErrors(field, index)
|
|
521
|
-
if (!itemErrors) {
|
|
522
|
-
return []
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
const fieldErrors = itemErrors[innerKey]
|
|
526
|
-
if (isErrorMessages(fieldErrors)) {
|
|
527
|
-
return fieldErrors
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
if (isErrorObject(fieldErrors)) {
|
|
531
|
-
const nestedErrors = fieldErrors['']
|
|
532
|
-
return isErrorMessages(nestedErrors) ? nestedErrors : []
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
return []
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
private getArrayItemErrorMessages(field: string, index: number): ErrorMessages {
|
|
539
|
-
const errors = this._errors[field]
|
|
540
|
-
if (!Array.isArray(errors)) {
|
|
541
|
-
return []
|
|
542
|
-
}
|
|
543
|
-
const item = errors[index]
|
|
544
|
-
if (isErrorMessages(item)) {
|
|
545
|
-
return item
|
|
546
|
-
}
|
|
547
|
-
if (isErrorObject(item)) {
|
|
548
|
-
const nestedErrors = item['']
|
|
549
|
-
return isErrorMessages(nestedErrors) ? nestedErrors : []
|
|
550
|
-
}
|
|
551
|
-
return []
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
private setArrayDirty(field: keyof FormBody, index: number, value: DirtyState): void {
|
|
555
|
-
const dirtyState = this.dirty[field]
|
|
556
|
-
if (Array.isArray(dirtyState)) {
|
|
557
|
-
dirtyState[index] = this.normalizeItemDirtyState(value)
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
/**
|
|
562
|
-
* Collapse nested array dirty states into a single boolean/object for array entries.
|
|
563
|
-
*/
|
|
564
|
-
private normalizeItemDirtyState(value: DirtyState): boolean | DirtyObject {
|
|
565
|
-
if (!Array.isArray(value)) {
|
|
566
|
-
return value
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
return value.some((entry) => {
|
|
570
|
-
if (typeof entry === 'boolean') {
|
|
571
|
-
return entry
|
|
572
|
-
}
|
|
573
|
-
if (isRecord(entry)) {
|
|
574
|
-
return Object.values(entry).some((item) => item === true)
|
|
575
|
-
}
|
|
576
|
-
return false
|
|
577
|
-
})
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
private getArrayItemDirty(field: keyof FormBody, index: number, innerKey: string): boolean {
|
|
581
|
-
const dirtyState = this.dirty[field]
|
|
582
|
-
if (!Array.isArray(dirtyState)) {
|
|
583
|
-
return false
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
const entry = dirtyState[index]
|
|
587
|
-
if (typeof entry === 'boolean') {
|
|
588
|
-
return entry
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
if (isRecord(entry)) {
|
|
592
|
-
return entry[innerKey] === true
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
return false
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
private getArrayItemDirtyValue(field: keyof FormBody, index: number): boolean {
|
|
599
|
-
const dirtyState = this.dirty[field]
|
|
600
|
-
if (!Array.isArray(dirtyState)) {
|
|
601
|
-
return false
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
const entry = dirtyState[index]
|
|
605
|
-
return typeof entry === 'boolean' ? entry : false
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
/**
|
|
609
|
-
* Map server-side errors (including dot-notation paths) into the form error bag.
|
|
610
|
-
*/
|
|
611
|
-
public fillErrors<ErrorInterface extends Record<string, FieldErrors>>(errorsData: ErrorInterface): void {
|
|
612
|
-
this.clearErrors()
|
|
613
|
-
|
|
614
|
-
for (const serverKey in errorsData) {
|
|
615
|
-
if (Object.prototype.hasOwnProperty.call(errorsData, serverKey)) {
|
|
616
|
-
const errorMessage = errorsData[serverKey]
|
|
617
|
-
if (errorMessage === undefined) {
|
|
618
|
-
continue
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
let targetKeys: string[] = [serverKey]
|
|
622
|
-
|
|
623
|
-
const mapping = this.errorMap?.[serverKey]
|
|
624
|
-
if (mapping) {
|
|
625
|
-
targetKeys = Array.isArray(mapping) ? mapping : [mapping]
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
for (const targetKey of targetKeys) {
|
|
629
|
-
const parts = targetKey.split('.')
|
|
630
|
-
if (parts.length > 1) {
|
|
631
|
-
const topKey = parts[0] ?? ''
|
|
632
|
-
const indexPart = parts[1] ?? ''
|
|
633
|
-
const index = Number.parseInt(indexPart, 10)
|
|
634
|
-
if (!topKey || !Number.isFinite(index)) {
|
|
635
|
-
this._errors[targetKey] = errorMessage
|
|
636
|
-
continue
|
|
637
|
-
}
|
|
638
|
-
const errorSubKey = parts.slice(2).join('.')
|
|
639
|
-
|
|
640
|
-
const errors = this.getOrCreateErrorArray(topKey)
|
|
641
|
-
const errorObject = this.getOrCreateErrorObject(errors, index)
|
|
642
|
-
|
|
643
|
-
if (errorSubKey.length === 0) {
|
|
644
|
-
errorObject[''] = errorMessage
|
|
645
|
-
} else {
|
|
646
|
-
errorObject[errorSubKey] = errorMessage
|
|
647
|
-
}
|
|
648
|
-
} else {
|
|
649
|
-
this._errors[targetKey] = errorMessage
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
/**
|
|
657
|
-
* Mark a field as touched, which indicates user interaction
|
|
658
|
-
* Optionally triggers validation
|
|
659
|
-
* @param field The field to mark as touched
|
|
660
|
-
*/
|
|
661
|
-
public touch(field: keyof FormBody): void {
|
|
662
|
-
this.touched[field] = true
|
|
663
|
-
|
|
664
|
-
const fieldConfig = this.rules[field]
|
|
665
|
-
if (fieldConfig) {
|
|
666
|
-
const mode = fieldConfig.options?.mode ?? ValidationMode.DEFAULT
|
|
667
|
-
|
|
668
|
-
if (mode & ValidationMode.ON_TOUCH) {
|
|
669
|
-
this.validateField(field, {
|
|
670
|
-
isSubmitting: false,
|
|
671
|
-
isDependentChange: false
|
|
672
|
-
})
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
if (this.options?.persist !== false) {
|
|
677
|
-
this.persistState()
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
/**
|
|
682
|
-
* Check if a field has been touched (user interacted with it)
|
|
683
|
-
* @param field The field to check
|
|
684
|
-
* @returns boolean indicating if the field has been touched
|
|
685
|
-
*/
|
|
686
|
-
public isTouched(field: keyof FormBody): boolean {
|
|
687
|
-
return !!this.touched[field]
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
protected validateField(
|
|
691
|
-
field: keyof FormBody,
|
|
692
|
-
context: {
|
|
693
|
-
isDirty?: boolean
|
|
694
|
-
isSubmitting?: boolean
|
|
695
|
-
isDependentChange?: boolean
|
|
696
|
-
isTouched?: boolean
|
|
697
|
-
} = {}
|
|
698
|
-
): void {
|
|
699
|
-
const emptyErrors: ErrorMessages = []
|
|
700
|
-
const errorKey = String(field)
|
|
701
|
-
this._errors[errorKey] = emptyErrors
|
|
702
|
-
|
|
703
|
-
const value = this.state[field]
|
|
704
|
-
|
|
705
|
-
const fieldConfig = this.rules[field]
|
|
706
|
-
if (!fieldConfig?.rules || fieldConfig.rules.length === 0) {
|
|
707
|
-
return // No rules to validate
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
const mode = fieldConfig.options?.mode ?? ValidationMode.DEFAULT
|
|
711
|
-
|
|
712
|
-
const isDirty = context.isDirty !== undefined ? context.isDirty : this.isDirty(field)
|
|
713
|
-
const isTouched = context.isTouched !== undefined ? context.isTouched : this.isTouched(field)
|
|
714
|
-
|
|
715
|
-
const shouldValidate =
|
|
716
|
-
(context.isSubmitting && mode & ValidationMode.ON_SUBMIT) ||
|
|
717
|
-
(isDirty && mode & ValidationMode.ON_DIRTY) ||
|
|
718
|
-
(isTouched && mode & ValidationMode.ON_TOUCH) ||
|
|
719
|
-
mode & ValidationMode.INSTANTLY ||
|
|
720
|
-
(context.isDependentChange && mode & ValidationMode.ON_DEPENDENT_CHANGE)
|
|
721
|
-
|
|
722
|
-
if (shouldValidate) {
|
|
723
|
-
for (const rule of fieldConfig.rules) {
|
|
724
|
-
const isValid = rule.validate(value, this.state)
|
|
725
|
-
if (!isValid) {
|
|
726
|
-
this.getOrCreateFieldErrors(errorKey).push(rule.getMessage())
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
public validate(isSubmitting: boolean = false): boolean {
|
|
733
|
-
let isValid = true
|
|
734
|
-
|
|
735
|
-
for (const key in this._errors) {
|
|
736
|
-
delete this._errors[key]
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
for (const field in this.rules) {
|
|
740
|
-
if (Object.prototype.hasOwnProperty.call(this.rules, field)) {
|
|
741
|
-
this.validateField(field as keyof FormBody, {
|
|
742
|
-
isSubmitting,
|
|
743
|
-
isDependentChange: false,
|
|
744
|
-
isTouched: this.isTouched(field as keyof FormBody)
|
|
745
|
-
})
|
|
746
|
-
|
|
747
|
-
const fieldErrors = this._errors[String(field)]
|
|
748
|
-
if (isErrorMessages(fieldErrors) && fieldErrors.length > 0) {
|
|
749
|
-
isValid = false
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
return isValid
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
public fillState(data: Partial<FormBody>): void {
|
|
758
|
-
const driver = this.getPersistenceDriver(this.options?.persistSuffix)
|
|
759
|
-
for (const key of Object.keys(data) as Array<keyof FormBody>) {
|
|
760
|
-
if (!Object.prototype.hasOwnProperty.call(data, key) || !(key in this.state)) {
|
|
761
|
-
continue
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
const currentVal = this.state[key]
|
|
765
|
-
const newVal = data[key] as FormBody[typeof key] | undefined
|
|
766
|
-
|
|
767
|
-
if (currentVal instanceof PropertyAwareArray) {
|
|
768
|
-
const values = newVal instanceof PropertyAwareArray || Array.isArray(newVal) ? Array.from(newVal) : []
|
|
769
|
-
this.replacePropertyAwareArray(key, values)
|
|
770
|
-
|
|
771
|
-
this.dirty[key] = values.map(() => false)
|
|
772
|
-
this.touched[key] = true
|
|
773
|
-
continue
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
if (Array.isArray(newVal) && Array.isArray(currentVal)) {
|
|
777
|
-
const merged = newVal.length === currentVal.length ? deepMergeArrays(currentVal, newVal) : newVal
|
|
778
|
-
this.state[key] = merged as FormBody[typeof key]
|
|
779
|
-
this.dirty[key] = this.computeDirtyState(this.state[key], this.original[key])
|
|
780
|
-
this.touched[key] = true
|
|
781
|
-
continue
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
if (isRecord(newVal) && isRecord(currentVal)) {
|
|
785
|
-
this.state[key] = shallowMerge({ ...currentVal }, newVal) as FormBody[typeof key]
|
|
786
|
-
this.dirty[key] = this.computeDirtyState(this.state[key], this.original[key])
|
|
787
|
-
this.touched[key] = true
|
|
788
|
-
continue
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
this.state[key] = newVal as FormBody[typeof key]
|
|
792
|
-
this.dirty[key] = this.computeDirtyState(this.state[key], this.original[key])
|
|
793
|
-
this.touched[key] = true
|
|
794
|
-
}
|
|
795
|
-
this.persistState(driver)
|
|
796
|
-
|
|
797
|
-
for (const key in data) {
|
|
798
|
-
if (Object.prototype.hasOwnProperty.call(data, key) && key in this.state) {
|
|
799
|
-
this.validateField(key as keyof FormBody)
|
|
800
|
-
this.validateDependentFields(key as keyof FormBody)
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
private getValueGetter(name: string): ((value: unknown) => unknown) | undefined {
|
|
806
|
-
const candidate = (this as Record<string, unknown>)[name]
|
|
807
|
-
if (typeof candidate !== 'function') {
|
|
808
|
-
return undefined
|
|
809
|
-
}
|
|
810
|
-
return (candidate as (value: unknown) => unknown).bind(this)
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
private getNoArgGetter(name: string): (() => unknown) | undefined {
|
|
814
|
-
const candidate = (this as Record<string, unknown>)[name]
|
|
815
|
-
if (typeof candidate !== 'function') {
|
|
816
|
-
return undefined
|
|
817
|
-
}
|
|
818
|
-
return (candidate as () => unknown).bind(this)
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
private transformValue(value: unknown, parentKey?: string): unknown {
|
|
822
|
-
if (value instanceof Date) {
|
|
823
|
-
return value
|
|
824
|
-
}
|
|
825
|
-
if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
826
|
-
return value
|
|
827
|
-
}
|
|
828
|
-
if (value instanceof PropertyAwareArray) {
|
|
829
|
-
return [...value].map((item) => this.transformValue(item, parentKey))
|
|
830
|
-
}
|
|
831
|
-
if (Array.isArray(value)) {
|
|
832
|
-
return value.map((item) => this.transformValue(item, parentKey))
|
|
833
|
-
} else if (isRecord(value)) {
|
|
834
|
-
const result: Record<string, unknown> = {}
|
|
835
|
-
for (const prop in value) {
|
|
836
|
-
if (parentKey) {
|
|
837
|
-
const compositeMethod = 'get' + upperFirst(parentKey) + upperFirst(camelCase(prop))
|
|
838
|
-
const getter = this.getValueGetter(compositeMethod)
|
|
839
|
-
if (getter) {
|
|
840
|
-
const transformed = getter(value[prop])
|
|
841
|
-
if (transformed !== undefined) {
|
|
842
|
-
result[prop] = transformed
|
|
843
|
-
}
|
|
844
|
-
continue
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
const transformed = this.transformValue(value[prop], parentKey)
|
|
848
|
-
if (transformed !== undefined) {
|
|
849
|
-
result[prop] = transformed
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
return result
|
|
853
|
-
}
|
|
854
|
-
return value
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
/**
|
|
858
|
-
* Build the request payload, applying field/composite/appended getters when present.
|
|
859
|
-
*/
|
|
860
|
-
public buildPayload(): RequestBody {
|
|
861
|
-
const payload = {} as RequestBody
|
|
862
|
-
for (const key of Object.keys(this.state) as Array<FormKey<FormBody> & RequestKey<RequestBody>>) {
|
|
863
|
-
if (this.ignore.includes(key)) {
|
|
864
|
-
continue
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
const value = this.state[key]
|
|
868
|
-
|
|
869
|
-
const getterName = 'get' + upperFirst(camelCase(key))
|
|
870
|
-
const typedKey = key
|
|
871
|
-
const getter = this.getValueGetter(getterName)
|
|
872
|
-
if (getter) {
|
|
873
|
-
const transformed = getter(value)
|
|
874
|
-
if (transformed !== undefined) {
|
|
875
|
-
payload[typedKey] = transformed as RequestBody[typeof typedKey]
|
|
876
|
-
}
|
|
877
|
-
} else {
|
|
878
|
-
const transformed = this.transformValue(value, key)
|
|
879
|
-
if (transformed !== undefined) {
|
|
880
|
-
payload[typedKey] = transformed as RequestBody[typeof typedKey]
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
for (const fieldName of this.append) {
|
|
886
|
-
if (Array.isArray(this.ignore) && this.ignore.includes(fieldName)) {
|
|
887
|
-
console.warn(`Appended field '${fieldName}' is also in ignore list in ${this.constructor.name}. It will be skipped.`)
|
|
888
|
-
continue
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
const getterName = 'get' + upperFirst(camelCase(fieldName))
|
|
892
|
-
const getter = this.getNoArgGetter(getterName)
|
|
893
|
-
if (getter) {
|
|
894
|
-
const transformed = getter()
|
|
895
|
-
if (transformed !== undefined) {
|
|
896
|
-
payload[fieldName as keyof RequestBody] = transformed as RequestBody[keyof RequestBody]
|
|
897
|
-
}
|
|
898
|
-
} else {
|
|
899
|
-
console.warn(`Getter method '${getterName}' not found for appended field '${fieldName}' in ${this.constructor.name}.`)
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
return payload
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
public reset(): void {
|
|
907
|
-
const driver = this.getPersistenceDriver(this.options?.persistSuffix)
|
|
908
|
-
for (const key in this.state) {
|
|
909
|
-
if (this.state[key] instanceof PropertyAwareArray) {
|
|
910
|
-
const originalValue = this.original[key] as PropertyAwareArray
|
|
911
|
-
const values = [...originalValue].map((item) => cloneDeep(item))
|
|
912
|
-
const typedKey = key as keyof FormBody
|
|
913
|
-
this.replacePropertyAwareArray(typedKey, values as Array<ArrayItem<FormBody[typeof typedKey]>>)
|
|
914
|
-
this.dirty[typedKey] = values.map(() => false)
|
|
915
|
-
this.touched[typedKey] = false
|
|
916
|
-
} else if (Array.isArray(this.original[key])) {
|
|
917
|
-
this.state[key] = cloneDeep(this.original[key])
|
|
918
|
-
this.dirty[key as keyof FormBody] = this.computeDirtyState(this.state[key], this.original[key])
|
|
919
|
-
this.touched[key as keyof FormBody] = false
|
|
920
|
-
} else {
|
|
921
|
-
this.state[key] = cloneDeep(this.original[key])
|
|
922
|
-
this.dirty[key as keyof FormBody] = false
|
|
923
|
-
this.touched[key as keyof FormBody] = false
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
for (const key in this._errors) {
|
|
927
|
-
delete this._errors[key]
|
|
928
|
-
}
|
|
929
|
-
this.persistState(driver)
|
|
930
|
-
|
|
931
|
-
this.validate()
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
protected addToArrayProperty<K extends keyof FormBody>(property: K, newElement: ArrayItem<FormBody[K]>): void {
|
|
935
|
-
const driver = this.getPersistenceDriver(this.options?.persistSuffix)
|
|
936
|
-
const arr = this.state[property]
|
|
937
|
-
if (arr instanceof PropertyAwareArray) {
|
|
938
|
-
arr.push(newElement)
|
|
939
|
-
this.touched[property] = true
|
|
940
|
-
this.persistState(driver)
|
|
941
|
-
|
|
942
|
-
return
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
if (!Array.isArray(arr)) {
|
|
946
|
-
throw new Error(`Property "${String(property)}" is not an array.`)
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
arr.push(newElement)
|
|
950
|
-
this.dirty[property] = this.computeDirtyState(arr, this.original[property])
|
|
951
|
-
this.touched[property] = true
|
|
952
|
-
this.persistState(driver)
|
|
953
|
-
|
|
954
|
-
this.validateField(property)
|
|
955
|
-
this.validateDependentFields(property)
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
protected removeArrayItem<K extends keyof FormBody>(arrayIndex: K, filter: (item: ArrayItem<FormBody[K]>) => boolean): void {
|
|
959
|
-
const current = this.state[arrayIndex]
|
|
960
|
-
if (current instanceof PropertyAwareArray) {
|
|
961
|
-
const filtered = [...current].filter(filter)
|
|
962
|
-
current.length = 0
|
|
963
|
-
filtered.forEach((item) => current.push(item))
|
|
964
|
-
} else if (Array.isArray(current)) {
|
|
965
|
-
this.state[arrayIndex] = current.filter(filter) as FormBody[K]
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
this.touched[arrayIndex] = true
|
|
969
|
-
|
|
970
|
-
this.validateField(arrayIndex)
|
|
971
|
-
this.validateDependentFields(arrayIndex)
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
protected resetArrayCounter(arrayIndex: keyof FormBody, counterIndex: string): void {
|
|
975
|
-
let count = 1
|
|
976
|
-
const current = this.state[arrayIndex]
|
|
977
|
-
if (current instanceof PropertyAwareArray) {
|
|
978
|
-
;[...current].forEach((item): void => {
|
|
979
|
-
if (isRecord(item)) {
|
|
980
|
-
item[counterIndex] = count
|
|
981
|
-
count++
|
|
982
|
-
}
|
|
983
|
-
})
|
|
984
|
-
} else if (Array.isArray(current)) {
|
|
985
|
-
current.forEach((item): void => {
|
|
986
|
-
if (isRecord(item)) {
|
|
987
|
-
item[counterIndex] = count
|
|
988
|
-
count++
|
|
989
|
-
}
|
|
990
|
-
})
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
this.touched[arrayIndex as keyof FormBody] = true
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
public get properties(): FormProperties<FormBody> {
|
|
997
|
-
const props: Partial<FormProperties<FormBody>> = {}
|
|
998
|
-
for (const key of Object.keys(this.state) as Array<FormKey<FormBody>>) {
|
|
999
|
-
const value = this.state[key]
|
|
1000
|
-
if (value instanceof PropertyAwareArray) {
|
|
1001
|
-
const arrayProps = [...value].map((item, index) => {
|
|
1002
|
-
if (isRecord(item)) {
|
|
1003
|
-
const elementProps: Record<string, FieldProperty<unknown>> = {}
|
|
1004
|
-
for (const innerKey of Object.keys(item)) {
|
|
1005
|
-
elementProps[innerKey] = {
|
|
1006
|
-
model: computed({
|
|
1007
|
-
get: () => {
|
|
1008
|
-
const current = value[index]
|
|
1009
|
-
return isRecord(current) ? current[innerKey] : undefined
|
|
1010
|
-
},
|
|
1011
|
-
set: (newVal) => {
|
|
1012
|
-
const current = value[index]
|
|
1013
|
-
if (isRecord(current)) {
|
|
1014
|
-
current[innerKey] = newVal
|
|
1015
|
-
}
|
|
1016
|
-
const updatedElement = value[index]
|
|
1017
|
-
const originalElement = (this.original[key] as PropertyAwareArray)[index]
|
|
1018
|
-
this.setArrayDirty(key, index, this.computeDirtyState(updatedElement, originalElement))
|
|
1019
|
-
this.touched[key] = true
|
|
1020
|
-
|
|
1021
|
-
this.validateField(key)
|
|
1022
|
-
this.validateDependentFields(key)
|
|
1023
|
-
}
|
|
1024
|
-
}),
|
|
1025
|
-
errors: this.getArrayItemFieldErrors(key, index, innerKey),
|
|
1026
|
-
dirty: this.getArrayItemDirty(key, index, innerKey),
|
|
1027
|
-
touched: this.touched[key] || false
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
return elementProps
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
return {
|
|
1034
|
-
value: {
|
|
1035
|
-
model: computed({
|
|
1036
|
-
get: () => value[index],
|
|
1037
|
-
set: (newVal) => {
|
|
1038
|
-
value[index] = newVal as ArrayItem<FormBody[typeof key]>
|
|
1039
|
-
const updatedValue = value[index]
|
|
1040
|
-
const originalValue = (this.original[key] as PropertyAwareArray)[index]
|
|
1041
|
-
this.setArrayDirty(key, index, this.computeDirtyState(updatedValue, originalValue))
|
|
1042
|
-
this.touched[key] = true
|
|
1043
|
-
|
|
1044
|
-
this.validateField(key)
|
|
1045
|
-
this.validateDependentFields(key)
|
|
1046
|
-
}
|
|
1047
|
-
}),
|
|
1048
|
-
errors: this.getArrayItemErrorMessages(key, index),
|
|
1049
|
-
dirty: this.getArrayItemDirtyValue(key, index),
|
|
1050
|
-
touched: this.touched[key] || false
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
})
|
|
1054
|
-
|
|
1055
|
-
props[key] = arrayProps as FormProperties<FormBody>[typeof key]
|
|
1056
|
-
continue
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
props[key] = {
|
|
1060
|
-
model: this._model[key],
|
|
1061
|
-
errors: this.getFieldErrors(key),
|
|
1062
|
-
dirty: this.dirty[key] || false,
|
|
1063
|
-
touched: this.touched[key] || false
|
|
1064
|
-
} as FormProperties<FormBody>[typeof key]
|
|
1065
|
-
}
|
|
1066
|
-
return props as FormProperties<FormBody>
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
/**
|
|
1070
|
-
* Checks if the form or a specific field is dirty
|
|
1071
|
-
* @param field Optional field name to check, if not provided checks the entire form
|
|
1072
|
-
* @returns boolean indicating if the form or specified field is dirty
|
|
1073
|
-
*/
|
|
1074
|
-
public isDirty(field?: keyof FormBody): boolean {
|
|
1075
|
-
if (field !== undefined) {
|
|
1076
|
-
const dirtyState = this.dirty[field]
|
|
1077
|
-
|
|
1078
|
-
if (typeof dirtyState === 'boolean') {
|
|
1079
|
-
return dirtyState
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
if (Array.isArray(dirtyState)) {
|
|
1083
|
-
return dirtyState.some((item) => {
|
|
1084
|
-
if (typeof item === 'boolean') {
|
|
1085
|
-
return item
|
|
1086
|
-
}
|
|
1087
|
-
if (item && typeof item === 'object') {
|
|
1088
|
-
return Object.values(item).some((v) => v === true)
|
|
1089
|
-
}
|
|
1090
|
-
return false
|
|
1091
|
-
})
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
if (dirtyState && typeof dirtyState === 'object') {
|
|
1095
|
-
return Object.values(dirtyState).some((v) => v === true)
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
return false
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
for (const key in this.dirty) {
|
|
1102
|
-
const dirtyState = this.dirty[key as keyof FormBody]
|
|
1103
|
-
|
|
1104
|
-
if (typeof dirtyState === 'boolean' && dirtyState) {
|
|
1105
|
-
return true
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
if (Array.isArray(dirtyState)) {
|
|
1109
|
-
for (const item of dirtyState) {
|
|
1110
|
-
if (typeof item === 'boolean' && item) {
|
|
1111
|
-
return true
|
|
1112
|
-
}
|
|
1113
|
-
if (item && typeof item === 'object' && Object.values(item).some((v) => v === true)) {
|
|
1114
|
-
return true
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
if (dirtyState && typeof dirtyState === 'object' && Object.values(dirtyState).some((v) => v === true)) {
|
|
1120
|
-
return true
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
return false
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
/**
|
|
1128
|
-
* Returns whether the form has validation errors
|
|
1129
|
-
* @returns boolean indicating if the form has errors
|
|
1130
|
-
*/
|
|
1131
|
-
public hasErrors(): boolean {
|
|
1132
|
-
return this._hasErrors.value
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
/**
|
|
1136
|
-
* Updates both the state and original value for a given property,
|
|
1137
|
-
* keeping the field in a clean (not dirty) state.
|
|
1138
|
-
* Supports all field types including PropertyAwareArray.
|
|
1139
|
-
*
|
|
1140
|
-
* @param key The property key to update
|
|
1141
|
-
* @param value The new value to set
|
|
1142
|
-
*/
|
|
1143
|
-
public syncValue<K extends keyof FormBody>(key: K, value: FormBody[K]): void {
|
|
1144
|
-
const driver = this.getPersistenceDriver(this.options?.persistSuffix)
|
|
1145
|
-
const currentVal = this.state[key]
|
|
1146
|
-
|
|
1147
|
-
if (currentVal instanceof PropertyAwareArray) {
|
|
1148
|
-
const arr = this.state[key] as PropertyAwareArray
|
|
1149
|
-
const originalArr = this.original[key] as PropertyAwareArray
|
|
1150
|
-
|
|
1151
|
-
arr.length = 0
|
|
1152
|
-
originalArr.length = 0
|
|
1153
|
-
|
|
1154
|
-
if (Array.isArray(value)) {
|
|
1155
|
-
value.forEach((item) => {
|
|
1156
|
-
arr.push(cloneDeep(item))
|
|
1157
|
-
originalArr.push(cloneDeep(item))
|
|
1158
|
-
})
|
|
1159
|
-
} else if (value instanceof PropertyAwareArray) {
|
|
1160
|
-
;[...value].forEach((item) => {
|
|
1161
|
-
arr.push(cloneDeep(item))
|
|
1162
|
-
originalArr.push(cloneDeep(item))
|
|
1163
|
-
})
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
this.dirty[key] = Array.from(arr).map(() => false)
|
|
1167
|
-
this.touched[key] = true
|
|
1168
|
-
} else if (Array.isArray(currentVal)) {
|
|
1169
|
-
this.state[key] = cloneDeep(value)
|
|
1170
|
-
this.original[key] = cloneDeep(value)
|
|
1171
|
-
this.dirty[key] = false
|
|
1172
|
-
this.touched[key] = true
|
|
1173
|
-
} else if (typeof currentVal === 'object' && currentVal !== null) {
|
|
1174
|
-
this.state[key] = cloneDeep(value)
|
|
1175
|
-
this.original[key] = cloneDeep(value)
|
|
1176
|
-
this.dirty[key] = false
|
|
1177
|
-
this.touched[key] = true
|
|
1178
|
-
} else {
|
|
1179
|
-
this.state[key] = value
|
|
1180
|
-
this.original[key] = value
|
|
1181
|
-
this.dirty[key] = false
|
|
1182
|
-
this.touched[key] = true
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
if (this.options?.persist !== false) {
|
|
1186
|
-
this.persistState(driver)
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
this.validateField(key)
|
|
1190
|
-
this.validateDependentFields(key)
|
|
1191
|
-
}
|
|
1192
|
-
}
|