api-def 0.9.4-alpha.2 → 0.10.0-alpha.1

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.
Files changed (43) hide show
  1. package/cjs/Api.js +0 -1
  2. package/cjs/ApiTypes.d.ts +15 -8
  3. package/cjs/Endpoint.d.ts +11 -11
  4. package/cjs/EndpointBuilder.d.ts +8 -7
  5. package/cjs/EndpointBuilder.js +4 -0
  6. package/cjs/MockingTypes.d.ts +12 -11
  7. package/cjs/RequestConfig.d.ts +2 -2
  8. package/cjs/RequestConfig.js +3 -0
  9. package/cjs/RequestContext.d.ts +14 -10
  10. package/cjs/RequestContext.js +7 -0
  11. package/cjs/Requester.d.ts +2 -2
  12. package/cjs/TextDecoding.js +0 -2
  13. package/cjs/Utils.js +0 -2
  14. package/cjs/Validation.d.ts +7 -6
  15. package/cjs/backend/AxiosRequestBackend.js +4 -4
  16. package/cjs/backend/FetchRequestBackend.d.ts +1 -1
  17. package/cjs/backend/FetchRequestBackend.js +1 -0
  18. package/cjs/backend/MockRequestBackend.js +5 -3
  19. package/cjs/cache/LocalForageCacheBackend.js +0 -1
  20. package/cjs/middleware/LoggingMiddleware.js +0 -3
  21. package/cjs/util/retry/lib/retry.js +0 -1
  22. package/esm/Api.js +0 -1
  23. package/esm/ApiTypes.d.ts +15 -8
  24. package/esm/Endpoint.d.ts +11 -11
  25. package/esm/EndpointBuilder.d.ts +8 -7
  26. package/esm/EndpointBuilder.js +4 -0
  27. package/esm/MockingTypes.d.ts +12 -11
  28. package/esm/RequestConfig.d.ts +2 -2
  29. package/esm/RequestConfig.js +3 -0
  30. package/esm/RequestContext.d.ts +14 -10
  31. package/esm/RequestContext.js +3 -1
  32. package/esm/Requester.d.ts +2 -2
  33. package/esm/TextDecoding.js +0 -2
  34. package/esm/Utils.js +0 -2
  35. package/esm/Validation.d.ts +7 -6
  36. package/esm/backend/AxiosRequestBackend.js +4 -4
  37. package/esm/backend/FetchRequestBackend.d.ts +1 -1
  38. package/esm/backend/FetchRequestBackend.js +1 -0
  39. package/esm/backend/MockRequestBackend.js +5 -3
  40. package/esm/cache/LocalForageCacheBackend.js +0 -1
  41. package/esm/middleware/LoggingMiddleware.js +0 -3
  42. package/esm/util/retry/lib/retry.js +0 -1
  43. package/package.json +4 -4
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<P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = (P extends undefined ? {
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<P extends Params ? P : never, string>;
48
- }) & (Q extends undefined ? {
49
+ params: Record<TParams extends Params ? TParams : never, string>;
50
+ }) & (TQuery extends undefined ? {
49
51
  query?: never;
50
52
  } : {
51
- query: Q;
52
- }) & (B extends undefined ? {
53
+ query: TQuery;
54
+ }) & (TBody extends undefined ? {
53
55
  body?: never;
54
56
  } : {
55
- body: B;
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<P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = Omit<RequestConfig<P, Q, B>, "queryParser" | "query" | "queryHandling"> & {
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<P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined>(config: RequestConfig<P, Q, B>): ComputedRequestConfig<P, Q, B>;
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<R, P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined, Path extends string = string> {
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: 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<R, P, Q, B>;
33
- readonly validation?: Validation<R, P, Q, B>;
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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> implements EndpointConfig<R, P, Q, B>, RequestHost {
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<R, P, Q, B>;
45
- readonly validation: Validation<R, P, Q, B>;
46
- constructor(api: Api, info: EndpointConfig<R, P, Q, B>);
47
- submit(config: RequestConfig<P, Q, B>): Promise<ApiResponse<R>>;
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<P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined>(config: RequestConfig<P, Q, B>): ComputedRequestConfig<P, Q, B>;
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
  }
@@ -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<R = any, P extends Params | undefined = undefined, Q extends Query | undefined = undefined, B extends Body | undefined = undefined> {
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<Q extends Query>(schema?: zod.Schema<Q>): EndpointBuilder<R, P, Q, B>;
10
- paramsOf<P extends Params>(): EndpointBuilder<R, P, Q, B>;
11
- bodyOf<B extends Body>(schema?: zod.Schema<B>): EndpointBuilder<R, P, Q, B>;
12
- responseOf<R>(schema?: zod.Schema<R>): EndpointBuilder<R, P, Q, B>;
13
- build<Path extends string>(config: Omit<EndpointConfig<R, P, Q, B, Path>, "validation">): Endpoint<R, P, Q, B>;
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
  }
@@ -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;
@@ -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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
6
- params: P extends Params ? Record<P, string> : {};
7
- body: B;
8
- query: Q;
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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
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: R | undefined;
15
+ response: TResponse | undefined;
15
16
  headers: Headers;
16
17
  status(statusCode: number): this;
17
- send(response: R): this;
18
+ send(response: TResponse): this;
18
19
  }
19
20
  export type MockRequestError = Error & {
20
21
  response?: ApiResponse;
21
22
  };
22
- export type EndpointMockingFunction<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = (req: MockRequest<R, P, Q, B>, res: MockResponse<R, P, Q, B>) => Promise<MockResponse<R, P, Q, B>> | MockResponse<R, P, Q, B>;
23
- export interface EndpointMockingConfig<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
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<R, P, Q, B>;
30
+ handler: EndpointMockingFunction<TResponse, TParams, TQuery, TBody, TState>;
30
31
  }
@@ -1,2 +1,2 @@
1
- import { type BaseRequestConfig, type Body, type ComputedRequestConfig, type Query, type RequestConfig } from "./ApiTypes";
2
- export declare const computeRequestConfig: <P extends string | undefined, Q extends Query, B extends Body | undefined>(configs: (RequestConfig<P, Q, B> | BaseRequestConfig | undefined)[]) => ComputedRequestConfig<P, Q, B>;
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>;
@@ -69,6 +69,9 @@ var computeRequestConfig = function (configs) {
69
69
  },
70
70
  });
