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.
@@ -1,21 +1,38 @@
1
1
  import { isRpcHttpMethod, removeDisallowedChars, SCHEMA_VERSION } from 'arri-codegen-utils';
2
- import { createError, isError, setResponseStatus, send, eventHandler, isPreflightRequest, setResponseHeader, readRawBody, getValidatedQuery, defineEventHandler, getQuery, setHeader, createRouter, createApp, sendError } from 'h3';
2
+ import { isError, setResponseStatus, setResponseHeader, send, eventHandler, isPreflightRequest, readRawBody, getValidatedQuery, defineEventHandler, getQuery, setHeader, createRouter, createApp } from 'h3';
3
3
  import { a, isAObjectSchema, isADiscriminatorSchema } from 'arri-validate';
4
4
  import { createEventStream } from 'h3-sse';
5
5
  import { kebabCase, pascalCase } from 'scule';
6
6
 
7
- const ErrorResponse = a.object({
8
- statusCode: a.int8(),
9
- statusMessage: a.string(),
10
- stack: a.optional(a.string()),
7
+ var __defProp$3 = Object.defineProperty;
8
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __publicField$3 = (obj, key, value) => {
10
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
11
+ return value;
12
+ };
13
+ class ArriServerError extends Error {
14
+ constructor(err) {
15
+ super(err.message);
16
+ __publicField$3(this, "code");
17
+ __publicField$3(this, "data");
18
+ this.code = err.code;
19
+ this.data = err.data;
20
+ if (err.stack) {
21
+ this.stack = err.stack;
22
+ }
23
+ }
24
+ }
25
+ const ArriServerErrorResponse = a.object({
26
+ code: a.int16(),
27
+ message: a.string(),
28
+ stack: a.optional(a.array(a.string())),
11
29
  data: a.optional(a.any())
12
30
  });
13
31
  function defineError(statusCode, input = {}) {
14
32
  const defaultVals = errorResponseDefaults[statusCode];
15
- return createError({
16
- statusCode,
17
- statusMessage: input.statusMessage ?? defaultVals.message ?? "An unknown error occurred",
18
- stack: input.stack ?? "",
33
+ return new ArriServerError({
34
+ code: statusCode,
35
+ message: input.message ?? defaultVals?.message ?? "An unknown error occurred",
19
36
  data: input.data
20
37
  });
21
38
  }
@@ -23,7 +40,7 @@ function errorResponseFromValidationErrors(errors, prefixText = `Missing or inva
23
40
  const errorParts = [];
24
41
  for (const err of errors) {
25
42
  const propName = err.instancePath?.split("/") ?? [];
26
- if (propName.length) {
43
+ if (propName.length > 0) {
27
44
  propName.shift();
28
45
  }
29
46
  if (!errorParts.includes(propName.join("."))) {
@@ -31,7 +48,7 @@ function errorResponseFromValidationErrors(errors, prefixText = `Missing or inva
31
48
  }
32
49
  }
33
50
  throw defineError(400, {
34
- statusMessage: `${prefixText}: [${errorParts.join(",")}]`,
51
+ message: `${prefixText}: [${errorParts.join(",")}]`,
35
52
  data: errors
36
53
  });
37
54
  }
@@ -185,28 +202,55 @@ const errorResponseDefaults = {
185
202
  message: "Network Authentication Required"
186
203
  }
187
204
  };
188
- async function handleH3Error(err, event, onError) {
189
- const error = isError(err) ? err : defineError(500, {
190
- statusMessage: typeof err === "object" && err != null && "message" in err && typeof err.message === "string" ? err.message : void 0,
191
- data: err,
192
- stack: `${err}`
193
- });
194
- setResponseStatus(event, error.statusCode);
205
+ async function handleH3Error(err, event, onError, debug) {
206
+ let arriErr;
207
+ if (err instanceof ArriServerError) {
208
+ arriErr = err;
209
+ } else if (isError(err)) {
210
+ arriErr = new ArriServerError({
211
+ code: err.statusCode,
212
+ message: err.message,
213
+ stack: err.stack,
214
+ data: err.data
215
+ });
216
+ } else if (err instanceof Error) {
217
+ arriErr = new ArriServerError({
218
+ code: 500,
219
+ message: err.message,
220
+ data: err,
221
+ stack: err.stack
222
+ });
223
+ } else {
224
+ arriErr = new ArriServerError({
225
+ code: 500,
226
+ message: `An unknown error occurred`,
227
+ data: err
228
+ });
229
+ }
230
+ if (!arriErr) {
231
+ return;
232
+ }
233
+ setResponseStatus(event, arriErr.code);
195
234
  if (onError) {
196
- await onError(error, event);
235
+ await onError(arriErr, event);
197
236
  }
198
237
  if (event.handled) {
199
238
  return;
200
239
  }
201
- await send(
202
- event,
203
- JSON.stringify({
204
- statusCode: error.statusCode,
205
- statusMessage: error.statusMessage,
206
- data: error.data,
207
- stack: error.stack
208
- })
209
- );
240
+ return sendArriError(event, arriErr, debug);
241
+ }
242
+ async function sendArriError(event, error, debug) {
243
+ const payload = {
244
+ code: error.code,
245
+ message: error.message,
246
+ data: error.data
247
+ };
248
+ if (debug) {
249
+ payload.stack = error.stack?.split("\n").map((l) => l.trim());
250
+ }
251
+ setResponseHeader(event, "Content-Type", "application/json");
252
+ setResponseStatus(event, error.code);
253
+ return send(event, JSON.stringify(payload));
210
254
  }
211
255
 
212
256
  function isRpcParamSchema(input) {
@@ -319,7 +363,7 @@ function registerRpc(router, path, procedure, opts) {
319
363
  if (!responseValidator?.validate(response)) {
320
364
  const errors = a.errors(procedure.response, response);
321
365
  throw defineError(500, {
322
- statusMessage: "Failed to serialize response. Response does not match specified schema",
366
+ message: "Failed to serialize response. Response does not match specified schema",
323
367
  data: errors
324
368
  });
325
369
  }
@@ -342,7 +386,7 @@ function registerRpc(router, path, procedure, opts) {
342
386
  );
343
387
  }
344
388
  } catch (err) {
345
- await handleH3Error(err, event, opts.onError);
389
+ await handleH3Error(err, event, opts.onError, opts.debug ?? false);
346
390
  }
347
391
  return "";
348
392
  });
