api-def 0.9.4-alpha.2 → 0.10.0-alpha.2
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/cjs/Api.js +0 -1
- package/cjs/ApiTypes.d.ts +15 -8
- package/cjs/Endpoint.d.ts +11 -11
- package/cjs/EndpointBuilder.d.ts +8 -7
- package/cjs/EndpointBuilder.js +4 -0
- package/cjs/MockingTypes.d.ts +12 -11
- package/cjs/RequestConfig.d.ts +2 -2
- package/cjs/RequestConfig.js +3 -0
- package/cjs/RequestContext.d.ts +14 -10
- package/cjs/RequestContext.js +7 -0
- package/cjs/Requester.d.ts +2 -2
- package/cjs/TextDecoding.js +0 -2
- package/cjs/Utils.js +0 -2
- package/cjs/Validation.d.ts +7 -6
- package/cjs/backend/AxiosRequestBackend.js +4 -4
- package/cjs/backend/FetchRequestBackend.d.ts +1 -1
- package/cjs/backend/FetchRequestBackend.js +4 -2
- package/cjs/backend/MockRequestBackend.js +5 -3
- package/cjs/cache/LocalForageCacheBackend.js +0 -1
- package/cjs/middleware/LoggingMiddleware.js +0 -3
- package/cjs/util/retry/lib/retry.js +0 -1
- package/esm/Api.js +0 -1
- package/esm/ApiTypes.d.ts +15 -8
- package/esm/Endpoint.d.ts +11 -11
- package/esm/EndpointBuilder.d.ts +8 -7
- package/esm/EndpointBuilder.js +4 -0
- package/esm/MockingTypes.d.ts +12 -11
- package/esm/RequestConfig.d.ts +2 -2
- package/esm/RequestConfig.js +3 -0
- package/esm/RequestContext.d.ts +14 -10
- package/esm/RequestContext.js +3 -1
- package/esm/Requester.d.ts +2 -2
- package/esm/TextDecoding.js +0 -2
- package/esm/Utils.js +0 -2
- package/esm/Validation.d.ts +7 -6
- package/esm/backend/AxiosRequestBackend.js +4 -4
- package/esm/backend/FetchRequestBackend.d.ts +1 -1
- package/esm/backend/FetchRequestBackend.js +4 -2
- package/esm/backend/MockRequestBackend.js +5 -3
- package/esm/cache/LocalForageCacheBackend.js +0 -1
- package/esm/middleware/LoggingMiddleware.js +0 -3
- package/esm/util/retry/lib/retry.js +0 -1
- package/package.json +5 -5
package/cjs/Api.js
CHANGED
|
@@ -120,7 +120,6 @@ var Api = /** @class */ (function () {
|
|
|
120
120
|
if (process.env.NODE_ENV === "development") {
|
|
121
121
|
if ((0, exports.isRequestBackendDefault)() && !defaultBackendMessageShown) {
|
|
122
122
|
defaultBackendMessageShown = true;
|
|
123
|
-
// eslint-disable-next-line
|
|
124
123
|
console.warn("[api-def] Using default fetch backend, you can use a different one with 'setRequestBackend()' (dev only message)");
|
|
125
124
|
}
|
|
126
125
|
}
|
package/cjs/ApiTypes.d.ts
CHANGED
|
@@ -8,12 +8,14 @@ export type Headers = Record<string, string | number | boolean | null | undefine
|
|
|
8
8
|
export type Params = string;
|
|
9
9
|
export type Query = string | undefined | Record<string, any>;
|
|
10
10
|
export type Body = string | number | Record<string, any>;
|
|
11
|
+
export type State = Record<string, any>;
|
|
11
12
|
export interface ApiResponse<T = any> {
|
|
12
13
|
readonly method: RequestMethod;
|
|
13
14
|
readonly url: string;
|
|
14
15
|
readonly status: number;
|
|
15
16
|
readonly data: T;
|
|
16
17
|
readonly headers: Record<string, string>;
|
|
18
|
+
readonly state: State;
|
|
17
19
|
}
|
|
18
20
|
export type RequestLock = string | false;
|
|
19
21
|
export type QueryStringify = (query: any) => string;
|
|
@@ -41,22 +43,27 @@ export interface BaseRequestConfig {
|
|
|
41
43
|
queryParser?: QueryStringify;
|
|
42
44
|
queryHandling?: Partial<QueryHandling>;
|
|
43
45
|
}
|
|
44
|
-
export type RequestConfig<
|
|
46
|
+
export type RequestConfig<TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> = (TParams extends undefined ? {
|
|
45
47
|
params?: never;
|
|
46
48
|
} : {
|
|
47
|
-
params: Record<
|
|
48
|
-
}) & (
|
|
49
|
+
params: Record<TParams extends Params ? TParams : never, string>;
|
|
50
|
+
}) & (TQuery extends undefined ? {
|
|
49
51
|
query?: never;
|
|
50
52
|
} : {
|
|
51
|
-
query:
|
|
52
|
-
}) & (
|
|
53
|
+
query: TQuery;
|
|
54
|
+
}) & (TBody extends undefined ? {
|
|
53
55
|
body?: never;
|
|
54
56
|
} : {
|
|
55
|
-
body:
|
|
57
|
+
body: TBody;
|
|
58
|
+
}) & ({} extends TState ? {
|
|
59
|
+
state?: TState;
|
|
60
|
+
} : {
|
|
61
|
+
state: TState;
|
|
56
62
|
}) & BaseRequestConfig;
|
|
57
63
|
export declare const COMPUTED_CONFIG_SYMBOL: unique symbol;
|
|
58
|
-
export type ComputedRequestConfig<
|
|
64
|
+
export type ComputedRequestConfig<TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> = Omit<RequestConfig<TParams, TQuery, TBody, TState>, "queryParser" | "query" | "queryHandling" | "state"> & {
|
|
59
65
|
[COMPUTED_CONFIG_SYMBOL]: true;
|
|
66
|
+
state: TState;
|
|
60
67
|
queryObject: Record<string, any> | undefined;
|
|
61
68
|
queryString: string | undefined;
|
|
62
69
|
queryHandling: QueryHandling;
|
|
@@ -90,7 +97,7 @@ export interface RequestHost {
|
|
|
90
97
|
readonly path: string;
|
|
91
98
|
readonly responseType: ResponseType | undefined;
|
|
92
99
|
readonly validation: Validation;
|
|
93
|
-
computeConfig<
|
|
100
|
+
computeConfig<TParams extends Params | undefined, TQuery extends Query | undefined, TBody extends Body | undefined, TState extends State>(config: RequestConfig<TParams, TQuery, TBody, TState>): ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
94
101
|
computePath(path: string, config: RequestConfig): string;
|
|
95
102
|
getRequestBackend(): RequestBackend;
|
|
96
103
|
}
|
package/cjs/Endpoint.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { Api } from "./Api";
|
|
2
2
|
import type { RequestMethod, ResponseType } from "./ApiConstants";
|
|
3
|
-
import type { ApiResponse, BaseRequestConfig, Body, ComputedRequestConfig, Params, Query, RequestConfig, RequestHost } from "./ApiTypes";
|
|
3
|
+
import type { ApiResponse, BaseRequestConfig, Body, ComputedRequestConfig, Params, Query, RequestConfig, RequestHost, State } from "./ApiTypes";
|
|
4
4
|
import type * as Mocking from "./MockingTypes";
|
|
5
5
|
import type { Validation } from "./Validation";
|
|
6
6
|
import type RequestBackend from "./backend/RequestBackend";
|
|
7
|
-
export interface EndpointConfig<
|
|
7
|
+
export interface EndpointConfig<TResult, TParams extends Params | undefined, TQuery extends Query | undefined, TBody extends Body | undefined, TState extends State = State, TPath extends string = string> {
|
|
8
8
|
readonly id: string;
|
|
9
9
|
readonly method: RequestMethod;
|
|
10
|
-
readonly path:
|
|
10
|
+
readonly path: TPath;
|
|
11
11
|
/**
|
|
12
12
|
* Name your endpoint to help with debugging and documentation
|
|
13
13
|
* @default `id` is used as the name if no name is supplied
|
|
@@ -29,10 +29,10 @@ export interface EndpointConfig<R, P extends Params | undefined, Q extends Query
|
|
|
29
29
|
* and testing.
|
|
30
30
|
* Enable/disable mocked returns for all endpoints on your API object.
|
|
31
31
|
*/
|
|
32
|
-
readonly mocking?: Mocking.EndpointMockingConfig<
|
|
33
|
-
readonly validation?: Validation<
|
|
32
|
+
readonly mocking?: Mocking.EndpointMockingConfig<TResult, TParams, TQuery, TBody, TState>;
|
|
33
|
+
readonly validation?: Validation<TResult, TParams, TQuery, TBody, TState>;
|
|
34
34
|
}
|
|
35
|
-
export default class Endpoint<
|
|
35
|
+
export default class Endpoint<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> implements EndpointConfig<TResponse, TParams, TQuery, TBody, TState>, RequestHost {
|
|
36
36
|
readonly api: Api;
|
|
37
37
|
readonly id: string;
|
|
38
38
|
readonly method: RequestMethod;
|
|
@@ -41,12 +41,12 @@ export default class Endpoint<R = any, P extends Params | undefined = Params | u
|
|
|
41
41
|
readonly path: string;
|
|
42
42
|
readonly config?: BaseRequestConfig;
|
|
43
43
|
readonly responseType: ResponseType | undefined;
|
|
44
|
-
readonly mocking?: Mocking.EndpointMockingConfig<
|
|
45
|
-
readonly validation: Validation<
|
|
46
|
-
constructor(api: Api, info: EndpointConfig<
|
|
47
|
-
submit(config: RequestConfig<
|
|
44
|
+
readonly mocking?: Mocking.EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState>;
|
|
45
|
+
readonly validation: Validation<TResponse, TParams, TQuery, TBody, TState>;
|
|
46
|
+
constructor(api: Api, info: EndpointConfig<TResponse, TParams, TQuery, TBody, TState>);
|
|
47
|
+
submit(config: RequestConfig<TParams, TQuery, TBody, TState>): Promise<ApiResponse<TResponse>>;
|
|
48
48
|
computePath(path: string, request: RequestConfig): string;
|
|
49
49
|
get baseUrl(): string;
|
|
50
|
-
computeConfig<
|
|
50
|
+
computeConfig<TParams extends Params | undefined, TQuery extends Query | undefined, TBody extends Body | undefined, TState extends State>(config: RequestConfig<TParams, TQuery, TBody, TState>): ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
51
51
|
getRequestBackend(): RequestBackend;
|
|
52
52
|
}
|
package/cjs/EndpointBuilder.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type * as zod from "zod";
|
|
2
2
|
import type { Api } from "./Api";
|
|
3
|
-
import type { Body, Params, Query } from "./ApiTypes";
|
|
3
|
+
import type { Body, Params, Query, State } from "./ApiTypes";
|
|
4
4
|
import Endpoint, { type EndpointConfig } from "./Endpoint";
|
|
5
|
-
export default class EndpointBuilder<
|
|
5
|
+
export default class EndpointBuilder<TResponse = any, TParams extends Params | undefined = undefined, TQuery extends Query | undefined = undefined, TBody extends Body | undefined = undefined, TState extends State = State> {
|
|
6
6
|
private api;
|
|
7
7
|
private readonly validation;
|
|
8
8
|
constructor(api: Api);
|
|
9
|
-
queryOf<
|
|
10
|
-
paramsOf<
|
|
11
|
-
bodyOf<
|
|
12
|
-
responseOf<
|
|
13
|
-
|
|
9
|
+
queryOf<TNewQuery extends Query>(schema?: zod.Schema<TNewQuery>): EndpointBuilder<TResponse, TParams, TNewQuery, TBody>;
|
|
10
|
+
paramsOf<TNewParams extends Params>(): EndpointBuilder<TResponse, TNewParams, TQuery, TBody, TState>;
|
|
11
|
+
bodyOf<TNewBody extends Body>(schema?: zod.Schema<TNewBody>): EndpointBuilder<TResponse, TParams, TQuery, TNewBody, TState>;
|
|
12
|
+
responseOf<TNewResponse>(schema?: zod.Schema<TNewResponse>): EndpointBuilder<TNewResponse, TParams, TQuery, TBody, TState>;
|
|
13
|
+
stateOf<TNewState extends State>(schema?: zod.Schema<TNewState>): EndpointBuilder<TResponse, TParams, TQuery, TBody, TNewState>;
|
|
14
|
+
build<TPath extends string>(config: Omit<EndpointConfig<TResponse, TParams, TQuery, TBody, TState, TPath>, "validation">): Endpoint<TResponse, TParams, TQuery, TBody, TState>;
|
|
14
15
|
}
|
package/cjs/EndpointBuilder.js
CHANGED
|
@@ -36,6 +36,10 @@ var EndpointBuilder = /** @class */ (function () {
|
|
|
36
36
|
this.validation.response = schema;
|
|
37
37
|
return this;
|
|
38
38
|
};
|
|
39
|
+
EndpointBuilder.prototype.stateOf = function (schema) {
|
|
40
|
+
this.validation.state = schema;
|
|
41
|
+
return this;
|
|
42
|
+
};
|
|
39
43
|
EndpointBuilder.prototype.build = function (config) {
|
|
40
44
|
var endpoint = new Endpoint_1.default(this.api, __assign(__assign({}, config), { validation: this.validation }));
|
|
41
45
|
this.api.endpoints[endpoint.id] = endpoint;
|
package/cjs/MockingTypes.d.ts
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
import type { ApiResponse, Body, Headers, Params, Query } from "./ApiTypes";
|
|
1
|
+
import type { ApiResponse, Body, Headers, Params, Query, State } from "./ApiTypes";
|
|
2
2
|
export interface ApiMockingConfig {
|
|
3
3
|
enabled: boolean | (() => boolean);
|
|
4
4
|
}
|
|
5
|
-
export interface MockRequest<
|
|
6
|
-
params:
|
|
7
|
-
body:
|
|
8
|
-
query:
|
|
5
|
+
export interface MockRequest<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
6
|
+
params: TParams extends Params ? Record<TParams, string> : {};
|
|
7
|
+
body: TBody;
|
|
8
|
+
query: TQuery;
|
|
9
9
|
headers: Readonly<Headers>;
|
|
10
10
|
url: string;
|
|
11
|
+
state: TState;
|
|
11
12
|
}
|
|
12
|
-
export interface MockResponse<
|
|
13
|
+
export interface MockResponse<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
13
14
|
statusCode: number;
|
|
14
|
-
response:
|
|
15
|
+
response: TResponse | undefined;
|
|
15
16
|
headers: Headers;
|
|
16
17
|
status(statusCode: number): this;
|
|
17
|
-
send(response:
|
|
18
|
+
send(response: TResponse): this;
|
|
18
19
|
}
|
|
19
20
|
export type MockRequestError = Error & {
|
|
20
21
|
response?: ApiResponse;
|
|
21
22
|
};
|
|
22
|
-
export type EndpointMockingFunction<
|
|
23
|
-
export interface EndpointMockingConfig<
|
|
23
|
+
export type EndpointMockingFunction<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> = (req: MockRequest<TResponse, TParams, TQuery, TBody, TState>, res: MockResponse<TResponse, TParams, TQuery, TBody, TState>) => Promise<MockResponse<TResponse, TParams, TQuery, TBody>> | MockResponse<TResponse, TParams, TQuery, TBody, TState>;
|
|
24
|
+
export interface EndpointMockingConfig<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
24
25
|
/**-
|
|
25
26
|
* The range supplied will be used to simulate the lag in obtaining a response
|
|
26
27
|
* your endpoint. If no values are supplied, a response will be returned immediately
|
|
27
28
|
*/
|
|
28
29
|
delay?: number | [minMs: number, maxMs: number];
|
|
29
|
-
handler: EndpointMockingFunction<
|
|
30
|
+
handler: EndpointMockingFunction<TResponse, TParams, TQuery, TBody, TState>;
|
|
30
31
|
}
|
package/cjs/RequestConfig.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type BaseRequestConfig, type Body, type ComputedRequestConfig, type Query, type RequestConfig } from "./ApiTypes";
|
|
2
|
-
export declare const computeRequestConfig: <
|
|
1
|
+
import { type BaseRequestConfig, type Body, type ComputedRequestConfig, type Query, type RequestConfig, type State } from "./ApiTypes";
|
|
2
|
+
export declare const computeRequestConfig: <TParams extends string | undefined, TQuery extends Query, TBody extends Body | undefined, TState extends State>(configs: (RequestConfig<TParams, TQuery, TBody, TState> | BaseRequestConfig | undefined)[]) => ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
package/cjs/RequestConfig.js
CHANGED
package/cjs/RequestContext.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Api } from "./Api";
|
|
2
2
|
import type { RequestEvent, RequestMethod, ResponseType } from "./ApiConstants";
|
|
3
|
-
import type { ApiResponse, Body, ComputedRequestConfig, EventResult, Headers, Params, Query, RequestCacheInfo, RequestContextStats, RequestEventHandlers, RequestHost } from "./ApiTypes";
|
|
3
|
+
import type { ApiResponse, Body, ComputedRequestConfig, EventResult, Headers, Params, Query, RequestCacheInfo, RequestContextStats, RequestEventHandlers, RequestHost, State } from "./ApiTypes";
|
|
4
4
|
import type { EndpointMockingConfig } from "./MockingTypes";
|
|
5
5
|
import type { RequestError } from "./RequestError";
|
|
6
6
|
import type { Validation } from "./Validation";
|
|
7
7
|
import type RequestBackend from "./backend/RequestBackend";
|
|
8
|
-
export default class RequestContext<
|
|
8
|
+
export default class RequestContext<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
9
9
|
readonly id: number;
|
|
10
10
|
readonly key: string;
|
|
11
11
|
private computedPath;
|
|
@@ -13,19 +13,23 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
|
|
|
13
13
|
private computedMethod;
|
|
14
14
|
readonly stats: RequestContextStats;
|
|
15
15
|
private readonly host;
|
|
16
|
-
readonly eventHandlers: RequestEventHandlers<
|
|
16
|
+
readonly eventHandlers: RequestEventHandlers<TResponse>;
|
|
17
17
|
readonly backend: RequestBackend;
|
|
18
18
|
private canceler;
|
|
19
|
-
response: ApiResponse<
|
|
19
|
+
response: ApiResponse<TResponse> | null | undefined;
|
|
20
20
|
error: RequestError | null;
|
|
21
21
|
readonly cacheInfo: RequestCacheInfo;
|
|
22
22
|
cancelled: boolean;
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Use `requestConfig` instead
|
|
25
|
+
*/
|
|
26
|
+
readonly computedConfig: ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
24
27
|
private computedRequestUrl;
|
|
25
|
-
readonly mocking: EndpointMockingConfig<
|
|
28
|
+
readonly mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined;
|
|
26
29
|
private parsedBody;
|
|
27
|
-
readonly validation: Validation<
|
|
28
|
-
constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<
|
|
30
|
+
readonly validation: Validation<TResponse, TParams, TQuery, TBody, TState>;
|
|
31
|
+
constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<TParams, TQuery, TBody, TState>, computedPath: string, mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined);
|
|
32
|
+
get requestConfig(): ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
29
33
|
get method(): RequestMethod;
|
|
30
34
|
get api(): Api;
|
|
31
35
|
get baseUrl(): string;
|
|
@@ -35,8 +39,8 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
|
|
|
35
39
|
updateHeaders(newHeaders: Headers): this;
|
|
36
40
|
private parseRequestBody;
|
|
37
41
|
getParsedBody(): any;
|
|
38
|
-
updateQuery(newQuery: Partial<
|
|
39
|
-
triggerEvent(eventType: RequestEvent): Promise<EventResult<
|
|
42
|
+
updateQuery(newQuery: Partial<TQuery>): this;
|
|
43
|
+
triggerEvent(eventType: RequestEvent): Promise<EventResult<TResponse> | undefined>;
|
|
40
44
|
addCanceller(canceler: () => void): void;
|
|
41
45
|
cancel(): void;
|
|
42
46
|
get requestUrl(): URL;
|
package/cjs/RequestContext.js
CHANGED
|
@@ -65,6 +65,13 @@ var RequestContext = /** @class */ (function () {
|
|
|
65
65
|
this.parseRequestBody();
|
|
66
66
|
this.computedRequestUrl = this.generateRequestUrl();
|
|
67
67
|
}
|
|
68
|
+
Object.defineProperty(RequestContext.prototype, "requestConfig", {
|
|
69
|
+
get: function () {
|
|
70
|
+
return this.computedConfig;
|
|
71
|
+
},
|
|
72
|
+
enumerable: false,
|
|
73
|
+
configurable: true
|
|
74
|
+
});
|
|
68
75
|
Object.defineProperty(RequestContext.prototype, "method", {
|
|
69
76
|
get: function () {
|
|
70
77
|
return this.computedMethod;
|
package/cjs/Requester.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { ApiResponse, Body, Query, RequestConfig, RequestHost } from "./ApiTypes";
|
|
1
|
+
import type { ApiResponse, Body, Query, RequestConfig, RequestHost, State } from "./ApiTypes";
|
|
2
2
|
import type { EndpointMockingConfig } from "./MockingTypes";
|
|
3
|
-
export declare const submit: <
|
|
3
|
+
export declare const submit: <TResponse, TParams extends string | undefined, TQuery extends Query, TBody extends Body | undefined, TState extends State>(host: RequestHost, config: RequestConfig<TParams, TQuery, TBody, TState>, mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined) => Promise<ApiResponse<TResponse>>;
|
package/cjs/TextDecoding.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable prefer-const */
|
|
3
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
4
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
3
|
exports.textDecode = void 0;
|
|
6
4
|
// polyfill from https://github.com/anonyco/FastestSmallestTextEncoderDecoder/blob/master/EncoderDecoderTogether.src.js
|
package/cjs/Utils.js
CHANGED
|
@@ -13,7 +13,6 @@ exports.assign = Object.assign ||
|
|
|
13
13
|
}
|
|
14
14
|
var to = Object(target);
|
|
15
15
|
for (var index = 0; index < varArgs.length; index++) {
|
|
16
|
-
// eslint-disable-next-line prefer-rest-params
|
|
17
16
|
var nextSource = varArgs[index];
|
|
18
17
|
if (nextSource !== null && nextSource !== undefined) {
|
|
19
18
|
for (var nextKey in nextSource) {
|
|
@@ -49,7 +48,6 @@ var getGlobalFetch = function () {
|
|
|
49
48
|
return undefined;
|
|
50
49
|
};
|
|
51
50
|
exports.getGlobalFetch = getGlobalFetch;
|
|
52
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
53
51
|
var noop = function () { };
|
|
54
52
|
exports.noop = noop;
|
|
55
53
|
/**
|
package/cjs/Validation.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type * as zod from "zod";
|
|
2
|
-
import type { Body, Params, Query } from "./ApiTypes";
|
|
3
|
-
export interface Validation<
|
|
4
|
-
query?: zod.Schema<
|
|
5
|
-
params?: zod.Schema<
|
|
6
|
-
body?: zod.Schema<
|
|
7
|
-
response?: zod.Schema<
|
|
2
|
+
import type { Body, Params, Query, State } from "./ApiTypes";
|
|
3
|
+
export interface Validation<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
4
|
+
query?: zod.Schema<TQuery>;
|
|
5
|
+
params?: zod.Schema<TParams>;
|
|
6
|
+
body?: zod.Schema<TBody>;
|
|
7
|
+
response?: zod.Schema<TResponse>;
|
|
8
|
+
state?: zod.Schema<TState>;
|
|
8
9
|
}
|
|
@@ -43,7 +43,6 @@ var isAxiosError = function (error) {
|
|
|
43
43
|
};
|
|
44
44
|
exports.isAxiosError = isAxiosError;
|
|
45
45
|
var AxiosRequestBackend = /** @class */ (function () {
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
47
46
|
function AxiosRequestBackend(axiosLibrary) {
|
|
48
47
|
this.id = "axios";
|
|
49
48
|
axios = axiosLibrary;
|
|
@@ -67,22 +66,23 @@ var AxiosRequestBackend = /** @class */ (function () {
|
|
|
67
66
|
data: response.data,
|
|
68
67
|
headers: response.headers,
|
|
69
68
|
status: response.status,
|
|
69
|
+
state: context.requestConfig.state,
|
|
70
70
|
__lowercaseHeaders: response._lowerCaseResponseHeaders,
|
|
71
71
|
}];
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
74
|
};
|
|
75
75
|
AxiosRequestBackend.prototype.makeRequest = function (context) {
|
|
76
|
-
var
|
|
76
|
+
var requestConfig = context.requestConfig;
|
|
77
77
|
var url = context.requestUrl;
|
|
78
78
|
var canceler = null;
|
|
79
79
|
var promise = axios({
|
|
80
80
|
method: context.method,
|
|
81
81
|
url: url.href,
|
|
82
82
|
data: context.getParsedBody(),
|
|
83
|
-
headers:
|
|
83
|
+
headers: requestConfig.headers || {},
|
|
84
84
|
responseType: context.responseType,
|
|
85
|
-
withCredentials:
|
|
85
|
+
withCredentials: requestConfig.includeCredentials,
|
|
86
86
|
cancelToken: new axios.CancelToken(function (cancellerFunc) {
|
|
87
87
|
canceler = cancellerFunc;
|
|
88
88
|
}),
|
|
@@ -4,7 +4,7 @@ import { type Fetch } from "../Utils";
|
|
|
4
4
|
import type RequestBackend from "./RequestBackend";
|
|
5
5
|
import type { ConvertedApiResponse, RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
6
6
|
export default class FetchRequestBackend implements RequestBackend<Response> {
|
|
7
|
-
fetch: (((input:
|
|
7
|
+
fetch: (((input: URL | RequestInfo, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
|
|
8
8
|
readonly id = "fetch";
|
|
9
9
|
constructor(fetchLibrary?: Fetch);
|
|
10
10
|
extractResponseFromError(error: Error): Promise<Response | null | undefined>;
|
|
@@ -105,6 +105,7 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
105
105
|
data: undefined,
|
|
106
106
|
status: status,
|
|
107
107
|
headers: processedHeaders,
|
|
108
|
+
state: context.requestConfig.state,
|
|
108
109
|
};
|
|
109
110
|
responseType = (_a = context.responseType) !== null && _a !== void 0 ? _a : (0, ApiUtils_1.inferResponseType)(response.headers.get("Content-Type"));
|
|
110
111
|
_b.label = 1;
|
|
@@ -172,13 +173,14 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
172
173
|
method: context.method.toUpperCase(),
|
|
173
174
|
body: bodyJsonify ? JSON.stringify(body) : body,
|
|
174
175
|
headers: parsedHeaders,
|
|
175
|
-
credentials: context.computedConfig.includeCredentials ? "include" : undefined,
|
|
176
176
|
signal: abortSignal,
|
|
177
177
|
};
|
|
178
|
-
// edge doesn't support mode
|
|
179
178
|
if ("mode" in Request.prototype) {
|
|
180
179
|
fetchOptions.mode = "cors";
|
|
181
180
|
}
|
|
181
|
+
if ("credentials" in Request.prototype) {
|
|
182
|
+
fetchOptions.credentials = context.requestConfig.includeCredentials ? "include" : undefined;
|
|
183
|
+
}
|
|
182
184
|
var promise = this.fetch(url.href, fetchOptions).then(function (response) {
|
|
183
185
|
responded = true;
|
|
184
186
|
if (!response.ok) {
|
|
@@ -79,10 +79,11 @@ var MockRequestBackend = /** @class */ (function () {
|
|
|
79
79
|
}
|
|
80
80
|
req = {
|
|
81
81
|
body: context.getParsedBody(),
|
|
82
|
-
params: (_c = context.
|
|
83
|
-
query: context.
|
|
84
|
-
headers: (_d = context.
|
|
82
|
+
params: (_c = context.requestConfig.params) !== null && _c !== void 0 ? _c : {},
|
|
83
|
+
query: context.requestConfig.queryObject,
|
|
84
|
+
headers: (_d = context.requestConfig.headers) !== null && _d !== void 0 ? _d : {},
|
|
85
85
|
url: context.requestUrl.toString(),
|
|
86
|
+
state: context.requestConfig.state,
|
|
86
87
|
};
|
|
87
88
|
res = {
|
|
88
89
|
statusCode: -1,
|
|
@@ -145,6 +146,7 @@ var MockRequestBackend = /** @class */ (function () {
|
|
|
145
146
|
headers: parsedHeaders,
|
|
146
147
|
data: res.response,
|
|
147
148
|
status: res.statusCode,
|
|
149
|
+
state: context.requestConfig.state,
|
|
148
150
|
}];
|
|
149
151
|
}
|
|
150
152
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
var LocalForageCacheBackend = /** @class */ (function () {
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
5
4
|
function LocalForageCacheBackend(localforage) {
|
|
6
5
|
this.store = localforage.createInstance({
|
|
7
6
|
name: "requestCache",
|
|
@@ -50,11 +50,8 @@ var log = function (context, type, message, config, objects) {
|
|
|
50
50
|
"color:".concat(color),
|
|
51
51
|
"color:gray",
|
|
52
52
|
];
|
|
53
|
-
/* eslint-disable-next-line no-console */
|
|
54
53
|
console.groupCollapsed.apply(console, args);
|
|
55
|
-
/* eslint-disable-next-line no-console */
|
|
56
54
|
console.log(Utils.assign({ context: context }, objects || {}));
|
|
57
|
-
/* eslint-disable-next-line no-console */
|
|
58
55
|
console.groupEnd();
|
|
59
56
|
};
|
|
60
57
|
var LoggingMiddleware = function (config) {
|
|
@@ -32,7 +32,6 @@ var _timeouts = function (options) {
|
|
|
32
32
|
};
|
|
33
33
|
var defaultRetries = 10;
|
|
34
34
|
var opts = __assign({ retries: defaultRetries, factor: 2, minTimeout: 1 * 1000, maxTimeout: Number.POSITIVE_INFINITY, randomize: false }, options);
|
|
35
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
36
35
|
if (opts.minTimeout > opts.maxTimeout) {
|
|
37
36
|
throw new Error("minTimeout is greater than maxTimeout");
|
|
38
37
|
}
|
package/esm/Api.js
CHANGED
|
@@ -74,7 +74,6 @@ export class Api {
|
|
|
74
74
|
if (process.env.NODE_ENV === "development") {
|
|
75
75
|
if (isRequestBackendDefault() && !defaultBackendMessageShown) {
|
|
76
76
|
defaultBackendMessageShown = true;
|
|
77
|
-
// eslint-disable-next-line
|
|
78
77
|
console.warn("[api-def] Using default fetch backend, you can use a different one with 'setRequestBackend()' (dev only message)");
|
|
79
78
|
}
|
|
80
79
|
}
|
package/esm/ApiTypes.d.ts
CHANGED
|
@@ -8,12 +8,14 @@ export type Headers = Record<string, string | number | boolean | null | undefine
|
|
|
8
8
|
export type Params = string;
|
|
9
9
|
export type Query = string | undefined | Record<string, any>;
|
|
10
10
|
export type Body = string | number | Record<string, any>;
|
|
11
|
+
export type State = Record<string, any>;
|
|
11
12
|
export interface ApiResponse<T = any> {
|
|
12
13
|
readonly method: RequestMethod;
|
|
13
14
|
readonly url: string;
|
|
14
15
|
readonly status: number;
|
|
15
16
|
readonly data: T;
|
|
16
17
|
readonly headers: Record<string, string>;
|
|
18
|
+
readonly state: State;
|
|
17
19
|
}
|
|
18
20
|
export type RequestLock = string | false;
|
|
19
21
|
export type QueryStringify = (query: any) => string;
|
|
@@ -41,22 +43,27 @@ export interface BaseRequestConfig {
|
|
|
41
43
|
queryParser?: QueryStringify;
|
|
42
44
|
queryHandling?: Partial<QueryHandling>;
|
|
43
45
|
}
|
|
44
|
-
export type RequestConfig<
|
|
46
|
+
export type RequestConfig<TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> = (TParams extends undefined ? {
|
|
45
47
|
params?: never;
|
|
46
48
|
} : {
|
|
47
|
-
params: Record<
|
|
48
|
-
}) & (
|
|
49
|
+
params: Record<TParams extends Params ? TParams : never, string>;
|
|
50
|
+
}) & (TQuery extends undefined ? {
|
|
49
51
|
query?: never;
|
|
50
52
|
} : {
|
|
51
|
-
query:
|
|
52
|
-
}) & (
|
|
53
|
+
query: TQuery;
|
|
54
|
+
}) & (TBody extends undefined ? {
|
|
53
55
|
body?: never;
|
|
54
56
|
} : {
|
|
55
|
-
body:
|
|
57
|
+
body: TBody;
|
|
58
|
+
}) & ({} extends TState ? {
|
|
59
|
+
state?: TState;
|
|
60
|
+
} : {
|
|
61
|
+
state: TState;
|
|
56
62
|
}) & BaseRequestConfig;
|
|
57
63
|
export declare const COMPUTED_CONFIG_SYMBOL: unique symbol;
|
|
58
|
-
export type ComputedRequestConfig<
|
|
64
|
+
export type ComputedRequestConfig<TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> = Omit<RequestConfig<TParams, TQuery, TBody, TState>, "queryParser" | "query" | "queryHandling" | "state"> & {
|
|
59
65
|
[COMPUTED_CONFIG_SYMBOL]: true;
|
|
66
|
+
state: TState;
|
|
60
67
|
queryObject: Record<string, any> | undefined;
|
|
61
68
|
queryString: string | undefined;
|
|
62
69
|
queryHandling: QueryHandling;
|
|
@@ -90,7 +97,7 @@ export interface RequestHost {
|
|
|
90
97
|
readonly path: string;
|
|
91
98
|
readonly responseType: ResponseType | undefined;
|
|
92
99
|
readonly validation: Validation;
|
|
93
|
-
computeConfig<
|
|
100
|
+
computeConfig<TParams extends Params | undefined, TQuery extends Query | undefined, TBody extends Body | undefined, TState extends State>(config: RequestConfig<TParams, TQuery, TBody, TState>): ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
94
101
|
computePath(path: string, config: RequestConfig): string;
|
|
95
102
|
getRequestBackend(): RequestBackend;
|
|
96
103
|
}
|
package/esm/Endpoint.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { Api } from "./Api";
|
|
2
2
|
import type { RequestMethod, ResponseType } from "./ApiConstants";
|
|
3
|
-
import type { ApiResponse, BaseRequestConfig, Body, ComputedRequestConfig, Params, Query, RequestConfig, RequestHost } from "./ApiTypes";
|
|
3
|
+
import type { ApiResponse, BaseRequestConfig, Body, ComputedRequestConfig, Params, Query, RequestConfig, RequestHost, State } from "./ApiTypes";
|
|
4
4
|
import type * as Mocking from "./MockingTypes";
|
|
5
5
|
import type { Validation } from "./Validation";
|
|
6
6
|
import type RequestBackend from "./backend/RequestBackend";
|
|
7
|
-
export interface EndpointConfig<
|
|
7
|
+
export interface EndpointConfig<TResult, TParams extends Params | undefined, TQuery extends Query | undefined, TBody extends Body | undefined, TState extends State = State, TPath extends string = string> {
|
|
8
8
|
readonly id: string;
|
|
9
9
|
readonly method: RequestMethod;
|
|
10
|
-
readonly path:
|
|
10
|
+
readonly path: TPath;
|
|
11
11
|
/**
|
|
12
12
|
* Name your endpoint to help with debugging and documentation
|
|
13
13
|
* @default `id` is used as the name if no name is supplied
|
|
@@ -29,10 +29,10 @@ export interface EndpointConfig<R, P extends Params | undefined, Q extends Query
|
|
|
29
29
|
* and testing.
|
|
30
30
|
* Enable/disable mocked returns for all endpoints on your API object.
|
|
31
31
|
*/
|
|
32
|
-
readonly mocking?: Mocking.EndpointMockingConfig<
|
|
33
|
-
readonly validation?: Validation<
|
|
32
|
+
readonly mocking?: Mocking.EndpointMockingConfig<TResult, TParams, TQuery, TBody, TState>;
|
|
33
|
+
readonly validation?: Validation<TResult, TParams, TQuery, TBody, TState>;
|
|
34
34
|
}
|
|
35
|
-
export default class Endpoint<
|
|
35
|
+
export default class Endpoint<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> implements EndpointConfig<TResponse, TParams, TQuery, TBody, TState>, RequestHost {
|
|
36
36
|
readonly api: Api;
|
|
37
37
|
readonly id: string;
|
|
38
38
|
readonly method: RequestMethod;
|
|
@@ -41,12 +41,12 @@ export default class Endpoint<R = any, P extends Params | undefined = Params | u
|
|
|
41
41
|
readonly path: string;
|
|
42
42
|
readonly config?: BaseRequestConfig;
|
|
43
43
|
readonly responseType: ResponseType | undefined;
|
|
44
|
-
readonly mocking?: Mocking.EndpointMockingConfig<
|
|
45
|
-
readonly validation: Validation<
|
|
46
|
-
constructor(api: Api, info: EndpointConfig<
|
|
47
|
-
submit(config: RequestConfig<
|
|
44
|
+
readonly mocking?: Mocking.EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState>;
|
|
45
|
+
readonly validation: Validation<TResponse, TParams, TQuery, TBody, TState>;
|
|
46
|
+
constructor(api: Api, info: EndpointConfig<TResponse, TParams, TQuery, TBody, TState>);
|
|
47
|
+
submit(config: RequestConfig<TParams, TQuery, TBody, TState>): Promise<ApiResponse<TResponse>>;
|
|
48
48
|
computePath(path: string, request: RequestConfig): string;
|
|
49
49
|
get baseUrl(): string;
|
|
50
|
-
computeConfig<
|
|
50
|
+
computeConfig<TParams extends Params | undefined, TQuery extends Query | undefined, TBody extends Body | undefined, TState extends State>(config: RequestConfig<TParams, TQuery, TBody, TState>): ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
51
51
|
getRequestBackend(): RequestBackend;
|
|
52
52
|
}
|
package/esm/EndpointBuilder.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type * as zod from "zod";
|
|
2
2
|
import type { Api } from "./Api";
|
|
3
|
-
import type { Body, Params, Query } from "./ApiTypes";
|
|
3
|
+
import type { Body, Params, Query, State } from "./ApiTypes";
|
|
4
4
|
import Endpoint, { type EndpointConfig } from "./Endpoint";
|
|
5
|
-
export default class EndpointBuilder<
|
|
5
|
+
export default class EndpointBuilder<TResponse = any, TParams extends Params | undefined = undefined, TQuery extends Query | undefined = undefined, TBody extends Body | undefined = undefined, TState extends State = State> {
|
|
6
6
|
private api;
|
|
7
7
|
private readonly validation;
|
|
8
8
|
constructor(api: Api);
|
|
9
|
-
queryOf<
|
|
10
|
-
paramsOf<
|
|
11
|
-
bodyOf<
|
|
12
|
-
responseOf<
|
|
13
|
-
|
|
9
|
+
queryOf<TNewQuery extends Query>(schema?: zod.Schema<TNewQuery>): EndpointBuilder<TResponse, TParams, TNewQuery, TBody>;
|
|
10
|
+
paramsOf<TNewParams extends Params>(): EndpointBuilder<TResponse, TNewParams, TQuery, TBody, TState>;
|
|
11
|
+
bodyOf<TNewBody extends Body>(schema?: zod.Schema<TNewBody>): EndpointBuilder<TResponse, TParams, TQuery, TNewBody, TState>;
|
|
12
|
+
responseOf<TNewResponse>(schema?: zod.Schema<TNewResponse>): EndpointBuilder<TNewResponse, TParams, TQuery, TBody, TState>;
|
|
13
|
+
stateOf<TNewState extends State>(schema?: zod.Schema<TNewState>): EndpointBuilder<TResponse, TParams, TQuery, TBody, TNewState>;
|
|
14
|
+
build<TPath extends string>(config: Omit<EndpointConfig<TResponse, TParams, TQuery, TBody, TState, TPath>, "validation">): Endpoint<TResponse, TParams, TQuery, TBody, TState>;
|
|
14
15
|
}
|
package/esm/EndpointBuilder.js
CHANGED
|
@@ -23,6 +23,10 @@ export default class EndpointBuilder {
|
|
|
23
23
|
this.validation.response = schema;
|
|
24
24
|
return this;
|
|
25
25
|
}
|
|
26
|
+
stateOf(schema) {
|
|
27
|
+
this.validation.state = schema;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
26
30
|
build(config) {
|
|
27
31
|
const endpoint = new Endpoint(this.api, Object.assign(Object.assign({}, config), { validation: this.validation }));
|
|
28
32
|
this.api.endpoints[endpoint.id] = endpoint;
|
package/esm/MockingTypes.d.ts
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
import type { ApiResponse, Body, Headers, Params, Query } from "./ApiTypes";
|
|
1
|
+
import type { ApiResponse, Body, Headers, Params, Query, State } from "./ApiTypes";
|
|
2
2
|
export interface ApiMockingConfig {
|
|
3
3
|
enabled: boolean | (() => boolean);
|
|
4
4
|
}
|
|
5
|
-
export interface MockRequest<
|
|
6
|
-
params:
|
|
7
|
-
body:
|
|
8
|
-
query:
|
|
5
|
+
export interface MockRequest<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
6
|
+
params: TParams extends Params ? Record<TParams, string> : {};
|
|
7
|
+
body: TBody;
|
|
8
|
+
query: TQuery;
|
|
9
9
|
headers: Readonly<Headers>;
|
|
10
10
|
url: string;
|
|
11
|
+
state: TState;
|
|
11
12
|
}
|
|
12
|
-
export interface MockResponse<
|
|
13
|
+
export interface MockResponse<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
13
14
|
statusCode: number;
|
|
14
|
-
response:
|
|
15
|
+
response: TResponse | undefined;
|
|
15
16
|
headers: Headers;
|
|
16
17
|
status(statusCode: number): this;
|
|
17
|
-
send(response:
|
|
18
|
+
send(response: TResponse): this;
|
|
18
19
|
}
|
|
19
20
|
export type MockRequestError = Error & {
|
|
20
21
|
response?: ApiResponse;
|
|
21
22
|
};
|
|
22
|
-
export type EndpointMockingFunction<
|
|
23
|
-
export interface EndpointMockingConfig<
|
|
23
|
+
export type EndpointMockingFunction<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> = (req: MockRequest<TResponse, TParams, TQuery, TBody, TState>, res: MockResponse<TResponse, TParams, TQuery, TBody, TState>) => Promise<MockResponse<TResponse, TParams, TQuery, TBody>> | MockResponse<TResponse, TParams, TQuery, TBody, TState>;
|
|
24
|
+
export interface EndpointMockingConfig<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
24
25
|
/**-
|
|
25
26
|
* The range supplied will be used to simulate the lag in obtaining a response
|
|
26
27
|
* your endpoint. If no values are supplied, a response will be returned immediately
|
|
27
28
|
*/
|
|
28
29
|
delay?: number | [minMs: number, maxMs: number];
|
|
29
|
-
handler: EndpointMockingFunction<
|
|
30
|
+
handler: EndpointMockingFunction<TResponse, TParams, TQuery, TBody, TState>;
|
|
30
31
|
}
|
package/esm/RequestConfig.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type BaseRequestConfig, type Body, type ComputedRequestConfig, type Query, type RequestConfig } from "./ApiTypes";
|
|
2
|
-
export declare const computeRequestConfig: <
|
|
1
|
+
import { type BaseRequestConfig, type Body, type ComputedRequestConfig, type Query, type RequestConfig, type State } from "./ApiTypes";
|
|
2
|
+
export declare const computeRequestConfig: <TParams extends string | undefined, TQuery extends Query, TBody extends Body | undefined, TState extends State>(configs: (RequestConfig<TParams, TQuery, TBody, TState> | BaseRequestConfig | undefined)[]) => ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
package/esm/RequestConfig.js
CHANGED
package/esm/RequestContext.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Api } from "./Api";
|
|
2
2
|
import type { RequestEvent, RequestMethod, ResponseType } from "./ApiConstants";
|
|
3
|
-
import type { ApiResponse, Body, ComputedRequestConfig, EventResult, Headers, Params, Query, RequestCacheInfo, RequestContextStats, RequestEventHandlers, RequestHost } from "./ApiTypes";
|
|
3
|
+
import type { ApiResponse, Body, ComputedRequestConfig, EventResult, Headers, Params, Query, RequestCacheInfo, RequestContextStats, RequestEventHandlers, RequestHost, State } from "./ApiTypes";
|
|
4
4
|
import type { EndpointMockingConfig } from "./MockingTypes";
|
|
5
5
|
import type { RequestError } from "./RequestError";
|
|
6
6
|
import type { Validation } from "./Validation";
|
|
7
7
|
import type RequestBackend from "./backend/RequestBackend";
|
|
8
|
-
export default class RequestContext<
|
|
8
|
+
export default class RequestContext<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
9
9
|
readonly id: number;
|
|
10
10
|
readonly key: string;
|
|
11
11
|
private computedPath;
|
|
@@ -13,19 +13,23 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
|
|
|
13
13
|
private computedMethod;
|
|
14
14
|
readonly stats: RequestContextStats;
|
|
15
15
|
private readonly host;
|
|
16
|
-
readonly eventHandlers: RequestEventHandlers<
|
|
16
|
+
readonly eventHandlers: RequestEventHandlers<TResponse>;
|
|
17
17
|
readonly backend: RequestBackend;
|
|
18
18
|
private canceler;
|
|
19
|
-
response: ApiResponse<
|
|
19
|
+
response: ApiResponse<TResponse> | null | undefined;
|
|
20
20
|
error: RequestError | null;
|
|
21
21
|
readonly cacheInfo: RequestCacheInfo;
|
|
22
22
|
cancelled: boolean;
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Use `requestConfig` instead
|
|
25
|
+
*/
|
|
26
|
+
readonly computedConfig: ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
24
27
|
private computedRequestUrl;
|
|
25
|
-
readonly mocking: EndpointMockingConfig<
|
|
28
|
+
readonly mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined;
|
|
26
29
|
private parsedBody;
|
|
27
|
-
readonly validation: Validation<
|
|
28
|
-
constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<
|
|
30
|
+
readonly validation: Validation<TResponse, TParams, TQuery, TBody, TState>;
|
|
31
|
+
constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<TParams, TQuery, TBody, TState>, computedPath: string, mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined);
|
|
32
|
+
get requestConfig(): ComputedRequestConfig<TParams, TQuery, TBody, TState>;
|
|
29
33
|
get method(): RequestMethod;
|
|
30
34
|
get api(): Api;
|
|
31
35
|
get baseUrl(): string;
|
|
@@ -35,8 +39,8 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
|
|
|
35
39
|
updateHeaders(newHeaders: Headers): this;
|
|
36
40
|
private parseRequestBody;
|
|
37
41
|
getParsedBody(): any;
|
|
38
|
-
updateQuery(newQuery: Partial<
|
|
39
|
-
triggerEvent(eventType: RequestEvent): Promise<EventResult<
|
|
42
|
+
updateQuery(newQuery: Partial<TQuery>): this;
|
|
43
|
+
triggerEvent(eventType: RequestEvent): Promise<EventResult<TResponse> | undefined>;
|
|
40
44
|
addCanceller(canceler: () => void): void;
|
|
41
45
|
cancel(): void;
|
|
42
46
|
get requestUrl(): URL;
|
package/esm/RequestContext.js
CHANGED
|
@@ -36,6 +36,9 @@ export default class RequestContext {
|
|
|
36
36
|
this.parseRequestBody();
|
|
37
37
|
this.computedRequestUrl = this.generateRequestUrl();
|
|
38
38
|
}
|
|
39
|
+
get requestConfig() {
|
|
40
|
+
return this.computedConfig;
|
|
41
|
+
}
|
|
39
42
|
get method() {
|
|
40
43
|
return this.computedMethod;
|
|
41
44
|
}
|
|
@@ -110,7 +113,6 @@ export default class RequestContext {
|
|
|
110
113
|
if (eventHandlers) {
|
|
111
114
|
for (let i = 0; i < eventHandlers.length; i++) {
|
|
112
115
|
const eventHandler = eventHandlers[i];
|
|
113
|
-
// eslint-disable-next-line no-await-in-loop
|
|
114
116
|
const eventResult = yield eventHandler(this);
|
|
115
117
|
if (eventResult) {
|
|
116
118
|
return eventResult;
|
package/esm/Requester.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { ApiResponse, Body, Query, RequestConfig, RequestHost } from "./ApiTypes";
|
|
1
|
+
import type { ApiResponse, Body, Query, RequestConfig, RequestHost, State } from "./ApiTypes";
|
|
2
2
|
import type { EndpointMockingConfig } from "./MockingTypes";
|
|
3
|
-
export declare const submit: <
|
|
3
|
+
export declare const submit: <TResponse, TParams extends string | undefined, TQuery extends Query, TBody extends Body | undefined, TState extends State>(host: RequestHost, config: RequestConfig<TParams, TQuery, TBody, TState>, mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined) => Promise<ApiResponse<TResponse>>;
|
package/esm/TextDecoding.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable prefer-const */
|
|
2
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
3
1
|
// polyfill from https://github.com/anonyco/FastestSmallestTextEncoderDecoder/blob/master/EncoderDecoderTogether.src.js
|
|
4
2
|
export const textDecode = (inputArrayOrBuffer, options) => {
|
|
5
3
|
if (typeof TextDecoder !== "undefined") {
|
package/esm/Utils.js
CHANGED
|
@@ -6,7 +6,6 @@ export const assign = Object.assign ||
|
|
|
6
6
|
}
|
|
7
7
|
const to = Object(target);
|
|
8
8
|
for (let index = 0; index < varArgs.length; index++) {
|
|
9
|
-
// eslint-disable-next-line prefer-rest-params
|
|
10
9
|
const nextSource = varArgs[index];
|
|
11
10
|
if (nextSource !== null && nextSource !== undefined) {
|
|
12
11
|
for (const nextKey in nextSource) {
|
|
@@ -39,7 +38,6 @@ export const getGlobalFetch = () => {
|
|
|
39
38
|
}
|
|
40
39
|
return undefined;
|
|
41
40
|
};
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
43
41
|
export const noop = () => { };
|
|
44
42
|
/**
|
|
45
43
|
* Just used to simulate lag, or loading times.
|
package/esm/Validation.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type * as zod from "zod";
|
|
2
|
-
import type { Body, Params, Query } from "./ApiTypes";
|
|
3
|
-
export interface Validation<
|
|
4
|
-
query?: zod.Schema<
|
|
5
|
-
params?: zod.Schema<
|
|
6
|
-
body?: zod.Schema<
|
|
7
|
-
response?: zod.Schema<
|
|
2
|
+
import type { Body, Params, Query, State } from "./ApiTypes";
|
|
3
|
+
export interface Validation<TResponse = any, TParams extends Params | undefined = Params | undefined, TQuery extends Query | undefined = Query | undefined, TBody extends Body | undefined = Body | undefined, TState extends State = State> {
|
|
4
|
+
query?: zod.Schema<TQuery>;
|
|
5
|
+
params?: zod.Schema<TParams>;
|
|
6
|
+
body?: zod.Schema<TBody>;
|
|
7
|
+
response?: zod.Schema<TResponse>;
|
|
8
|
+
state?: zod.Schema<TState>;
|
|
8
9
|
}
|
|
@@ -12,7 +12,6 @@ export const isAxiosError = (error) => {
|
|
|
12
12
|
return "isAxiosError" in error;
|
|
13
13
|
};
|
|
14
14
|
export default class AxiosRequestBackend {
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
16
15
|
constructor(axiosLibrary) {
|
|
17
16
|
this.id = "axios";
|
|
18
17
|
axios = axiosLibrary;
|
|
@@ -33,21 +32,22 @@ export default class AxiosRequestBackend {
|
|
|
33
32
|
data: response.data,
|
|
34
33
|
headers: response.headers,
|
|
35
34
|
status: response.status,
|
|
35
|
+
state: context.requestConfig.state,
|
|
36
36
|
__lowercaseHeaders: response._lowerCaseResponseHeaders,
|
|
37
37
|
};
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
makeRequest(context) {
|
|
41
|
-
const {
|
|
41
|
+
const { requestConfig } = context;
|
|
42
42
|
const url = context.requestUrl;
|
|
43
43
|
let canceler = null;
|
|
44
44
|
const promise = axios({
|
|
45
45
|
method: context.method,
|
|
46
46
|
url: url.href,
|
|
47
47
|
data: context.getParsedBody(),
|
|
48
|
-
headers:
|
|
48
|
+
headers: requestConfig.headers || {},
|
|
49
49
|
responseType: context.responseType,
|
|
50
|
-
withCredentials:
|
|
50
|
+
withCredentials: requestConfig.includeCredentials,
|
|
51
51
|
cancelToken: new axios.CancelToken((cancellerFunc) => {
|
|
52
52
|
canceler = cancellerFunc;
|
|
53
53
|
}),
|
|
@@ -4,7 +4,7 @@ import { type Fetch } from "../Utils";
|
|
|
4
4
|
import type RequestBackend from "./RequestBackend";
|
|
5
5
|
import type { ConvertedApiResponse, RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
6
6
|
export default class FetchRequestBackend implements RequestBackend<Response> {
|
|
7
|
-
fetch: (((input:
|
|
7
|
+
fetch: (((input: URL | RequestInfo, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
|
|
8
8
|
readonly id = "fetch";
|
|
9
9
|
constructor(fetchLibrary?: Fetch);
|
|
10
10
|
extractResponseFromError(error: Error): Promise<Response | null | undefined>;
|
|
@@ -49,6 +49,7 @@ export default class FetchRequestBackend {
|
|
|
49
49
|
data: undefined,
|
|
50
50
|
status: status,
|
|
51
51
|
headers: processedHeaders,
|
|
52
|
+
state: context.requestConfig.state,
|
|
52
53
|
};
|
|
53
54
|
const responseType = (_a = context.responseType) !== null && _a !== void 0 ? _a : inferResponseType(response.headers.get("Content-Type"));
|
|
54
55
|
let text;
|
|
@@ -107,13 +108,14 @@ export default class FetchRequestBackend {
|
|
|
107
108
|
method: context.method.toUpperCase(),
|
|
108
109
|
body: bodyJsonify ? JSON.stringify(body) : body,
|
|
109
110
|
headers: parsedHeaders,
|
|
110
|
-
credentials: context.computedConfig.includeCredentials ? "include" : undefined,
|
|
111
111
|
signal: abortSignal,
|
|
112
112
|
};
|
|
113
|
-
// edge doesn't support mode
|
|
114
113
|
if ("mode" in Request.prototype) {
|
|
115
114
|
fetchOptions.mode = "cors";
|
|
116
115
|
}
|
|
116
|
+
if ("credentials" in Request.prototype) {
|
|
117
|
+
fetchOptions.credentials = context.requestConfig.includeCredentials ? "include" : undefined;
|
|
118
|
+
}
|
|
117
119
|
const promise = this.fetch(url.href, fetchOptions).then((response) => {
|
|
118
120
|
responded = true;
|
|
119
121
|
if (!response.ok) {
|
|
@@ -41,10 +41,11 @@ export default class MockRequestBackend {
|
|
|
41
41
|
}
|
|
42
42
|
const req = {
|
|
43
43
|
body: context.getParsedBody(),
|
|
44
|
-
params: (_b = context.
|
|
45
|
-
query: context.
|
|
46
|
-
headers: (_c = context.
|
|
44
|
+
params: (_b = context.requestConfig.params) !== null && _b !== void 0 ? _b : {},
|
|
45
|
+
query: context.requestConfig.queryObject,
|
|
46
|
+
headers: (_c = context.requestConfig.headers) !== null && _c !== void 0 ? _c : {},
|
|
47
47
|
url: context.requestUrl.toString(),
|
|
48
|
+
state: context.requestConfig.state,
|
|
48
49
|
};
|
|
49
50
|
const res = {
|
|
50
51
|
statusCode: -1,
|
|
@@ -101,6 +102,7 @@ export default class MockRequestBackend {
|
|
|
101
102
|
headers: parsedHeaders,
|
|
102
103
|
data: res.response,
|
|
103
104
|
status: res.statusCode,
|
|
105
|
+
state: context.requestConfig.state,
|
|
104
106
|
};
|
|
105
107
|
});
|
|
106
108
|
}
|
|
@@ -47,11 +47,8 @@ const log = (context, type, message, config, objects) => {
|
|
|
47
47
|
`color:${color}`,
|
|
48
48
|
"color:gray",
|
|
49
49
|
];
|
|
50
|
-
/* eslint-disable-next-line no-console */
|
|
51
50
|
console.groupCollapsed(...args);
|
|
52
|
-
/* eslint-disable-next-line no-console */
|
|
53
51
|
console.log(Utils.assign({ context: context }, objects || {}));
|
|
54
|
-
/* eslint-disable-next-line no-console */
|
|
55
52
|
console.groupEnd();
|
|
56
53
|
};
|
|
57
54
|
const LoggingMiddleware = (config = {}) => {
|
|
@@ -17,7 +17,6 @@ const _timeouts = (options) => {
|
|
|
17
17
|
};
|
|
18
18
|
const defaultRetries = 10;
|
|
19
19
|
const opts = Object.assign({ retries: defaultRetries, factor: 2, minTimeout: 1 * 1000, maxTimeout: Number.POSITIVE_INFINITY, randomize: false }, options);
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
21
20
|
if (opts.minTimeout > opts.maxTimeout) {
|
|
22
21
|
throw new Error("minTimeout is greater than maxTimeout");
|
|
23
22
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api-def",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0-alpha.2",
|
|
4
4
|
"description": "Typed API definitions with middleware support",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"types": "esm/index.d.ts",
|
|
@@ -30,20 +30,20 @@
|
|
|
30
30
|
},
|
|
31
31
|
"repository": "https://github.com/Censkh/api-def",
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@biomejs/biome": "
|
|
33
|
+
"@biomejs/biome": "1.7.3",
|
|
34
34
|
"@swc/core": "latest",
|
|
35
35
|
"@swc/jest": "latest",
|
|
36
36
|
"@types/axios": "0.14.0",
|
|
37
37
|
"@types/jest": "^29.5.12",
|
|
38
|
-
"@types/node": "20.12.
|
|
38
|
+
"@types/node": "20.12.11",
|
|
39
39
|
"@types/qs": "6.9.15",
|
|
40
40
|
"axios": "1.6.8",
|
|
41
41
|
"cross-env": "7.0.3",
|
|
42
42
|
"jest": "latest",
|
|
43
43
|
"npm-run-all": "4.1.5",
|
|
44
44
|
"qs": "6.12.1",
|
|
45
|
-
"rimraf": "5.0.
|
|
45
|
+
"rimraf": "5.0.6",
|
|
46
46
|
"typescript": "5.4.5",
|
|
47
|
-
"zod": "3.
|
|
47
|
+
"zod": "3.23.8"
|
|
48
48
|
}
|
|
49
49
|
}
|