71
71
  }
72
+ if (!computedConfig.state) {
73
+ computedConfig.state = {};
74
+ }
72
75
  return computedConfig;
73
76
  };
74
77
  exports.computeRequestConfig = computeRequestConfig;
@@ -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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
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<R>;
16
+ readonly eventHandlers: RequestEventHandlers<TResponse>;
17
17
  readonly backend: RequestBackend;
18
18
  private canceler;
19
- response: ApiResponse<R> | null | undefined;
19
+ response: ApiResponse<TResponse> | null | undefined;
20
20
  error: RequestError | null;
21
21
  readonly cacheInfo: RequestCacheInfo;
22
22
  cancelled: boolean;
23
- readonly computedConfig: ComputedRequestConfig<P, Q, B>;
23
+ /**
24
+ * @deprecated Use `requestConfig` instead
25
+ */
26
+ readonly computedConfig: ComputedRequestConfig<TParams, TQuery, TBody, TState>;
24
27
  private computedRequestUrl;
25
- readonly mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined;
28
+ readonly mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined;
26
29
  private parsedBody;
27
- readonly validation: Validation<R, P, Q, B>;
28
- constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<P, Q, B>, computedPath: string, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined);
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<Q>): this;
39
- triggerEvent(eventType: RequestEvent): Promise<EventResult<R> | undefined>;
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;
@@ -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;
@@ -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: <R, P extends string | undefined, Q extends Query, B extends Body | undefined>(host: RequestHost, config: RequestConfig<P, Q, B>, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined) => Promise<ApiResponse<R>>;
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>>;
@@ -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
  /**
@@ -1,8 +1,9 @@
1
1
  import type * as zod from "zod";
2
- import type { Body, Params, Query } from "./ApiTypes";
3
- export interface Validation<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
4
- query?: zod.Schema<Q>;
5
- params?: zod.Schema<P>;
6
- body?: zod.Schema<B>;
7
- response?: zod.Schema<R>;
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 computedConfig = context.computedConfig;
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: computedConfig.headers || {},
83
+ headers: requestConfig.headers || {},
84
84
  responseType: context.responseType,
85
- withCredentials: computedConfig.includeCredentials,
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: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
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;
@@ -79,10 +79,11 @@ var MockRequestBackend = /** @class */ (function () {
79
79
  }
80
80
  req = {
81
81
  body: context.getParsedBody(),
82
- params: (_c = context.computedConfig.params) !== null && _c !== void 0 ? _c : {},
83
- query: context.computedConfig.queryObject,
84
- headers: (_d = context.computedConfig.headers) !== null && _d !== void 0 ? _d : {},
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<P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = (P extends undefined ? {
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<P extends Params ? P : never, string>;
48
- }) & (Q extends undefined ? {
49
+ params: Record<TParams extends Params ? TParams : never, string>;
50
+ }) & (TQuery extends undefined ? {
49
51
  query?: never;
50
52
  } : {
51
- query: Q;
52
- }) & (B extends undefined ? {
53
+ query: TQuery;
54
+ }) & (TBody extends undefined ? {
53
55
  body?: never;
54
56
  } : {
55
- body: B;
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<P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = Omit<RequestConfig<P, Q, B>, "queryParser" | "query" | "queryHandling"> & {
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<P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined>(config: RequestConfig<P, Q, B>): ComputedRequestConfig<P, Q, B>;
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<R, P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined, Path extends string = string> {
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: 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<R, P, Q, B>;
33
- readonly validation?: Validation<R, P, Q, B>;
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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> implements EndpointConfig<R, P, Q, B>, RequestHost {
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<R, P, Q, B>;
45
- readonly validation: Validation<R, P, Q, B>;
46
- constructor(api: Api, info: EndpointConfig<R, P, Q, B>);
47
- submit(config: RequestConfig<P, Q, B>): Promise<ApiResponse<R>>;
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<P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined>(config: RequestConfig<P, Q, B>): ComputedRequestConfig<P, Q, B>;
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
  }
@@ -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<R = any, P extends Params | undefined = undefined, Q extends Query | undefined = undefined, B extends Body | undefined = undefined> {
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<Q extends Query>(schema?: zod.Schema<Q>): EndpointBuilder<R, P, Q, B>;
10
- paramsOf<P extends Params>(): EndpointBuilder<R, P, Q, B>;
11
- bodyOf<B extends Body>(schema?: zod.Schema<B>): EndpointBuilder<R, P, Q, B>;
12
- responseOf<R>(schema?: zod.Schema<R>): EndpointBuilder<R, P, Q, B>;
13
- build<Path extends string>(config: Omit<EndpointConfig<R, P, Q, B, Path>, "validation">): Endpoint<R, P, Q, B>;
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
  }
@@ -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;
@@ -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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
6
- params: P extends Params ? Record<P, string> : {};
7
- body: B;
8
- query: Q;
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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
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: R | undefined;
15
+ response: TResponse | undefined;
15
16
  headers: Headers;
16
17
  status(statusCode: number): this;
17
- send(response: R): this;
18
+ send(response: TResponse): this;
18
19
  }
19
20
  export type MockRequestError = Error & {
20
21
  response?: ApiResponse;
21
22
  };
22
- export type EndpointMockingFunction<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = (req: MockRequest<R, P, Q, B>, res: MockResponse<R, P, Q, B>) => Promise<MockResponse<R, P, Q, B>> | MockResponse<R, P, Q, B>;
23
- export interface EndpointMockingConfig<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
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<R, P, Q, B>;
30
+ handler: EndpointMockingFunction<TResponse, TParams, TQuery, TBody, TState>;
30
31
  }
@@ -1,2 +1,2 @@
1
- import { type BaseRequestConfig, type Body, type ComputedRequestConfig, type Query, type RequestConfig } from "./ApiTypes";
2
- export declare const computeRequestConfig: <P extends string | undefined, Q extends Query, B extends Body | undefined>(configs: (RequestConfig<P, Q, B> | BaseRequestConfig | undefined)[]) => ComputedRequestConfig<P, Q, B>;
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>;
@@ -52,5 +52,8 @@ export const computeRequestConfig = (configs) => {
52
52
  },
53
53
  });
54
54
  }
55
+ if (!computedConfig.state) {
56
+ computedConfig.state = {};
57
+ }
55
58
  return computedConfig;
56
59
  };
