arri 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,18 +6,35 @@ const arriValidate = require('arri-validate');
6
6
  const h3Sse = require('h3-sse');
7
7
  const scule = require('scule');
8
8
 
9
- const ErrorResponse = arriValidate.a.object({
10
- statusCode: arriValidate.a.int8(),
11
- statusMessage: arriValidate.a.string(),
12
- stack: arriValidate.a.optional(arriValidate.a.string()),
9
+ var __defProp$3 = Object.defineProperty;
10
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __publicField$3 = (obj, key, value) => {
12
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
13
+ return value;
14
+ };
15
+ class ArriServerError extends Error {
16
+ constructor(err) {
17
+ super(err.message);
18
+ __publicField$3(this, "code");
19
+ __publicField$3(this, "data");
20
+ this.code = err.code;
21
+ this.data = err.data;
22
+ if (err.stack) {
23
+ this.stack = err.stack;
24
+ }
25
+ }
26
+ }
27
+ const ArriServerErrorResponse = arriValidate.a.object({
28
+ code: arriValidate.a.int16(),
29
+ message: arriValidate.a.string(),
30
+ stack: arriValidate.a.optional(arriValidate.a.array(arriValidate.a.string())),
13
31
  data: arriValidate.a.optional(arriValidate.a.any())
14
32
  });
15
33
  function defineError(statusCode, input = {}) {
16
34
  const defaultVals = errorResponseDefaults[statusCode];
17
- return h3.createError({
18
- statusCode,
19
- statusMessage: input.statusMessage ?? defaultVals.message ?? "An unknown error occurred",
20
- stack: input.stack ?? "",
35
+ return new ArriServerError({
36
+ code: statusCode,
37
+ message: input.message ?? defaultVals?.message ?? "An unknown error occurred",
21
38
  data: input.data
22
39
  });
23
40
  }
@@ -25,7 +42,7 @@ function errorResponseFromValidationErrors(errors, prefixText = `Missing or inva
25
42
  const errorParts = [];
26
43
  for (const err of errors) {
27
44
  const propName = err.instancePath?.split("/") ?? [];
28
- if (propName.length) {
45
+ if (propName.length > 0) {
29
46
  propName.shift();
30
47
  }
31
48
  if (!errorParts.includes(propName.join("."))) {
@@ -33,7 +50,7 @@ function errorResponseFromValidationErrors(errors, prefixText = `Missing or inva
33
50
  }
34
51
  }
35
52
  throw defineError(400, {
36
- statusMessage: `${prefixText}: [${errorParts.join(",")}]`,
53
+ message: `${prefixText}: [${errorParts.join(",")}]`,
37
54
  data: errors
38
55
  });
39
56
  }
@@ -187,28 +204,55 @@ const errorResponseDefaults = {
187
204
  message: "Network Authentication Required"
188
205
  }
189
206
  };
190
- async function handleH3Error(err, event, onError) {
191
- const error = h3.isError(err) ? err : defineError(500, {
192
- statusMessage: typeof err === "object" && err != null && "message" in err && typeof err.message === "string" ? err.message : void 0,
193
- data: err,
194
- stack: `${err}`
195
- });
196
- h3.setResponseStatus(event, error.statusCode);
207
+ async function handleH3Error(err, event, onError, debug) {
208
+ let arriErr;
209
+ if (err instanceof ArriServerError) {
210
+ arriErr = err;
211
+ } else if (h3.isError(err)) {
212
+ arriErr = new ArriServerError({
213
+ code: err.statusCode,
214
+ message: err.message,
215
+ stack: err.stack,
216
+ data: err.data
217
+ });
218
+ } else if (err instanceof Error) {
219
+ arriErr = new ArriServerError({
220
+ code: 500,
221
+ message: err.message,
222
+ data: err,
223
+ stack: err.stack
224
+ });
225
+ } else {
226
+ arriErr = new ArriServerError({
227
+ code: 500,
228
+ message: `An unknown error occurred`,
229
+ data: err
230
+ });
231
+ }
232
+ if (!arriErr) {
233
+ return;
234
+ }
235
+ h3.setResponseStatus(event, arriErr.code);
197
236
  if (onError) {
198
- await onError(error, event);
237
+ await onError(arriErr, event);
199
238
  }
200
239
  if (event.handled) {
201
240
  return;
202
241
  }
203
- await h3.send(
204
- event,
205
- JSON.stringify({
206
- statusCode: error.statusCode,
207
- statusMessage: error.statusMessage,
208
- data: error.data,
209
- stack: error.stack
210
- })
211
- );
242
+ return sendArriError(event, arriErr, debug);
243
+ }
244
+ async function sendArriError(event, error, debug) {
245
+ const payload = {
246
+ code: error.code,
247
+ message: error.message,
248
+ data: error.data
249
+ };
250
+ if (debug) {
251
+ payload.stack = error.stack?.split("\n").map((l) => l.trim());
252
+ }
253
+ h3.setResponseHeader(event, "Content-Type", "application/json");
254
+ h3.setResponseStatus(event, error.code);
255
+ return h3.send(event, JSON.stringify(payload));
212
256
  }
213
257
 
214
258
  function isRpcParamSchema(input) {
@@ -321,7 +365,7 @@ function registerRpc(router, path, procedure, opts) {
321
365
  if (!responseValidator?.validate(response)) {
322
366
  const errors = arriValidate.a.errors(procedure.response, response);
323
367
  throw defineError(500, {
324
- statusMessage: "Failed to serialize response. Response does not match specified schema",
368
+ message: "Failed to serialize response. Response does not match specified schema",
325
369
  data: errors
326
370
  });
327
371
  }
@@ -344,7 +388,7 @@ function registerRpc(router, path, procedure, opts) {
344
388
  );
345
389
  }
346
390
  } catch (err) {
347
- await handleH3Error(err, event, opts.onError);
391
+ await handleH3Error(err, event, opts.onError, opts.debug ?? false);
348
392
  }
349
393
  return "";
350
394
  });
