@blueprint-ts/core 4.1.0-beta.5 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/persistenceDrivers/MemoryPersistenceDriver.d.ts +11 -0
- package/dist/persistenceDrivers/MemoryPersistenceDriver.js +22 -0
- package/dist/persistenceDrivers/index.d.ts +2 -1
- package/dist/persistenceDrivers/index.js +2 -1
- package/dist/requests/BaseRequest.d.ts +2 -0
- package/dist/requests/BaseRequest.js +7 -2
- package/dist/requests/contracts/BaseRequestContract.d.ts +2 -0
- package/dist/requests/drivers/mock/MockRequestAssertionError.d.ts +3 -0
- package/dist/requests/drivers/mock/MockRequestAssertionError.js +6 -0
- package/dist/requests/drivers/mock/MockRequestDriver.d.ts +160 -0
- package/dist/requests/drivers/mock/MockRequestDriver.js +588 -0
- package/dist/requests/drivers/mock/MockRequestTestHelpers.d.ts +20 -0
- package/dist/requests/drivers/mock/MockRequestTestHelpers.js +70 -0
- package/dist/requests/drivers/mock/MockResponseHandler.d.ts +22 -0
- package/dist/requests/drivers/mock/MockResponseHandler.js +59 -0
- package/dist/requests/index.d.ts +5 -2
- package/dist/requests/index.js +4 -1
- package/dist/vue/forms/index.d.ts +2 -1
- package/dist/vue/forms/index.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type PersistenceDriver } from './types/PersistenceDriver';
|
|
2
|
+
export declare class MemoryPersistenceDriver implements PersistenceDriver {
|
|
3
|
+
protected suffix?: string | undefined;
|
|
4
|
+
protected static store: Map<string, string>;
|
|
5
|
+
constructor(suffix?: string | undefined);
|
|
6
|
+
static clear(): void;
|
|
7
|
+
protected storageKey(key: string): string;
|
|
8
|
+
get<T>(key: string): T | null;
|
|
9
|
+
set<T>(key: string, state: T): void;
|
|
10
|
+
remove(key: string): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class MemoryPersistenceDriver {
|
|
2
|
+
constructor(suffix) {
|
|
3
|
+
this.suffix = suffix;
|
|
4
|
+
}
|
|
5
|
+
static clear() {
|
|
6
|
+
MemoryPersistenceDriver.store.clear();
|
|
7
|
+
}
|
|
8
|
+
storageKey(key) {
|
|
9
|
+
return this.suffix ? `state_${key}_${this.suffix}` : `state_${key}`;
|
|
10
|
+
}
|
|
11
|
+
get(key) {
|
|
12
|
+
const data = MemoryPersistenceDriver.store.get(this.storageKey(key));
|
|
13
|
+
return data ? JSON.parse(data) : null;
|
|
14
|
+
}
|
|
15
|
+
set(key, state) {
|
|
16
|
+
MemoryPersistenceDriver.store.set(this.storageKey(key), JSON.stringify(state));
|
|
17
|
+
}
|
|
18
|
+
remove(key) {
|
|
19
|
+
MemoryPersistenceDriver.store.delete(this.storageKey(key));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
MemoryPersistenceDriver.store = new Map();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LocalStorageDriver } from './LocalStorageDriver';
|
|
2
|
+
import { MemoryPersistenceDriver } from './MemoryPersistenceDriver';
|
|
2
3
|
import { NonPersistentDriver } from './NonPersistentDriver';
|
|
3
4
|
import { SessionStorageDriver } from './SessionStorageDriver';
|
|
4
5
|
import { type PersistenceDriver } from './types/PersistenceDriver';
|
|
5
|
-
export { LocalStorageDriver, NonPersistentDriver, SessionStorageDriver };
|
|
6
|
+
export { LocalStorageDriver, MemoryPersistenceDriver, NonPersistentDriver, SessionStorageDriver };
|
|
6
7
|
export type { PersistenceDriver };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LocalStorageDriver } from './LocalStorageDriver';
|
|
2
|
+
import { MemoryPersistenceDriver } from './MemoryPersistenceDriver';
|
|
2
3
|
import { NonPersistentDriver } from './NonPersistentDriver';
|
|
3
4
|
import { SessionStorageDriver } from './SessionStorageDriver';
|
|
4
|
-
export { LocalStorageDriver, NonPersistentDriver, SessionStorageDriver };
|
|
5
|
+
export { LocalStorageDriver, MemoryPersistenceDriver, NonPersistentDriver, SessionStorageDriver };
|
|
@@ -20,6 +20,7 @@ export declare abstract class BaseRequest<RequestLoaderLoadingType, ResponseErro
|
|
|
20
20
|
protected abortSignal: AbortSignal | undefined;
|
|
21
21
|
protected concurrencyOptions: RequestConcurrencyOptions | undefined;
|
|
22
22
|
protected additionalHeaders: HeadersContract;
|
|
23
|
+
protected instanceRequestDriver: RequestDriverContract | undefined;
|
|
23
24
|
protected events: {
|
|
24
25
|
[key in RequestEvents]?: EventHandlerCallback[];
|
|
25
26
|
};
|
|
@@ -35,6 +36,7 @@ export declare abstract class BaseRequest<RequestLoaderLoadingType, ResponseErro
|
|
|
35
36
|
static setDefaultBaseUrl(url: string): void;
|
|
36
37
|
setRequestLoader(loader: RequestLoaderContract<RequestLoaderLoadingType>): this;
|
|
37
38
|
setConcurrency(options?: RequestConcurrencyOptions): this;
|
|
39
|
+
setRequestDriver(driver: RequestDriverContract): this;
|
|
38
40
|
getRequestId(): string;
|
|
39
41
|
abstract method(): RequestMethodEnum;
|
|
40
42
|
abstract url(): URL | string;
|
|
@@ -24,6 +24,7 @@ export class BaseRequest {
|
|
|
24
24
|
this.abortSignal = undefined;
|
|
25
25
|
this.concurrencyOptions = undefined;
|
|
26
26
|
this.additionalHeaders = {};
|
|
27
|
+
this.instanceRequestDriver = undefined;
|
|
27
28
|
/* @ts-expect-error Ignore generics */
|
|
28
29
|
this.events = {};
|
|
29
30
|
if (BaseRequest.requestLoaderFactory !== undefined) {
|
|
@@ -47,6 +48,10 @@ export class BaseRequest {
|
|
|
47
48
|
this.concurrencyOptions = options;
|
|
48
49
|
return this;
|
|
49
50
|
}
|
|
51
|
+
setRequestDriver(driver) {
|
|
52
|
+
this.instanceRequestDriver = driver;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
50
55
|
getRequestId() {
|
|
51
56
|
return this.requestId;
|
|
52
57
|
}
|
|
@@ -227,8 +232,8 @@ export class BaseRequest {
|
|
|
227
232
|
};
|
|
228
233
|
}
|
|
229
234
|
resolveRequestDriver() {
|
|
230
|
-
var _a;
|
|
231
|
-
return (_a = this.getRequestDriver()) !== null &&
|
|
235
|
+
var _a, _b;
|
|
236
|
+
return (_b = (_a = this.instanceRequestDriver) !== null && _a !== void 0 ? _a : this.getRequestDriver()) !== null && _b !== void 0 ? _b : BaseRequest.requestDriver;
|
|
232
237
|
}
|
|
233
238
|
getRequestDriver() {
|
|
234
239
|
return undefined;
|
|
@@ -4,6 +4,7 @@ import { type BodyFactoryContract } from './BodyFactoryContract';
|
|
|
4
4
|
import { type HeadersContract } from './HeadersContract';
|
|
5
5
|
import { type RequestConcurrencyOptions } from '../types/RequestConcurrencyOptions';
|
|
6
6
|
import { type ResponseHandlerContract } from '../drivers/contracts/ResponseHandlerContract';
|
|
7
|
+
import { type RequestDriverContract } from './RequestDriverContract';
|
|
7
8
|
export type EventHandlerCallback<T> = (value: T) => void;
|
|
8
9
|
export interface SendRequestOptions {
|
|
9
10
|
resolveBody?: boolean;
|
|
@@ -30,4 +31,5 @@ export interface BaseRequestContract<RequestLoaderLoadingType, RequestBodyInterf
|
|
|
30
31
|
getResponse(): ResponseClass;
|
|
31
32
|
setAbortSignal(signal: AbortSignal): this;
|
|
32
33
|
setConcurrency(options?: RequestConcurrencyOptions): this;
|
|
34
|
+
setRequestDriver(driver: RequestDriverContract): this;
|
|
33
35
|
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { type BodyContent, type BodyContract } from '../../contracts/BodyContract';
|
|
2
|
+
import { type DriverConfigContract } from '../../contracts/DriverConfigContract';
|
|
3
|
+
import { type HeadersContract, type ResolvedHeadersContract } from '../../contracts/HeadersContract';
|
|
4
|
+
import { type RequestDriverContract } from '../../contracts/RequestDriverContract';
|
|
5
|
+
import { RequestMethodEnum } from '../../RequestMethod.enum';
|
|
6
|
+
import { type ResponseHandlerContract } from '../contracts/ResponseHandlerContract';
|
|
7
|
+
import { type MockResponseBody, type MockResponseDefinition } from './MockResponseHandler';
|
|
8
|
+
export type MockRequestBody = BodyContent | Record<string, unknown> | unknown[] | null | undefined;
|
|
9
|
+
export type MockRequestMatchMode = 'ordered' | 'unordered';
|
|
10
|
+
export type MockRequestPredicate<T> = ((value: T) => boolean) & {
|
|
11
|
+
description?: string;
|
|
12
|
+
};
|
|
13
|
+
export interface MockRequestDriverOptions {
|
|
14
|
+
matchMode?: MockRequestMatchMode;
|
|
15
|
+
}
|
|
16
|
+
export interface MockRequestQuery {
|
|
17
|
+
[key: string]: string | string[];
|
|
18
|
+
}
|
|
19
|
+
export interface MockRequestBodyMatchContext {
|
|
20
|
+
method: RequestMethodEnum;
|
|
21
|
+
url: string;
|
|
22
|
+
headers: ResolvedHeadersContract;
|
|
23
|
+
body?: MockNormalizedRequestBody;
|
|
24
|
+
getJson<T>(): T | undefined;
|
|
25
|
+
getText(): string | undefined;
|
|
26
|
+
getQuery(): MockRequestQuery;
|
|
27
|
+
}
|
|
28
|
+
export type MockRequestMethodMatcher = RequestMethodEnum | MockRequestPredicate<RequestMethodEnum>;
|
|
29
|
+
export type MockRequestUrlMatcher = URL | string | MockRequestPredicate<URL>;
|
|
30
|
+
export type MockRequestHeadersMatcher = HeadersContract | ResolvedHeadersContract | MockRequestPredicate<ResolvedHeadersContract>;
|
|
31
|
+
export type MockRequestQueryMatcher = MockRequestQuery | MockRequestPredicate<MockRequestQuery>;
|
|
32
|
+
export type MockRequestBodyMatcher = MockRequestBody | MockRequestPredicate<MockRequestBodyMatchContext>;
|
|
33
|
+
export interface MockRequestExpectation {
|
|
34
|
+
method: MockRequestMethodMatcher;
|
|
35
|
+
url: MockRequestUrlMatcher;
|
|
36
|
+
headers?: MockRequestHeadersMatcher;
|
|
37
|
+
query?: MockRequestQueryMatcher;
|
|
38
|
+
body?: MockRequestBodyMatcher;
|
|
39
|
+
response: MockResponseDefinition;
|
|
40
|
+
}
|
|
41
|
+
export interface MockRequestExpectationCriteria {
|
|
42
|
+
method: MockRequestMethodMatcher;
|
|
43
|
+
url: MockRequestUrlMatcher;
|
|
44
|
+
headers?: MockRequestHeadersMatcher;
|
|
45
|
+
query?: MockRequestQueryMatcher;
|
|
46
|
+
body?: MockRequestBodyMatcher;
|
|
47
|
+
}
|
|
48
|
+
export type MockNormalizedRequestBody = {
|
|
49
|
+
kind: 'text';
|
|
50
|
+
value: string;
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'binary';
|
|
53
|
+
mimeType?: string;
|
|
54
|
+
bytes: number[];
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'form-data';
|
|
57
|
+
entries: MockNormalizedFormDataEntry[];
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'null';
|
|
60
|
+
};
|
|
61
|
+
export interface MockNormalizedFormDataEntry {
|
|
62
|
+
key: string;
|
|
63
|
+
value: {
|
|
64
|
+
kind: 'text';
|
|
65
|
+
value: string;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'file';
|
|
68
|
+
name?: string;
|
|
69
|
+
mimeType?: string;
|
|
70
|
+
bytes: number[];
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export interface MockRequestHistoryEntry {
|
|
74
|
+
method: RequestMethodEnum;
|
|
75
|
+
url: string;
|
|
76
|
+
headers: ResolvedHeadersContract;
|
|
77
|
+
body?: MockNormalizedRequestBody;
|
|
78
|
+
}
|
|
79
|
+
interface NormalizedMockRequest {
|
|
80
|
+
method: RequestMethodEnum;
|
|
81
|
+
url: string;
|
|
82
|
+
urlWithoutQuery: string;
|
|
83
|
+
parsedUrl: URL;
|
|
84
|
+
headers: ResolvedHeadersContract;
|
|
85
|
+
query: MockRequestQuery;
|
|
86
|
+
body?: MockNormalizedRequestBody;
|
|
87
|
+
}
|
|
88
|
+
interface MockRequestMatchFailure {
|
|
89
|
+
field: 'method' | 'url' | 'headers' | 'query' | 'body';
|
|
90
|
+
message: string;
|
|
91
|
+
expectation: MockRequestExpectation;
|
|
92
|
+
expectedValue?: unknown;
|
|
93
|
+
actualValue?: unknown;
|
|
94
|
+
diffPaths?: string[];
|
|
95
|
+
}
|
|
96
|
+
export declare class MockRequestExpectationBuilder {
|
|
97
|
+
protected readonly driver: MockRequestDriver;
|
|
98
|
+
protected criteria: MockRequestExpectationCriteria;
|
|
99
|
+
constructor(driver: MockRequestDriver, criteria: MockRequestExpectationCriteria);
|
|
100
|
+
withHeaders(headers: MockRequestHeadersMatcher): this;
|
|
101
|
+
withQuery(query: MockRequestQueryMatcher): this;
|
|
102
|
+
withBody(body: MockRequestBodyMatcher): this;
|
|
103
|
+
respond(response: MockResponseDefinition): MockRequestDriver;
|
|
104
|
+
}
|
|
105
|
+
export declare class MockRequestDriver implements RequestDriverContract {
|
|
106
|
+
protected config?: DriverConfigContract | undefined;
|
|
107
|
+
protected expectations: MockRequestExpectation[];
|
|
108
|
+
protected history: MockRequestHistoryEntry[];
|
|
109
|
+
protected matchMode: MockRequestMatchMode;
|
|
110
|
+
constructor(config?: DriverConfigContract | undefined, expectations?: MockRequestExpectation[], options?: MockRequestDriverOptions);
|
|
111
|
+
setMatchMode(mode: MockRequestMatchMode): this;
|
|
112
|
+
ordered(): this;
|
|
113
|
+
unordered(): this;
|
|
114
|
+
expect(expectation: MockRequestExpectation): this;
|
|
115
|
+
expectAny(criteria: MockRequestExpectationCriteria): MockRequestExpectationBuilder;
|
|
116
|
+
reset(): this;
|
|
117
|
+
getHistory(): MockRequestHistoryEntry[];
|
|
118
|
+
assertNoPendingExpectations(): void;
|
|
119
|
+
assertExpectationsMet(): void;
|
|
120
|
+
send(url: URL | string, method: RequestMethodEnum, headers: HeadersContract, body?: BodyContract, requestConfig?: DriverConfigContract): Promise<ResponseHandlerContract>;
|
|
121
|
+
protected selectExpectation(actualRequest: NormalizedMockRequest): Promise<{
|
|
122
|
+
index: number;
|
|
123
|
+
expectation: MockRequestExpectation;
|
|
124
|
+
}>;
|
|
125
|
+
protected matchExpectation(expectation: MockRequestExpectation, actualRequest: NormalizedMockRequest): Promise<MockRequestMatchFailure | undefined>;
|
|
126
|
+
protected matchMethod(method: MockRequestMethodMatcher, actualRequest: NormalizedMockRequest, expectation: MockRequestExpectation): MockRequestMatchFailure | undefined;
|
|
127
|
+
protected matchUrl(expectation: MockRequestExpectation, actualRequest: NormalizedMockRequest): MockRequestMatchFailure | undefined;
|
|
128
|
+
protected matchHeaders(headers: MockRequestHeadersMatcher | undefined, actualRequest: NormalizedMockRequest, expectation: MockRequestExpectation): MockRequestMatchFailure | undefined;
|
|
129
|
+
protected matchQuery(query: MockRequestQueryMatcher | undefined, actualRequest: NormalizedMockRequest, expectation: MockRequestExpectation): MockRequestMatchFailure | undefined;
|
|
130
|
+
protected matchBody(body: MockRequestBodyMatcher | undefined, actualRequest: NormalizedMockRequest, expectation: MockRequestExpectation): Promise<MockRequestMatchFailure | undefined>;
|
|
131
|
+
protected createBodyMatchContext(actualRequest: NormalizedMockRequest): MockRequestBodyMatchContext;
|
|
132
|
+
protected normalizeActualRequest(url: URL | string, method: RequestMethodEnum, headers: HeadersContract, body?: BodyContract): Promise<NormalizedMockRequest>;
|
|
133
|
+
protected toHistoryEntry(request: NormalizedMockRequest): MockRequestHistoryEntry;
|
|
134
|
+
protected buildUnexpectedRequestMessage(actualRequest: NormalizedMockRequest): string;
|
|
135
|
+
protected buildUnorderedMismatchMessage(actualRequest: NormalizedMockRequest, failures: MockRequestMatchFailure[]): string;
|
|
136
|
+
protected buildMismatchMessage(failure: MockRequestMatchFailure, actualRequest: NormalizedMockRequest): string;
|
|
137
|
+
protected formatExpectationSnapshot(expectation: MockRequestExpectation): string;
|
|
138
|
+
protected formatRequestSnapshot(request: NormalizedMockRequest): string;
|
|
139
|
+
protected describeExpectation(expectation: MockRequestExpectation): string;
|
|
140
|
+
protected describeMatcher(matcher: unknown): string;
|
|
141
|
+
protected describeUrlMatcher(expectation: MockRequestExpectation): string;
|
|
142
|
+
protected describeBodyMatcher(body: MockRequestBodyMatcher): string;
|
|
143
|
+
protected describeBodyForMessage(body?: MockNormalizedRequestBody): unknown;
|
|
144
|
+
protected normalizeUrl(url: URL | string): string;
|
|
145
|
+
protected resolveHeaders(headers: HeadersContract | ResolvedHeadersContract): ResolvedHeadersContract;
|
|
146
|
+
protected normalizeBody(body: MockRequestBody): Promise<MockNormalizedRequestBody | undefined>;
|
|
147
|
+
protected normalizeFormData(body: FormData): Promise<MockNormalizedRequestBody>;
|
|
148
|
+
protected getBlobName(value: Blob): string | undefined;
|
|
149
|
+
protected getOptionalBlobDetails(value: Blob): {
|
|
150
|
+
name?: string;
|
|
151
|
+
mimeType?: string;
|
|
152
|
+
};
|
|
153
|
+
protected readBlob(value: Blob): Promise<ArrayBuffer>;
|
|
154
|
+
protected isBufferSource(value: MockRequestBody): value is BufferSource;
|
|
155
|
+
protected toArrayBuffer(value: BufferSource): ArrayBuffer;
|
|
156
|
+
}
|
|
157
|
+
export type { MockResponseBody, MockResponseDefinition };
|
|
158
|
+
export declare function getMockRequestJsonBody<T>(request: Pick<MockRequestHistoryEntry, 'body'>): T | undefined;
|
|
159
|
+
export declare function getMockRequestTextBody(request: Pick<MockRequestHistoryEntry, 'body'>): string | undefined;
|
|
160
|
+
export declare function getMockRequestQuery(request: Pick<MockRequestHistoryEntry, 'url'>): MockRequestQuery;
|
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { ResponseException } from '../../exceptions/ResponseException';
|
|
11
|
+
import { isEqual } from 'lodash-es';
|
|
12
|
+
import { MockRequestAssertionError } from './MockRequestAssertionError';
|
|
13
|
+
import { MockResponseHandler } from './MockResponseHandler';
|
|
14
|
+
function isPredicate(value) {
|
|
15
|
+
return typeof value === 'function';
|
|
16
|
+
}
|
|
17
|
+
function parseUrl(url) {
|
|
18
|
+
if (url instanceof URL) {
|
|
19
|
+
return url;
|
|
20
|
+
}
|
|
21
|
+
return new URL(url, 'https://mock-request.invalid');
|
|
22
|
+
}
|
|
23
|
+
function buildUrlWithoutQuery(url) {
|
|
24
|
+
const clone = new URL(url.toString());
|
|
25
|
+
clone.search = '';
|
|
26
|
+
return clone.toString();
|
|
27
|
+
}
|
|
28
|
+
function parseQuery(url) {
|
|
29
|
+
const query = {};
|
|
30
|
+
for (const [key, value] of url.searchParams.entries()) {
|
|
31
|
+
const current = query[key];
|
|
32
|
+
if (current === undefined) {
|
|
33
|
+
query[key] = value;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(current)) {
|
|
37
|
+
current.push(value);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
query[key] = [current, value];
|
|
41
|
+
}
|
|
42
|
+
return query;
|
|
43
|
+
}
|
|
44
|
+
function stringify(value) {
|
|
45
|
+
return value === undefined ? 'undefined' : JSON.stringify(value, null, 2);
|
|
46
|
+
}
|
|
47
|
+
function getPredicateDescription(predicate) {
|
|
48
|
+
var _a;
|
|
49
|
+
return (_a = predicate.description) !== null && _a !== void 0 ? _a : '[custom matcher]';
|
|
50
|
+
}
|
|
51
|
+
function getTextBody(body) {
|
|
52
|
+
if (!body || body.kind !== 'text') {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return body.value;
|
|
56
|
+
}
|
|
57
|
+
function getJsonBody(body) {
|
|
58
|
+
const textBody = getTextBody(body);
|
|
59
|
+
if (textBody === undefined) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
return JSON.parse(textBody);
|
|
64
|
+
}
|
|
65
|
+
catch (_a) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function collectJsonDiffPaths(expected, actual, path = '', maxPaths = 10) {
|
|
70
|
+
const mismatches = [];
|
|
71
|
+
const visit = (left, right, currentPath) => {
|
|
72
|
+
if (mismatches.length >= maxPaths) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (JSON.stringify(left) === JSON.stringify(right)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
79
|
+
if (left.length !== right.length) {
|
|
80
|
+
mismatches.push(currentPath || '(root)');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
left.forEach((item, index) => {
|
|
84
|
+
visit(item, right[index], currentPath ? `${currentPath}.${index}` : String(index));
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (isRecord(left) && isRecord(right)) {
|
|
89
|
+
const keys = new Set([...Object.keys(left), ...Object.keys(right)]);
|
|
90
|
+
for (const key of keys) {
|
|
91
|
+
visit(left[key], right[key], currentPath ? `${currentPath}.${key}` : key);
|
|
92
|
+
if (mismatches.length >= maxPaths) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
mismatches.push(currentPath || '(root)');
|
|
99
|
+
};
|
|
100
|
+
visit(expected, actual, path);
|
|
101
|
+
return mismatches;
|
|
102
|
+
}
|
|
103
|
+
function isRecord(value) {
|
|
104
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
105
|
+
}
|
|
106
|
+
export class MockRequestExpectationBuilder {
|
|
107
|
+
constructor(driver, criteria) {
|
|
108
|
+
this.driver = driver;
|
|
109
|
+
this.criteria = Object.assign({}, criteria);
|
|
110
|
+
}
|
|
111
|
+
withHeaders(headers) {
|
|
112
|
+
this.criteria.headers = headers;
|
|
113
|
+
return this;
|
|
114
|
+
}
|
|
115
|
+
withQuery(query) {
|
|
116
|
+
this.criteria.query = query;
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
withBody(body) {
|
|
120
|
+
this.criteria.body = body;
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
respond(response) {
|
|
124
|
+
this.driver.expect(Object.assign(Object.assign({}, this.criteria), { response }));
|
|
125
|
+
return this.driver;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export class MockRequestDriver {
|
|
129
|
+
constructor(config, expectations = [], options = {}) {
|
|
130
|
+
var _a;
|
|
131
|
+
this.config = config;
|
|
132
|
+
this.expectations = [];
|
|
133
|
+
this.history = [];
|
|
134
|
+
this.expectations.push(...expectations);
|
|
135
|
+
this.matchMode = (_a = options.matchMode) !== null && _a !== void 0 ? _a : 'ordered';
|
|
136
|
+
}
|
|
137
|
+
setMatchMode(mode) {
|
|
138
|
+
this.matchMode = mode;
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
ordered() {
|
|
142
|
+
return this.setMatchMode('ordered');
|
|
143
|
+
}
|
|
144
|
+
unordered() {
|
|
145
|
+
return this.setMatchMode('unordered');
|
|
146
|
+
}
|
|
147
|
+
expect(expectation) {
|
|
148
|
+
this.expectations.push(expectation);
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
expectAny(criteria) {
|
|
152
|
+
return new MockRequestExpectationBuilder(this, criteria);
|
|
153
|
+
}
|
|
154
|
+
reset() {
|
|
155
|
+
this.expectations = [];
|
|
156
|
+
this.history = [];
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
getHistory() {
|
|
160
|
+
return [...this.history];
|
|
161
|
+
}
|
|
162
|
+
assertNoPendingExpectations() {
|
|
163
|
+
this.assertExpectationsMet();
|
|
164
|
+
}
|
|
165
|
+
assertExpectationsMet() {
|
|
166
|
+
if (this.expectations.length === 0) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const nextExpectation = this.expectations[0];
|
|
170
|
+
if (!nextExpectation) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
throw new MockRequestAssertionError([
|
|
174
|
+
`Expected ${this.expectations.length} more mocked request(s).`,
|
|
175
|
+
`Match mode: ${this.matchMode}`,
|
|
176
|
+
`Next expected request: ${this.describeExpectation(nextExpectation)}`
|
|
177
|
+
].join('\n'));
|
|
178
|
+
}
|
|
179
|
+
send(url, method, headers, body, requestConfig) {
|
|
180
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
var _a;
|
|
182
|
+
if ((_a = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) {
|
|
183
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
184
|
+
}
|
|
185
|
+
const actualRequest = yield this.normalizeActualRequest(url, method, headers, body);
|
|
186
|
+
const { index, expectation } = yield this.selectExpectation(actualRequest);
|
|
187
|
+
this.expectations.splice(index, 1);
|
|
188
|
+
this.history.push(this.toHistoryEntry(actualRequest));
|
|
189
|
+
const response = new MockResponseHandler(expectation.response);
|
|
190
|
+
if (!response.getRawResponse().ok) {
|
|
191
|
+
throw new ResponseException(response);
|
|
192
|
+
}
|
|
193
|
+
return response;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
selectExpectation(actualRequest) {
|
|
197
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
+
if (this.expectations.length === 0) {
|
|
199
|
+
throw new MockRequestAssertionError(this.buildUnexpectedRequestMessage(actualRequest));
|
|
200
|
+
}
|
|
201
|
+
if (this.matchMode === 'ordered') {
|
|
202
|
+
const expectation = this.expectations[0];
|
|
203
|
+
if (!expectation) {
|
|
204
|
+
throw new MockRequestAssertionError(this.buildUnexpectedRequestMessage(actualRequest));
|
|
205
|
+
}
|
|
206
|
+
const failure = yield this.matchExpectation(expectation, actualRequest);
|
|
207
|
+
if (failure) {
|
|
208
|
+
throw new MockRequestAssertionError(this.buildMismatchMessage(failure, actualRequest));
|
|
209
|
+
}
|
|
210
|
+
return { index: 0, expectation };
|
|
211
|
+
}
|
|
212
|
+
const failures = [];
|
|
213
|
+
for (const [index, expectation] of this.expectations.entries()) {
|
|
214
|
+
const failure = yield this.matchExpectation(expectation, actualRequest);
|
|
215
|
+
if (!failure) {
|
|
216
|
+
return { index, expectation };
|
|
217
|
+
}
|
|
218
|
+
failures.push(failure);
|
|
219
|
+
}
|
|
220
|
+
throw new MockRequestAssertionError(this.buildUnorderedMismatchMessage(actualRequest, failures));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
matchExpectation(expectation, actualRequest) {
|
|
224
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
225
|
+
const methodFailure = this.matchMethod(expectation.method, actualRequest, expectation);
|
|
226
|
+
if (methodFailure) {
|
|
227
|
+
return methodFailure;
|
|
228
|
+
}
|
|
229
|
+
const urlFailure = this.matchUrl(expectation, actualRequest);
|
|
230
|
+
if (urlFailure) {
|
|
231
|
+
return urlFailure;
|
|
232
|
+
}
|
|
233
|
+
const headersFailure = this.matchHeaders(expectation.headers, actualRequest, expectation);
|
|
234
|
+
if (headersFailure) {
|
|
235
|
+
return headersFailure;
|
|
236
|
+
}
|
|
237
|
+
const queryFailure = this.matchQuery(expectation.query, actualRequest, expectation);
|
|
238
|
+
if (queryFailure) {
|
|
239
|
+
return queryFailure;
|
|
240
|
+
}
|
|
241
|
+
return yield this.matchBody(expectation.body, actualRequest, expectation);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
matchMethod(method, actualRequest, expectation) {
|
|
245
|
+
if (isPredicate(method)) {
|
|
246
|
+
if (method(actualRequest.method)) {
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
field: 'method',
|
|
251
|
+
message: 'Method matcher returned false.',
|
|
252
|
+
expectation,
|
|
253
|
+
expectedValue: getPredicateDescription(method),
|
|
254
|
+
actualValue: actualRequest.method
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
if (method === actualRequest.method) {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
field: 'method',
|
|
262
|
+
message: 'HTTP method did not match.',
|
|
263
|
+
expectation,
|
|
264
|
+
expectedValue: method,
|
|
265
|
+
actualValue: actualRequest.method
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
matchUrl(expectation, actualRequest) {
|
|
269
|
+
if (isPredicate(expectation.url)) {
|
|
270
|
+
if (expectation.url(actualRequest.parsedUrl)) {
|
|
271
|
+
return undefined;
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
field: 'url',
|
|
275
|
+
message: 'URL matcher returned false.',
|
|
276
|
+
expectation,
|
|
277
|
+
expectedValue: getPredicateDescription(expectation.url),
|
|
278
|
+
actualValue: actualRequest.url
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const expectedUrl = parseUrl(expectation.url);
|
|
282
|
+
const actualComparableUrl = expectation.query !== undefined && expectedUrl.search.length === 0 ? actualRequest.urlWithoutQuery : actualRequest.url;
|
|
283
|
+
const expectedComparableUrl = expectation.query !== undefined && expectedUrl.search.length === 0 ? buildUrlWithoutQuery(expectedUrl) : this.normalizeUrl(expectation.url);
|
|
284
|
+
if (expectedComparableUrl === actualComparableUrl) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
field: 'url',
|
|
289
|
+
message: 'URL did not match.',
|
|
290
|
+
expectation,
|
|
291
|
+
expectedValue: expectedComparableUrl,
|
|
292
|
+
actualValue: actualComparableUrl
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
matchHeaders(headers, actualRequest, expectation) {
|
|
296
|
+
if (headers === undefined) {
|
|
297
|
+
return undefined;
|
|
298
|
+
}
|
|
299
|
+
if (isPredicate(headers)) {
|
|
300
|
+
if (headers(actualRequest.headers)) {
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
field: 'headers',
|
|
305
|
+
message: 'Header matcher returned false.',
|
|
306
|
+
expectation,
|
|
307
|
+
expectedValue: getPredicateDescription(headers),
|
|
308
|
+
actualValue: actualRequest.headers
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
const expectedHeaders = this.resolveHeaders(headers);
|
|
312
|
+
if (isEqual(expectedHeaders, actualRequest.headers)) {
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
field: 'headers',
|
|
317
|
+
message: 'Headers did not match exactly.',
|
|
318
|
+
expectation,
|
|
319
|
+
expectedValue: expectedHeaders,
|
|
320
|
+
actualValue: actualRequest.headers
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
matchQuery(query, actualRequest, expectation) {
|
|
324
|
+
if (query === undefined) {
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
if (isPredicate(query)) {
|
|
328
|
+
if (query(actualRequest.query)) {
|
|
329
|
+
return undefined;
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
field: 'query',
|
|
333
|
+
message: 'Query matcher returned false.',
|
|
334
|
+
expectation,
|
|
335
|
+
expectedValue: getPredicateDescription(query),
|
|
336
|
+
actualValue: actualRequest.query
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
if (isEqual(query, actualRequest.query)) {
|
|
340
|
+
return undefined;
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
field: 'query',
|
|
344
|
+
message: 'Query parameters did not match exactly.',
|
|
345
|
+
expectation,
|
|
346
|
+
expectedValue: query,
|
|
347
|
+
actualValue: actualRequest.query
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
matchBody(body, actualRequest, expectation) {
|
|
351
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
352
|
+
if (body === undefined) {
|
|
353
|
+
return undefined;
|
|
354
|
+
}
|
|
355
|
+
if (isPredicate(body)) {
|
|
356
|
+
const context = this.createBodyMatchContext(actualRequest);
|
|
357
|
+
if (body(context)) {
|
|
358
|
+
return undefined;
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
field: 'body',
|
|
362
|
+
message: 'Body matcher returned false.',
|
|
363
|
+
expectation,
|
|
364
|
+
expectedValue: getPredicateDescription(body),
|
|
365
|
+
actualValue: this.describeBodyForMessage(actualRequest.body)
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
const expectedBody = yield this.normalizeBody(body);
|
|
369
|
+
if (JSON.stringify(expectedBody) === JSON.stringify(actualRequest.body)) {
|
|
370
|
+
return undefined;
|
|
371
|
+
}
|
|
372
|
+
const expectedJson = getJsonBody(expectedBody);
|
|
373
|
+
const actualJson = getJsonBody(actualRequest.body);
|
|
374
|
+
return Object.assign({ field: 'body', message: expectedJson !== undefined && actualJson !== undefined ? 'JSON body did not match.' : 'Body did not match exactly.', expectation, expectedValue: expectedJson !== null && expectedJson !== void 0 ? expectedJson : expectedBody, actualValue: actualJson !== null && actualJson !== void 0 ? actualJson : actualRequest.body }, (expectedJson !== undefined && actualJson !== undefined ? { diffPaths: collectJsonDiffPaths(expectedJson, actualJson) } : {}));
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
createBodyMatchContext(actualRequest) {
|
|
378
|
+
return Object.assign(Object.assign({ method: actualRequest.method, url: actualRequest.url, headers: actualRequest.headers }, (actualRequest.body !== undefined ? { body: actualRequest.body } : {})), { getJson: () => getJsonBody(actualRequest.body), getText: () => getTextBody(actualRequest.body), getQuery: () => actualRequest.query });
|
|
379
|
+
}
|
|
380
|
+
normalizeActualRequest(url, method, headers, body) {
|
|
381
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
382
|
+
var _a;
|
|
383
|
+
const resolvedUrl = parseUrl(url);
|
|
384
|
+
const normalizedBody = yield this.normalizeBody(body === null || body === void 0 ? void 0 : body.getContent());
|
|
385
|
+
return Object.assign({ method, url: this.normalizeUrl(url), urlWithoutQuery: buildUrlWithoutQuery(resolvedUrl), parsedUrl: resolvedUrl, headers: this.resolveHeaders(Object.assign(Object.assign(Object.assign({}, (_a = this.config) === null || _a === void 0 ? void 0 : _a.headers), headers), body === null || body === void 0 ? void 0 : body.getHeaders())), query: parseQuery(resolvedUrl) }, (normalizedBody !== undefined ? { body: normalizedBody } : {}));
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
toHistoryEntry(request) {
|
|
389
|
+
return Object.assign({ method: request.method, url: request.url, headers: request.headers }, (request.body !== undefined ? { body: request.body } : {}));
|
|
390
|
+
}
|
|
391
|
+
buildUnexpectedRequestMessage(actualRequest) {
|
|
392
|
+
return ['Unexpected request received with no expectations left.', '', 'Actual request:', this.formatRequestSnapshot(actualRequest)].join('\n');
|
|
393
|
+
}
|
|
394
|
+
buildUnorderedMismatchMessage(actualRequest, failures) {
|
|
395
|
+
const pending = this.expectations.map((expectation, index) => `${index + 1}. ${this.describeExpectation(expectation)}`).join('\n');
|
|
396
|
+
const firstFailure = failures[0];
|
|
397
|
+
return [
|
|
398
|
+
'Mock request did not match any pending expectation.',
|
|
399
|
+
firstFailure ? `Closest failure: ${firstFailure.message}` : 'No expectation matched.',
|
|
400
|
+
'',
|
|
401
|
+
'Actual request:',
|
|
402
|
+
this.formatRequestSnapshot(actualRequest),
|
|
403
|
+
'',
|
|
404
|
+
'Pending expectations:',
|
|
405
|
+
pending
|
|
406
|
+
].join('\n');
|
|
407
|
+
}
|
|
408
|
+
buildMismatchMessage(failure, actualRequest) {
|
|
409
|
+
const lines = [
|
|
410
|
+
`Mock request ${failure.field} mismatch.`,
|
|
411
|
+
failure.message,
|
|
412
|
+
'',
|
|
413
|
+
'Expected request:',
|
|
414
|
+
this.formatExpectationSnapshot(failure.expectation),
|
|
415
|
+
'',
|
|
416
|
+
'Actual request:',
|
|
417
|
+
this.formatRequestSnapshot(actualRequest)
|
|
418
|
+
];
|
|
419
|
+
if (failure.expectedValue !== undefined || failure.actualValue !== undefined) {
|
|
420
|
+
lines.push('', `Expected ${failure.field}: ${stringify(failure.expectedValue)}`, `Actual ${failure.field}: ${stringify(failure.actualValue)}`);
|
|
421
|
+
}
|
|
422
|
+
if (failure.diffPaths && failure.diffPaths.length > 0) {
|
|
423
|
+
lines.push('', `Differing JSON paths: ${failure.diffPaths.join(', ')}`);
|
|
424
|
+
}
|
|
425
|
+
return lines.join('\n');
|
|
426
|
+
}
|
|
427
|
+
formatExpectationSnapshot(expectation) {
|
|
428
|
+
const lines = [`method: ${this.describeMatcher(expectation.method)}`, `url: ${this.describeUrlMatcher(expectation)}`];
|
|
429
|
+
if (expectation.headers !== undefined) {
|
|
430
|
+
lines.push(`headers: ${this.describeMatcher(expectation.headers)}`);
|
|
431
|
+
}
|
|
432
|
+
if (expectation.query !== undefined) {
|
|
433
|
+
lines.push(`query: ${this.describeMatcher(expectation.query)}`);
|
|
434
|
+
}
|
|
435
|
+
if (expectation.body !== undefined) {
|
|
436
|
+
lines.push(`body: ${this.describeBodyMatcher(expectation.body)}`);
|
|
437
|
+
}
|
|
438
|
+
return lines.join('\n');
|
|
439
|
+
}
|
|
440
|
+
formatRequestSnapshot(request) {
|
|
441
|
+
const lines = [
|
|
442
|
+
`method: ${request.method}`,
|
|
443
|
+
`url: ${request.url}`,
|
|
444
|
+
`headers: ${stringify(request.headers)}`,
|
|
445
|
+
`query: ${stringify(request.query)}`,
|
|
446
|
+
`body: ${stringify(this.describeBodyForMessage(request.body))}`
|
|
447
|
+
];
|
|
448
|
+
return lines.join('\n');
|
|
449
|
+
}
|
|
450
|
+
describeExpectation(expectation) {
|
|
451
|
+
return `${this.describeMatcher(expectation.method)} ${this.describeUrlMatcher(expectation)}`;
|
|
452
|
+
}
|
|
453
|
+
describeMatcher(matcher) {
|
|
454
|
+
if (isPredicate(matcher)) {
|
|
455
|
+
return getPredicateDescription(matcher);
|
|
456
|
+
}
|
|
457
|
+
if (typeof matcher === 'object') {
|
|
458
|
+
return stringify(matcher);
|
|
459
|
+
}
|
|
460
|
+
return String(matcher);
|
|
461
|
+
}
|
|
462
|
+
describeUrlMatcher(expectation) {
|
|
463
|
+
if (isPredicate(expectation.url)) {
|
|
464
|
+
return getPredicateDescription(expectation.url);
|
|
465
|
+
}
|
|
466
|
+
const url = parseUrl(expectation.url);
|
|
467
|
+
if (expectation.query !== undefined && url.search.length === 0) {
|
|
468
|
+
return buildUrlWithoutQuery(url);
|
|
469
|
+
}
|
|
470
|
+
return this.normalizeUrl(expectation.url);
|
|
471
|
+
}
|
|
472
|
+
describeBodyMatcher(body) {
|
|
473
|
+
if (isPredicate(body)) {
|
|
474
|
+
return getPredicateDescription(body);
|
|
475
|
+
}
|
|
476
|
+
return stringify(body);
|
|
477
|
+
}
|
|
478
|
+
describeBodyForMessage(body) {
|
|
479
|
+
const json = getJsonBody(body);
|
|
480
|
+
return json !== null && json !== void 0 ? json : body;
|
|
481
|
+
}
|
|
482
|
+
normalizeUrl(url) {
|
|
483
|
+
return parseUrl(url).toString();
|
|
484
|
+
}
|
|
485
|
+
resolveHeaders(headers) {
|
|
486
|
+
const resolved = {};
|
|
487
|
+
for (const key in headers) {
|
|
488
|
+
const value = headers[key];
|
|
489
|
+
if (value === undefined) {
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
resolved[key] = typeof value === 'function' ? value() : value;
|
|
493
|
+
}
|
|
494
|
+
return resolved;
|
|
495
|
+
}
|
|
496
|
+
normalizeBody(body) {
|
|
497
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
498
|
+
if (body === undefined) {
|
|
499
|
+
return undefined;
|
|
500
|
+
}
|
|
501
|
+
if (body === null) {
|
|
502
|
+
return { kind: 'null' };
|
|
503
|
+
}
|
|
504
|
+
if (typeof body === 'string') {
|
|
505
|
+
return { kind: 'text', value: body };
|
|
506
|
+
}
|
|
507
|
+
if (body instanceof FormData) {
|
|
508
|
+
return yield this.normalizeFormData(body);
|
|
509
|
+
}
|
|
510
|
+
if (body instanceof Blob) {
|
|
511
|
+
const mimeType = body.type || undefined;
|
|
512
|
+
return Object.assign(Object.assign({ kind: 'binary' }, (mimeType !== undefined ? { mimeType } : {})), { bytes: Array.from(new Uint8Array(yield this.readBlob(body))) });
|
|
513
|
+
}
|
|
514
|
+
if (this.isBufferSource(body)) {
|
|
515
|
+
return {
|
|
516
|
+
kind: 'binary',
|
|
517
|
+
bytes: Array.from(new Uint8Array(this.toArrayBuffer(body)))
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
return {
|
|
521
|
+
kind: 'text',
|
|
522
|
+
value: JSON.stringify(body)
|
|
523
|
+
};
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
normalizeFormData(body) {
|
|
527
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
528
|
+
const entries = [];
|
|
529
|
+
for (const [key, value] of body.entries()) {
|
|
530
|
+
if (typeof value === 'string') {
|
|
531
|
+
entries.push({ key, value: { kind: 'text', value } });
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
entries.push({
|
|
535
|
+
key,
|
|
536
|
+
value: Object.assign(Object.assign({ kind: 'file' }, this.getOptionalBlobDetails(value)), { bytes: Array.from(new Uint8Array(yield this.readBlob(value))) })
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
return { kind: 'form-data', entries };
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
getBlobName(value) {
|
|
543
|
+
if (typeof File !== 'undefined' && value instanceof File) {
|
|
544
|
+
return value.name;
|
|
545
|
+
}
|
|
546
|
+
return undefined;
|
|
547
|
+
}
|
|
548
|
+
getOptionalBlobDetails(value) {
|
|
549
|
+
const name = this.getBlobName(value);
|
|
550
|
+
const mimeType = value.type || undefined;
|
|
551
|
+
return Object.assign(Object.assign({}, (name !== undefined ? { name } : {})), (mimeType !== undefined ? { mimeType } : {}));
|
|
552
|
+
}
|
|
553
|
+
readBlob(value) {
|
|
554
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
555
|
+
const blobWithReader = value;
|
|
556
|
+
if (typeof blobWithReader.arrayBuffer === 'function') {
|
|
557
|
+
return yield blobWithReader.arrayBuffer();
|
|
558
|
+
}
|
|
559
|
+
if (typeof FileReader !== 'undefined') {
|
|
560
|
+
return yield new Promise((resolve, reject) => {
|
|
561
|
+
const reader = new FileReader();
|
|
562
|
+
reader.onload = () => resolve(reader.result);
|
|
563
|
+
reader.onerror = () => { var _a; return reject((_a = reader.error) !== null && _a !== void 0 ? _a : new Error('Failed to read Blob contents.')); };
|
|
564
|
+
reader.readAsArrayBuffer(value);
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
return yield new Response(value).arrayBuffer();
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
isBufferSource(value) {
|
|
571
|
+
return value instanceof ArrayBuffer || ArrayBuffer.isView(value);
|
|
572
|
+
}
|
|
573
|
+
toArrayBuffer(value) {
|
|
574
|
+
if (value instanceof ArrayBuffer) {
|
|
575
|
+
return value.slice(0);
|
|
576
|
+
}
|
|
577
|
+
return value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
export function getMockRequestJsonBody(request) {
|
|
581
|
+
return getJsonBody(request.body);
|
|
582
|
+
}
|
|
583
|
+
export function getMockRequestTextBody(request) {
|
|
584
|
+
return getTextBody(request.body);
|
|
585
|
+
}
|
|
586
|
+
export function getMockRequestQuery(request) {
|
|
587
|
+
return parseQuery(parseUrl(request.url));
|
|
588
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type DriverConfigContract } from '../../contracts/DriverConfigContract';
|
|
2
|
+
import { type ResolvedHeadersContract } from '../../contracts/HeadersContract';
|
|
3
|
+
import { type MockNormalizedRequestBody, type MockRequestBodyMatchContext, type MockRequestDriverOptions, MockRequestDriver, type MockRequestExpectation, type MockRequestHistoryEntry, type MockRequestPredicate, type MockRequestQuery, getMockRequestJsonBody, getMockRequestQuery, getMockRequestTextBody } from './MockRequestDriver';
|
|
4
|
+
import { type MockResponseDefinition } from './MockResponseHandler';
|
|
5
|
+
export interface InstallMockRequestDriverOptions extends MockRequestDriverOptions {
|
|
6
|
+
config?: DriverConfigContract;
|
|
7
|
+
expectations?: MockRequestExpectation[];
|
|
8
|
+
}
|
|
9
|
+
export declare function matchHeaders(expectedSubset: ResolvedHeadersContract): MockRequestPredicate<ResolvedHeadersContract>;
|
|
10
|
+
export declare function matchQuery(expectedSubset: MockRequestQuery): MockRequestPredicate<MockRequestQuery>;
|
|
11
|
+
export declare function expectJsonBody(expected: unknown, options?: {
|
|
12
|
+
partial?: boolean;
|
|
13
|
+
}): MockRequestPredicate<MockRequestBodyMatchContext>;
|
|
14
|
+
export declare function jsonResponse<ResponseBody extends object | string | Blob | BufferSource | null | undefined>(status: number, body: ResponseBody, headers?: ResolvedHeadersContract): MockResponseDefinition;
|
|
15
|
+
export declare function validationError(errors: Record<string, string[]>, message?: string): MockResponseDefinition;
|
|
16
|
+
export declare function emptyResponse(status?: number, headers?: ResolvedHeadersContract): MockResponseDefinition;
|
|
17
|
+
export declare function installMockRequestDriver(options?: InstallMockRequestDriverOptions): MockRequestDriver;
|
|
18
|
+
export declare function resetMockRequestDriver(): MockRequestDriver;
|
|
19
|
+
export { getMockRequestJsonBody, getMockRequestTextBody, getMockRequestQuery };
|
|
20
|
+
export type { MockNormalizedRequestBody, MockRequestHistoryEntry };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { isEqual } from 'lodash-es';
|
|
2
|
+
import { BaseRequest } from '../../BaseRequest';
|
|
3
|
+
import { MockRequestDriver, getMockRequestJsonBody, getMockRequestQuery, getMockRequestTextBody } from './MockRequestDriver';
|
|
4
|
+
function createPredicate(description, predicate) {
|
|
5
|
+
const matcher = ((value) => predicate(value));
|
|
6
|
+
matcher.description = description;
|
|
7
|
+
return matcher;
|
|
8
|
+
}
|
|
9
|
+
function matchesSubset(actual, expected) {
|
|
10
|
+
if (Array.isArray(expected)) {
|
|
11
|
+
if (!Array.isArray(actual) || actual.length < expected.length) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return expected.every((item, index) => matchesSubset(actual[index], item));
|
|
15
|
+
}
|
|
16
|
+
if (isRecord(expected)) {
|
|
17
|
+
if (!isRecord(actual)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return Object.keys(expected).every((key) => matchesSubset(actual[key], expected[key]));
|
|
21
|
+
}
|
|
22
|
+
return isEqual(actual, expected);
|
|
23
|
+
}
|
|
24
|
+
function isRecord(value) {
|
|
25
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
26
|
+
}
|
|
27
|
+
export function matchHeaders(expectedSubset) {
|
|
28
|
+
return createPredicate(`headers subset ${JSON.stringify(expectedSubset)}`, (actual) => Object.entries(expectedSubset).every(([key, value]) => actual[key] === value));
|
|
29
|
+
}
|
|
30
|
+
export function matchQuery(expectedSubset) {
|
|
31
|
+
return createPredicate(`query subset ${JSON.stringify(expectedSubset)}`, (actual) => Object.entries(expectedSubset).every(([key, value]) => isEqual(actual[key], value)));
|
|
32
|
+
}
|
|
33
|
+
export function expectJsonBody(expected, options = {}) {
|
|
34
|
+
return createPredicate(options.partial ? `JSON body partial ${JSON.stringify(expected)}` : `JSON body ${JSON.stringify(expected)}`, (context) => {
|
|
35
|
+
const actual = context.getJson();
|
|
36
|
+
if (actual === undefined) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return options.partial ? matchesSubset(actual, expected) : isEqual(actual, expected);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export function jsonResponse(status, body, headers) {
|
|
43
|
+
return Object.assign(Object.assign({ status }, (headers !== undefined ? { headers } : {})), { body });
|
|
44
|
+
}
|
|
45
|
+
export function validationError(errors, message = 'The given data was invalid.') {
|
|
46
|
+
return jsonResponse(422, {
|
|
47
|
+
message,
|
|
48
|
+
errors
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export function emptyResponse(status = 204, headers) {
|
|
52
|
+
return Object.assign({ status }, (headers !== undefined ? { headers } : {}));
|
|
53
|
+
}
|
|
54
|
+
let installedMockRequestDriver;
|
|
55
|
+
export function installMockRequestDriver(options = {}) {
|
|
56
|
+
var _a;
|
|
57
|
+
const driver = new MockRequestDriver(options.config, (_a = options.expectations) !== null && _a !== void 0 ? _a : [], options.matchMode !== undefined ? { matchMode: options.matchMode } : {});
|
|
58
|
+
BaseRequest.setRequestDriver(driver);
|
|
59
|
+
installedMockRequestDriver = driver;
|
|
60
|
+
return driver;
|
|
61
|
+
}
|
|
62
|
+
export function resetMockRequestDriver() {
|
|
63
|
+
if (!installedMockRequestDriver) {
|
|
64
|
+
return installMockRequestDriver();
|
|
65
|
+
}
|
|
66
|
+
installedMockRequestDriver.reset();
|
|
67
|
+
BaseRequest.setRequestDriver(installedMockRequestDriver);
|
|
68
|
+
return installedMockRequestDriver;
|
|
69
|
+
}
|
|
70
|
+
export { getMockRequestJsonBody, getMockRequestTextBody, getMockRequestQuery };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ResolvedHeadersContract } from '../../contracts/HeadersContract';
|
|
2
|
+
import { type ResponseHandlerContract } from '../contracts/ResponseHandlerContract';
|
|
3
|
+
export type MockResponseBody = string | Blob | BufferSource | object | null | undefined;
|
|
4
|
+
export interface MockResponseDefinition {
|
|
5
|
+
status?: number;
|
|
6
|
+
statusText?: string;
|
|
7
|
+
headers?: ResolvedHeadersContract;
|
|
8
|
+
body?: MockResponseBody;
|
|
9
|
+
}
|
|
10
|
+
export declare class MockResponseHandler implements ResponseHandlerContract {
|
|
11
|
+
protected response: Response;
|
|
12
|
+
constructor(definition: MockResponseDefinition);
|
|
13
|
+
getStatusCode(): number | undefined;
|
|
14
|
+
getHeaders(): ResolvedHeadersContract;
|
|
15
|
+
getRawResponse(): Response;
|
|
16
|
+
json<ResponseBodyInterface>(): Promise<ResponseBodyInterface>;
|
|
17
|
+
text(): Promise<string>;
|
|
18
|
+
blob(): Promise<Blob>;
|
|
19
|
+
protected resolveBody(body: MockResponseBody, headers: Headers): BodyInit | null | undefined;
|
|
20
|
+
protected isJsonValue(value: MockResponseBody): value is object;
|
|
21
|
+
protected hasHeader(headers: Headers, key: string): boolean;
|
|
22
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
export class MockResponseHandler {
|
|
11
|
+
constructor(definition) {
|
|
12
|
+
var _a;
|
|
13
|
+
const headers = new Headers(definition.headers);
|
|
14
|
+
const body = this.resolveBody(definition.body, headers);
|
|
15
|
+
this.response = new Response(body, Object.assign({ status: (_a = definition.status) !== null && _a !== void 0 ? _a : 200, headers }, (definition.statusText !== undefined ? { statusText: definition.statusText } : {})));
|
|
16
|
+
}
|
|
17
|
+
getStatusCode() {
|
|
18
|
+
return this.response.status;
|
|
19
|
+
}
|
|
20
|
+
getHeaders() {
|
|
21
|
+
return Object.fromEntries(this.response.headers);
|
|
22
|
+
}
|
|
23
|
+
getRawResponse() {
|
|
24
|
+
return this.response;
|
|
25
|
+
}
|
|
26
|
+
json() {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
return yield this.response.clone().json();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
text() {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
return yield this.response.clone().text();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
blob() {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
return yield this.response.clone().blob();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
resolveBody(body, headers) {
|
|
42
|
+
if (body === undefined || body === null) {
|
|
43
|
+
return body;
|
|
44
|
+
}
|
|
45
|
+
if (this.isJsonValue(body)) {
|
|
46
|
+
if (!this.hasHeader(headers, 'content-type')) {
|
|
47
|
+
headers.set('content-type', 'application/json');
|
|
48
|
+
}
|
|
49
|
+
return JSON.stringify(body);
|
|
50
|
+
}
|
|
51
|
+
return body;
|
|
52
|
+
}
|
|
53
|
+
isJsonValue(value) {
|
|
54
|
+
return typeof value === 'object' && value !== null && !(value instanceof Blob) && !(value instanceof ArrayBuffer) && !ArrayBuffer.isView(value);
|
|
55
|
+
}
|
|
56
|
+
hasHeader(headers, key) {
|
|
57
|
+
return Array.from(headers.keys()).some((headerKey) => headerKey.toLowerCase() === key.toLowerCase());
|
|
58
|
+
}
|
|
59
|
+
}
|
package/dist/requests/index.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ import { BinaryBody } from './bodies/BinaryBody';
|
|
|
13
13
|
import { JsonBodyFactory } from './factories/JsonBodyFactory';
|
|
14
14
|
import { BinaryBodyFactory, type BinaryBodyContent } from './factories/BinaryBodyFactory';
|
|
15
15
|
import { FormDataFactory } from './factories/FormDataFactory';
|
|
16
|
+
import { MockRequestDriver, MockRequestExpectationBuilder, getMockRequestJsonBody, getMockRequestQuery, getMockRequestTextBody, type MockNormalizedRequestBody, type MockRequestBody, type MockRequestBodyMatchContext, type MockRequestBodyMatcher, type MockRequestDriverOptions, type MockRequestExpectation, type MockRequestExpectationCriteria, type MockRequestHeadersMatcher, type MockRequestHistoryEntry, type MockRequestMatchMode, type MockRequestMethodMatcher, type MockRequestPredicate, type MockRequestQuery, type MockRequestQueryMatcher, type MockRequestUrlMatcher, type MockResponseBody, type MockResponseDefinition } from './drivers/mock/MockRequestDriver';
|
|
17
|
+
import { MockRequestAssertionError } from './drivers/mock/MockRequestAssertionError';
|
|
18
|
+
import { emptyResponse, expectJsonBody, installMockRequestDriver, jsonResponse, matchHeaders, matchQuery, resetMockRequestDriver, validationError, type InstallMockRequestDriverOptions } from './drivers/mock/MockRequestTestHelpers';
|
|
16
19
|
import { type BodyContent, type BodyContract } from './contracts/BodyContract';
|
|
17
20
|
import { type RequestLoaderContract } from './contracts/RequestLoaderContract';
|
|
18
21
|
import { type RequestDriverContract } from './contracts/RequestDriverContract';
|
|
@@ -27,5 +30,5 @@ import { type HeaderValue, type HeadersContract, type ResolvedHeadersContract }
|
|
|
27
30
|
import { type RequestConcurrencyOptions } from './types/RequestConcurrencyOptions';
|
|
28
31
|
import { type RequestUploadProgress } from './types/RequestUploadProgress';
|
|
29
32
|
import { XMLHttpRequestDriver } from './drivers/xhr/XMLHttpRequestDriver';
|
|
30
|
-
export { FetchDriver, BaseResponse, JsonResponse, BlobResponse, PlainTextResponse, BaseRequest, ErrorHandler, RequestErrorRouter, RequestEvents, RequestMethodEnum, RequestConcurrencyMode, ResponseException, StaleResponseException, BinaryBody, JsonBodyFactory, BinaryBodyFactory, FormDataFactory, XMLHttpRequestDriver };
|
|
31
|
-
export type { BodyContent, BinaryBodyContent, RequestDriverContract, RequestLoaderContract, BodyContract, RequestLoaderFactoryContract, DriverConfigContract, BodyFactoryContract, ResponseHandlerContract, BaseRequestContract, HeaderValue, HeadersContract, ResolvedHeadersContract, RequestConcurrencyOptions, RequestUploadProgress };
|
|
33
|
+
export { FetchDriver, BaseResponse, JsonResponse, BlobResponse, PlainTextResponse, BaseRequest, ErrorHandler, RequestErrorRouter, RequestEvents, RequestMethodEnum, RequestConcurrencyMode, ResponseException, StaleResponseException, BinaryBody, JsonBodyFactory, BinaryBodyFactory, FormDataFactory, XMLHttpRequestDriver, MockRequestDriver, MockRequestExpectationBuilder, MockRequestAssertionError, expectJsonBody, matchHeaders, matchQuery, jsonResponse, validationError, emptyResponse, installMockRequestDriver, resetMockRequestDriver, getMockRequestJsonBody, getMockRequestTextBody, getMockRequestQuery };
|
|
34
|
+
export type { BodyContent, BinaryBodyContent, RequestDriverContract, RequestLoaderContract, BodyContract, RequestLoaderFactoryContract, DriverConfigContract, BodyFactoryContract, ResponseHandlerContract, BaseRequestContract, HeaderValue, HeadersContract, ResolvedHeadersContract, RequestConcurrencyOptions, RequestUploadProgress, MockNormalizedRequestBody, MockRequestBody, MockRequestBodyMatchContext, MockRequestBodyMatcher, MockRequestDriverOptions, MockRequestExpectation, MockRequestExpectationCriteria, MockRequestHeadersMatcher, MockRequestHistoryEntry, MockRequestMatchMode, MockRequestMethodMatcher, MockRequestPredicate, MockRequestQuery, MockRequestQueryMatcher, MockRequestUrlMatcher, MockResponseBody, MockResponseDefinition, InstallMockRequestDriverOptions };
|
package/dist/requests/index.js
CHANGED
|
@@ -13,7 +13,10 @@ import { BinaryBody } from './bodies/BinaryBody';
|
|
|
13
13
|
import { JsonBodyFactory } from './factories/JsonBodyFactory';
|
|
14
14
|
import { BinaryBodyFactory } from './factories/BinaryBodyFactory';
|
|
15
15
|
import { FormDataFactory } from './factories/FormDataFactory';
|
|
16
|
+
import { MockRequestDriver, MockRequestExpectationBuilder, getMockRequestJsonBody, getMockRequestQuery, getMockRequestTextBody } from './drivers/mock/MockRequestDriver';
|
|
17
|
+
import { MockRequestAssertionError } from './drivers/mock/MockRequestAssertionError';
|
|
18
|
+
import { emptyResponse, expectJsonBody, installMockRequestDriver, jsonResponse, matchHeaders, matchQuery, resetMockRequestDriver, validationError } from './drivers/mock/MockRequestTestHelpers';
|
|
16
19
|
import { ResponseException } from './exceptions/ResponseException';
|
|
17
20
|
import { StaleResponseException } from './exceptions/StaleResponseException';
|
|
18
21
|
import { XMLHttpRequestDriver } from './drivers/xhr/XMLHttpRequestDriver';
|
|
19
|
-
export { FetchDriver, BaseResponse, JsonResponse, BlobResponse, PlainTextResponse, BaseRequest, ErrorHandler, RequestErrorRouter, RequestEvents, RequestMethodEnum, RequestConcurrencyMode, ResponseException, StaleResponseException, BinaryBody, JsonBodyFactory, BinaryBodyFactory, FormDataFactory, XMLHttpRequestDriver };
|
|
22
|
+
export { FetchDriver, BaseResponse, JsonResponse, BlobResponse, PlainTextResponse, BaseRequest, ErrorHandler, RequestErrorRouter, RequestEvents, RequestMethodEnum, RequestConcurrencyMode, ResponseException, StaleResponseException, BinaryBody, JsonBodyFactory, BinaryBodyFactory, FormDataFactory, XMLHttpRequestDriver, MockRequestDriver, MockRequestExpectationBuilder, MockRequestAssertionError, expectJsonBody, matchHeaders, matchQuery, jsonResponse, validationError, emptyResponse, installMockRequestDriver, resetMockRequestDriver, getMockRequestJsonBody, getMockRequestTextBody, getMockRequestQuery };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BaseForm, propertyAwareToRaw } from './BaseForm';
|
|
2
2
|
import { type PersistedForm } from './types/PersistedForm';
|
|
3
3
|
import { LocalStorageDriver } from '../../persistenceDrivers/LocalStorageDriver';
|
|
4
|
+
import { MemoryPersistenceDriver } from '../../persistenceDrivers/MemoryPersistenceDriver';
|
|
4
5
|
import { NonPersistentDriver } from '../../persistenceDrivers/NonPersistentDriver';
|
|
5
6
|
import { SessionStorageDriver } from '../../persistenceDrivers/SessionStorageDriver';
|
|
6
7
|
import { type PersistenceDriver } from '../../persistenceDrivers/types/PersistenceDriver';
|
|
@@ -8,5 +9,5 @@ import { PropertyAwareArray, type PropertyAwareField, type PropertyAware } from
|
|
|
8
9
|
import { PropertyAwareObject } from './PropertyAwareObject';
|
|
9
10
|
import { StrictPersistenceRestorePolicy } from './persistence';
|
|
10
11
|
import type { PersistenceDebugEvent, PersistenceRestoreContext, PersistenceRestorePolicy, PersistenceRestoreResult } from './persistence';
|
|
11
|
-
export { BaseForm, propertyAwareToRaw, PropertyAwareArray, PropertyAwareObject, NonPersistentDriver, SessionStorageDriver, LocalStorageDriver, StrictPersistenceRestorePolicy };
|
|
12
|
+
export { BaseForm, propertyAwareToRaw, PropertyAwareArray, PropertyAwareObject, NonPersistentDriver, SessionStorageDriver, LocalStorageDriver, MemoryPersistenceDriver, StrictPersistenceRestorePolicy };
|
|
12
13
|
export type { PersistedForm, PersistenceDriver, PropertyAwareField, PropertyAware, PersistenceDebugEvent, PersistenceRestoreContext, PersistenceRestorePolicy, PersistenceRestoreResult };
|
package/dist/vue/forms/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { BaseForm, propertyAwareToRaw } from './BaseForm';
|
|
2
2
|
import { LocalStorageDriver } from '../../persistenceDrivers/LocalStorageDriver';
|
|
3
|
+
import { MemoryPersistenceDriver } from '../../persistenceDrivers/MemoryPersistenceDriver';
|
|
3
4
|
import { NonPersistentDriver } from '../../persistenceDrivers/NonPersistentDriver';
|
|
4
5
|
import { SessionStorageDriver } from '../../persistenceDrivers/SessionStorageDriver';
|
|
5
6
|
import { PropertyAwareArray } from './PropertyAwareArray';
|
|
6
7
|
import { PropertyAwareObject } from './PropertyAwareObject';
|
|
7
8
|
import { StrictPersistenceRestorePolicy } from './persistence';
|
|
8
|
-
export { BaseForm, propertyAwareToRaw, PropertyAwareArray, PropertyAwareObject, NonPersistentDriver, SessionStorageDriver, LocalStorageDriver, StrictPersistenceRestorePolicy };
|
|
9
|
+
export { BaseForm, propertyAwareToRaw, PropertyAwareArray, PropertyAwareObject, NonPersistentDriver, SessionStorageDriver, LocalStorageDriver, MemoryPersistenceDriver, StrictPersistenceRestorePolicy };
|