@@ -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<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
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<R>;
16
+ readonly eventHandlers: RequestEventHandlers<TResponse>;
17
17
  readonly backend: RequestBackend;
18
18
  private canceler;
19
- response: ApiResponse<R> | null | undefined;
19
+ response: ApiResponse<TResponse> | null | undefined;
20
20
  error: RequestError | null;
21
21
  readonly cacheInfo: RequestCacheInfo;
22
22
  cancelled: boolean;
23
- readonly computedConfig: ComputedRequestConfig<P, Q, B>;
23
+ /**
24
+ * @deprecated Use `requestConfig` instead
25
+ */
26
+ readonly computedConfig: ComputedRequestConfig<TParams, TQuery, TBody, TState>;
24
27
  private computedRequestUrl;
25
- readonly mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined;
28
+ readonly mocking: EndpointMockingConfig<TResponse, TParams, TQuery, TBody, TState> | null | undefined;
26
29
  private parsedBody;
27
- readonly validation: Validation<R, P, Q, B>;
28
- constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<P, Q, B>, computedPath: string, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined);
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<Q>): this;
39
- triggerEvent(eventType: RequestEvent): Promise<EventResult<R> | undefined>;
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;
@@ -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;
@@ -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: <R, P extends string | undefined, Q extends Query, B extends Body | undefined>(host: RequestHost, config: RequestConfig<P, Q, B>, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined) => Promise<ApiResponse<R>>;
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>>;
@@ -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.
@@ -1,8 +1,9 @@
1
1
  import type * as zod from "zod";
