api-def 0.8.3 → 0.8.5

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 CHANGED
@@ -62,6 +62,7 @@ exports.setRequestBackend = setRequestBackend;
62
62
  var HotRequestHost = /** @class */ (function () {
63
63
  function HotRequestHost(api, path, method) {
64
64
  this.responseType = undefined;
65
+ this.validation = {};
65
66
  this.api = api;
66
67
  this.method = method;
67
68
  this.path = path;
package/cjs/ApiTypes.d.ts CHANGED
@@ -2,6 +2,7 @@ import RequestContext from "./RequestContext";
2
2
  import { Api } from "./Api";
3
3
  import { CacheSource, EventResultType, RequestEvent, RequestMethod, ResponseType } from "./ApiConstants";
4
4
  import RequestBackend from "./backend/RequestBackend";
5
+ import { Validation } from "./Validation";
5
6
  export declare type AcceptableStatus = number | [min: number, max: number];
6
7
  export declare type Headers = Record<string, string | number | boolean | null | undefined>;
7
8
  export declare type Params = string;
@@ -87,6 +88,7 @@ export interface RequestHost {
87
88
  readonly baseUrl: string;
88
89
  readonly path: string;
89
90
  readonly responseType: ResponseType | undefined;
91
+ readonly validation: Validation;
90
92
  computeConfig<P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined>(config: RequestConfig<P, Q, B>): ComputedRequestConfig<P, Q, B>;
91
93
  computePath(path: string, config: RequestConfig): string;
92
94
  getRequestBackend(): RequestBackend;
package/cjs/Endpoint.d.ts CHANGED
@@ -3,10 +3,11 @@ import { ApiResponse, BaseRequestConfig, Body, ComputedRequestConfig, Params, Qu
3
3
  import * as Mocking from "./MockingTypes";
4
4
  import { RequestMethod, ResponseType } from "./ApiConstants";
5
5
  import RequestBackend from "./backend/RequestBackend";
6
- export interface EndpointConfig<R, P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined> {
6
+ import { Validation } from "./Validation";
7
+ export interface EndpointConfig<R, P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined, Path extends string = string> {
7
8
  readonly id: string;
8
9
  readonly method: RequestMethod;
9
- readonly path: string;
10
+ readonly path: Path;
10
11
  /**
11
12
  * Name your endpoint to help with debugging and documentation
12
13
  * @default `id` is used as the name if no name is supplied
@@ -29,6 +30,7 @@ export interface EndpointConfig<R, P extends Params | undefined, Q extends Query
29
30
  * Enable/disable mocked returns for all endpoints on your API object.
30
31
  */
31
32
  readonly mocking?: Mocking.EndpointMockingConfig<R, P, Q, B>;
33
+ readonly validation?: Validation<R, P, Q, B>;
32
34
  }
33
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 {
34
36
  readonly api: Api;
@@ -40,6 +42,7 @@ export default class Endpoint<R = any, P extends Params | undefined = Params | u
40
42
  readonly config?: BaseRequestConfig;
41
43
  readonly responseType: ResponseType | undefined;
42
44
  readonly mocking?: Mocking.EndpointMockingConfig<R, P, Q, B>;
45
+ readonly validation: Validation<R, P, Q, B>;
43
46
  constructor(api: Api, info: EndpointConfig<R, P, Q, B>);
44
47
  submit(config: RequestConfig<P, Q, B>): Promise<ApiResponse<R>>;
45
48
  computePath(path: string, request: RequestConfig): string;
package/cjs/Endpoint.js CHANGED
@@ -49,6 +49,7 @@ var Endpoint = /** @class */ (function () {
49
49
  this.config = info.config;
50
50
  this.responseType = info.responseType;
51
51
  this.mocking = info.mocking;
52
+ this.validation = info.validation || {};
52
53
  }
53
54
  Endpoint.prototype.submit = function (config) {
54
55
  var _a, _b;
@@ -1,12 +1,14 @@
1
1
  import { Body, Params, Query } from "./ApiTypes";
2
2
  import Endpoint, { EndpointConfig } from "./Endpoint";
3
3
  import { Api } from "./Api";
4
+ import * as zod from "zod";
4
5
  export default class EndpointBuilder<R = any, P extends Params | undefined = undefined, Q extends Query | undefined = undefined, B extends Body | undefined = undefined> {
5
6
  private api;
7
+ private readonly validation;
6
8
  constructor(api: Api);
7
- queryOf<Q extends Query>(): EndpointBuilder<R, P, Q, B>;
9
+ queryOf<Q extends Query>(schema?: zod.Schema<Q>): EndpointBuilder<R, P, Q, B>;
8
10
  paramsOf<P extends Params>(): EndpointBuilder<R, P, Q, B>;
9
- bodyOf<B extends Body>(): EndpointBuilder<R, P, Q, B>;
10
- responseOf<R>(): EndpointBuilder<R, P, Q, B>;
11
- build(config: EndpointConfig<R, P, Q, B>): Endpoint<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>;
12
14
  }
@@ -1,24 +1,43 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
3
14
  var Endpoint_1 = require("./Endpoint");
15
+ /*type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}`
16
+ ? Segment extends `:${infer Param}` ? Param | ExtractParams<Rest> : ExtractParams<Rest>
17
+ : Path extends `:${infer Param}` ? Param : undefined;
18
+ */
4
19
  var EndpointBuilder = /** @class */ (function () {
5
20
  function EndpointBuilder(api) {
21
+ this.validation = {};
6
22
  this.api = api;
7
23
  }
8
- EndpointBuilder.prototype.queryOf = function () {
24
+ EndpointBuilder.prototype.queryOf = function (schema) {
25
+ this.validation.query = schema;
9
26
  return this;
10
27
  };
11
28
  EndpointBuilder.prototype.paramsOf = function () {
12
29
  return this;
13
30
  };
14
- EndpointBuilder.prototype.bodyOf = function () {
31
+ EndpointBuilder.prototype.bodyOf = function (schema) {
32
+ this.validation.body = schema;
15
33
  return this;
16
34
  };
17
- EndpointBuilder.prototype.responseOf = function () {
35
+ EndpointBuilder.prototype.responseOf = function (schema) {
36
+ this.validation.response = schema;
18
37
  return this;
19
38
  };
20
39
  EndpointBuilder.prototype.build = function (config) {
21
- var endpoint = new Endpoint_1.default(this.api, config);
40
+ var endpoint = new Endpoint_1.default(this.api, __assign(__assign({}, config), { validation: this.validation }));
22
41
  this.api.endpoints[endpoint.id] = endpoint;
23
42
  return endpoint;
24
43
  };
@@ -4,6 +4,7 @@ import { RequestEvent, RequestMethod, ResponseType } from "./ApiConstants";
4
4
  import { EndpointMockingConfig } from "./MockingTypes";
5
5
  import { RequestError } from "./RequestError";
6
6
  import RequestBackend from "./backend/RequestBackend";
7
+ import { Validation } from "./Validation";
7
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
9
  readonly id: number;
9
10
  readonly key: string;
@@ -20,6 +21,7 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
20
21
  readonly computedConfig: ComputedRequestConfig<P, Q, B>;
21
22
  readonly mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined;
22
23
  private parsedBody;
24
+ readonly validation: Validation<R, P, Q, B>;
23
25
  constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<P, Q, B>, computedPath: string, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined);
24
26
  get method(): RequestMethod;
25
27
  get api(): Api;
@@ -58,6 +58,7 @@ var RequestContext = /** @class */ (function () {
58
58
  };
59
59
  this.eventHandlers = {};
60
60
  this.mocking = mocking;
61
+ this.validation = host.validation;
61
62
  this.initMiddleware();
62
63
  this.parseRequestBody();
63
64
  }
@@ -7,6 +7,10 @@ export declare const RequestErrorCode: {
7
7
  readonly REQUEST_INVALID_STATUS: "request/invalid-status";
8
8
  readonly REQUEST_INVALID_CONFIG: "request/invalid-config";
9
9
  readonly REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type";
10
+ readonly VALIDATION_QUERY_VALIDATE_ERROR: "validation/query-validate-error";
11
+ readonly VALIDATION_PARAMS_VALIDATE_ERROR: "validation/params-validate-error";
12
+ readonly VALIDATION_BODY_VALIDATE_ERROR: "validation/body-validate-error";
13
+ readonly VALIDATION_RESPONSE_VALIDATE_ERROR: "validation/response-validate-error";
10
14
  };
11
15
  export declare type RequestErrorCode = EnumOf<typeof RequestErrorCode>;
12
16
  export interface RequestError extends Error {
@@ -7,6 +7,10 @@ exports.RequestErrorCode = {
7
7
  REQUEST_INVALID_STATUS: "request/invalid-status",
8
8
  REQUEST_INVALID_CONFIG: "request/invalid-config",
9
9
  REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type",
10
+ VALIDATION_QUERY_VALIDATE_ERROR: "validation/query-validate-error",
11
+ VALIDATION_PARAMS_VALIDATE_ERROR: "validation/params-validate-error",
12
+ VALIDATION_BODY_VALIDATE_ERROR: "validation/body-validate-error",
13
+ VALIDATION_RESPONSE_VALIDATE_ERROR: "validation/response-validate-error",
10
14
  };
11
15
  var isRequestError = function (error) {
12
16
  return "isRequestError" in error;
package/cjs/Requester.js CHANGED
@@ -125,6 +125,31 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
125
125
  beforeSendEventResult.type === ApiConstants_1.EventResultType.Respond) {
126
126
  return [2 /*return*/, (context.response = beforeSendEventResult.response)];
127
127
  }
128
+ // validation
129
+ if (context.validation.query) {
130
+ try {
131
+ context.computedConfig.queryObject = context.validation.query.parse(context.computedConfig.queryObject);
132
+ }
133
+ catch (error) {
134
+ throw (0, RequestError_1.convertToRequestError)({
135
+ error: error,
136
+ code: RequestError_1.RequestErrorCode.VALIDATION_QUERY_VALIDATE_ERROR,
137
+ context: context,
138
+ });
139
+ }
140
+ }
141
+ if (context.validation.body) {
142
+ try {
143
+ context.computedConfig.body = context.validation.body.parse(context.computedConfig.body);
144
+ }
145
+ catch (error) {
146
+ throw (0, RequestError_1.convertToRequestError)({
147
+ error: error,
148
+ code: RequestError_1.RequestErrorCode.VALIDATION_BODY_VALIDATE_ERROR,
149
+ context: context,
150
+ });
151
+ }
152
+ }
128
153
  retryOptions = parseRetryOptions((_a = context.computedConfig) === null || _a === void 0 ? void 0 : _a.retry);
129
154
  internalRetryOptions = {
130
155
  retries: retryOptions.maxAttempts,
@@ -202,6 +227,18 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
202
227
  return [4 /*yield*/, (0, retry_1.default)(performRequest, internalRetryOptions)];
203
228
  case 2:
204
229
  response = _d.sent();
230
+ if (context.validation.response) {
231
+ try {
232
+ response.data = context.validation.response.parse(response.data);
233
+ }
234
+ catch (error) {
235
+ throw (0, RequestError_1.convertToRequestError)({
236
+ error: error,
237
+ code: RequestError_1.RequestErrorCode.VALIDATION_RESPONSE_VALIDATE_ERROR,
238
+ context: context,
239
+ });
240
+ }
241
+ }
205
242
  return [2 /*return*/, (response)];
206
243
  }
207
244
  });
@@ -0,0 +1,8 @@
1
+ import * as zod from "zod";
2
+ import { 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>;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -163,7 +163,7 @@ var FetchRequestBackend = /** @class */ (function () {
163
163
  }, {});
164
164
  var url = context.getRequestUrl();
165
165
  var promise = this.fetch(url.href, {
166
- method: context.method,
166
+ method: context.method.toUpperCase(),
167
167
  body: bodyJsonify ? JSON.stringify(body) : body,
168
168
  headers: parsedHeaders,
169
169
  mode: "cors",
package/esm/Api.js CHANGED
@@ -29,6 +29,7 @@ export const setRequestBackend = (backend) => {
29
29
  class HotRequestHost {
30
30
  constructor(api, path, method) {
31
31
  this.responseType = undefined;
32
+ this.validation = {};
32
33
  this.api = api;
33
34
  this.method = method;
34
35
  this.path = path;
package/esm/ApiTypes.d.ts CHANGED
@@ -2,6 +2,7 @@ import RequestContext from "./RequestContext";
2
2
  import { Api } from "./Api";
3
3
  import { CacheSource, EventResultType, RequestEvent, RequestMethod, ResponseType } from "./ApiConstants";
4
4
  import RequestBackend from "./backend/RequestBackend";
5
+ import { Validation } from "./Validation";
5
6
  export declare type AcceptableStatus = number | [min: number, max: number];
6
7
  export declare type Headers = Record<string, string | number | boolean | null | undefined>;
7
8
  export declare type Params = string;
@@ -87,6 +88,7 @@ export interface RequestHost {
87
88
  readonly baseUrl: string;
88
89
  readonly path: string;
89
90
  readonly responseType: ResponseType | undefined;
91
+ readonly validation: Validation;
90
92
  computeConfig<P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined>(config: RequestConfig<P, Q, B>): ComputedRequestConfig<P, Q, B>;
91
93
  computePath(path: string, config: RequestConfig): string;
92
94
  getRequestBackend(): RequestBackend;
package/esm/Endpoint.d.ts CHANGED
@@ -3,10 +3,11 @@ import { ApiResponse, BaseRequestConfig, Body, ComputedRequestConfig, Params, Qu
3
3
  import * as Mocking from "./MockingTypes";
4
4
  import { RequestMethod, ResponseType } from "./ApiConstants";
5
5
  import RequestBackend from "./backend/RequestBackend";
6
- export interface EndpointConfig<R, P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined> {
6
+ import { Validation } from "./Validation";
7
+ export interface EndpointConfig<R, P extends Params | undefined, Q extends Query | undefined, B extends Body | undefined, Path extends string = string> {
7
8
  readonly id: string;
8
9
  readonly method: RequestMethod;
9
- readonly path: string;
10
+ readonly path: Path;
10
11
  /**
11
12
  * Name your endpoint to help with debugging and documentation
12
13
  * @default `id` is used as the name if no name is supplied
@@ -29,6 +30,7 @@ export interface EndpointConfig<R, P extends Params | undefined, Q extends Query
29
30
  * Enable/disable mocked returns for all endpoints on your API object.
30
31
  */
31
32
  readonly mocking?: Mocking.EndpointMockingConfig<R, P, Q, B>;
33
+ readonly validation?: Validation<R, P, Q, B>;
32
34
  }
33
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 {
34
36
  readonly api: Api;
@@ -40,6 +42,7 @@ export default class Endpoint<R = any, P extends Params | undefined = Params | u
40
42
  readonly config?: BaseRequestConfig;
41
43
  readonly responseType: ResponseType | undefined;
42
44
  readonly mocking?: Mocking.EndpointMockingConfig<R, P, Q, B>;
45
+ readonly validation: Validation<R, P, Q, B>;
43
46
  constructor(api: Api, info: EndpointConfig<R, P, Q, B>);
44
47
  submit(config: RequestConfig<P, Q, B>): Promise<ApiResponse<R>>;
45
48
  computePath(path: string, request: RequestConfig): string;
package/esm/Endpoint.js CHANGED
@@ -20,6 +20,7 @@ export default class Endpoint {
20
20
  this.config = info.config;
21
21
  this.responseType = info.responseType;
22
22
  this.mocking = info.mocking;
23
+ this.validation = info.validation || {};
23
24
  }
24
25
  submit(config) {
25
26
  var _a, _b;
@@ -1,12 +1,14 @@
1
1
  import { Body, Params, Query } from "./ApiTypes";
2
2
  import Endpoint, { EndpointConfig } from "./Endpoint";
3
3
  import { Api } from "./Api";
4
+ import * as zod from "zod";
4
5
  export default class EndpointBuilder<R = any, P extends Params | undefined = undefined, Q extends Query | undefined = undefined, B extends Body | undefined = undefined> {
5
6
  private api;
7
+ private readonly validation;
6
8
  constructor(api: Api);
7
- queryOf<Q extends Query>(): EndpointBuilder<R, P, Q, B>;
9
+ queryOf<Q extends Query>(schema?: zod.Schema<Q>): EndpointBuilder<R, P, Q, B>;
8
10
  paramsOf<P extends Params>(): EndpointBuilder<R, P, Q, B>;
9
- bodyOf<B extends Body>(): EndpointBuilder<R, P, Q, B>;
10
- responseOf<R>(): EndpointBuilder<R, P, Q, B>;
11
- build(config: EndpointConfig<R, P, Q, B>): Endpoint<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>;
12
14
  }
@@ -1,22 +1,30 @@
1
1
  import Endpoint from "./Endpoint";
2
+ /*type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}`
3
+ ? Segment extends `:${infer Param}` ? Param | ExtractParams<Rest> : ExtractParams<Rest>
4
+ : Path extends `:${infer Param}` ? Param : undefined;
5
+ */
2
6
  export default class EndpointBuilder {
3
7
  constructor(api) {
8
+ this.validation = {};
4
9
  this.api = api;
5
10
  }
6
- queryOf() {
11
+ queryOf(schema) {
12
+ this.validation.query = schema;
7
13
  return this;
8
14
  }
9
15
  paramsOf() {
10
16
  return this;
11
17
  }
12
- bodyOf() {
18
+ bodyOf(schema) {
19
+ this.validation.body = schema;
13
20
  return this;
14
21
  }
15
- responseOf() {
22
+ responseOf(schema) {
23
+ this.validation.response = schema;
16
24
  return this;
17
25
  }
18
26
  build(config) {
19
- const endpoint = new Endpoint(this.api, config);
27
+ const endpoint = new Endpoint(this.api, Object.assign(Object.assign({}, config), { validation: this.validation }));
20
28
  this.api.endpoints[endpoint.id] = endpoint;
21
29
  return endpoint;
22
30
  }
@@ -4,6 +4,7 @@ import { RequestEvent, RequestMethod, ResponseType } from "./ApiConstants";
4
4
  import { EndpointMockingConfig } from "./MockingTypes";
5
5
  import { RequestError } from "./RequestError";
6
6
  import RequestBackend from "./backend/RequestBackend";
7
+ import { Validation } from "./Validation";
7
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
9
  readonly id: number;
9
10
  readonly key: string;
@@ -20,6 +21,7 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
20
21
  readonly computedConfig: ComputedRequestConfig<P, Q, B>;
21
22
  readonly mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined;
22
23
  private parsedBody;
24
+ readonly validation: Validation<R, P, Q, B>;
23
25
  constructor(backend: RequestBackend, host: RequestHost, config: ComputedRequestConfig<P, Q, B>, computedPath: string, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined);
24
26
  get method(): RequestMethod;
25
27
  get api(): Api;
@@ -29,6 +29,7 @@ export default class RequestContext {
29
29
  };
30
30
  this.eventHandlers = {};
31
31
  this.mocking = mocking;
32
+ this.validation = host.validation;
32
33
  this.initMiddleware();
33
34
  this.parseRequestBody();
34
35
  }
@@ -7,6 +7,10 @@ export declare const RequestErrorCode: {
7
7
  readonly REQUEST_INVALID_STATUS: "request/invalid-status";
8
8
  readonly REQUEST_INVALID_CONFIG: "request/invalid-config";
9
9
  readonly REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type";
10
+ readonly VALIDATION_QUERY_VALIDATE_ERROR: "validation/query-validate-error";
11
+ readonly VALIDATION_PARAMS_VALIDATE_ERROR: "validation/params-validate-error";
12
+ readonly VALIDATION_BODY_VALIDATE_ERROR: "validation/body-validate-error";
13
+ readonly VALIDATION_RESPONSE_VALIDATE_ERROR: "validation/response-validate-error";
10
14
  };
11
15
  export declare type RequestErrorCode = EnumOf<typeof RequestErrorCode>;
12
16
  export interface RequestError extends Error {
@@ -4,6 +4,10 @@ export const RequestErrorCode = {
4
4
  REQUEST_INVALID_STATUS: "request/invalid-status",
5
5
  REQUEST_INVALID_CONFIG: "request/invalid-config",
6
6
  REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type",
7
+ VALIDATION_QUERY_VALIDATE_ERROR: "validation/query-validate-error",
8
+ VALIDATION_PARAMS_VALIDATE_ERROR: "validation/params-validate-error",
9
+ VALIDATION_BODY_VALIDATE_ERROR: "validation/body-validate-error",
10
+ VALIDATION_RESPONSE_VALIDATE_ERROR: "validation/response-validate-error",
7
11
  };
8
12
  export const isRequestError = (error) => {
9
13
  return "isRequestError" in error;
package/esm/Requester.js CHANGED
@@ -74,6 +74,31 @@ const makeRequest = (context) => __awaiter(void 0, void 0, void 0, function* ()
74
74
  beforeSendEventResult.type === EventResultType.Respond) {
75
75
  return (context.response = beforeSendEventResult.response);
76
76
  }
77
+ // validation
78
+ if (context.validation.query) {
79
+ try {
80
+ context.computedConfig.queryObject = context.validation.query.parse(context.computedConfig.queryObject);
81
+ }
82
+ catch (error) {
83
+ throw convertToRequestError({
84
+ error: error,
85
+ code: RequestErrorCode.VALIDATION_QUERY_VALIDATE_ERROR,
86
+ context: context,
87
+ });
88
+ }
89
+ }
90
+ if (context.validation.body) {
91
+ try {
92
+ context.computedConfig.body = context.validation.body.parse(context.computedConfig.body);
93
+ }
94
+ catch (error) {
95
+ throw convertToRequestError({
96
+ error: error,
97
+ code: RequestErrorCode.VALIDATION_BODY_VALIDATE_ERROR,
98
+ context: context,
99
+ });
100
+ }
101
+ }
77
102
  const retryOptions = parseRetryOptions((_a = context.computedConfig) === null || _a === void 0 ? void 0 : _a.retry);
78
103
  const internalRetryOptions = {
79
104
  retries: retryOptions.maxAttempts,
@@ -137,6 +162,18 @@ const makeRequest = (context) => __awaiter(void 0, void 0, void 0, function* ()
137
162
  }
138
163
  });
139
164
  const response = yield retry(performRequest, internalRetryOptions);
165
+ if (context.validation.response) {
166
+ try {
167
+ response.data = context.validation.response.parse(response.data);
168
+ }
169
+ catch (error) {
170
+ throw convertToRequestError({
171
+ error: error,
172
+ code: RequestErrorCode.VALIDATION_RESPONSE_VALIDATE_ERROR,
173
+ context: context,
174
+ });
175
+ }
176
+ }
140
177
  return (response);
141
178
  });
142
179
  const parseResponse = (context, response, error) => __awaiter(void 0, void 0, void 0, function* () {
@@ -0,0 +1,8 @@
1
+ import * as zod from "zod";
2
+ import { 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>;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -94,7 +94,7 @@ export default class FetchRequestBackend {
94
94
  }, {});
95
95
  const url = context.getRequestUrl();
96
96
  const promise = this.fetch(url.href, {
97
- method: context.method,
97
+ method: context.method.toUpperCase(),
98
98
  body: bodyJsonify ? JSON.stringify(body) : body,
99
99
  headers: parsedHeaders,
100
100
  mode: "cors",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-def",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "description": "Typed API definitions with middleware support",
5
5
  "main": "cjs/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -73,6 +73,7 @@
73
73
  "eslint-watch": "7.0.0",
74
74
  "npm-run-all": "4.1.5",
75
75
  "qs": "6.11.2",
76
- "typescript": "4.8.4"
76
+ "typescript": "4.8.4",
77
+ "zod": "3.22.4"
77
78
  }
78
79
  }