@blueprint-ts/core 4.1.0-beta.3 → 4.1.0-beta.4
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/requests/BaseRequest.d.ts +9 -0
- package/dist/requests/BaseRequest.js +22 -7
- package/dist/requests/contracts/BaseRequestContract.d.ts +10 -0
- package/dist/vue/forms/BaseForm.d.ts +83 -21
- package/dist/vue/forms/BaseForm.js +793 -221
- package/dist/vue/forms/PropertyAwareArray.d.ts +1 -0
- package/dist/vue/forms/PropertyAwareObject.d.ts +13 -0
- package/dist/vue/forms/PropertyAwareObject.js +18 -0
- package/dist/vue/forms/index.d.ts +2 -1
- package/dist/vue/forms/index.js +2 -1
- package/dist/vue/forms/validation/index.d.ts +4 -3
- package/dist/vue/forms/validation/index.js +2 -1
- package/dist/vue/forms/validation/rules/BaseRule.d.ts +7 -0
- package/dist/vue/forms/validation/rules/BaseRule.js +19 -0
- package/dist/vue/forms/validation/rules/PrecognitiveRule.d.ts +22 -0
- package/dist/vue/forms/validation/rules/PrecognitiveRule.js +58 -0
- package/dist/vue/forms/validation/types/ValidationRules.d.ts +3 -0
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import { type RequestDriverContract } from './contracts/RequestDriverContract';
|
|
|
9
9
|
import { type RequestLoaderFactoryContract } from './contracts/RequestLoaderFactoryContract';
|
|
10
10
|
import { type BaseRequestContract, type EventHandlerCallback } from './contracts/BaseRequestContract';
|
|
11
11
|
import { type HeadersContract } from './contracts/HeadersContract';
|
|
12
|
+
import { type ResponseHandlerContract } from './drivers/contracts/ResponseHandlerContract';
|
|
12
13
|
import { type ResponseContract } from './contracts/ResponseContract';
|
|
13
14
|
import { type RequestConcurrencyOptions } from './types/RequestConcurrencyOptions';
|
|
14
15
|
export declare abstract class BaseRequest<RequestLoaderLoadingType, ResponseErrorBody, ResponseBodyInterface = undefined, ResponseClass extends ResponseContract<ResponseBodyInterface> = BaseResponse<ResponseBodyInterface>, RequestBodyInterface = undefined, RequestParamsInterface extends object = object> implements BaseRequestContract<RequestLoaderLoadingType, RequestBodyInterface, ResponseClass, RequestParamsInterface> {
|
|
@@ -18,6 +19,7 @@ export declare abstract class BaseRequest<RequestLoaderLoadingType, ResponseErro
|
|
|
18
19
|
protected requestLoader: RequestLoaderContract<RequestLoaderLoadingType> | undefined;
|
|
19
20
|
protected abortSignal: AbortSignal | undefined;
|
|
20
21
|
protected concurrencyOptions: RequestConcurrencyOptions | undefined;
|
|
22
|
+
protected additionalHeaders: HeadersContract;
|
|
21
23
|
protected events: {
|
|
22
24
|
[key in RequestEvents]?: EventHandlerCallback[];
|
|
23
25
|
};
|
|
@@ -40,12 +42,19 @@ export declare abstract class BaseRequest<RequestLoaderLoadingType, ResponseErro
|
|
|
40
42
|
withParams(params: RequestParamsInterface): this;
|
|
41
43
|
getParams(): RequestParamsInterface | undefined;
|
|
42
44
|
setBody(requestBody: RequestBodyInterface): this;
|
|
45
|
+
setHeaders(headers: HeadersContract): this;
|
|
43
46
|
getBody(): RequestBodyInterface | undefined;
|
|
44
47
|
requestHeaders(): HeadersContract;
|
|
45
48
|
buildUrl(): URL;
|
|
46
49
|
on<T>(event: RequestEvents, handler: EventHandlerCallback<T>): this;
|
|
47
50
|
protected dispatch<T>(event: RequestEvents, value: T): void;
|
|
48
51
|
send(): Promise<ResponseClass>;
|
|
52
|
+
send(options: {
|
|
53
|
+
resolveBody?: true;
|
|
54
|
+
}): Promise<ResponseClass>;
|
|
55
|
+
send(options: {
|
|
56
|
+
resolveBody: false;
|
|
57
|
+
}): Promise<ResponseHandlerContract>;
|
|
49
58
|
isLoading(): RequestLoaderLoadingType;
|
|
50
59
|
abstract getResponse(): ResponseClass;
|
|
51
60
|
getRequestBodyFactory(): BodyFactoryContract<RequestBodyInterface | undefined> | undefined;
|
|
@@ -23,6 +23,7 @@ export class BaseRequest {
|
|
|
23
23
|
this.requestLoader = undefined;
|
|
24
24
|
this.abortSignal = undefined;
|
|
25
25
|
this.concurrencyOptions = undefined;
|
|
26
|
+
this.additionalHeaders = {};
|
|
26
27
|
/* @ts-expect-error Ignore generics */
|
|
27
28
|
this.events = {};
|
|
28
29
|
if (BaseRequest.requestLoaderFactory !== undefined) {
|
|
@@ -64,6 +65,10 @@ export class BaseRequest {
|
|
|
64
65
|
this.requestBody = requestBody;
|
|
65
66
|
return this;
|
|
66
67
|
}
|
|
68
|
+
setHeaders(headers) {
|
|
69
|
+
this.additionalHeaders = Object.assign(Object.assign({}, this.additionalHeaders), headers);
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
67
72
|
getBody() {
|
|
68
73
|
return this.requestBody;
|
|
69
74
|
}
|
|
@@ -90,8 +95,10 @@ export class BaseRequest {
|
|
|
90
95
|
this.events[event].forEach((handler) => handler(value));
|
|
91
96
|
}
|
|
92
97
|
send() {
|
|
93
|
-
return __awaiter(this,
|
|
98
|
+
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
94
99
|
var _a, _b, _c, _d, _e, _f;
|
|
100
|
+
const responseSkeleton = this.getResponse();
|
|
101
|
+
const acceptHeader = responseSkeleton.getAcceptHeader();
|
|
95
102
|
const concurrencyMode = (_b = (_a = this.concurrencyOptions) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : RequestConcurrencyMode.ALLOW;
|
|
96
103
|
const concurrencyKey = (_d = (_c = this.concurrencyOptions) === null || _c === void 0 ? void 0 : _c.key) !== null && _d !== void 0 ? _d : this.requestId;
|
|
97
104
|
const useReplace = concurrencyMode === RequestConcurrencyMode.REPLACE || concurrencyMode === RequestConcurrencyMode.REPLACE_LATEST;
|
|
@@ -109,17 +116,20 @@ export class BaseRequest {
|
|
|
109
116
|
}
|
|
110
117
|
this.dispatch(RequestEvents.LOADING, true);
|
|
111
118
|
(_e = this.requestLoader) === null || _e === void 0 ? void 0 : _e.setLoading(true);
|
|
112
|
-
const responseSkeleton = this.getResponse();
|
|
113
119
|
const requestBody = this.requestBody === undefined ? undefined : (_f = this.getRequestBodyFactory()) === null || _f === void 0 ? void 0 : _f.make(this.requestBody);
|
|
114
120
|
const requestConfig = this.buildRequestConfig(requestBody, concurrencyKey, sequence, useLatest);
|
|
115
|
-
|
|
116
|
-
.send(this.buildUrl(), this.method(), Object.assign({ Accept:
|
|
117
|
-
.then((
|
|
121
|
+
const responseHandler = yield this.resolveRequestDriver()
|
|
122
|
+
.send(this.buildUrl(), this.method(), Object.assign(Object.assign({ Accept: acceptHeader }, this.requestHeaders()), this.additionalHeaders), requestBody, requestConfig)
|
|
123
|
+
.then((driverResponseHandler) => __awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
var _a;
|
|
118
125
|
if (useLatest && !this.isLatestSequence(concurrencyKey, sequence)) {
|
|
119
126
|
throw new StaleResponseException();
|
|
120
127
|
}
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
if (((_a = driverResponseHandler.getStatusCode()) !== null && _a !== void 0 ? _a : 0) >= 400) {
|
|
129
|
+
const handler = new ErrorHandler(driverResponseHandler);
|
|
130
|
+
yield handler.handle();
|
|
131
|
+
}
|
|
132
|
+
return driverResponseHandler;
|
|
123
133
|
}))
|
|
124
134
|
.catch((error) => __awaiter(this, void 0, void 0, function* () {
|
|
125
135
|
if (useLatest && !this.isLatestSequence(concurrencyKey, sequence)) {
|
|
@@ -144,6 +154,11 @@ export class BaseRequest {
|
|
|
144
154
|
}
|
|
145
155
|
this.decrementConcurrencyInFlight(concurrencyKey);
|
|
146
156
|
});
|
|
157
|
+
if (options.resolveBody === false) {
|
|
158
|
+
return responseHandler;
|
|
159
|
+
}
|
|
160
|
+
yield responseSkeleton.setResponse(responseHandler);
|
|
161
|
+
return responseSkeleton;
|
|
147
162
|
});
|
|
148
163
|
}
|
|
149
164
|
isLoading() {
|
|
@@ -3,7 +3,11 @@ import { RequestEvents } from '../RequestEvents.enum';
|
|
|
3
3
|
import { type BodyFactoryContract } from './BodyFactoryContract';
|
|
4
4
|
import { type HeadersContract } from './HeadersContract';
|
|
5
5
|
import { type RequestConcurrencyOptions } from '../types/RequestConcurrencyOptions';
|
|
6
|
+
import { type ResponseHandlerContract } from '../drivers/contracts/ResponseHandlerContract';
|
|
6
7
|
export type EventHandlerCallback<T> = (value: T) => void;
|
|
8
|
+
export interface SendRequestOptions {
|
|
9
|
+
resolveBody?: boolean;
|
|
10
|
+
}
|
|
7
11
|
export interface BaseRequestContract<RequestLoaderLoadingType, RequestBodyInterface, ResponseClass, RequestParamsInterface extends object> {
|
|
8
12
|
method(): RequestMethodEnum;
|
|
9
13
|
url(): URL | string;
|
|
@@ -15,6 +19,12 @@ export interface BaseRequestContract<RequestLoaderLoadingType, RequestBodyInterf
|
|
|
15
19
|
buildUrl(): URL;
|
|
16
20
|
on<T>(event: RequestEvents, handler: EventHandlerCallback<T>): this;
|
|
17
21
|
send(): Promise<ResponseClass>;
|
|
22
|
+
send(options: {
|
|
23
|
+
resolveBody?: true;
|
|
24
|
+
}): Promise<ResponseClass>;
|
|
25
|
+
send(options: {
|
|
26
|
+
resolveBody: false;
|
|
27
|
+
}): Promise<ResponseHandlerContract>;
|
|
18
28
|
isLoading(): RequestLoaderLoadingType;
|
|
19
29
|
getRequestBodyFactory(): BodyFactoryContract<RequestBodyInterface> | undefined;
|
|
20
30
|
getResponse(): ResponseClass;
|
|
@@ -1,20 +1,26 @@
|
|
|
1
|
-
import { type WritableComputedRef } from 'vue';
|
|
2
1
|
import { type PersistenceDriver } from '../../persistenceDrivers/types/PersistenceDriver';
|
|
3
|
-
import { PropertyAwareArray } from './PropertyAwareArray';
|
|
4
|
-
import {
|
|
2
|
+
import { PropertyAwareArray, type PropertyAwareField } from './PropertyAwareArray';
|
|
3
|
+
import { PropertyAwareObject } from './PropertyAwareObject';
|
|
4
|
+
import { type ValidationGroups, type ValidationRules } from './validation';
|
|
5
5
|
type ErrorMessages = string[];
|
|
6
6
|
interface ErrorObject {
|
|
7
7
|
[key: string]: FieldErrors;
|
|
8
8
|
}
|
|
9
9
|
type ErrorArray = Array<ErrorObject>;
|
|
10
10
|
type FieldErrors = ErrorMessages | ErrorObject | ErrorArray;
|
|
11
|
-
type FieldProperty<T> =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
type FieldProperty<T> = PropertyAwareField<T>;
|
|
12
|
+
type NestedPropertyAwareValue<T> = T extends PropertyAwareArray<infer Item> ? ArrayProperty<Item> : T extends PropertyAwareObject<infer Shape> ? ObjectProperty<Shape> : FieldProperty<T>;
|
|
13
|
+
type ArrayProperty<T> = Array<T extends object ? {
|
|
14
|
+
[P in keyof T]: NestedPropertyAwareValue<T[P]>;
|
|
15
|
+
} : {
|
|
16
|
+
value: FieldProperty<T>;
|
|
17
|
+
}>;
|
|
18
|
+
type ObjectProperty<T extends object> = {
|
|
19
|
+
[K in keyof T]: NestedPropertyAwareValue<T[K]>;
|
|
16
20
|
};
|
|
17
|
-
type PropertyAwareToRaw<T> = T extends Array<infer U> ? Array<PropertyAwareToRaw<U>> : T extends {
|
|
21
|
+
type PropertyAwareToRaw<T> = T extends Array<infer U> ? Array<PropertyAwareToRaw<U>> : T extends PropertyAwareObject<infer Shape> ? {
|
|
22
|
+
[K in keyof Shape]: PropertyAwareToRaw<Shape[K]>;
|
|
23
|
+
} : T extends {
|
|
18
24
|
model: {
|
|
19
25
|
value: infer V;
|
|
20
26
|
};
|
|
@@ -23,12 +29,18 @@ type PropertyAwareToRaw<T> = T extends Array<infer U> ? Array<PropertyAwareToRaw
|
|
|
23
29
|
} : T;
|
|
24
30
|
type ArrayItem<T> = T extends Array<infer Item> ? Item : never;
|
|
25
31
|
type FormProperties<FormBody extends object> = {
|
|
26
|
-
[K in keyof FormBody]: FormBody[K] extends PropertyAwareArray<infer Item> ?
|
|
27
|
-
[P in keyof Item]: FieldProperty<Item[P]>;
|
|
28
|
-
} : {
|
|
29
|
-
value: FieldProperty<Item>;
|
|
30
|
-
}> : FieldProperty<FormBody[K]>;
|
|
32
|
+
[K in keyof FormBody]: FormBody[K] extends PropertyAwareArray<infer Item> ? ArrayProperty<Item> : FormBody[K] extends PropertyAwareObject<infer Shape> ? ObjectProperty<Shape> : FieldProperty<FormBody[K]>;
|
|
31
33
|
};
|
|
34
|
+
interface ValidationContext {
|
|
35
|
+
isDirty?: boolean;
|
|
36
|
+
isSubmitting?: boolean;
|
|
37
|
+
isDependentChange?: boolean;
|
|
38
|
+
isTouched?: boolean;
|
|
39
|
+
}
|
|
40
|
+
interface AsyncValidationContext extends ValidationContext {
|
|
41
|
+
skipSyncValidation?: boolean;
|
|
42
|
+
skipAsyncValidation?: boolean;
|
|
43
|
+
}
|
|
32
44
|
export declare function propertyAwareToRaw<T>(propertyAwareObject: T): PropertyAwareToRaw<T>;
|
|
33
45
|
/**
|
|
34
46
|
* A generic base class for forms.
|
|
@@ -49,6 +61,7 @@ export declare abstract class BaseForm<RequestBody extends object, FormBody exte
|
|
|
49
61
|
private readonly original;
|
|
50
62
|
private readonly _model;
|
|
51
63
|
private _errors;
|
|
64
|
+
private _asyncErrors;
|
|
52
65
|
private _hasErrors;
|
|
53
66
|
protected append: string[];
|
|
54
67
|
protected ignore: string[];
|
|
@@ -56,7 +69,13 @@ export declare abstract class BaseForm<RequestBody extends object, FormBody exte
|
|
|
56
69
|
[serverKey: string]: string | string[];
|
|
57
70
|
};
|
|
58
71
|
protected rules: ValidationRules<FormBody>;
|
|
72
|
+
protected validationGroups: ValidationGroups<FormBody>;
|
|
59
73
|
private fieldDependencies;
|
|
74
|
+
private readonly arrayWrapperCache;
|
|
75
|
+
private readonly arrayItemWrapperCache;
|
|
76
|
+
private readonly asyncValidationDebouncers;
|
|
77
|
+
private readonly pendingAsyncValidationContexts;
|
|
78
|
+
private readonly asyncValidationTokens;
|
|
60
79
|
/**
|
|
61
80
|
* Returns the persistence driver to use.
|
|
62
81
|
* The default is a NonPersistentDriver.
|
|
@@ -87,7 +106,29 @@ export declare abstract class BaseForm<RequestBody extends object, FormBody exte
|
|
|
87
106
|
persistSuffix?: string;
|
|
88
107
|
} | undefined);
|
|
89
108
|
protected defineRules(): ValidationRules<FormBody>;
|
|
109
|
+
protected defineValidationGroups(): ValidationGroups<FormBody>;
|
|
110
|
+
private clearErrorBag;
|
|
111
|
+
private clearSyncErrors;
|
|
112
|
+
private clearAsyncErrors;
|
|
90
113
|
private clearErrors;
|
|
114
|
+
private hasAsyncRules;
|
|
115
|
+
private bumpAsyncValidationToken;
|
|
116
|
+
private cancelPendingAsyncValidations;
|
|
117
|
+
private scheduleAsyncValidation;
|
|
118
|
+
private executeScheduledAsyncValidation;
|
|
119
|
+
private flattenErrorValue;
|
|
120
|
+
private flattenErrorsFromBag;
|
|
121
|
+
private mergeErrorMessages;
|
|
122
|
+
private flattenErrors;
|
|
123
|
+
private applyErrors;
|
|
124
|
+
private getValidationGroupPaths;
|
|
125
|
+
private matchesValidationGroupPath;
|
|
126
|
+
private errorKeyBelongsToGroup;
|
|
127
|
+
private getValidationGroupFields;
|
|
128
|
+
private clearGroupErrors;
|
|
129
|
+
private collectSiblingNestedErrors;
|
|
130
|
+
private validateFieldPreservingNestedErrors;
|
|
131
|
+
private clearErrorBagPaths;
|
|
91
132
|
private getOrCreateErrorArray;
|
|
92
133
|
private getOrCreateErrorObject;
|
|
93
134
|
private getFieldErrors;
|
|
@@ -95,6 +136,9 @@ export declare abstract class BaseForm<RequestBody extends object, FormBody exte
|
|
|
95
136
|
private getArrayItemErrors;
|
|
96
137
|
private getArrayItemFieldErrors;
|
|
97
138
|
private getArrayItemErrorMessages;
|
|
139
|
+
private getObjectFieldErrors;
|
|
140
|
+
private getArrayItemErrorsFromBag;
|
|
141
|
+
private getArrayItemErrorMessagesFromBag;
|
|
98
142
|
private setArrayDirty;
|
|
99
143
|
/**
|
|
100
144
|
* Collapse nested array dirty states into a single boolean/object for array entries.
|
|
@@ -102,6 +146,16 @@ export declare abstract class BaseForm<RequestBody extends object, FormBody exte
|
|
|
102
146
|
private normalizeItemDirtyState;
|
|
103
147
|
private getArrayItemDirty;
|
|
104
148
|
private getArrayItemDirtyValue;
|
|
149
|
+
private getNestedErrorMessagesFromValue;
|
|
150
|
+
private setNestedError;
|
|
151
|
+
private getNestedDirtyValue;
|
|
152
|
+
private createFieldProperty;
|
|
153
|
+
private resolveArrayItemIndex;
|
|
154
|
+
private getArrayItemValueByPath;
|
|
155
|
+
private setArrayItemValueByPath;
|
|
156
|
+
private createObjectWrapperFromShape;
|
|
157
|
+
private getOrCreateArrayItemWrapper;
|
|
158
|
+
private getOrCreateArrayWrappers;
|
|
105
159
|
/**
|
|
106
160
|
* Map server-side errors (including dot-notation paths) into the form error bag.
|
|
107
161
|
*/
|
|
@@ -118,13 +172,18 @@ export declare abstract class BaseForm<RequestBody extends object, FormBody exte
|
|
|
118
172
|
* @returns boolean indicating if the field has been touched
|
|
119
173
|
*/
|
|
120
174
|
isTouched(field: keyof FormBody): boolean;
|
|
121
|
-
protected validateField(field: keyof FormBody, context?:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
175
|
+
protected validateField(field: keyof FormBody, context?: AsyncValidationContext): void;
|
|
176
|
+
validate(isSubmitting?: boolean, options?: {
|
|
177
|
+
skipAsyncValidation?: boolean;
|
|
178
|
+
}): boolean;
|
|
179
|
+
validateGroup(group: string, isSubmitting?: boolean, options?: {
|
|
180
|
+
skipAsyncValidation?: boolean;
|
|
181
|
+
}): boolean;
|
|
182
|
+
private runFieldAsyncValidation;
|
|
183
|
+
validateFieldAsync(field: keyof FormBody, context?: AsyncValidationContext): Promise<boolean>;
|
|
184
|
+
validateAsync(isSubmitting?: boolean): Promise<boolean>;
|
|
185
|
+
validateGroupAsync(group: string, isSubmitting?: boolean): Promise<boolean>;
|
|
186
|
+
touchGroup(group: string): void;
|
|
128
187
|
fillState(data: Partial<FormBody>): void;
|
|
129
188
|
private getValueGetter;
|
|
130
189
|
private getNoArgGetter;
|
|
@@ -149,6 +208,9 @@ export declare abstract class BaseForm<RequestBody extends object, FormBody exte
|
|
|
149
208
|
* @returns boolean indicating if the form has errors
|
|
150
209
|
*/
|
|
151
210
|
hasErrors(): boolean;
|
|
211
|
+
getErrors(): Record<string, ErrorMessages>;
|
|
212
|
+
hasErrorsInGroup(group: string): boolean;
|
|
213
|
+
getErrorsInGroup(group: string): Record<string, ErrorMessages>;
|
|
152
214
|
/**
|
|
153
215
|
* Updates both the state and original value for a given property,
|
|
154
216
|
* keeping the field in a clean (not dirty) state.
|