better-call 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { et as HasRequiredKeys, i as Endpoint, st as UnionToIntersection, t as Router } from "./router.cjs";
1
+ import { ct as UnionToIntersection, i as Endpoint, t as Router, tt as HasRequiredKeys } from "./router.cjs";
2
2
  import { BetterFetchOption, BetterFetchResponse } from "@better-fetch/fetch";
3
3
 
4
4
  //#region src/client.d.ts
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { et as HasRequiredKeys, i as Endpoint, st as UnionToIntersection, t as Router } from "./router.js";
1
+ import { ct as UnionToIntersection, i as Endpoint, t as Router, tt as HasRequiredKeys } from "./router.js";
2
2
  import { BetterFetchOption, BetterFetchResponse } from "@better-fetch/fetch";
3
3
 
4
4
  //#region src/client.d.ts
package/dist/index.cjs CHANGED
@@ -116,6 +116,17 @@ var InternalAPIError = class extends Error {
116
116
  } : void 0;
117
117
  }
118
118
  };
119
+ var ValidationError = class extends InternalAPIError {
120
+ constructor(message, issues) {
121
+ super(400, {
122
+ message,
123
+ code: "VALIDATION_ERROR"
124
+ });
125
+ this.message = message;
126
+ this.issues = issues;
127
+ this.issues = issues;
128
+ }
129
+ };
119
130
  var BetterCallError = class extends Error {
120
131
  constructor(message) {
121
132
  super(message);
@@ -126,6 +137,7 @@ const APIError = makeErrorForHideStackFrame(InternalAPIError, Error);
126
137
 
127
138
  //#endregion
128
139
  //#region src/utils.ts
140
+ const jsonContentTypeRegex = /^application\/([a-z0-9.+-]*\+)?json/i;
129
141
  async function getBody(request, allowedMediaTypes) {
130
142
  const contentType = request.headers.get("content-type") || "";
131
143
  const normalizedContentType = contentType.toLowerCase();
@@ -146,7 +158,7 @@ async function getBody(request, allowedMediaTypes) {
146
158
  });
147
159
  }
148
160
  }
149
- if (normalizedContentType.includes("application/json")) return await request.json();
161
+ if (jsonContentTypeRegex.test(normalizedContentType)) return await request.json();
150
162
  if (normalizedContentType.includes("application/x-www-form-urlencoded")) {
151
163
  const formData = await request.formData();
152
164
  const result = {};
@@ -179,6 +191,19 @@ function tryDecode(str) {
179
191
  return str;
180
192
  }
181
193
  }
194
+ async function tryCatch(promise) {
195
+ try {
196
+ return {
197
+ data: await promise,
198
+ error: null
199
+ };
200
+ } catch (error) {
201
+ return {
202
+ data: null,
203
+ error
204
+ };
205
+ }
206
+ }
182
207
 
183
208
  //#endregion
184
209
  //#region src/to-response.ts
@@ -300,11 +325,17 @@ async function runValidation(options, context = {}) {
300
325
  }
301
326
  if (options.requireHeaders && !context.headers) return {
302
327
  data: null,
303
- error: { message: "Headers is required" }
328
+ error: {
329
+ message: "Headers is required",
330
+ issues: []
331
+ }
304
332
  };
305
333
  if (options.requireRequest && !context.request) return {
306
334
  data: null,
307
- error: { message: "Request is required" }
335
+ error: {
336
+ message: "Request is required",
337
+ issues: []
338
+ }
308
339
  };
309
340
  return {
310
341
  data: request,
@@ -312,12 +343,12 @@ async function runValidation(options, context = {}) {
312
343
  };
313
344
  }
314
345
  function fromError(error, validating) {
315
- const errorMessages = [];
316
- for (const issue of error) {
317
- const message = issue.message;
318
- errorMessages.push(message);
319
- }
320
- return { message: `Invalid ${validating} parameters` };
346
+ return {
347
+ message: error.map((e) => {
348
+ return `[${e.path?.length ? `${validating}.` + e.path.map((x) => typeof x === "object" ? x.key : x).join(".") : validating}] ${e.message}`;
349
+ }).join("; "),
350
+ issues: error
351
+ };
321
352
  }
322
353
 
323
354
  //#endregion
@@ -437,10 +468,7 @@ const createInternalContext = async (context, { options, path }) => {
437
468
  const headers = new Headers();
438
469
  let responseStatus = void 0;
439
470
  const { data, error } = await runValidation(options, context);
440
- if (error) throw new APIError(400, {
441
- message: error.message,
442
- code: "VALIDATION_ERROR"
443
- });
471
+ if (error) throw new ValidationError(error.message, error.issues);
444
472
  const requestHeaders = "headers" in context ? context.headers instanceof Headers ? context.headers : new Headers(context.headers) : "request" in context && context.request instanceof Request ? context.request.headers : null;
445
473
  const requestCookies = requestHeaders?.get("cookie");
446
474
  const parsedCookies = requestCookies ? parseCookies(requestCookies) : void 0;
@@ -538,10 +566,21 @@ function createEndpoint(pathOrOptions, handlerOrOptions, handlerOrNever) {
538
566
  if ((options.method === "GET" || options.method === "HEAD") && options.body) throw new BetterCallError("Body is not allowed with GET or HEAD methods");
539
567
  const internalHandler = async (...inputCtx) => {
540
568
  const context = inputCtx[0] || {};
541
- const internalContext = await createInternalContext(context, {
569
+ const { data: internalContext, error: validationError } = await tryCatch(createInternalContext(context, {
542
570
  options,
543
571
  path
544
- });
572
+ }));
573
+ if (validationError) {
574
+ if (!(validationError instanceof ValidationError)) throw validationError;
575
+ if (options.onValidationError) await options.onValidationError({
576
+ message: validationError.message,
577
+ issues: validationError.issues
578
+ });
579
+ throw new APIError(400, {
580
+ message: validationError.message,
581
+ code: "VALIDATION_ERROR"
582
+ });
583
+ }
545
584
  const response = await handler(internalContext).catch(async (e) => {
546
585
  if (isAPIError(e)) {
547
586
  const onAPIError = options.onAPIError;
@@ -901,6 +940,7 @@ const createRouter = (endpoints, config) => {
901
940
  //#endregion
902
941
  exports.APIError = APIError;
903
942
  exports.BetterCallError = BetterCallError;
943
+ exports.ValidationError = ValidationError;
904
944
  exports.createEndpoint = createEndpoint;
905
945
  exports.createInternalContext = createInternalContext;
906
946
  exports.createMiddleware = createMiddleware;