@blueprint-ts/core 3.0.0 → 4.0.0-beta.10
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/CHANGELOG.md +94 -0
- package/README.md +25 -1
- package/docs/.vitepress/config.ts +81 -23
- package/docs/index.md +6 -63
- package/docs/{services/laravel → laravel}/pagination.md +19 -6
- package/docs/{services/laravel → laravel}/requests.md +2 -2
- package/docs/services/pagination/index.md +46 -0
- package/docs/services/pagination/infinite-scroller.md +20 -0
- package/docs/services/pagination/page-aware.md +51 -0
- package/docs/services/pagination/state-pagination.md +77 -0
- package/docs/services/pagination/updating-rows.md +52 -0
- package/docs/services/persistence/index.md +46 -0
- package/docs/services/requests/abort-requests.md +29 -0
- package/docs/services/requests/bulk-requests.md +70 -0
- package/docs/services/requests/concurrency.md +58 -0
- package/docs/services/requests/drivers.md +50 -0
- package/docs/services/requests/error-handling.md +153 -0
- package/docs/services/requests/events.md +31 -0
- package/docs/services/requests/getting-started.md +201 -0
- package/docs/services/requests/headers.md +40 -0
- package/docs/services/requests/loading.md +63 -0
- package/docs/services/requests/request-bodies.md +59 -0
- package/docs/services/requests/responses.md +34 -0
- package/docs/services/support/deferred-promise.md +63 -0
- package/docs/services/support/helpers.md +77 -0
- package/docs/services/support/index.md +6 -0
- package/docs/upgrading/v1-to-v2.md +64 -0
- package/docs/upgrading/v2-to-v3.md +52 -0
- package/docs/upgrading/v3-to-v4.md +214 -0
- package/docs/upgrading.md +0 -0
- package/docs/vue/composables/use-confirm-dialog.md +96 -0
- package/docs/vue/composables/use-global-checkbox.md +73 -0
- package/docs/vue/composables/use-is-empty.md +26 -0
- package/docs/vue/composables/use-is-open-from-var.md +32 -0
- package/docs/vue/composables/use-is-open.md +28 -0
- package/docs/vue/composables/use-model-wrapper.md +29 -0
- package/docs/vue/composables/use-on-open.md +26 -0
- package/docs/vue/forms/arrays.md +102 -0
- package/docs/vue/forms/errors.md +52 -0
- package/docs/vue/forms/index.md +99 -0
- package/docs/vue/forms/payloads.md +99 -0
- package/docs/vue/forms/persistence.md +19 -0
- package/docs/vue/forms/state-and-properties.md +26 -0
- package/docs/vue/forms/utilities.md +27 -0
- package/docs/vue/forms/validation.md +189 -0
- package/docs/vue/requests/loading.md +51 -0
- package/docs/vue/{requests → router}/route-resource-binding.md +33 -27
- package/docs/vue/state.md +27 -11
- package/package.json +12 -13
- package/release-tool.json +22 -3
- package/src/{service/bulkRequests → bulkRequests}/BulkRequestSender.ts +29 -17
- package/src/{service/bulkRequests → bulkRequests}/BulkRequestWrapper.ts +5 -5
- package/src/laravel/pagination/dataDrivers/RequestDriver.ts +30 -0
- package/src/laravel/pagination/index.ts +6 -0
- package/src/pagination/BasePaginator.ts +94 -0
- package/src/{service/pagination → pagination}/InfiniteScroller.ts +1 -0
- package/src/{service/pagination → pagination}/PageAwarePaginator.ts +34 -26
- package/src/{service/pagination → pagination}/StatePaginator.ts +2 -8
- package/src/{service/pagination → pagination}/index.ts +1 -3
- package/src/{service/requests → requests}/BaseRequest.ts +89 -4
- package/src/requests/ErrorHandler.ts +144 -0
- package/src/requests/RequestConcurrencyMode.enum.ts +6 -0
- package/src/requests/RequestErrorRouter.ts +89 -0
- package/src/{service/requests → requests}/bodies/FormDataBody.ts +10 -6
- package/src/{service/requests → requests}/contracts/BaseRequestContract.ts +3 -0
- package/src/requests/exceptions/BadGatewayException.ts +3 -0
- package/src/requests/exceptions/BadRequestException.ts +3 -0
- package/src/requests/exceptions/ConflictException.ts +3 -0
- package/src/requests/exceptions/ForbiddenException.ts +3 -0
- package/src/requests/exceptions/GatewayTimeoutException.ts +3 -0
- package/src/requests/exceptions/GoneException.ts +3 -0
- package/src/requests/exceptions/InvalidJsonException.ts +15 -0
- package/src/requests/exceptions/LockedException.ts +3 -0
- package/src/requests/exceptions/MethodNotAllowedException.ts +3 -0
- package/src/requests/exceptions/NotImplementedException.ts +3 -0
- package/src/requests/exceptions/PayloadTooLargeException.ts +3 -0
- package/src/requests/exceptions/PreconditionFailedException.ts +3 -0
- package/src/requests/exceptions/RequestTimeoutException.ts +3 -0
- package/src/requests/exceptions/ServiceUnavailableException.ts +3 -0
- package/src/requests/exceptions/StaleResponseException.ts +13 -0
- package/src/requests/exceptions/TooManyRequestsException.ts +3 -0
- package/src/requests/exceptions/UnsupportedMediaTypeException.ts +3 -0
- package/src/requests/exceptions/index.ts +51 -0
- package/src/requests/factories/FormDataFactory.ts +17 -0
- package/src/{service/requests → requests}/index.ts +9 -3
- package/src/requests/types/RequestConcurrencyOptions.ts +6 -0
- package/src/{service/support → support}/DeferredPromise.ts +1 -1
- package/src/support/index.ts +4 -0
- package/src/vue/composables/useConfirmDialog.ts +5 -1
- package/src/vue/composables/useModelWrapper.ts +3 -0
- package/src/vue/forms/BaseForm.ts +512 -399
- package/src/vue/forms/PropertyAwareArray.ts +6 -2
- package/src/vue/forms/index.ts +4 -4
- package/src/vue/forms/validation/index.ts +5 -2
- package/src/vue/forms/validation/rules/ConfirmedRule.ts +3 -3
- package/src/vue/forms/validation/rules/EmailRule.ts +23 -0
- package/src/vue/forms/validation/rules/JsonRule.ts +28 -0
- package/src/vue/forms/validation/types/BidirectionalRule.ts +2 -2
- package/src/vue/forms/validation/types/ValidationRules.ts +15 -0
- package/src/vue/index.ts +3 -3
- package/src/vue/requests/factories/VueRequestLoaderFactory.ts +3 -2
- package/src/vue/requests/loaders/VueRequestBatchLoader.ts +6 -1
- package/src/vue/requests/loaders/VueRequestLoader.ts +1 -1
- package/src/vue/router/routeResourceBinding/types.ts +3 -3
- package/src/vue/state/State.ts +38 -50
- package/tests/service/helpers/mergeDeep.test.ts +1 -1
- package/tests/service/laravel/pagination/dataDrivers/RequestDriver.test.ts +3 -3
- package/tests/service/laravel/requests/JsonBaseRequest.test.ts +4 -4
- package/tests/service/laravel/requests/PaginationJsonBaseRequest.test.ts +3 -3
- package/tests/service/laravel/requests/responses/JsonResponse.test.ts +2 -2
- package/tests/service/laravel/requests/responses/PaginationResponse.test.ts +2 -2
- package/tests/service/pagination/dtos/PaginationDataDto.test.ts +1 -1
- package/tests/service/pagination/factories/VuePaginationDriverFactory.test.ts +2 -2
- package/tests/service/pagination/frontendDrivers/VuePaginationDriver.test.ts +1 -1
- package/tests/service/requests/ErrorHandler.test.ts +61 -58
- package/tests/service/requests/FormDataBody.test.ts +1 -1
- package/tests/vue/forms/BaseForm.behavior.test.ts +98 -0
- package/docs/.vitepress/theme/Layout.vue +0 -14
- package/docs/.vitepress/theme/components/VersionSelector.vue +0 -64
- package/docs/.vitepress/theme/index.js +0 -13
- package/docs/services/requests/index.md +0 -74
- package/docs/vue/forms.md +0 -477
- package/examples/files/7z2404-x64.exe +0 -0
- package/examples/index.html +0 -14
- package/examples/js/app.js +0 -8
- package/examples/js/router.js +0 -22
- package/examples/js/view/App.vue +0 -49
- package/examples/js/view/layout/DemoPage.vue +0 -28
- package/examples/js/view/pagination/Pagination.vue +0 -28
- package/examples/js/view/pagination/components/errorPagination/ErrorPagination.vue +0 -71
- package/examples/js/view/pagination/components/errorPagination/GetProductsRequest.ts +0 -54
- package/examples/js/view/pagination/components/infiniteScrolling/GetProductsRequest.ts +0 -50
- package/examples/js/view/pagination/components/infiniteScrolling/InfiniteScrolling.vue +0 -57
- package/examples/js/view/pagination/components/tablePagination/GetProductsRequest.ts +0 -50
- package/examples/js/view/pagination/components/tablePagination/TablePagination.vue +0 -63
- package/examples/js/view/requests/Requests.vue +0 -34
- package/examples/js/view/requests/components/abortableRequest/AbortableRequest.vue +0 -36
- package/examples/js/view/requests/components/abortableRequest/GetProductsRequest.ts +0 -25
- package/examples/js/view/requests/components/fileDownloadRequest/DownloadFileRequest.ts +0 -15
- package/examples/js/view/requests/components/fileDownloadRequest/FileDownloadRequest.vue +0 -44
- package/examples/js/view/requests/components/getRequestWithDynamicParams/GetProductsRequest.ts +0 -34
- package/examples/js/view/requests/components/getRequestWithDynamicParams/GetRequestWithDynamicParams.vue +0 -59
- package/examples/js/view/requests/components/serverErrorRequest/ServerErrorRequest.ts +0 -21
- package/examples/js/view/requests/components/serverErrorRequest/ServerErrorRequest.vue +0 -53
- package/src/service/laravel/pagination/contracts/PaginationParamsContract.ts +0 -4
- package/src/service/laravel/pagination/dataDrivers/RequestDriver.ts +0 -32
- package/src/service/laravel/pagination/index.ts +0 -7
- package/src/service/pagination/BasePaginator.ts +0 -36
- package/src/service/pagination/Paginator.ts +0 -11
- package/src/service/requests/ErrorHandler.ts +0 -64
- package/src/service/requests/exceptions/index.ts +0 -19
- package/src/service/requests/factories/FormDataFactory.ts +0 -9
- package/src/service/support/index.ts +0 -3
- /package/src/{service/bulkRequests → bulkRequests}/BulkRequestEvent.enum.ts +0 -0
- /package/src/{service/bulkRequests → bulkRequests}/index.ts +0 -0
- /package/src/{service/laravel → laravel}/pagination/contracts/PaginationResponseBodyContract.ts +0 -0
- /package/src/{service/laravel → laravel}/requests/JsonBaseRequest.ts +0 -0
- /package/src/{service/laravel → laravel}/requests/PaginationJsonBaseRequest.ts +0 -0
- /package/src/{service/laravel → laravel}/requests/index.ts +0 -0
- /package/src/{service/laravel → laravel}/requests/responses/JsonResponse.ts +0 -0
- /package/src/{service/laravel → laravel}/requests/responses/PaginationResponse.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/BaseViewDriverContract.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/BaseViewDriverFactoryContract.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/PaginateableRequestContract.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/PaginationDataDriverContract.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/PaginationResponseContract.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/PaginatorLoadDataOptions.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/StatePaginationDataDriverContract.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/ViewDriverContract.ts +0 -0
- /package/src/{service/pagination → pagination}/contracts/ViewDriverFactoryContract.ts +0 -0
- /package/src/{service/pagination → pagination}/dataDrivers/ArrayDriver.ts +0 -0
- /package/src/{service/pagination → pagination}/dtos/PaginationDataDto.ts +0 -0
- /package/src/{service/pagination → pagination}/dtos/StatePaginationDataDto.ts +0 -0
- /package/src/{service/pagination → pagination}/factories/VueBaseViewDriverFactory.ts +0 -0
- /package/src/{service/pagination → pagination}/factories/VuePaginationDriverFactory.ts +0 -0
- /package/src/{service/pagination → pagination}/frontendDrivers/VueBaseViewDriver.ts +0 -0
- /package/src/{service/pagination → pagination}/frontendDrivers/VuePaginationDriver.ts +0 -0
- /package/src/{service/persistenceDrivers → persistenceDrivers}/LocalStorageDriver.ts +0 -0
- /package/src/{service/persistenceDrivers → persistenceDrivers}/NonPersistentDriver.ts +0 -0
- /package/src/{service/persistenceDrivers → persistenceDrivers}/SessionStorageDriver.ts +0 -0
- /package/src/{service/persistenceDrivers → persistenceDrivers}/index.ts +0 -0
- /package/src/{service/persistenceDrivers → persistenceDrivers}/types/PersistenceDriver.ts +0 -0
- /package/src/{service/requests → requests}/RequestEvents.enum.ts +0 -0
- /package/src/{service/requests → requests}/RequestMethod.enum.ts +0 -0
- /package/src/{service/requests → requests}/bodies/JsonBody.ts +0 -0
- /package/src/{service/requests → requests}/contracts/AbortableRequestContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/BodyContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/BodyFactoryContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/DriverConfigContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/HeadersContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/RequestDriverContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/RequestLoaderContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/RequestLoaderFactoryContract.ts +0 -0
- /package/src/{service/requests → requests}/contracts/ResponseContract.ts +0 -0
- /package/src/{service/requests → requests}/drivers/contracts/ResponseHandlerContract.ts +0 -0
- /package/src/{service/requests → requests}/drivers/fetch/FetchDriver.ts +0 -0
- /package/src/{service/requests → requests}/drivers/fetch/FetchResponse.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/NoResponseReceivedException.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/NotFoundException.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/PageExpiredException.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/ResponseBodyException.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/ResponseException.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/ServerErrorException.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/UnauthorizedException.ts +0 -0
- /package/src/{service/requests → requests}/exceptions/ValidationException.ts +0 -0
- /package/src/{service/requests → requests}/factories/JsonBodyFactory.ts +0 -0
- /package/src/{service/requests → requests}/responses/BaseResponse.ts +0 -0
- /package/src/{service/requests → requests}/responses/BlobResponse.ts +0 -0
- /package/src/{service/requests → requests}/responses/JsonResponse.ts +0 -0
- /package/src/{service/requests → requests}/responses/PlainTextResponse.ts +0 -0
- /package/src/{helpers.ts → support/helpers.ts} +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# State And Properties
|
|
2
|
+
|
|
3
|
+
`BaseForm` tracks the original state and the current state of each field.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
form.isDirty() // any field modified
|
|
7
|
+
form.isDirty('email') // specific field modified
|
|
8
|
+
|
|
9
|
+
form.touch('email')
|
|
10
|
+
form.isTouched('email')
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Properties**
|
|
14
|
+
|
|
15
|
+
`properties.<field>` exposes:
|
|
16
|
+
- `model` (a `ComputedRef` compatible with `v-model`)
|
|
17
|
+
- `errors` (array)
|
|
18
|
+
- `dirty` and `touched`
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<input v-model="form.properties.email.model.value" />
|
|
24
|
+
<div v-if="form.properties.email.dirty">This field has been changed</div>
|
|
25
|
+
<div v-if="form.properties.email.errors.length">{{ form.properties.email.errors[0] }}</div>
|
|
26
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Utilities
|
|
2
|
+
|
|
3
|
+
Update multiple fields at once:
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
form.fillState({ name: 'John Doe', email: 'john@example.com' })
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Synchronize a value without marking dirty:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
form.syncValue('email', 'new@example.com')
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Reset the form to its original state:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
form.reset()
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Convert `properties` back to raw data:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { propertyAwareToRaw } from '@blueprint-ts/core/vue/forms'
|
|
25
|
+
|
|
26
|
+
const raw = propertyAwareToRaw<FormState>(form.properties)
|
|
27
|
+
```
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Validation
|
|
2
|
+
|
|
3
|
+
Define validation rules by overriding `defineRules()` in your form class.
|
|
4
|
+
|
|
5
|
+
Validation errors are exposed on `properties.<field>.errors`, as documented in [Errors](/vue/forms/errors).
|
|
6
|
+
|
|
7
|
+
## Available Rules
|
|
8
|
+
|
|
9
|
+
- `RequiredRule` — checks that the value is not `null`, `undefined`, or `''`
|
|
10
|
+
- `MinRule` — minimum length for strings/arrays or minimum value for numbers
|
|
11
|
+
- `ConfirmedRule` — validates that two fields match (e.g. password confirmation)
|
|
12
|
+
- `UrlRule` — validates that the value is a valid URL
|
|
13
|
+
- `EmailRule` — validates that the value is a valid email address
|
|
14
|
+
- `JsonRule` — validates that the value is valid JSON
|
|
15
|
+
|
|
16
|
+
All rules are exported from `@blueprint-ts/core/vue/forms/validation`.
|
|
17
|
+
|
|
18
|
+
## Validation Modes
|
|
19
|
+
|
|
20
|
+
Validation modes are bit flags. You can use the presets below or combine flags with `|`.
|
|
21
|
+
|
|
22
|
+
**Flags**
|
|
23
|
+
|
|
24
|
+
- `ValidationMode.NEVER` — never validate this field
|
|
25
|
+
- `ValidationMode.INSTANTLY` — validate immediately when the field is evaluated, even if not dirty/touched
|
|
26
|
+
- `ValidationMode.ON_TOUCH` — validate after the field is touched
|
|
27
|
+
- `ValidationMode.ON_DIRTY` — validate when the field becomes dirty
|
|
28
|
+
- `ValidationMode.ON_SUBMIT` — validate on submit
|
|
29
|
+
- `ValidationMode.ON_DEPENDENT_CHANGE` — validate when a dependent field changes
|
|
30
|
+
|
|
31
|
+
**Presets**
|
|
32
|
+
|
|
33
|
+
- `ValidationMode.DEFAULT` — `ON_TOUCH | ON_DIRTY | ON_SUBMIT`
|
|
34
|
+
- `ValidationMode.AGGRESSIVE` — `INSTANTLY | ON_TOUCH | ON_DIRTY | ON_SUBMIT`
|
|
35
|
+
- `ValidationMode.PASSIVE` — `ON_SUBMIT`
|
|
36
|
+
|
|
37
|
+
**Custom Combination**
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
options: { mode: ValidationMode.ON_TOUCH | ValidationMode.ON_SUBMIT }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Internal vs External**
|
|
44
|
+
|
|
45
|
+
- Internal means validation runs from within `BaseForm` based on user interaction or dependencies.
|
|
46
|
+
- External means you explicitly trigger validation via `validate(true)`, typically on submit.
|
|
47
|
+
|
|
48
|
+
- Internal triggers: `INSTANTLY`, `ON_TOUCH`, `ON_DIRTY`, `ON_DEPENDENT_CHANGE`
|
|
49
|
+
- External trigger (`validate(true)`): `ON_SUBMIT` (and `PASSIVE` preset)
|
|
50
|
+
- `NEVER` disables validation entirely
|
|
51
|
+
|
|
52
|
+
Rules can declare dependencies via `rule.dependsOn = ['otherField']`. Some rules, such as `ConfirmedRule`, automatically set up bidirectional dependencies.
|
|
53
|
+
|
|
54
|
+
## Externally Triggering Validation
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const ok = form.validate(true)
|
|
58
|
+
if (!ok) return
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Some modes (notably `PASSIVE` / `ON_SUBMIT`) only validate when you trigger validation manually.
|
|
62
|
+
|
|
63
|
+
### How `validate(isSubmitting)` Behaves
|
|
64
|
+
|
|
65
|
+
- `validate(true)` enables `ON_SUBMIT` rules. Fields with `PASSIVE` mode will validate only here.
|
|
66
|
+
- `validate(false)` still validates fields that are currently dirty, touched, or set to `INSTANTLY`.
|
|
67
|
+
- `ValidationMode.NEVER` prevents validation in all cases, even during submit.
|
|
68
|
+
|
|
69
|
+
## Typing `defineRules`
|
|
70
|
+
|
|
71
|
+
Use `ValidationRules<FormBody>` for a concise, strongly-typed return type:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { type ValidationRules } from '@blueprint-ts/core/vue/forms/validation'
|
|
75
|
+
|
|
76
|
+
protected override defineRules(): ValidationRules<MyFormBody> {
|
|
77
|
+
return {
|
|
78
|
+
// ...
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Custom Rules
|
|
84
|
+
|
|
85
|
+
Create your own rules by extending `BaseRule`:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { BaseRule } from '@blueprint-ts/core/vue/forms/validation'
|
|
89
|
+
|
|
90
|
+
export class MaxRule<FormBody extends object> extends BaseRule<FormBody> {
|
|
91
|
+
public constructor(
|
|
92
|
+
protected max: number,
|
|
93
|
+
protected message: string = 'Value is too large'
|
|
94
|
+
) {
|
|
95
|
+
super()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public validate(value: unknown): boolean {
|
|
99
|
+
if (value === null || value === undefined) {
|
|
100
|
+
return true
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (typeof value === 'string') {
|
|
104
|
+
return value.length <= this.max
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (typeof value === 'number') {
|
|
108
|
+
return value <= this.max
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (Array.isArray(value)) {
|
|
112
|
+
return value.length <= this.max
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public getMessage(): string {
|
|
119
|
+
return this.message
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
If a rule depends on other fields, set `dependsOn` or implement bidirectional validation:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { BaseRule } from '@blueprint-ts/core/vue/forms/validation'
|
|
128
|
+
import { type BidirectionalRule } from '@blueprint-ts/core/vue/forms/validation'
|
|
129
|
+
|
|
130
|
+
export class MatchesOtherRule<FormBody extends object> extends BaseRule<FormBody> implements BidirectionalRule {
|
|
131
|
+
public dependsOn: Array<keyof FormBody> = ['other']
|
|
132
|
+
|
|
133
|
+
public validate(value: unknown, state: FormBody): boolean {
|
|
134
|
+
return value === state['other' as keyof FormBody]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public getMessage(): string {
|
|
138
|
+
return 'Values do not match'
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public getBidirectionalFields(): string[] {
|
|
142
|
+
return ['other']
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Example
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { BaseForm } from '@blueprint-ts/core/vue/forms'
|
|
151
|
+
import { ConfirmedRule, MinRule, RequiredRule, type ValidationRules } from '@blueprint-ts/core/vue/forms/validation'
|
|
152
|
+
|
|
153
|
+
export interface PinUpdateFormBody {
|
|
154
|
+
current_pin: string
|
|
155
|
+
new_pin: string
|
|
156
|
+
new_pin_confirmation: string
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export class PinUpdateForm extends BaseForm<PinUpdateFormBody, PinUpdateFormBody> {
|
|
160
|
+
public constructor() {
|
|
161
|
+
super({
|
|
162
|
+
current_pin: '',
|
|
163
|
+
new_pin: '',
|
|
164
|
+
new_pin_confirmation: ''
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
protected override defineRules(): ValidationRules<PinUpdateFormBody> {
|
|
169
|
+
return {
|
|
170
|
+
current_pin: {
|
|
171
|
+
rules: [
|
|
172
|
+
new RequiredRule('This field is required.'),
|
|
173
|
+
new MinRule(4, 'This field must be at least 4 characters long.')
|
|
174
|
+
]
|
|
175
|
+
},
|
|
176
|
+
new_pin: {
|
|
177
|
+
rules: [
|
|
178
|
+
new RequiredRule('This field is required.'),
|
|
179
|
+
new MinRule(4, 'This field must be at least 4 characters long.'),
|
|
180
|
+
new ConfirmedRule('new_pin_confirmation', 'This field must match the confirmation.')
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
new_pin_confirmation: {
|
|
184
|
+
rules: [new RequiredRule('This field is required.')]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Loading
|
|
2
|
+
|
|
3
|
+
For Vue apps, the library includes `VueRequestLoader`, `VueRequestLoaderFactory`, and `VueRequestBatchLoader`, which
|
|
4
|
+
use Vue refs to track loading state.
|
|
5
|
+
|
|
6
|
+
## Registering the Vue Loader Factory
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import { BaseRequest } from '@blueprint-ts/core/requests'
|
|
10
|
+
import { VueRequestLoaderFactory } from '@blueprint-ts/core/vue/requests'
|
|
11
|
+
|
|
12
|
+
BaseRequest.setRequestLoaderFactory(new VueRequestLoaderFactory())
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Reading Loading State
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
const request = new ExpenseIndexRequest()
|
|
19
|
+
|
|
20
|
+
request.send()
|
|
21
|
+
|
|
22
|
+
const isLoading = request.isLoading()
|
|
23
|
+
// isLoading is a Ref<boolean> when using VueRequestLoaderFactory
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Batch Loading
|
|
27
|
+
|
|
28
|
+
`VueRequestBatchLoader` can track the loading state of multiple requests. Use it when you want a single loading ref to
|
|
29
|
+
reflect a batch of requests.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { VueRequestBatchLoader } from '@blueprint-ts/core/vue/requests'
|
|
33
|
+
|
|
34
|
+
const batchLoader = new VueRequestBatchLoader(2)
|
|
35
|
+
batchLoader.startBatch(2)
|
|
36
|
+
|
|
37
|
+
const requestA = new ExpenseIndexRequest().setRequestLoader(batchLoader)
|
|
38
|
+
const requestB = new ExpenseIndexRequest().setRequestLoader(batchLoader)
|
|
39
|
+
|
|
40
|
+
requestA.send()
|
|
41
|
+
requestB.send()
|
|
42
|
+
|
|
43
|
+
const isLoading = batchLoader.isLoading()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If the batch will not complete (for example, when a chained request fails), call `abortBatch()` to stop waiting for the
|
|
47
|
+
remaining requests:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
batchLoader.abortBatch()
|
|
51
|
+
```
|
|
@@ -7,7 +7,7 @@ When using `vue-router`, you can automatically bind route parameters to resource
|
|
|
7
7
|
To enable the router to load resources automatically, install the route injection plugin when initializing your router:
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
|
-
import { installRouteInjection } from '@blueprint-ts/core'
|
|
10
|
+
import { installRouteInjection } from '@blueprint-ts/core/vue/router/routeResourceBinding'
|
|
11
11
|
|
|
12
12
|
installRouteInjection(router)
|
|
13
13
|
```
|
|
@@ -17,7 +17,7 @@ installRouteInjection(router)
|
|
|
17
17
|
Use the `defineRoute` helper to define your routes and specify which parameters should be resolved into resources:
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
|
-
import { defineRoute, RouteResourceRequestResolver } from '@blueprint-ts/core'
|
|
20
|
+
import { defineRoute, RouteResourceRequestResolver } from '@blueprint-ts/core/vue/router/routeResourceBinding'
|
|
21
21
|
import ProductDetailPage from '@/pages/ProductDetailPage.vue'
|
|
22
22
|
|
|
23
23
|
export default defineRoute<{
|
|
@@ -26,20 +26,22 @@ export default defineRoute<{
|
|
|
26
26
|
path: ':productId',
|
|
27
27
|
name: 'products.show',
|
|
28
28
|
component: ProductDetailPage,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
new
|
|
35
|
-
|
|
29
|
+
meta: {
|
|
30
|
+
inject: {
|
|
31
|
+
product: {
|
|
32
|
+
from: 'productId',
|
|
33
|
+
resolve: (productId: string) => {
|
|
34
|
+
return new RouteResourceRequestResolver(
|
|
35
|
+
new ProductShowRequest(productId)
|
|
36
|
+
)
|
|
37
|
+
}
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
})
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
Navigation is
|
|
44
|
+
Navigation is blocking by default. Cached values are reused when navigating between child routes with unchanged parameters.
|
|
43
45
|
|
|
44
46
|
## Usage in Components
|
|
45
47
|
|
|
@@ -60,7 +62,7 @@ const props = defineProps<{
|
|
|
60
62
|
`RouteResourceBoundView` is a drop-in replacement for `<RouterView>` that automatically handles loading and error states. Define error and loading components directly in the route:
|
|
61
63
|
|
|
62
64
|
```ts
|
|
63
|
-
import { defineRoute, RouteResourceRequestResolver } from '@blueprint-ts/core'
|
|
65
|
+
import { defineRoute, RouteResourceRequestResolver } from '@blueprint-ts/core/vue/router/routeResourceBinding'
|
|
64
66
|
import ProductDetailPage from '@/pages/ProductDetailPage.vue'
|
|
65
67
|
import GenericErrorPage from '@/pages/GenericErrorPage.vue'
|
|
66
68
|
import LoadingSpinner from '@/components/LoadingSpinner.vue'
|
|
@@ -73,13 +75,15 @@ export default defineRoute<{
|
|
|
73
75
|
component: ProductDetailPage,
|
|
74
76
|
errorComponent: GenericErrorPage,
|
|
75
77
|
loadingComponent: LoadingSpinner,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
new
|
|
82
|
-
|
|
78
|
+
meta: {
|
|
79
|
+
inject: {
|
|
80
|
+
product: {
|
|
81
|
+
from: 'productId',
|
|
82
|
+
resolve: (productId: string) => {
|
|
83
|
+
return new RouteResourceRequestResolver(
|
|
84
|
+
new ProductShowRequest(productId)
|
|
85
|
+
)
|
|
86
|
+
}
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
89
|
}
|
|
@@ -94,7 +98,7 @@ Then replace `<RouterView>` with `<RouteResourceBoundView>` in your layout:
|
|
|
94
98
|
</template>
|
|
95
99
|
|
|
96
100
|
<script setup lang="ts">
|
|
97
|
-
import { RouteResourceBoundView } from '@blueprint-ts/core'
|
|
101
|
+
import { RouteResourceBoundView } from '@blueprint-ts/core/vue/router/routeResourceBinding'
|
|
98
102
|
</script>
|
|
99
103
|
```
|
|
100
104
|
|
|
@@ -164,13 +168,15 @@ export default defineRoute<{
|
|
|
164
168
|
name: 'products.show',
|
|
165
169
|
component: ProductDetailPage,
|
|
166
170
|
lazy: false,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
new
|
|
173
|
-
|
|
171
|
+
meta: {
|
|
172
|
+
inject: {
|
|
173
|
+
product: {
|
|
174
|
+
from: 'productId',
|
|
175
|
+
resolve: (productId: string) => {
|
|
176
|
+
return new RouteResourceRequestResolver(
|
|
177
|
+
new ProductShowRequest(productId)
|
|
178
|
+
)
|
|
179
|
+
}
|
|
174
180
|
}
|
|
175
181
|
}
|
|
176
182
|
}
|
|
@@ -192,7 +198,7 @@ Then use the `useRouteResource` composable inside your component:
|
|
|
192
198
|
</template>
|
|
193
199
|
|
|
194
200
|
<script setup lang="ts">
|
|
195
|
-
import { useRouteResource } from '@blueprint-ts/core'
|
|
201
|
+
import { useRouteResource } from '@blueprint-ts/core/vue/router/routeResourceBinding'
|
|
196
202
|
|
|
197
203
|
const props = defineProps<{
|
|
198
204
|
product: ProductResource
|
package/docs/vue/state.md
CHANGED
|
@@ -19,6 +19,9 @@ The `State` class provides a reactive, type-safe state management system with ri
|
|
|
19
19
|
Create a new state by extending the base class and defining your interface:
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
|
+
import { State } from '@blueprint-ts/core/vue/state'
|
|
23
|
+
import { type PersistenceDriver, LocalStorageDriver } from '@blueprint-ts/core/persistenceDrivers'
|
|
24
|
+
|
|
22
25
|
// Define your state interface
|
|
23
26
|
interface UserStateInterface {
|
|
24
27
|
name: string;
|
|
@@ -42,14 +45,15 @@ class UserState extends State<UserStateInterface> {
|
|
|
42
45
|
}
|
|
43
46
|
},
|
|
44
47
|
{
|
|
45
|
-
persist: true // Enable persistence
|
|
48
|
+
persist: true, // Enable persistence
|
|
49
|
+
persistSuffix: 'user' // Optional namespace for the storage key
|
|
46
50
|
}
|
|
47
51
|
);
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
// Optional: Override persistence method
|
|
51
55
|
protected override getPersistenceDriver(): PersistenceDriver {
|
|
52
|
-
return new LocalStorageDriver()
|
|
56
|
+
return new LocalStorageDriver()
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
|
|
@@ -81,6 +85,16 @@ userState.subscribe(
|
|
|
81
85
|
);
|
|
82
86
|
````
|
|
83
87
|
|
|
88
|
+
`subscribe` returns an unsubscribe function:
|
|
89
|
+
|
|
90
|
+
````typescript
|
|
91
|
+
const unsubscribe = userState.subscribe('name', () => {
|
|
92
|
+
// ...
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
unsubscribe();
|
|
96
|
+
````
|
|
97
|
+
|
|
84
98
|
#### Subscribing to nested properties
|
|
85
99
|
|
|
86
100
|
````typescript
|
|
@@ -121,7 +135,7 @@ userState.subscribe(
|
|
|
121
135
|
````
|
|
122
136
|
|
|
123
137
|
### State Persistence
|
|
124
|
-
Enable state persistence by passing `persist: true` in the constructor options. Override the method `getPersistenceDriver` to use different storage mechanisms:
|
|
138
|
+
Enable state persistence by passing `persist: true` in the constructor options. You can optionally set `persistSuffix` to namespace the storage key. Override the method `getPersistenceDriver` to use different storage mechanisms:
|
|
125
139
|
|
|
126
140
|
````typescript
|
|
127
141
|
// Examples of different persistence drivers:
|
|
@@ -137,6 +151,8 @@ protected override getPersistenceDriver(): PersistenceDriver {
|
|
|
137
151
|
}
|
|
138
152
|
````
|
|
139
153
|
|
|
154
|
+
You can inspect the computed key via `state.persistKey`.
|
|
155
|
+
|
|
140
156
|
### Importing and Exporting State
|
|
141
157
|
|
|
142
158
|
Export the current state to a plain object or import values:
|
|
@@ -154,13 +170,6 @@ userState.import({
|
|
|
154
170
|
}
|
|
155
171
|
});
|
|
156
172
|
|
|
157
|
-
// Import with hook suppression (doesn't trigger change handlers)
|
|
158
|
-
userState.import(
|
|
159
|
-
{
|
|
160
|
-
name: 'Jane Doe'
|
|
161
|
-
},
|
|
162
|
-
true // suppress hooks
|
|
163
|
-
);
|
|
164
173
|
````
|
|
165
174
|
|
|
166
175
|
### Resetting State
|
|
@@ -181,6 +190,13 @@ userState.subscribe(
|
|
|
181
190
|
);
|
|
182
191
|
````
|
|
183
192
|
|
|
193
|
+
### Cleanup
|
|
194
|
+
If you create short‑lived state instances, call `destroy()` to remove watchers and release references:
|
|
195
|
+
|
|
196
|
+
````typescript
|
|
197
|
+
userState.destroy();
|
|
198
|
+
````
|
|
199
|
+
|
|
184
200
|
## Advanced Features
|
|
185
201
|
### Deep Object Watching
|
|
186
202
|
When you modify nested properties, the system automatically detects these changes and triggers appropriate callbacks:
|
|
@@ -290,4 +306,4 @@ formState.state.password = 'securePassword123';
|
|
|
290
306
|
document.getElementById('reset').addEventListener('click', () => {
|
|
291
307
|
formState.reset();
|
|
292
308
|
});
|
|
293
|
-
````
|
|
309
|
+
````
|
package/package.json
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blueprint-ts/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-beta.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"type": "module",
|
|
9
9
|
"exports": {
|
|
10
|
-
"./
|
|
11
|
-
"./
|
|
12
|
-
"./
|
|
13
|
-
"./
|
|
14
|
-
"./
|
|
15
|
-
"./
|
|
16
|
-
"./
|
|
17
|
-
"./
|
|
18
|
-
"./helpers": "./src/helpers.ts",
|
|
10
|
+
"./pagination": "./src/pagination/index.ts",
|
|
11
|
+
"./support": "./src/support/index.ts",
|
|
12
|
+
"./requests": "./src/requests/index.ts",
|
|
13
|
+
"./bulkRequests": "./src/bulkRequests/index.ts",
|
|
14
|
+
"./persistenceDrivers": "./src/persistenceDrivers/index.ts",
|
|
15
|
+
"./requests/exceptions": "./src/requests/exceptions/index.ts",
|
|
16
|
+
"./laravel/requests": "./src/laravel/requests/index.ts",
|
|
17
|
+
"./laravel/pagination": "./src/laravel/pagination/index.ts",
|
|
19
18
|
"./vue": "./src/vue/index.ts",
|
|
20
19
|
"./vue/forms": "./src/vue/forms/index.ts",
|
|
21
20
|
"./vue/forms/validation": "./src/vue/forms/validation/index.ts",
|
|
@@ -75,8 +74,8 @@
|
|
|
75
74
|
"vue-router": "^4.3.2"
|
|
76
75
|
},
|
|
77
76
|
"dependencies": {
|
|
78
|
-
"lodash-es": "^4.17.
|
|
79
|
-
"qs": "^6.
|
|
80
|
-
"uuid": "^
|
|
77
|
+
"lodash-es": "^4.17.23",
|
|
78
|
+
"qs": "^6.15.0",
|
|
79
|
+
"uuid": "^13.0.0"
|
|
81
80
|
}
|
|
82
81
|
}
|
package/release-tool.json
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version_file": "package.json",
|
|
3
|
-
"version_pattern": "\"version\":\\s*\"([0-9]+\\.[0-9]+\\.[0-9]+)\"",
|
|
3
|
+
"version_pattern": "\"version\":\\s*\"([0-9]+\\.[0-9]+\\.[0-9]+(?:-[a-z]+\\.[0-9]+)?)\"",
|
|
4
4
|
"version_template": "\"version\": \"{}\"",
|
|
5
5
|
"develop_branch": "develop",
|
|
6
|
-
"main_branch": "main"
|
|
7
|
-
|
|
6
|
+
"main_branch": "main",
|
|
7
|
+
"docs": {
|
|
8
|
+
"build": {
|
|
9
|
+
"cwd": "./docs",
|
|
10
|
+
"commands": [
|
|
11
|
+
["npm", "ci"],
|
|
12
|
+
["npm", "run", "docs:build"]
|
|
13
|
+
],
|
|
14
|
+
"output_dir": ".vitepress/dist"
|
|
15
|
+
},
|
|
16
|
+
"publish": {
|
|
17
|
+
"repo_path": "./docs",
|
|
18
|
+
"remote": "origin",
|
|
19
|
+
"branch": "gh-pages",
|
|
20
|
+
"subdir": "",
|
|
21
|
+
"commit_message": "docs: publish {tag}",
|
|
22
|
+
"add_nojekyll": true,
|
|
23
|
+
"force_push": false
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import { BulkRequestWrapper } from './BulkRequestWrapper'
|
|
2
2
|
import { BulkRequestEventEnum } from './BulkRequestEvent.enum'
|
|
3
|
-
import { BaseRequest } from '../requests'
|
|
4
3
|
|
|
5
4
|
export enum BulkRequestExecutionMode {
|
|
6
5
|
PARALLEL = 'parallel',
|
|
7
6
|
SEQUENTIAL = 'sequential'
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
export class BulkRequestSender
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
export class BulkRequestSender<
|
|
10
|
+
RequestLoaderLoadingType = unknown,
|
|
11
|
+
RequestBodyInterface = unknown,
|
|
12
|
+
ResponseClass = unknown,
|
|
13
|
+
RequestParamsInterface extends object = object
|
|
14
|
+
> {
|
|
15
|
+
protected events: Map<
|
|
16
|
+
BulkRequestEventEnum,
|
|
17
|
+
((req: BulkRequestWrapper<RequestLoaderLoadingType, RequestBodyInterface, ResponseClass, RequestParamsInterface>) => void)[]
|
|
18
|
+
> = new Map()
|
|
13
19
|
protected abortController: AbortController | undefined = undefined
|
|
14
20
|
|
|
15
21
|
public constructor(
|
|
16
|
-
|
|
17
|
-
protected requests: BulkRequestWrapper<BaseRequest>[] = [],
|
|
22
|
+
protected requests: BulkRequestWrapper<RequestLoaderLoadingType, RequestBodyInterface, ResponseClass, RequestParamsInterface>[] = [],
|
|
18
23
|
protected executionMode: BulkRequestExecutionMode = BulkRequestExecutionMode.PARALLEL,
|
|
19
24
|
protected retryCount: number = 0
|
|
20
25
|
) {}
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
public setRequests(requests: BulkRequestWrapper<BaseRequest>[] = []) {
|
|
27
|
+
public setRequests(requests: BulkRequestWrapper<RequestLoaderLoadingType, RequestBodyInterface, ResponseClass, RequestParamsInterface>[] = []) {
|
|
24
28
|
this.requests = requests
|
|
25
29
|
|
|
26
30
|
return this
|
|
@@ -39,11 +43,13 @@ export class BulkRequestSender {
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
public get isLoading(): boolean {
|
|
42
|
-
return this.requests.some((req) => req.isLoading())
|
|
46
|
+
return this.requests.some((req) => Boolean(req.isLoading() as unknown))
|
|
43
47
|
}
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
public on(
|
|
50
|
+
event: BulkRequestEventEnum,
|
|
51
|
+
callback: (req: BulkRequestWrapper<RequestLoaderLoadingType, RequestBodyInterface, ResponseClass, RequestParamsInterface>) => void
|
|
52
|
+
): this {
|
|
47
53
|
if (!this.events.has(event)) {
|
|
48
54
|
this.events.set(event, [])
|
|
49
55
|
}
|
|
@@ -59,8 +65,10 @@ export class BulkRequestSender {
|
|
|
59
65
|
return this
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
protected emit(
|
|
69
|
+
event: BulkRequestEventEnum,
|
|
70
|
+
req: BulkRequestWrapper<RequestLoaderLoadingType, RequestBodyInterface, ResponseClass, RequestParamsInterface>
|
|
71
|
+
): void {
|
|
64
72
|
const callbacks = this.events.get(event) || []
|
|
65
73
|
|
|
66
74
|
callbacks.forEach((callback) => callback(req))
|
|
@@ -89,10 +97,14 @@ export class BulkRequestSender {
|
|
|
89
97
|
}
|
|
90
98
|
|
|
91
99
|
return {
|
|
92
|
-
getSuccessCount: () => this.requests.filter((r) => !r.
|
|
93
|
-
getErrorCount: () => this.requests.filter((r) => r.
|
|
94
|
-
getSuccessfulResponses: () =>
|
|
95
|
-
|
|
100
|
+
getSuccessCount: () => this.requests.filter((r) => !r.hasError()).length,
|
|
101
|
+
getErrorCount: () => this.requests.filter((r) => r.hasError()).length,
|
|
102
|
+
getSuccessfulResponses: () =>
|
|
103
|
+
this.requests
|
|
104
|
+
.filter((r) => !r.hasError())
|
|
105
|
+
.map((r) => r.getResponse())
|
|
106
|
+
.filter((response): response is ResponseClass => response !== null),
|
|
107
|
+
getFailedResponses: () => this.requests.filter((r) => r.hasError()).map((r) => r.getError())
|
|
96
108
|
}
|
|
97
109
|
}
|
|
98
110
|
|