2
- import type { Body, Params, Query } from "./ApiTypes";
3
- export interface Validation<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
4
- query?: zod.Schema<Q>;
5
- params?: zod.Schema<P>;
6
- body?: zod.Schema<B>;
7
- response?: zod.Schema<R>;
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 { computedConfig } = context;
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: computedConfig.headers || {},
48
+ headers: requestConfig.headers || {},
49
49
  responseType: context.responseType,
50
- withCredentials: computedConfig.includeCredentials,
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: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
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;
@@ -41,10 +41,11 @@ export default class MockRequestBackend {
41
41
  }
42
42
  const req = {
43
43
  body: context.getParsedBody(),
44
- params: (_b = context.computedConfig.params) !== null && _b !== void 0 ? _b : {},
45
- query: context.computedConfig.queryObject,
46
- headers: (_c = context.computedConfig.headers) !== null && _c !== void 0 ? _c : {},
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
  }
@@ -1,5 +1,4 @@
1
1
  export default class LocalForageCacheBackend {
2
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
3
2
  constructor(localforage) {
4
3
  this.store = localforage.createInstance({
5
4
  name: "requestCache",
@@ -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.9.4-alpha.2",
3
+ "version": "0.10.0-alpha.1",
4
4
  "description": "Typed API definitions with middleware support",
5
5
  "main": "cjs/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -30,12 +30,12 @@
30
30
  },
31
31
  "repository": "https://github.com/Censkh/api-def",
32
32
  "devDependencies": {
33
- "@biomejs/biome": "latest",
33
+ "@biomejs/biome": "1.7.2",
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.7",
38
+ "@types/node": "20.12.8",
39
39
  "@types/qs": "6.9.15",
40
40
  "axios": "1.6.8",
41
41
  "cross-env": "7.0.3",
@@ -44,6 +44,6 @@
44
44
  "qs": "6.12.1",
45
45
  "rimraf": "5.0.5",
46
46
  "typescript": "5.4.5",
47
- "zod": "3.22.5"
47
+ "zod": "3.23.6"
48
48
  }
49
49
  }