@@ -390,7 +434,7 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
390
434
  ", "
391
435
  )}]`;
392
436
  throw defineError(400, {
393
- statusMessage: message,
437
+ message,
394
438
  data: parsedParams.error
395
439
  });
396
440
  }
@@ -403,7 +447,7 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
403
447
  const body = await h3.readRawBody(event);
404
448
  if (!body) {
405
449
  throw defineError(400, {
406
- statusMessage: `Invalid request body. Expected object. Got undefined.`
450
+ message: `Invalid request body. Expected object. Got undefined.`
407
451
  });
408
452
  }
409
453
  const parsedParams = arriValidate.a.safeParse(schema, body);
@@ -417,7 +461,7 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
417
461
  }
418
462
  }
419
463
  throw defineError(400, {
420
- statusMessage: `Invalid request body. Affected properties [${errorParts.join(
464
+ message: `Invalid request body. Affected properties [${errorParts.join(
421
465
  ", "
422
466
  )}]`,
423
467
  data: parsedParams.error
@@ -490,11 +534,10 @@ class EventStreamConnection {
490
534
  continue;
491
535
  }
492
536
  const errors2 = this.validationErrors(item);
493
- const errorResponse2 = {
494
- statusCode: 500,
495
- statusMessage: "Failed to serialize response. Response does not match specified schema.",
537
+ const errorResponse2 = defineError(500, {
538
+ message: "Failed to serialize response. Response does not match specified schema.",
496
539
  data: errors2
497
- };
540
+ });
498
541
  events.push({
499
542
  id: eventId,
500
543
  event: "error",
@@ -513,11 +556,10 @@ class EventStreamConnection {
513
556
  return;
514
557
  }
515
558
  const errors = this.validationErrors(data);
516
- const errorResponse = {
517
- statusCode: 500,
518
- statusMessage: "Failed to serialize response. Response does not match specified schema.",
559
+ const errorResponse = defineError(500, {
560
+ message: "Failed to serialize response. Response does not match specified schema.",
519
561
  data: errors
520
- };
562
+ });
521
563
  await this.eventStream.push({
522
564
  id: eventId,
523
565
  event: "error",
@@ -603,9 +645,12 @@ function registerEventStreamRpc(router, path, procedure, opts) {
603
645
  validator: responseValidator?.validate ?? function() {
604
646
  return true;
605
647
  },
606
- serializer: responseValidator?.serialize ?? function(_) {
607
- return "";
608
- },
648
+ serializer: (
649
+ // eslint-disable-next-line @typescript-eslint/unbound-method
650
+ responseValidator?.serialize ?? function(_) {
651
+ return "";
652
+ }
653
+ ),
609
654
  validationErrors(input) {
610
655
  if (procedure.response) {
611
656
  return arriValidate.a.errors(procedure.response, input);
@@ -622,7 +667,7 @@ function registerEventStreamRpc(router, path, procedure, opts) {
622
667
  stream.send();
623
668
  }
624
669
  } catch (err) {
625
- await handleH3Error(err, event, opts.onError);
670
+ await handleH3Error(err, event, opts.onError, opts.debug ?? false);
626
671
  }
627
672
  return "";
628
673
  });
@@ -689,7 +734,7 @@ function handleRoute(router, method, route, opts) {
689
734
  ", "
690
735
  )}]`;
691
736
  throw defineError(400, {
692
- statusMessage: message
737
+ message
693
738
  });
694
739
  }
695
740
  event.context.query = parsedQuery.value;
@@ -713,7 +758,7 @@ function handleRoute(router, method, route, opts) {
713
758
  }
714
759
  }
715
760
  throw defineError(400, {
716
- statusMessage: `Invalid request body. Affected properties [${errorParts.join(
761
+ message: `Invalid request body. Affected properties [${errorParts.join(
717
762
  ", "
718
763
  )}]`,
719
764
  data: parsedBody.error
@@ -741,7 +786,7 @@ function handleRoute(router, method, route, opts) {
741
786
  await route.postHandler(event);
742
787
  }
743
788
  } catch (err) {
744
- await handleH3Error(err, event, opts.onError);
789
+ await handleH3Error(err, event, opts.onError, opts.debug ?? false);
745
790
  }
746
791
  return "";
747
792
  });
@@ -815,29 +860,31 @@ class ArriApp {
815
860
  __publicField(this, "__isArri__", true);
816
861
  __publicField(this, "h3App");
817
862
  __publicField(this, "h3Router", h3.createRouter());
818
- __publicField(this, "rpcDefinitionPath");
819
- __publicField(this, "rpcRoutePrefix");
863
+ __publicField(this, "_rpcDefinitionPath");
864
+ __publicField(this, "_rpcRoutePrefix");
820
865
  __publicField(this, "appInfo");
821
- __publicField(this, "procedures", {});
822
- __publicField(this, "models", {});
823
- __publicField(this, "middlewares", []);
824
- __publicField(this, "onRequest");
825
- __publicField(this, "onAfterResponse");
826
- __publicField(this, "onBeforeResponse");
827
- __publicField(this, "onError");
866
+ __publicField(this, "_procedures", {});
867
+ __publicField(this, "_models", {});
868
+ __publicField(this, "_middlewares", []);
869
+ __publicField(this, "_onRequest");
870
+ __publicField(this, "_onAfterResponse");
871
+ __publicField(this, "_onBeforeResponse");
872
+ __publicField(this, "_onError");
873
+ __publicField(this, "_debug");
828
874
  this.appInfo = opts?.appInfo;
829
875
  this.h3App = h3.createApp({
830
876
  debug: opts?.debug
831
877
  });
832
- this.onRequest = opts.onRequest;
833
- this.onError = opts.onError;
834
- this.onAfterResponse = opts.onAfterResponse;
835
- this.onBeforeResponse = opts.onBeforeResponse;
836
- this.rpcRoutePrefix = opts?.rpcRoutePrefix ?? "";
837
- this.rpcDefinitionPath = opts?.rpcDefinitionPath ?? "__definition";
878
+ this._debug = opts.debug ?? false;
879
+ this._onRequest = opts.onRequest;
880
+ this._onError = opts.onError;
881
+ this._onAfterResponse = opts.onAfterResponse;
882
+ this._onBeforeResponse = opts.onBeforeResponse;
883
+ this._rpcRoutePrefix = opts?.rpcRoutePrefix ?? "";
884
+ this._rpcDefinitionPath = opts?.rpcDefinitionPath ?? "__definition";
838
885
  this.h3App.use(this.h3Router);
839
886
  this.h3Router.get(
840
- this.rpcRoutePrefix ? `/${this.rpcRoutePrefix}/${this.rpcDefinitionPath}`.split("//").join("/") : `/${this.rpcDefinitionPath}`,
887
+ this._rpcRoutePrefix ? `/${this._rpcRoutePrefix}/${this._rpcDefinitionPath}`.split("//").join("/") : `/${this._rpcDefinitionPath}`,
841
888
  h3.eventHandler(() => this.getAppDefinition())
842
889
  );
843
890
  if (process.env.ARRI_DEV_MODE === "true") {
@@ -852,22 +899,16 @@ class ArriApp {
852
899
  h3.setResponseStatus(event, 404);
853
900
  const error = defineError(404);
854
901
  try {
855
- if (this.onRequest) {
856
- await this.onRequest(event);
902
+ if (this._onRequest) {
903
+ await this._onRequest(event);
857
904
  }
858
905
  } catch (err) {
859
- await handleH3Error(err, event, this.onError);
860
- }
861
- if (event.handled) {
862
- return;
863
- }
864
- if (this.onError) {
865
- await this.onError(error, event);
906
+ await handleH3Error(err, event, this._onError, this._debug);
866
907
  }
867
908
  if (event.handled) {
868
909
  return;
869
910
  }
870
- h3.sendError(event, error);
911
+ return handleH3Error(error, event, this._onError, this._debug);
871
912
  })
872
913
  );
873
914
  }
@@ -882,11 +923,11 @@ class ArriApp {
882
923
  this.registerModels(input.getModels());
883
924
  return;
884
925
  }
885
- this.middlewares.push(input);
926
+ this._middlewares.push(input);
886
927
  }
887
928
  rpc(procedure) {
888
- const path = procedure.path ?? getRpcPath(procedure.name, this.rpcRoutePrefix);
889
- this.procedures[procedure.name] = createHttpRpcDefinition(
929
+ const path = procedure.path ?? getRpcPath(procedure.name, this._rpcRoutePrefix);
930
+ this._procedures[procedure.name] = createHttpRpcDefinition(
890
931
  procedure.name,
891
932
  path,
892
933
  procedure
@@ -894,45 +935,48 @@ class ArriApp {
894
935
  if (isRpcParamSchema(procedure.params)) {
895
936
  const paramName = getRpcParamName(procedure.name, procedure);
896
937
  if (paramName) {
897
- this.models[paramName] = procedure.params;
938
+ this._models[paramName] = procedure.params;
898
939
  }
899
940
  }
900
941
  if (isRpcParamSchema(procedure.response)) {
901
942
  const responseName = getRpcResponseName(procedure.name, procedure);
902
943
  if (responseName) {
903
- this.models[responseName] = procedure.response;
944
+ this._models[responseName] = procedure.response;
904
945
  }
905
946
  }
906
947
  if (isEventStreamRpc(procedure)) {
907
948
  registerEventStreamRpc(this.h3Router, path, procedure, {
908
- middleware: this.middlewares,
909
- onRequest: this.onRequest,
910
- onError: this.onError,
911
- onAfterResponse: this.onAfterResponse,
912
- onBeforeResponse: this.onBeforeResponse
949
+ middleware: this._middlewares,
950
+ onRequest: this._onRequest,
951
+ onError: this._onError,
952
+ onAfterResponse: this._onAfterResponse,
953
+ onBeforeResponse: this._onBeforeResponse,
954
+ debug: this._debug
913
955
  });
914
956
  return;
915
957
  }
916
958
  registerRpc(this.h3Router, path, procedure, {
917
- middleware: this.middlewares,
918
- onRequest: this.onRequest,
919
- onError: this.onError,
920
- onAfterResponse: this.onAfterResponse,
921
- onBeforeResponse: this.onBeforeResponse
959
+ middleware: this._middlewares,
960
+ onRequest: this._onRequest,
961
+ onError: this._onError,
962
+ onAfterResponse: this._onAfterResponse,
963
+ onBeforeResponse: this._onBeforeResponse,
964
+ debug: this._debug
922
965
  });
923
966
  }
924
967
  route(route) {
925
968
  registerRoute(this.h3Router, route, {
926
- middleware: this.middlewares,
927
- onRequest: this.onRequest,
928
- onError: this.onError,
929
- onAfterResponse: this.onAfterResponse,
930
- onBeforeResponse: this.onBeforeResponse
969
+ middleware: this._middlewares,
970
+ onRequest: this._onRequest,
971
+ onError: this._onError,
972
+ onAfterResponse: this._onAfterResponse,
973
+ onBeforeResponse: this._onBeforeResponse,
974
+ debug: this._debug
931
975
  });
932
976
  }
933
977
  registerModels(models) {
934
978
  for (const key of Object.keys(models)) {
935
- this.models[key] = models[key];
979
+ this._models[key] = models[key];
936
980
  }
937
981
  }
938
982
  getAppDefinition() {
@@ -940,10 +984,10 @@ class ArriApp {
940
984
  arriSchemaVersion: arriCodegenUtils.SCHEMA_VERSION,
941
985
  info: this.appInfo,
942
986
  procedures: {},
943
- models: this.models
987
+ models: this._models
944
988
  };
945
- for (const key of Object.keys(this.procedures)) {
946
- const rpc = this.procedures[key];
989
+ for (const key of Object.keys(this._procedures)) {
990
+ const rpc = this._procedures[key];
947
991
  appDef.procedures[key] = rpc;
948
992
  }
949
993
  return appDef;
@@ -1011,9 +1055,10 @@ function defineConfig(config) {
1011
1055
 
1012
1056
  exports.ArriApp = ArriApp;
1013
1057
  exports.ArriRouter = ArriRouter;
1058
+ exports.ArriServerError = ArriServerError;
1059
+ exports.ArriServerErrorResponse = ArriServerErrorResponse;
1014
1060
  exports.DEV_DEFINITION_ENDPOINT = DEV_DEFINITION_ENDPOINT;
1015
1061
  exports.DEV_ENDPOINT_ROOT = DEV_ENDPOINT_ROOT;
1016
- exports.ErrorResponse = ErrorResponse;
1017
1062
  exports.EventStreamConnection = EventStreamConnection;
1018
1063
  exports.createAppDefinition = createAppDefinition;
1019
1064
  exports.createHttpRpcDefinition = createHttpRpcDefinition;