@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
|
@@ -0,0 +1,997 @@
|
|
|
1
|
+
import { reactive, computed, toRaw, watch } from 'vue';
|
|
2
|
+
import { camelCase, upperFirst, cloneDeep, isEqual } from 'lodash-es';
|
|
3
|
+
import isEqualWith from 'lodash-es/isEqualWith';
|
|
4
|
+
import { NonPersistentDriver } from '../../persistenceDrivers/NonPersistentDriver';
|
|
5
|
+
import { PropertyAwareArray } from './PropertyAwareArray';
|
|
6
|
+
import { ValidationMode } from './validation';
|
|
7
|
+
function isRecord(value) {
|
|
8
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
function isErrorMessages(value) {
|
|
11
|
+
return Array.isArray(value) && (value.length === 0 || typeof value[0] === 'string');
|
|
12
|
+
}
|
|
13
|
+
function isErrorArray(value) {
|
|
14
|
+
return Array.isArray(value) && value.length > 0 && isRecord(value[0]);
|
|
15
|
+
}
|
|
16
|
+
function isErrorObject(value) {
|
|
17
|
+
return isRecord(value);
|
|
18
|
+
}
|
|
19
|
+
export function propertyAwareToRaw(propertyAwareObject) {
|
|
20
|
+
var _a;
|
|
21
|
+
if (Array.isArray(propertyAwareObject)) {
|
|
22
|
+
return propertyAwareObject.map((item) => propertyAwareToRaw(item));
|
|
23
|
+
}
|
|
24
|
+
if (!isRecord(propertyAwareObject)) {
|
|
25
|
+
return propertyAwareObject;
|
|
26
|
+
}
|
|
27
|
+
const result = {};
|
|
28
|
+
const record = propertyAwareObject;
|
|
29
|
+
for (const key in record) {
|
|
30
|
+
if (!Object.prototype.hasOwnProperty.call(record, key) || key.startsWith('_')) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const value = record[key];
|
|
34
|
+
const modelValue = isRecord(value) ? (_a = value.model) === null || _a === void 0 ? void 0 : _a.value : undefined;
|
|
35
|
+
if (modelValue !== undefined) {
|
|
36
|
+
result[key] = modelValue;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (value && typeof value === 'object') {
|
|
40
|
+
result[key] = propertyAwareToRaw(value);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
result[key] = value;
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
/** Helper: shallow-merge source object into target. */
|
|
48
|
+
function shallowMerge(target, source) {
|
|
49
|
+
Object.assign(target, source);
|
|
50
|
+
return target;
|
|
51
|
+
}
|
|
52
|
+
/** Helper: if both values are arrays, update each element if possible, otherwise replace. */
|
|
53
|
+
function deepMergeArrays(target, source) {
|
|
54
|
+
if (target.length !== source.length) {
|
|
55
|
+
return source;
|
|
56
|
+
}
|
|
57
|
+
return target.map((t, i) => {
|
|
58
|
+
const s = source[i];
|
|
59
|
+
if (s === undefined) {
|
|
60
|
+
return t;
|
|
61
|
+
}
|
|
62
|
+
if (t && typeof t === 'object' && s && typeof s === 'object') {
|
|
63
|
+
return shallowMerge(Object.assign({}, t), s);
|
|
64
|
+
}
|
|
65
|
+
return s;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Helper: Given the defaults and a state object (or original),
|
|
70
|
+
* for every key where the default is a PropertyAwareArray, rewrap the value if needed.
|
|
71
|
+
*/
|
|
72
|
+
function restorePropertyAwareArrays(defaults, state) {
|
|
73
|
+
for (const key in defaults) {
|
|
74
|
+
const defVal = defaults[key];
|
|
75
|
+
if (defVal instanceof PropertyAwareArray) {
|
|
76
|
+
if (!(state[key] instanceof PropertyAwareArray)) {
|
|
77
|
+
const values = Array.isArray(state[key]) ? Array.from(state[key]) : [];
|
|
78
|
+
state[key] = new PropertyAwareArray(values);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Compare values while treating PropertyAwareArray as its underlying array.
|
|
85
|
+
* This avoids false negatives when comparing persisted state to defaults.
|
|
86
|
+
*/
|
|
87
|
+
function propertyAwareDeepEqual(a, b) {
|
|
88
|
+
const getInner = (val) => {
|
|
89
|
+
if (val instanceof PropertyAwareArray) {
|
|
90
|
+
return val;
|
|
91
|
+
}
|
|
92
|
+
return val;
|
|
93
|
+
};
|
|
94
|
+
return isEqualWith(a, b, (aValue, bValue) => {
|
|
95
|
+
const normA = getInner(aValue);
|
|
96
|
+
const normB = getInner(bValue);
|
|
97
|
+
if (normA !== aValue || normB !== bValue) {
|
|
98
|
+
return isEqual(normA, normB);
|
|
99
|
+
}
|
|
100
|
+
return undefined; // use default comparison
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A generic base class for forms.
|
|
105
|
+
*
|
|
106
|
+
* @template RequestBody - The final payload shape (what is sent to the server).
|
|
107
|
+
* @template FormBody - The raw form data shape (before mutators are applied).
|
|
108
|
+
*
|
|
109
|
+
* (We assume that for every key in RequestBody there is a corresponding key in FormBody.)
|
|
110
|
+
*/
|
|
111
|
+
export class BaseForm {
|
|
112
|
+
/**
|
|
113
|
+
* Returns the persistence driver to use.
|
|
114
|
+
* The default is a NonPersistentDriver.
|
|
115
|
+
* Child classes can override this method to return a different driver.
|
|
116
|
+
*/
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
118
|
+
getPersistenceDriver(_suffix) {
|
|
119
|
+
return new NonPersistentDriver();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Helper: recursively computes the dirty state for a value based on the original.
|
|
123
|
+
* For plain arrays we compare the entire array (a single flag), not each element.
|
|
124
|
+
*/
|
|
125
|
+
computeDirtyState(current, original) {
|
|
126
|
+
if (Array.isArray(current) && Array.isArray(original)) {
|
|
127
|
+
return current.length !== original.length || !isEqual(current, original);
|
|
128
|
+
}
|
|
129
|
+
else if (current && typeof current === 'object' && original && typeof original === 'object') {
|
|
130
|
+
const dirty = {};
|
|
131
|
+
for (const key in current) {
|
|
132
|
+
if (Object.prototype.hasOwnProperty.call(current, key)) {
|
|
133
|
+
dirty[key] = !isEqual(current[key], original[key]);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return dirty;
|
|
137
|
+
}
|
|
138
|
+
return !isEqual(current, original);
|
|
139
|
+
}
|
|
140
|
+
initDirtyTouched(defaults) {
|
|
141
|
+
const initDirty = {};
|
|
142
|
+
const initTouched = {};
|
|
143
|
+
for (const key in defaults) {
|
|
144
|
+
const value = defaults[key];
|
|
145
|
+
if (value instanceof PropertyAwareArray) {
|
|
146
|
+
initDirty[key] = Array.from(value).map((item) => {
|
|
147
|
+
if (item && typeof item === 'object') {
|
|
148
|
+
const obj = {};
|
|
149
|
+
for (const k in item) {
|
|
150
|
+
if (Object.prototype.hasOwnProperty.call(item, k)) {
|
|
151
|
+
obj[k] = false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return obj;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
initDirty[key] = false;
|
|
161
|
+
}
|
|
162
|
+
initTouched[key] = false;
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
dirty: reactive(initDirty),
|
|
166
|
+
touched: reactive(initTouched)
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
replacePropertyAwareArray(key, values) {
|
|
170
|
+
const current = this.state[key];
|
|
171
|
+
if (current instanceof PropertyAwareArray) {
|
|
172
|
+
current.length = 0;
|
|
173
|
+
values.forEach((item) => current.push(item));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.state[key] = new PropertyAwareArray(values);
|
|
177
|
+
}
|
|
178
|
+
persistState(driver) {
|
|
179
|
+
var _a, _b;
|
|
180
|
+
if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.persist) === false) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const persistDriver = driver !== null && driver !== void 0 ? driver : this.getPersistenceDriver((_b = this.options) === null || _b === void 0 ? void 0 : _b.persistSuffix);
|
|
184
|
+
persistDriver.set(this.constructor.name, {
|
|
185
|
+
state: toRaw(this.state),
|
|
186
|
+
original: toRaw(this.original),
|
|
187
|
+
dirty: toRaw(this.dirty),
|
|
188
|
+
touched: toRaw(this.touched)
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
markFieldUpdated(key, driver) {
|
|
192
|
+
this.touched[key] = true;
|
|
193
|
+
this.validateField(key);
|
|
194
|
+
this.validateDependentFields(key);
|
|
195
|
+
this.persistState(driver);
|
|
196
|
+
}
|
|
197
|
+
updateField(key, value, driver) {
|
|
198
|
+
this.state[key] = value;
|
|
199
|
+
this.dirty[key] = this.computeDirtyState(value, this.original[key]);
|
|
200
|
+
this.markFieldUpdated(key, driver);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Build a map of field dependencies based on the rules
|
|
204
|
+
* This identifies which fields need to be revalidated when another field changes
|
|
205
|
+
*/
|
|
206
|
+
buildFieldDependencies() {
|
|
207
|
+
var _a, _b, _c, _d;
|
|
208
|
+
for (const field in this.rules) {
|
|
209
|
+
if (Object.prototype.hasOwnProperty.call(this.rules, field)) {
|
|
210
|
+
const fieldRules = ((_a = this.rules[field]) === null || _a === void 0 ? void 0 : _a.rules) || [];
|
|
211
|
+
for (const rule of fieldRules) {
|
|
212
|
+
for (const dependencyField of rule.dependsOn) {
|
|
213
|
+
if (!this.fieldDependencies.has(dependencyField)) {
|
|
214
|
+
this.fieldDependencies.set(dependencyField, new Set());
|
|
215
|
+
}
|
|
216
|
+
(_b = this.fieldDependencies.get(dependencyField)) === null || _b === void 0 ? void 0 : _b.add(field);
|
|
217
|
+
}
|
|
218
|
+
const bidirectionalFields = (_c = rule.getBidirectionalFields) === null || _c === void 0 ? void 0 : _c.call(rule);
|
|
219
|
+
if (bidirectionalFields && bidirectionalFields.length > 0) {
|
|
220
|
+
for (const bidirectionalField of bidirectionalFields) {
|
|
221
|
+
if (!this.fieldDependencies.has(field)) {
|
|
222
|
+
this.fieldDependencies.set(field, new Set());
|
|
223
|
+
}
|
|
224
|
+
(_d = this.fieldDependencies.get(field)) === null || _d === void 0 ? void 0 : _d.add(bidirectionalField);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Validate fields that depend on the changed field
|
|
233
|
+
*/
|
|
234
|
+
validateDependentFields(changedField) {
|
|
235
|
+
const dependentFields = this.fieldDependencies.get(changedField);
|
|
236
|
+
if (dependentFields) {
|
|
237
|
+
const fieldsToValidate = new Set(dependentFields);
|
|
238
|
+
for (const field of dependentFields) {
|
|
239
|
+
const fieldDeps = this.fieldDependencies.get(field);
|
|
240
|
+
if (fieldDeps && fieldDeps.has(changedField)) {
|
|
241
|
+
fieldsToValidate.add(field);
|
|
242
|
+
fieldsToValidate.add(changedField);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
for (const field of fieldsToValidate) {
|
|
246
|
+
this.validateField(field, {
|
|
247
|
+
isDependentChange: true,
|
|
248
|
+
isSubmitting: false
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
constructor(defaults, options) {
|
|
254
|
+
this.options = options;
|
|
255
|
+
this._errors = reactive({});
|
|
256
|
+
this.append = [];
|
|
257
|
+
this.ignore = [];
|
|
258
|
+
this.errorMap = {};
|
|
259
|
+
this.rules = {};
|
|
260
|
+
this.fieldDependencies = new Map();
|
|
261
|
+
const persist = (options === null || options === void 0 ? void 0 : options.persist) !== false;
|
|
262
|
+
let initialData;
|
|
263
|
+
const driver = this.getPersistenceDriver(options === null || options === void 0 ? void 0 : options.persistSuffix);
|
|
264
|
+
if (persist) {
|
|
265
|
+
const persisted = driver.get(this.constructor.name);
|
|
266
|
+
if (persisted && propertyAwareDeepEqual(defaults, persisted.original)) {
|
|
267
|
+
initialData = persisted.state;
|
|
268
|
+
this.original = cloneDeep(persisted.original);
|
|
269
|
+
this.dirty = reactive(persisted.dirty);
|
|
270
|
+
this.touched = reactive(persisted.touched || {});
|
|
271
|
+
restorePropertyAwareArrays(defaults, initialData);
|
|
272
|
+
restorePropertyAwareArrays(defaults, this.original);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
console.log('Discarding persisted data for ' + this.constructor.name + " because it doesn't match the defaults.");
|
|
276
|
+
initialData = defaults;
|
|
277
|
+
this.original = cloneDeep(defaults);
|
|
278
|
+
const init = this.initDirtyTouched(defaults);
|
|
279
|
+
this.dirty = init.dirty;
|
|
280
|
+
this.touched = init.touched;
|
|
281
|
+
driver.remove(this.constructor.name);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
initialData = defaults;
|
|
286
|
+
this.original = cloneDeep(defaults);
|
|
287
|
+
const init = this.initDirtyTouched(defaults);
|
|
288
|
+
this.dirty = init.dirty;
|
|
289
|
+
this.touched = init.touched;
|
|
290
|
+
}
|
|
291
|
+
this.rules = this.defineRules();
|
|
292
|
+
this.buildFieldDependencies();
|
|
293
|
+
this.state = reactive(initialData);
|
|
294
|
+
this._model = {};
|
|
295
|
+
for (const key in this.state) {
|
|
296
|
+
const value = this.state[key];
|
|
297
|
+
if (value instanceof PropertyAwareArray) {
|
|
298
|
+
this._model[key] = computed({
|
|
299
|
+
get: () => this.state[key],
|
|
300
|
+
set: (newVal) => {
|
|
301
|
+
const next = Array.isArray(newVal) ? Array.from(newVal) : [];
|
|
302
|
+
this.replacePropertyAwareArray(key, next);
|
|
303
|
+
this.dirty[key] = next.map(() => false);
|
|
304
|
+
this.markFieldUpdated(key, driver);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
this._model[key] = computed({
|
|
310
|
+
get: () => this.state[key],
|
|
311
|
+
set: (value) => {
|
|
312
|
+
this.updateField(key, value, driver);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
for (const key in this.state) {
|
|
318
|
+
const value = this.state[key];
|
|
319
|
+
if (Array.isArray(value) && !(value instanceof PropertyAwareArray)) {
|
|
320
|
+
watch(() => this.state[key], (newVal) => {
|
|
321
|
+
this.dirty[key] = this.computeDirtyState(newVal, this.original[key]);
|
|
322
|
+
this.touched[key] = true;
|
|
323
|
+
}, { deep: true });
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
this._hasErrors = computed(() => {
|
|
327
|
+
for (const field in this._errors) {
|
|
328
|
+
if (Object.prototype.hasOwnProperty.call(this._errors, field)) {
|
|
329
|
+
const fieldErrors = this._errors[field];
|
|
330
|
+
if (Array.isArray(fieldErrors) && fieldErrors.length > 0) {
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
if (fieldErrors && typeof fieldErrors === 'object') {
|
|
334
|
+
if (Array.isArray(fieldErrors)) {
|
|
335
|
+
for (const item of fieldErrors) {
|
|
336
|
+
if (item && typeof item === 'object' && Object.keys(item).length > 0) {
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else if (Object.keys(fieldErrors).length > 0) {
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return false;
|
|
348
|
+
});
|
|
349
|
+
if (persist) {
|
|
350
|
+
watch(() => this.state, () => this.persistState(driver), { deep: true, immediate: true });
|
|
351
|
+
}
|
|
352
|
+
this.validate();
|
|
353
|
+
}
|
|
354
|
+
defineRules() {
|
|
355
|
+
return {};
|
|
356
|
+
}
|
|
357
|
+
clearErrors() {
|
|
358
|
+
for (const key in this._errors) {
|
|
359
|
+
delete this._errors[key];
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
getOrCreateErrorArray(key) {
|
|
363
|
+
const existing = this._errors[key];
|
|
364
|
+
if (isErrorArray(existing)) {
|
|
365
|
+
return existing;
|
|
366
|
+
}
|
|
367
|
+
const next = [];
|
|
368
|
+
this._errors[key] = next;
|
|
369
|
+
return next;
|
|
370
|
+
}
|
|
371
|
+
getOrCreateErrorObject(errors, index) {
|
|
372
|
+
const existing = errors[index];
|
|
373
|
+
if (isErrorObject(existing)) {
|
|
374
|
+
return existing;
|
|
375
|
+
}
|
|
376
|
+
const next = {};
|
|
377
|
+
errors[index] = next;
|
|
378
|
+
return next;
|
|
379
|
+
}
|
|
380
|
+
getFieldErrors(field) {
|
|
381
|
+
const errors = this._errors[field];
|
|
382
|
+
return isErrorMessages(errors) ? errors : [];
|
|
383
|
+
}
|
|
384
|
+
getOrCreateFieldErrors(field) {
|
|
385
|
+
const existing = this._errors[field];
|
|
386
|
+
if (isErrorMessages(existing)) {
|
|
387
|
+
return existing;
|
|
388
|
+
}
|
|
389
|
+
const next = [];
|
|
390
|
+
this._errors[field] = next;
|
|
391
|
+
return next;
|
|
392
|
+
}
|
|
393
|
+
getArrayItemErrors(field, index) {
|
|
394
|
+
const errors = this._errors[field];
|
|
395
|
+
if (!isErrorArray(errors)) {
|
|
396
|
+
return undefined;
|
|
397
|
+
}
|
|
398
|
+
const item = errors[index];
|
|
399
|
+
return isErrorObject(item) ? item : undefined;
|
|
400
|
+
}
|
|
401
|
+
getArrayItemFieldErrors(field, index, innerKey) {
|
|
402
|
+
const itemErrors = this.getArrayItemErrors(field, index);
|
|
403
|
+
if (!itemErrors) {
|
|
404
|
+
return [];
|
|
405
|
+
}
|
|
406
|
+
const fieldErrors = itemErrors[innerKey];
|
|
407
|
+
if (isErrorMessages(fieldErrors)) {
|
|
408
|
+
return fieldErrors;
|
|
409
|
+
}
|
|
410
|
+
if (isErrorObject(fieldErrors)) {
|
|
411
|
+
const nestedErrors = fieldErrors[''];
|
|
412
|
+
return isErrorMessages(nestedErrors) ? nestedErrors : [];
|
|
413
|
+
}
|
|
414
|
+
return [];
|
|
415
|
+
}
|
|
416
|
+
getArrayItemErrorMessages(field, index) {
|
|
417
|
+
const errors = this._errors[field];
|
|
418
|
+
if (!Array.isArray(errors)) {
|
|
419
|
+
return [];
|
|
420
|
+
}
|
|
421
|
+
const item = errors[index];
|
|
422
|
+
if (isErrorMessages(item)) {
|
|
423
|
+
return item;
|
|
424
|
+
}
|
|
425
|
+
if (isErrorObject(item)) {
|
|
426
|
+
const nestedErrors = item[''];
|
|
427
|
+
return isErrorMessages(nestedErrors) ? nestedErrors : [];
|
|
428
|
+
}
|
|
429
|
+
return [];
|
|
430
|
+
}
|
|
431
|
+
setArrayDirty(field, index, value) {
|
|
432
|
+
const dirtyState = this.dirty[field];
|
|
433
|
+
if (Array.isArray(dirtyState)) {
|
|
434
|
+
dirtyState[index] = this.normalizeItemDirtyState(value);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Collapse nested array dirty states into a single boolean/object for array entries.
|
|
439
|
+
*/
|
|
440
|
+
normalizeItemDirtyState(value) {
|
|
441
|
+
if (!Array.isArray(value)) {
|
|
442
|
+
return value;
|
|
443
|
+
}
|
|
444
|
+
return value.some((entry) => {
|
|
445
|
+
if (typeof entry === 'boolean') {
|
|
446
|
+
return entry;
|
|
447
|
+
}
|
|
448
|
+
if (isRecord(entry)) {
|
|
449
|
+
return Object.values(entry).some((item) => item === true);
|
|
450
|
+
}
|
|
451
|
+
return false;
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
getArrayItemDirty(field, index, innerKey) {
|
|
455
|
+
const dirtyState = this.dirty[field];
|
|
456
|
+
if (!Array.isArray(dirtyState)) {
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
const entry = dirtyState[index];
|
|
460
|
+
if (typeof entry === 'boolean') {
|
|
461
|
+
return entry;
|
|
462
|
+
}
|
|
463
|
+
if (isRecord(entry)) {
|
|
464
|
+
return entry[innerKey] === true;
|
|
465
|
+
}
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
getArrayItemDirtyValue(field, index) {
|
|
469
|
+
const dirtyState = this.dirty[field];
|
|
470
|
+
if (!Array.isArray(dirtyState)) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
const entry = dirtyState[index];
|
|
474
|
+
return typeof entry === 'boolean' ? entry : false;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Map server-side errors (including dot-notation paths) into the form error bag.
|
|
478
|
+
*/
|
|
479
|
+
fillErrors(errorsData) {
|
|
480
|
+
var _a, _b, _c;
|
|
481
|
+
this.clearErrors();
|
|
482
|
+
for (const serverKey in errorsData) {
|
|
483
|
+
if (Object.prototype.hasOwnProperty.call(errorsData, serverKey)) {
|
|
484
|
+
const errorMessage = errorsData[serverKey];
|
|
485
|
+
if (errorMessage === undefined) {
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
let targetKeys = [serverKey];
|
|
489
|
+
const mapping = (_a = this.errorMap) === null || _a === void 0 ? void 0 : _a[serverKey];
|
|
490
|
+
if (mapping) {
|
|
491
|
+
targetKeys = Array.isArray(mapping) ? mapping : [mapping];
|
|
492
|
+
}
|
|
493
|
+
for (const targetKey of targetKeys) {
|
|
494
|
+
const parts = targetKey.split('.');
|
|
495
|
+
if (parts.length > 1) {
|
|
496
|
+
const topKey = (_b = parts[0]) !== null && _b !== void 0 ? _b : '';
|
|
497
|
+
const indexPart = (_c = parts[1]) !== null && _c !== void 0 ? _c : '';
|
|
498
|
+
const index = Number.parseInt(indexPart, 10);
|
|
499
|
+
if (!topKey || !Number.isFinite(index)) {
|
|
500
|
+
this._errors[targetKey] = errorMessage;
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
const errorSubKey = parts.slice(2).join('.');
|
|
504
|
+
const errors = this.getOrCreateErrorArray(topKey);
|
|
505
|
+
const errorObject = this.getOrCreateErrorObject(errors, index);
|
|
506
|
+
if (errorSubKey.length === 0) {
|
|
507
|
+
errorObject[''] = errorMessage;
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
errorObject[errorSubKey] = errorMessage;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
this._errors[targetKey] = errorMessage;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Mark a field as touched, which indicates user interaction
|
|
522
|
+
* Optionally triggers validation
|
|
523
|
+
* @param field The field to mark as touched
|
|
524
|
+
*/
|
|
525
|
+
touch(field) {
|
|
526
|
+
var _a, _b, _c;
|
|
527
|
+
this.touched[field] = true;
|
|
528
|
+
const fieldConfig = this.rules[field];
|
|
529
|
+
if (fieldConfig) {
|
|
530
|
+
const mode = (_b = (_a = fieldConfig.options) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : ValidationMode.DEFAULT;
|
|
531
|
+
if (mode & ValidationMode.ON_TOUCH) {
|
|
532
|
+
this.validateField(field, {
|
|
533
|
+
isSubmitting: false,
|
|
534
|
+
isDependentChange: false
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (((_c = this.options) === null || _c === void 0 ? void 0 : _c.persist) !== false) {
|
|
539
|
+
this.persistState();
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Check if a field has been touched (user interacted with it)
|
|
544
|
+
* @param field The field to check
|
|
545
|
+
* @returns boolean indicating if the field has been touched
|
|
546
|
+
*/
|
|
547
|
+
isTouched(field) {
|
|
548
|
+
return !!this.touched[field];
|
|
549
|
+
}
|
|
550
|
+
validateField(field, context = {}) {
|
|
551
|
+
var _a, _b;
|
|
552
|
+
const emptyErrors = [];
|
|
553
|
+
const errorKey = String(field);
|
|
554
|
+
this._errors[errorKey] = emptyErrors;
|
|
555
|
+
const value = this.state[field];
|
|
556
|
+
const fieldConfig = this.rules[field];
|
|
557
|
+
if (!(fieldConfig === null || fieldConfig === void 0 ? void 0 : fieldConfig.rules) || fieldConfig.rules.length === 0) {
|
|
558
|
+
return; // No rules to validate
|
|
559
|
+
}
|
|
560
|
+
const mode = (_b = (_a = fieldConfig.options) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : ValidationMode.DEFAULT;
|
|
561
|
+
const isDirty = context.isDirty !== undefined ? context.isDirty : this.isDirty(field);
|
|
562
|
+
const isTouched = context.isTouched !== undefined ? context.isTouched : this.isTouched(field);
|
|
563
|
+
const shouldValidate = (context.isSubmitting && mode & ValidationMode.ON_SUBMIT) ||
|
|
564
|
+
(isDirty && mode & ValidationMode.ON_DIRTY) ||
|
|
565
|
+
(isTouched && mode & ValidationMode.ON_TOUCH) ||
|
|
566
|
+
mode & ValidationMode.INSTANTLY ||
|
|
567
|
+
(context.isDependentChange && mode & ValidationMode.ON_DEPENDENT_CHANGE);
|
|
568
|
+
if (shouldValidate) {
|
|
569
|
+
for (const rule of fieldConfig.rules) {
|
|
570
|
+
const isValid = rule.validate(value, this.state);
|
|
571
|
+
if (!isValid) {
|
|
572
|
+
this.getOrCreateFieldErrors(errorKey).push(rule.getMessage());
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
validate(isSubmitting = false) {
|
|
578
|
+
let isValid = true;
|
|
579
|
+
for (const key in this._errors) {
|
|
580
|
+
delete this._errors[key];
|
|
581
|
+
}
|
|
582
|
+
for (const field in this.rules) {
|
|
583
|
+
if (Object.prototype.hasOwnProperty.call(this.rules, field)) {
|
|
584
|
+
this.validateField(field, {
|
|
585
|
+
isSubmitting,
|
|
586
|
+
isDependentChange: false,
|
|
587
|
+
isTouched: this.isTouched(field)
|
|
588
|
+
});
|
|
589
|
+
const fieldErrors = this._errors[String(field)];
|
|
590
|
+
if (isErrorMessages(fieldErrors) && fieldErrors.length > 0) {
|
|
591
|
+
isValid = false;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return isValid;
|
|
596
|
+
}
|
|
597
|
+
fillState(data) {
|
|
598
|
+
var _a;
|
|
599
|
+
const driver = this.getPersistenceDriver((_a = this.options) === null || _a === void 0 ? void 0 : _a.persistSuffix);
|
|
600
|
+
for (const key of Object.keys(data)) {
|
|
601
|
+
if (!Object.prototype.hasOwnProperty.call(data, key) || !(key in this.state)) {
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
const currentVal = this.state[key];
|
|
605
|
+
const newVal = data[key];
|
|
606
|
+
if (currentVal instanceof PropertyAwareArray) {
|
|
607
|
+
const values = newVal instanceof PropertyAwareArray || Array.isArray(newVal) ? Array.from(newVal) : [];
|
|
608
|
+
this.replacePropertyAwareArray(key, values);
|
|
609
|
+
this.dirty[key] = values.map(() => false);
|
|
610
|
+
this.touched[key] = true;
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
if (Array.isArray(newVal) && Array.isArray(currentVal)) {
|
|
614
|
+
const merged = newVal.length === currentVal.length ? deepMergeArrays(currentVal, newVal) : newVal;
|
|
615
|
+
this.state[key] = merged;
|
|
616
|
+
this.dirty[key] = this.computeDirtyState(this.state[key], this.original[key]);
|
|
617
|
+
this.touched[key] = true;
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
if (isRecord(newVal) && isRecord(currentVal)) {
|
|
621
|
+
this.state[key] = shallowMerge(Object.assign({}, currentVal), newVal);
|
|
622
|
+
this.dirty[key] = this.computeDirtyState(this.state[key], this.original[key]);
|
|
623
|
+
this.touched[key] = true;
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
this.state[key] = newVal;
|
|
627
|
+
this.dirty[key] = this.computeDirtyState(this.state[key], this.original[key]);
|
|
628
|
+
this.touched[key] = true;
|
|
629
|
+
}
|
|
630
|
+
this.persistState(driver);
|
|
631
|
+
for (const key in data) {
|
|
632
|
+
if (Object.prototype.hasOwnProperty.call(data, key) && key in this.state) {
|
|
633
|
+
this.validateField(key);
|
|
634
|
+
this.validateDependentFields(key);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
getValueGetter(name) {
|
|
639
|
+
const candidate = this[name];
|
|
640
|
+
if (typeof candidate !== 'function') {
|
|
641
|
+
return undefined;
|
|
642
|
+
}
|
|
643
|
+
return candidate.bind(this);
|
|
644
|
+
}
|
|
645
|
+
getNoArgGetter(name) {
|
|
646
|
+
const candidate = this[name];
|
|
647
|
+
if (typeof candidate !== 'function') {
|
|
648
|
+
return undefined;
|
|
649
|
+
}
|
|
650
|
+
return candidate.bind(this);
|
|
651
|
+
}
|
|
652
|
+
transformValue(value, parentKey) {
|
|
653
|
+
if (value instanceof Date) {
|
|
654
|
+
return value;
|
|
655
|
+
}
|
|
656
|
+
if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
657
|
+
return value;
|
|
658
|
+
}
|
|
659
|
+
if (value instanceof PropertyAwareArray) {
|
|
660
|
+
return [...value].map((item) => this.transformValue(item, parentKey));
|
|
661
|
+
}
|
|
662
|
+
if (Array.isArray(value)) {
|
|
663
|
+
return value.map((item) => this.transformValue(item, parentKey));
|
|
664
|
+
}
|
|
665
|
+
else if (isRecord(value)) {
|
|
666
|
+
const result = {};
|
|
667
|
+
for (const prop in value) {
|
|
668
|
+
if (parentKey) {
|
|
669
|
+
const compositeMethod = 'get' + upperFirst(parentKey) + upperFirst(camelCase(prop));
|
|
670
|
+
const getter = this.getValueGetter(compositeMethod);
|
|
671
|
+
if (getter) {
|
|
672
|
+
const transformed = getter(value[prop]);
|
|
673
|
+
if (transformed !== undefined) {
|
|
674
|
+
result[prop] = transformed;
|
|
675
|
+
}
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
const transformed = this.transformValue(value[prop], parentKey);
|
|
680
|
+
if (transformed !== undefined) {
|
|
681
|
+
result[prop] = transformed;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
return result;
|
|
685
|
+
}
|
|
686
|
+
return value;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Build the request payload, applying field/composite/appended getters when present.
|
|
690
|
+
*/
|
|
691
|
+
buildPayload() {
|
|
692
|
+
const payload = {};
|
|
693
|
+
for (const key of Object.keys(this.state)) {
|
|
694
|
+
if (this.ignore.includes(key)) {
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
const value = this.state[key];
|
|
698
|
+
const getterName = 'get' + upperFirst(camelCase(key));
|
|
699
|
+
const typedKey = key;
|
|
700
|
+
const getter = this.getValueGetter(getterName);
|
|
701
|
+
if (getter) {
|
|
702
|
+
const transformed = getter(value);
|
|
703
|
+
if (transformed !== undefined) {
|
|
704
|
+
payload[typedKey] = transformed;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
const transformed = this.transformValue(value, key);
|
|
709
|
+
if (transformed !== undefined) {
|
|
710
|
+
payload[typedKey] = transformed;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
for (const fieldName of this.append) {
|
|
715
|
+
if (Array.isArray(this.ignore) && this.ignore.includes(fieldName)) {
|
|
716
|
+
console.warn(`Appended field '${fieldName}' is also in ignore list in ${this.constructor.name}. It will be skipped.`);
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
const getterName = 'get' + upperFirst(camelCase(fieldName));
|
|
720
|
+
const getter = this.getNoArgGetter(getterName);
|
|
721
|
+
if (getter) {
|
|
722
|
+
const transformed = getter();
|
|
723
|
+
if (transformed !== undefined) {
|
|
724
|
+
payload[fieldName] = transformed;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
else {
|
|
728
|
+
console.warn(`Getter method '${getterName}' not found for appended field '${fieldName}' in ${this.constructor.name}.`);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return payload;
|
|
732
|
+
}
|
|
733
|
+
reset() {
|
|
734
|
+
var _a;
|
|
735
|
+
const driver = this.getPersistenceDriver((_a = this.options) === null || _a === void 0 ? void 0 : _a.persistSuffix);
|
|
736
|
+
for (const key in this.state) {
|
|
737
|
+
if (this.state[key] instanceof PropertyAwareArray) {
|
|
738
|
+
const originalValue = this.original[key];
|
|
739
|
+
const values = [...originalValue].map((item) => cloneDeep(item));
|
|
740
|
+
const typedKey = key;
|
|
741
|
+
this.replacePropertyAwareArray(typedKey, values);
|
|
742
|
+
this.dirty[typedKey] = values.map(() => false);
|
|
743
|
+
this.touched[typedKey] = false;
|
|
744
|
+
}
|
|
745
|
+
else if (Array.isArray(this.original[key])) {
|
|
746
|
+
this.state[key] = cloneDeep(this.original[key]);
|
|
747
|
+
this.dirty[key] = this.computeDirtyState(this.state[key], this.original[key]);
|
|
748
|
+
this.touched[key] = false;
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
this.state[key] = cloneDeep(this.original[key]);
|
|
752
|
+
this.dirty[key] = false;
|
|
753
|
+
this.touched[key] = false;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
for (const key in this._errors) {
|
|
757
|
+
delete this._errors[key];
|
|
758
|
+
}
|
|
759
|
+
this.persistState(driver);
|
|
760
|
+
this.validate();
|
|
761
|
+
}
|
|
762
|
+
addToArrayProperty(property, newElement) {
|
|
763
|
+
var _a;
|
|
764
|
+
const driver = this.getPersistenceDriver((_a = this.options) === null || _a === void 0 ? void 0 : _a.persistSuffix);
|
|
765
|
+
const arr = this.state[property];
|
|
766
|
+
if (arr instanceof PropertyAwareArray) {
|
|
767
|
+
arr.push(newElement);
|
|
768
|
+
this.touched[property] = true;
|
|
769
|
+
this.persistState(driver);
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
if (!Array.isArray(arr)) {
|
|
773
|
+
throw new Error(`Property "${String(property)}" is not an array.`);
|
|
774
|
+
}
|
|
775
|
+
arr.push(newElement);
|
|
776
|
+
this.dirty[property] = this.computeDirtyState(arr, this.original[property]);
|
|
777
|
+
this.touched[property] = true;
|
|
778
|
+
this.persistState(driver);
|
|
779
|
+
this.validateField(property);
|
|
780
|
+
this.validateDependentFields(property);
|
|
781
|
+
}
|
|
782
|
+
removeArrayItem(arrayIndex, filter) {
|
|
783
|
+
const current = this.state[arrayIndex];
|
|
784
|
+
if (current instanceof PropertyAwareArray) {
|
|
785
|
+
const filtered = [...current].filter(filter);
|
|
786
|
+
current.length = 0;
|
|
787
|
+
filtered.forEach((item) => current.push(item));
|
|
788
|
+
}
|
|
789
|
+
else if (Array.isArray(current)) {
|
|
790
|
+
this.state[arrayIndex] = current.filter(filter);
|
|
791
|
+
}
|
|
792
|
+
this.touched[arrayIndex] = true;
|
|
793
|
+
this.validateField(arrayIndex);
|
|
794
|
+
this.validateDependentFields(arrayIndex);
|
|
795
|
+
}
|
|
796
|
+
resetArrayCounter(arrayIndex, counterIndex) {
|
|
797
|
+
let count = 1;
|
|
798
|
+
const current = this.state[arrayIndex];
|
|
799
|
+
if (current instanceof PropertyAwareArray) {
|
|
800
|
+
;
|
|
801
|
+
[...current].forEach((item) => {
|
|
802
|
+
if (isRecord(item)) {
|
|
803
|
+
item[counterIndex] = count;
|
|
804
|
+
count++;
|
|
805
|
+
}
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
else if (Array.isArray(current)) {
|
|
809
|
+
current.forEach((item) => {
|
|
810
|
+
if (isRecord(item)) {
|
|
811
|
+
item[counterIndex] = count;
|
|
812
|
+
count++;
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
this.touched[arrayIndex] = true;
|
|
817
|
+
}
|
|
818
|
+
get properties() {
|
|
819
|
+
const props = {};
|
|
820
|
+
for (const key of Object.keys(this.state)) {
|
|
821
|
+
const value = this.state[key];
|
|
822
|
+
if (value instanceof PropertyAwareArray) {
|
|
823
|
+
const arrayProps = [...value].map((item, index) => {
|
|
824
|
+
if (isRecord(item)) {
|
|
825
|
+
const elementProps = {};
|
|
826
|
+
for (const innerKey of Object.keys(item)) {
|
|
827
|
+
elementProps[innerKey] = {
|
|
828
|
+
model: computed({
|
|
829
|
+
get: () => {
|
|
830
|
+
const current = value[index];
|
|
831
|
+
return isRecord(current) ? current[innerKey] : undefined;
|
|
832
|
+
},
|
|
833
|
+
set: (newVal) => {
|
|
834
|
+
const current = value[index];
|
|
835
|
+
if (isRecord(current)) {
|
|
836
|
+
current[innerKey] = newVal;
|
|
837
|
+
}
|
|
838
|
+
const updatedElement = value[index];
|
|
839
|
+
const originalElement = this.original[key][index];
|
|
840
|
+
this.setArrayDirty(key, index, this.computeDirtyState(updatedElement, originalElement));
|
|
841
|
+
this.touched[key] = true;
|
|
842
|
+
this.validateField(key);
|
|
843
|
+
this.validateDependentFields(key);
|
|
844
|
+
}
|
|
845
|
+
}),
|
|
846
|
+
errors: this.getArrayItemFieldErrors(key, index, innerKey),
|
|
847
|
+
dirty: this.getArrayItemDirty(key, index, innerKey),
|
|
848
|
+
touched: this.touched[key] || false
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
return elementProps;
|
|
852
|
+
}
|
|
853
|
+
return {
|
|
854
|
+
value: {
|
|
855
|
+
model: computed({
|
|
856
|
+
get: () => value[index],
|
|
857
|
+
set: (newVal) => {
|
|
858
|
+
value[index] = newVal;
|
|
859
|
+
const updatedValue = value[index];
|
|
860
|
+
const originalValue = this.original[key][index];
|
|
861
|
+
this.setArrayDirty(key, index, this.computeDirtyState(updatedValue, originalValue));
|
|
862
|
+
this.touched[key] = true;
|
|
863
|
+
this.validateField(key);
|
|
864
|
+
this.validateDependentFields(key);
|
|
865
|
+
}
|
|
866
|
+
}),
|
|
867
|
+
errors: this.getArrayItemErrorMessages(key, index),
|
|
868
|
+
dirty: this.getArrayItemDirtyValue(key, index),
|
|
869
|
+
touched: this.touched[key] || false
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
});
|
|
873
|
+
props[key] = arrayProps;
|
|
874
|
+
continue;
|
|
875
|
+
}
|
|
876
|
+
props[key] = {
|
|
877
|
+
model: this._model[key],
|
|
878
|
+
errors: this.getFieldErrors(key),
|
|
879
|
+
dirty: this.dirty[key] || false,
|
|
880
|
+
touched: this.touched[key] || false
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
return props;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Checks if the form or a specific field is dirty
|
|
887
|
+
* @param field Optional field name to check, if not provided checks the entire form
|
|
888
|
+
* @returns boolean indicating if the form or specified field is dirty
|
|
889
|
+
*/
|
|
890
|
+
isDirty(field) {
|
|
891
|
+
if (field !== undefined) {
|
|
892
|
+
const dirtyState = this.dirty[field];
|
|
893
|
+
if (typeof dirtyState === 'boolean') {
|
|
894
|
+
return dirtyState;
|
|
895
|
+
}
|
|
896
|
+
if (Array.isArray(dirtyState)) {
|
|
897
|
+
return dirtyState.some((item) => {
|
|
898
|
+
if (typeof item === 'boolean') {
|
|
899
|
+
return item;
|
|
900
|
+
}
|
|
901
|
+
if (item && typeof item === 'object') {
|
|
902
|
+
return Object.values(item).some((v) => v === true);
|
|
903
|
+
}
|
|
904
|
+
return false;
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
if (dirtyState && typeof dirtyState === 'object') {
|
|
908
|
+
return Object.values(dirtyState).some((v) => v === true);
|
|
909
|
+
}
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
for (const key in this.dirty) {
|
|
913
|
+
const dirtyState = this.dirty[key];
|
|
914
|
+
if (typeof dirtyState === 'boolean' && dirtyState) {
|
|
915
|
+
return true;
|
|
916
|
+
}
|
|
917
|
+
if (Array.isArray(dirtyState)) {
|
|
918
|
+
for (const item of dirtyState) {
|
|
919
|
+
if (typeof item === 'boolean' && item) {
|
|
920
|
+
return true;
|
|
921
|
+
}
|
|
922
|
+
if (item && typeof item === 'object' && Object.values(item).some((v) => v === true)) {
|
|
923
|
+
return true;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
if (dirtyState && typeof dirtyState === 'object' && Object.values(dirtyState).some((v) => v === true)) {
|
|
928
|
+
return true;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return false;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Returns whether the form has validation errors
|
|
935
|
+
* @returns boolean indicating if the form has errors
|
|
936
|
+
*/
|
|
937
|
+
hasErrors() {
|
|
938
|
+
return this._hasErrors.value;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Updates both the state and original value for a given property,
|
|
942
|
+
* keeping the field in a clean (not dirty) state.
|
|
943
|
+
* Supports all field types including PropertyAwareArray.
|
|
944
|
+
*
|
|
945
|
+
* @param key The property key to update
|
|
946
|
+
* @param value The new value to set
|
|
947
|
+
*/
|
|
948
|
+
syncValue(key, value) {
|
|
949
|
+
var _a, _b;
|
|
950
|
+
const driver = this.getPersistenceDriver((_a = this.options) === null || _a === void 0 ? void 0 : _a.persistSuffix);
|
|
951
|
+
const currentVal = this.state[key];
|
|
952
|
+
if (currentVal instanceof PropertyAwareArray) {
|
|
953
|
+
const arr = this.state[key];
|
|
954
|
+
const originalArr = this.original[key];
|
|
955
|
+
arr.length = 0;
|
|
956
|
+
originalArr.length = 0;
|
|
957
|
+
if (Array.isArray(value)) {
|
|
958
|
+
value.forEach((item) => {
|
|
959
|
+
arr.push(cloneDeep(item));
|
|
960
|
+
originalArr.push(cloneDeep(item));
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
else if (value instanceof PropertyAwareArray) {
|
|
964
|
+
;
|
|
965
|
+
[...value].forEach((item) => {
|
|
966
|
+
arr.push(cloneDeep(item));
|
|
967
|
+
originalArr.push(cloneDeep(item));
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
this.dirty[key] = Array.from(arr).map(() => false);
|
|
971
|
+
this.touched[key] = true;
|
|
972
|
+
}
|
|
973
|
+
else if (Array.isArray(currentVal)) {
|
|
974
|
+
this.state[key] = cloneDeep(value);
|
|
975
|
+
this.original[key] = cloneDeep(value);
|
|
976
|
+
this.dirty[key] = false;
|
|
977
|
+
this.touched[key] = true;
|
|
978
|
+
}
|
|
979
|
+
else if (typeof currentVal === 'object' && currentVal !== null) {
|
|
980
|
+
this.state[key] = cloneDeep(value);
|
|
981
|
+
this.original[key] = cloneDeep(value);
|
|
982
|
+
this.dirty[key] = false;
|
|
983
|
+
this.touched[key] = true;
|
|
984
|
+
}
|
|
985
|
+
else {
|
|
986
|
+
this.state[key] = value;
|
|
987
|
+
this.original[key] = value;
|
|
988
|
+
this.dirty[key] = false;
|
|
989
|
+
this.touched[key] = true;
|
|
990
|
+
}
|
|
991
|
+
if (((_b = this.options) === null || _b === void 0 ? void 0 : _b.persist) !== false) {
|
|
992
|
+
this.persistState(driver);
|
|
993
|
+
}
|
|
994
|
+
this.validateField(key);
|
|
995
|
+
this.validateDependentFields(key);
|
|
996
|
+
}
|
|
997
|
+
}
|