@@ -388,7 +432,7 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
388
432
  ", "
389
433
  )}]`;
390
434
  throw defineError(400, {
391
- statusMessage: message,
435
+ message,
392
436
  data: parsedParams.error
393
437
  });
394
438
  }
@@ -401,7 +445,7 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
401
445
  const body = await readRawBody(event);
402
446
  if (!body) {
403
447
  throw defineError(400, {
404
- statusMessage: `Invalid request body. Expected object. Got undefined.`
448
+ message: `Invalid request body. Expected object. Got undefined.`
405
449
  });
406
450
  }
407
451
  const parsedParams = a.safeParse(schema, body);
@@ -415,7 +459,7 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
415
459
  }
416
460
  }
417
461
  throw defineError(400, {
418
- statusMessage: `Invalid request body. Affected properties [${errorParts.join(
462
+ message: `Invalid request body. Affected properties [${errorParts.join(
419
463
  ", "
420
464
  )}]`,
421
465
  data: parsedParams.error
@@ -488,11 +532,10 @@ class EventStreamConnection {
488
532
  continue;
489
533
  }
490
534
  const errors2 = this.validationErrors(item);
491
- const errorResponse2 = {
492
- statusCode: 500,
493
- statusMessage: "Failed to serialize response. Response does not match specified schema.",
535
+ const errorResponse2 = defineError(500, {
536
+ message: "Failed to serialize response. Response does not match specified schema.",
494
537
  data: errors2
495
- };
538
+ });
496
539
  events.push({
497
540
  id: eventId,
498
541
  event: "error",
@@ -511,11 +554,10 @@ class EventStreamConnection {
511
554
  return;
512
555
  }
513
556
  const errors = this.validationErrors(data);
514
- const errorResponse = {
515
- statusCode: 500,
516
- statusMessage: "Failed to serialize response. Response does not match specified schema.",
557
+ const errorResponse = defineError(500, {
558
+ message: "Failed to serialize response. Response does not match specified schema.",
517
559
  data: errors
518
- };
560
+ });
519
561
  await this.eventStream.push({
520
562
  id: eventId,
521
563
  event: "error",
@@ -601,9 +643,12 @@ function registerEventStreamRpc(router, path, procedure, opts) {
601
643
  validator: responseValidator?.validate ?? function() {
602
644
  return true;
603
645
  },
604
- serializer: responseValidator?.serialize ?? function(_) {
605
- return "";
606
- },
646
+ serializer: (
647
+ // eslint-disable-next-line @typescript-eslint/unbound-method
648
+ responseValidator?.serialize ?? function(_) {
649
+ return "";
650
+ }
651
+ ),
607
652
  validationErrors(input) {
608
653
  if (procedure.response) {
609
654
  return a.errors(procedure.response, input);
@@ -620,7 +665,7 @@ function registerEventStreamRpc(router, path, procedure, opts) {
620
665
  stream.send();
621
666
  }
622
667
  } catch (err) {
623
- await handleH3Error(err, event, opts.onError);
668
+ await handleH3Error(err, event, opts.onError, opts.debug ?? false);
624
669
  }
625
670
  return "";
626
671
  });
@@ -687,7 +732,7 @@ function handleRoute(router, method, route, opts) {
687
732
  ", "
688
733
  )}]`;
689
734
  throw defineError(400, {
690
- statusMessage: message
735
+ message
691
736
  });
692
737
  }
693
738
  event.context.query = parsedQuery.value;
@@ -711,7 +756,7 @@ function handleRoute(router, method, route, opts) {
711
756
  }
712
757
  }
713
758
  throw defineError(400, {
714
- statusMessage: `Invalid request body. Affected properties [${errorParts.join(
759
+ message: `Invalid request body. Affected properties [${errorParts.join(
715
760
  ", "
716
761
  )}]`,
717
762
  data: parsedBody.error
@@ -739,7 +784,7 @@ function handleRoute(router, method, route, opts) {
739
784
  await route.postHandler(event);
740
785
  }
741
786
  } catch (err) {
742
- await handleH3Error(err, event, opts.onError);
787
+ await handleH3Error(err, event, opts.onError, opts.debug ?? false);
743
788
  }
744
789
  return "";
745
790
  });
@@ -813,29 +858,31 @@ class ArriApp {
813
858
  __publicField(this, "__isArri__", true);
814
859
  __publicField(this, "h3App");
815
860
  __publicField(this, "h3Router", createRouter());
816
- __publicField(this, "rpcDefinitionPath");
817
- __publicField(this, "rpcRoutePrefix");
861
+ __publicField(this, "_rpcDefinitionPath");
862
+ __publicField(this, "_rpcRoutePrefix");
818
863
  __publicField(this, "appInfo");
819
- __publicField(this, "procedures", {});
820
- __publicField(this, "models", {});
821
- __publicField(this, "middlewares", []);
822
- __publicField(this, "onRequest");
823
- __publicField(this, "onAfterResponse");
824
- __publicField(this, "onBeforeResponse");
825
- __publicField(this, "onError");
864
+ __publicField(this, "_procedures", {});
865
+ __publicField(this, "_models", {});
866
+ __publicField(this, "_middlewares", []);
867
+ __publicField(this, "_onRequest");
868
+ __publicField(this, "_onAfterResponse");
869
+ __publicField(this, "_onBeforeResponse");
870
+ __publicField(this, "_onError");
871
+ __publicField(this, "_debug");
826
872
  this.appInfo = opts?.appInfo;
827
873
  this.h3App = createApp({
828
874
  debug: opts?.debug
829
875
  });
830
- this.onRequest = opts.onRequest;
831
- this.onError = opts.onError;
832
- this.onAfterResponse = opts.onAfterResponse;
833
- this.onBeforeResponse = opts.onBeforeResponse;
834
- this.rpcRoutePrefix = opts?.rpcRoutePrefix ?? "";
835
- this.rpcDefinitionPath = opts?.rpcDefinitionPath ?? "__definition";
876
+ this._debug = opts.debug ?? false;
877
+ this._onRequest = opts.onRequest;
878
+ this._onError = opts.onError;
879
+ this._onAfterResponse = opts.onAfterResponse;
880
+ this._onBeforeResponse = opts.onBeforeResponse;
881
+ this._rpcRoutePrefix = opts?.rpcRoutePrefix ?? "";
882
+ this._rpcDefinitionPath = opts?.rpcDefinitionPath ?? "__definition";
836
883
  this.h3App.use(this.h3Router);
837
884
  this.h3Router.get(
838
- this.rpcRoutePrefix ? `/${this.rpcRoutePrefix}/${this.rpcDefinitionPath}`.split("//").join("/") : `/${this.rpcDefinitionPath}`,
885
+ this._rpcRoutePrefix ? `/${this._rpcRoutePrefix}/${this._rpcDefinitionPath}`.split("//").join("/") : `/${this._rpcDefinitionPath}`,
839
886
  eventHandler(() => this.getAppDefinition())
840
887
  );
841
888
  if (process.env.ARRI_DEV_MODE === "true") {
@@ -850,22 +897,16 @@ class ArriApp {
850
897
  setResponseStatus(event, 404);
851
898
  const error = defineError(404);
852
899
  try {
853
- if (this.onRequest) {
854
- await this.onRequest(event);
900
+ if (this._onRequest) {
901
+ await this._onRequest(event);
855
902
  }
856
903
  } catch (err) {
857
- await handleH3Error(err, event, this.onError);
858
- }
859
- if (event.handled) {
860
- return;
861
- }
862
- if (this.onError) {
863
- await this.onError(error, event);
904
+ await handleH3Error(err, event, this._onError, this._debug);
864
905
  }
865
906
  if (event.handled) {
866
907
  return;
867
908
  }
868
- sendError(event, error);
909
+ return handleH3Error(error, event, this._onError, this._debug);
869
910
  })
870
911
  );
871
912
  }
@@ -880,11 +921,11 @@ class ArriApp {
880
921
  this.registerModels(input.getModels());
881
922
  return;
882
923
  }
883
- this.middlewares.push(input);
924
+ this._middlewares.push(input);
884
925
  }
885
926
  rpc(procedure) {
886
- const path = procedure.path ?? getRpcPath(procedure.name, this.rpcRoutePrefix);
887
- this.procedures[procedure.name] = createHttpRpcDefinition(
927
+ const path = procedure.path ?? getRpcPath(procedure.name, this._rpcRoutePrefix);
928
+ this._procedures[procedure.name] = createHttpRpcDefinition(
888
929
  procedure.name,
889
930
  path,
890
931
  procedure
@@ -892,45 +933,48 @@ class ArriApp {
892
933
  if (isRpcParamSchema(procedure.params)) {
893
934
  const paramName = getRpcParamName(procedure.name, procedure);
894
935
  if (paramName) {
895
- this.models[paramName] = procedure.params;
936
+ this._models[paramName] = procedure.params;
896
937
  }
897
938
  }
898
939
  if (isRpcParamSchema(procedure.response)) {
899
940
  const responseName = getRpcResponseName(procedure.name, procedure);
900
941
  if (responseName) {
901
- this.models[responseName] = procedure.response;
942
+ this._models[responseName] = procedure.response;
902
943
  }
903
944
  }
904
945
  if (isEventStreamRpc(procedure)) {
905
946
  registerEventStreamRpc(this.h3Router, path, procedure, {
906
- middleware: this.middlewares,
907
- onRequest: this.onRequest,
908
- onError: this.onError,
909
- onAfterResponse: this.onAfterResponse,
910
- onBeforeResponse: this.onBeforeResponse
947
+ middleware: this._middlewares,
948
+ onRequest: this._onRequest,
949
+ onError: this._onError,
950
+ onAfterResponse: this._onAfterResponse,
951
+ onBeforeResponse: this._onBeforeResponse,
952
+ debug: this._debug
911
953
  });
912
954
  return;
913
955
  }
914
956
  registerRpc(this.h3Router, path, procedure, {
915
- middleware: this.middlewares,
916
- onRequest: this.onRequest,
917
- onError: this.onError,
918
- onAfterResponse: this.onAfterResponse,
919
- onBeforeResponse: this.onBeforeResponse
957
+ middleware: this._middlewares,
958
+ onRequest: this._onRequest,
959
+ onError: this._onError,
960
+ onAfterResponse: this._onAfterResponse,
961
+ onBeforeResponse: this._onBeforeResponse,
962
+ debug: this._debug
920
963
  });
921
964
  }
922
965
  route(route) {
923
966
  registerRoute(this.h3Router, route, {
924
- middleware: this.middlewares,
925
- onRequest: this.onRequest,
926
- onError: this.onError,
927
- onAfterResponse: this.onAfterResponse,
928
- onBeforeResponse: this.onBeforeResponse
967
+ middleware: this._middlewares,
968
+ onRequest: this._onRequest,
969
+ onError: this._onError,
970
+ onAfterResponse: this._onAfterResponse,
971
+ onBeforeResponse: this._onBeforeResponse,
972
+ debug: this._debug
929
973
  });
930
974
  }
931
975
  registerModels(models) {
932
976
  for (const key of Object.keys(models)) {
933
- this.models[key] = models[key];
977
+ this._models[key] = models[key];
934
978
  }
935
979
  }
936
980
  getAppDefinition() {
@@ -938,10 +982,10 @@ class ArriApp {
938
982
  arriSchemaVersion: SCHEMA_VERSION,
939
983
  info: this.appInfo,
940
984
  procedures: {},
941
- models: this.models
985
+ models: this._models
942
986
  };
943
- for (const key of Object.keys(this.procedures)) {
944
- const rpc = this.procedures[key];
987
+ for (const key of Object.keys(this._procedures)) {
988
+ const rpc = this._procedures[key];
945
989
  appDef.procedures[key] = rpc;
946
990
  }
947
991
  return appDef;
@@ -1007,4 +1051,4 @@ function defineConfig(config) {
1007
1051
  };
1008
1052
  }
1009
1053
 
1010
- export { ArriApp as A, DEV_ENDPOINT_ROOT as D, ErrorResponse as E, DEV_DEFINITION_ENDPOINT as a, isRpc as b, createAppDefinition as c, defineRpc as d, createHttpRpcDefinition as e, getRpcParamName as f, getRpcPath as g, getRpcResponseName as h, isRpcParamSchema as i, defineError as j, errorResponseFromValidationErrors as k, handleH3Error as l, isArriConfig as m, isResolvedArriConfig as n, defaultConfig as o, defineConfig as p, ArriRouter as q, registerRpc as r, defineRoute as s, registerRoute as t, handleRoute as u, validateRpcRequestInput as v, defineEventStreamRpc as w, isEventStreamRpc as x, EventStreamConnection as y, registerEventStreamRpc as z };
1054
+ export { ArriApp as A, registerEventStreamRpc as B, DEV_ENDPOINT_ROOT as D, EventStreamConnection as E, DEV_DEFINITION_ENDPOINT as a, isRpc as b, createAppDefinition as c, defineRpc as d, createHttpRpcDefinition as e, getRpcParamName as f, getRpcPath as g, getRpcResponseName as h, isRpcParamSchema as i, ArriServerError as j, ArriServerErrorResponse as k, defineError as l, errorResponseFromValidationErrors as m, handleH3Error as n, isArriConfig as o, isResolvedArriConfig as p, defaultConfig as q, registerRpc as r, defineConfig as s, ArriRouter as t, defineRoute as u, validateRpcRequestInput as v, registerRoute as w, handleRoute as x, defineEventStreamRpc as y, isEventStreamRpc as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arri",
3
- "version": "0.34.0",
3
+ "version": "0.36.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -43,10 +43,10 @@
43
43
  "prettier": "^3.2.5",
44
44
  "scule": "^1.3.0",
45
45
  "uncrypto": "^0.1.3",
46
- "arri-codegen-dart": "0.34.0",
47
- "arri-codegen-ts": "0.34.0",
48
- "arri-validate": "0.34.0",
49
- "arri-codegen-utils": "0.34.0"
46
+ "arri-codegen-dart": "0.36.0",
47
+ "arri-codegen-ts": "0.36.0",
48
+ "arri-codegen-utils": "0.36.0",
49
+ "arri-validate": "0.36.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/degit": "^2.8.6",