@arrirpc/server 0.55.0 → 0.57.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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,43 @@
1
1
  import { HttpMethod, WsRpcDefinition, RpcHttpMethod, HttpRpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition } from '@arrirpc/codegen-utils';
2
2
  import { AObjectSchema, a, ValidationError, ASchema, InferType, ValueError, CompiledValidator, ADiscriminatorSchema } from '@arrirpc/schema';
3
- import { StatusCode, H3Error, H3Event, H3EventContext, Router, EventStream, App } from 'h3';
3
+ import { H3Event, StatusCode, H3Error, Router, EventStream, App } from 'h3';
4
4
  export * from 'h3';
5
5
  import { Peer, WSError } from 'crossws';
6
6
 
7
+ interface MiddlewareEvent extends H3Event {
8
+ context: MiddlewareEventContext;
9
+ }
10
+ type Middleware = (event: MiddlewareEvent) => void | Promise<void>;
11
+ declare const defineMiddleware: (middleware: Middleware) => Middleware;
12
+ type ExtractParam<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
13
+ type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam<Segment, ExtractParams<Rest>> : ExtractParam<Path, {}>;
14
+
15
+ interface ArriEventContext extends Record<string, unknown> {
16
+ }
17
+ type RpcEventContext<TParams = undefined> = ArriEventContext & {
18
+ rpcName: string;
19
+ params: TParams;
20
+ };
21
+ type RpcPostEventContext<TParams = undefined, TResponse = undefined> = RpcEventContext<TParams> & {
22
+ response: TResponse;
23
+ };
24
+ type RouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> = ArriEventContext & {
25
+ params: ExtractParams<TPath>;
26
+ query: TQuery;
27
+ body: TBody;
28
+ };
29
+ type RoutePostEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> = RouteEventContext<TPath, TQuery, TBody> & {
30
+ response: TResponse;
31
+ };
32
+ type MiddlewareEventContext = ArriEventContext & {
33
+ rpcName?: string;
34
+ };
35
+ type RequestHookContext = ArriEventContext & {
36
+ rpcName?: string;
37
+ params?: Record<string, unknown>;
38
+ response?: unknown;
39
+ };
40
+
7
41
  declare class ArriServerError extends Error {
8
42
  code: number;
9
43
  data?: any;
@@ -25,34 +59,6 @@ declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ArriSe
25
59
  declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
26
60
  declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"], debug: boolean): Promise<void>;
27
61
 
28
- type ArriEventContext = Record<string, any>;
29
- interface RpcEventContext<TParams = undefined> extends ArriEventContext, Omit<H3EventContext, "params"> {
30
- rpcName: string;
31
- params: TParams;
32
- }
33
- interface RpcPostEventContext<TParams = undefined, TResponse = undefined> extends RpcEventContext<TParams> {
34
- response: TResponse;
35
- }
36
- interface RouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends ArriEventContext, H3EventContext {
37
- params: ExtractParams<TPath>;
38
- query: TQuery;
39
- body: TBody;
40
- }
41
- interface RoutePostEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends RouteEventContext<TPath, TQuery, TBody> {
42
- response: TResponse;
43
- }
44
- interface MiddlewareEventContext extends ArriEventContext, H3EventContext {
45
- rpcName?: string;
46
- }
47
-
48
- interface MiddlewareEvent extends H3Event {
49
- context: MiddlewareEventContext;
50
- }
51
- type Middleware = (event: MiddlewareEvent) => void | Promise<void>;
52
- declare const defineMiddleware: (middleware: Middleware) => Middleware;
53
- type ExtractParam<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
54
- type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam<Segment, ExtractParams<Rest>> : ExtractParam<Path, {}>;
55
-
56
62
  interface RouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3Event {
57
63
  context: RouteEventContext<TPath, TQuery, TBody>;
58
64
  }
@@ -74,9 +80,20 @@ type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "
74
80
  declare function registerRoute(router: Router, route: ArriRoute<any>, opts: RouteOptions): void;
75
81
  declare function handleRoute(router: Router, method: HttpMethod, route: ArriRoute<any>, opts: RouteOptions): void;
76
82
 
83
+ declare class ArriRouter {
84
+ private readonly routes;
85
+ private readonly definitions;
86
+ prefix: string;
87
+ constructor(routePrefix?: string);
88
+ route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
89
+ registerDefinitions(models: DefinitionMap): void;
90
+ getRoutes(): ArriRoute<any, any, any, any>[];
91
+ getDefinitions(): DefinitionMap;
92
+ }
93
+
77
94
  declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream" | "transport">): EventStreamRpc<TParams, TResponse>;
78
95
  declare function isEventStreamRpc(input: unknown): input is EventStreamRpc<any, any>;
79
- interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<Rpc<true, TParams, TResponse>, "handler" | "postHandler"> {
96
+ interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<HttpRpc<true, TParams, TResponse>, "handler" | "postHandler"> {
80
97
  isEventStream: true;
81
98
  handler: EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
82
99
  }
@@ -185,10 +202,11 @@ declare function createWsRpcDefinition(rpcName: string, path: string, rpc: Named
185
202
 
186
203
  type RpcParamSchema<TObjectInner = any, TDiscriminatorInner = any> = AObjectSchema<TObjectInner> | ADiscriminatorSchema<TDiscriminatorInner>;
187
204
  declare function isRpcParamSchema(input: unknown): input is RpcParamSchema;
188
- interface NamedRpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Rpc<TIsEventStream, TParams, TResponse> {
205
+ interface NamedHttpRpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends HttpRpc<TIsEventStream, TParams, TResponse> {
189
206
  name: string;
190
207
  }
191
- interface Rpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> {
208
+ type Rpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> = HttpRpc<TIsEventStream, TParams, TResponse> | WebsocketRpc<TParams, TResponse>;
209
+ interface HttpRpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> {
192
210
  transport: "http";
193
211
  method?: RpcHttpMethod;
194
212
  path?: string;
@@ -201,7 +219,6 @@ interface Rpc<TIsEventStream extends boolean = false, TParams extends RpcParamSc
201
219
  handler: TIsEventStream extends true ? EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined> : RpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : void>;
202
220
  postHandler?: TIsEventStream extends true ? undefined : RpcPostHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
203
221
  }
204
- type HttpRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined> = Omit<Rpc<false, TParams, TResponse>, "isEventStream">;
205
222
  interface RpcEvent<TParams = undefined> extends Omit<H3Event, "context"> {
206
223
  context: RpcEventContext<TParams>;
207
224
  }
@@ -210,37 +227,31 @@ interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<
210
227
  }
211
228
  type RpcHandler<TParams, TResponse> = (context: RpcEventContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
212
229
  type RpcPostHandler<TParams, TResponse> = (context: RpcPostEventContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
213
- declare function isRpc(input: unknown): input is Rpc<any, any>;
214
- declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<HttpRpc<TParams, TResponse>, "transport">): Rpc<false, TParams, TResponse>;
215
- declare function createHttpRpcDefinition(rpcName: string, httpPath: string, procedure: Rpc<any, any, any>): HttpRpcDefinition;
230
+ declare function isRpc(input: unknown): input is HttpRpc<any, any>;
231
+ declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<HttpRpc<false, TParams, TResponse>, "transport" | "isEventStream">): HttpRpc<false, TParams, TResponse>;
232
+ declare function createHttpRpcDefinition(rpcName: string, httpPath: string, procedure: HttpRpc<any, any, any>): HttpRpcDefinition;
216
233
  declare function getRpcPath(rpcName: string, prefix?: string): string;
217
- declare function getRpcParamName(rpcName: string, procedure: Rpc<any, any, any> | WebsocketRpc<any, any>): string | undefined;
218
- declare function getRpcResponseName(rpcName: string, procedure: Rpc<any, any, any> | WebsocketRpc<any, any>): string | undefined;
219
- declare function registerRpc(router: Router, path: string, procedure: NamedRpc<any, any, any>, opts: RouteOptions): void;
220
- declare function validateRpcRequestInput(event: H3Event, httpMethod: RpcHttpMethod, schema: ASchema): Promise<void>;
234
+ declare function getRpcParamName(rpcName: string, procedure: HttpRpc<any, any, any> | WebsocketRpc<any, any>): string | undefined;
235
+ declare function getRpcResponseName(rpcName: string, procedure: HttpRpc<any, any, any> | WebsocketRpc<any, any>): string | undefined;
236
+ declare function registerRpc(router: Router, path: string, procedure: NamedHttpRpc<any, any, any>, opts: RouteOptions): void;
237
+ declare function validateRpcRequestInput(event: H3Event, httpMethod: RpcHttpMethod, schema: ASchema, validator: ReturnType<typeof a.compile>): Promise<void>;
238
+ declare function getSchemaValidator(rpcName: string, type: "params" | "response", schema: ASchema<any>): ReturnType<typeof a.compile> | undefined;
221
239
 
222
- interface ArriRouterBase {
223
- rpc: <TIsEventStream extends boolean, TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: Omit<NamedRpc<TIsEventStream, TParams, TResponse>, "transport">) => void;
224
- wsRpc: <TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined>(procedure: Omit<NamedWebsocketRpc<TParams, TResponse>, "transport">) => void;
225
- route: <TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>) => void;
226
- registerDefinitions: (definitions: DefinitionMap) => void;
227
- }
228
- declare class ArriRouter implements ArriRouterBase {
240
+ declare class ArriService {
241
+ name: string;
242
+ constructor(name: string);
229
243
  private readonly procedures;
230
- private readonly routes;
231
244
  private readonly definitions;
232
- rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: Omit<NamedRpc<TIsEventStream, TParams, TResponse>, "transport">): void;
233
- wsRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined>(procedure: Omit<NamedWebsocketRpc<TParams, TResponse>, "transport">): void;
234
- route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
245
+ rpc(name: string, procedure: Rpc<any, any, any>): void;
235
246
  registerDefinitions(models: DefinitionMap): void;
236
- getProcedures(): (NamedWebsocketRpc<any, any> | NamedRpc<any, any, any>)[];
237
- getRoutes(): ArriRoute<any, any, any, any>[];
247
+ getProcedures(): (NamedWebsocketRpc<any, any> | NamedHttpRpc<any, any, any>)[];
238
248
  getDefinitions(): DefinitionMap;
239
249
  }
250
+ declare function defineService(name: string, procedures?: Record<string, HttpRpc<any, any, any> | WebsocketRpc<any, any>>): ArriService;
240
251
 
241
252
  type DefinitionMap = Record<string, SchemaFormProperties | SchemaFormDiscriminator | SchemaFormValues>;
242
253
  declare const createAppDefinition: (def: AppDefinition) => AppDefinition;
243
- declare class ArriApp implements ArriRouterBase {
254
+ declare class ArriApp {
244
255
  __isArri__: boolean;
245
256
  readonly h3App: App;
246
257
  readonly h3Router: Router;
@@ -257,9 +268,8 @@ declare class ArriApp implements ArriRouterBase {
257
268
  private readonly _debug;
258
269
  readonly definitionPath: string;
259
270
  constructor(opts?: ArriOptions);
260
- use(input: Middleware | ArriRouter): void;
261
- rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: Omit<NamedRpc<TIsEventStream, TParams, TResponse>, "transport">): void;
262
- wsRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined>(procedure: Omit<NamedWebsocketRpc<TParams, TResponse>, "transport">): void;
271
+ use(input: Middleware | ArriRouter | ArriService): void;
272
+ rpc(name: string, procedure: Rpc<any, any, any>): void;
263
273
  route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
264
274
  registerDefinitions(definitions: DefinitionMap): void;
265
275
  getAppDefinition(): AppDefinition;
@@ -279,9 +289,12 @@ interface ArriOptions {
279
289
  disableDefaultRoute?: boolean;
280
290
  disableDefinitionRoute?: boolean;
281
291
  onRequest?: (event: MiddlewareEvent) => void | Promise<void>;
282
- onAfterResponse?: (event: MiddlewareEvent) => void | Promise<void>;
283
- onBeforeResponse?: (event: MiddlewareEvent) => void | Promise<void>;
284
- onError?: (error: ArriServerError, event: MiddlewareEvent) => void | Promise<void>;
292
+ onAfterResponse?: (event: RequestHookEvent) => void | Promise<void>;
293
+ onBeforeResponse?: (event: RequestHookEvent) => void | Promise<void>;
294
+ onError?: (error: ArriServerError, event: RequestHookContext) => void | Promise<void>;
295
+ }
296
+ interface RequestHookEvent extends Omit<H3Event, "context"> {
297
+ context: RequestHookContext;
285
298
  }
286
299
 
287
- export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, ArriServerError, ArriServerErrorResponse, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedRpc, type NamedWebsocketRpc, type PostRouteEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type SsePushResult, type WebSocketRpcHandler, type WebsocketRpc, WsPeer, type WsPeerContext, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isEventStreamRpc, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
300
+ export { ArriApp, type ArriEventContext, type ArriOptions, type ArriRoute, ArriRouter, ArriServerError, ArriServerErrorResponse, ArriService, type DefinitionMap, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type NamedHttpRpc, type NamedWebsocketRpc, type PostRouteEvent, type RequestHookContext, type RequestHookEvent, type RouteEvent, type RouteEventContext, type RouteOptions, type RoutePostEventContext, type Rpc, type RpcEvent, type RpcEventContext, type RpcHandler, type RpcParamSchema, type RpcPostEvent, type RpcPostEventContext, type RpcPostHandler, type SsePushResult, type WebSocketRpcHandler, type WebsocketRpc, WsPeer, type WsPeerContext, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineService, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, getSchemaValidator, handleH3Error, handleRoute, isEventStreamRpc, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
package/dist/index.mjs CHANGED
@@ -2,20 +2,20 @@ import { isRpcHttpMethod, removeDisallowedChars, SCHEMA_VERSION } from '@arrirpc
2
2
  import { DEV_DEFINITION_ENDPOINT } from 'arri';
3
3
  import { isError, setResponseStatus, setResponseHeader, send, eventHandler, isPreflightRequest, readRawBody, getValidatedQuery, createEventStream, getHeader, defineEventHandler, getQuery, setHeader, defineWebSocketHandler, createRouter, createApp } from 'h3';
4
4
  export * from 'h3';
5
- import { a, isAObjectSchema, isADiscriminatorSchema } from '@arrirpc/schema';
5
+ import { a, isAObjectSchema, isADiscriminatorSchema, isAdaptedSchema, validatorFromAdaptedSchema } from '@arrirpc/schema';
6
6
  import { kebabCase, pascalCase } from 'scule';
7
7
 
8
- var __defProp$4 = Object.defineProperty;
9
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
- var __publicField$4 = (obj, key, value) => {
11
- __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
8
+ var __defProp$5 = Object.defineProperty;
9
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __publicField$5 = (obj, key, value) => {
11
+ __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
12
12
  return value;
13
13
  };
14
14
  class ArriServerError extends Error {
15
15
  constructor(err) {
16
16
  super(err.message);
17
- __publicField$4(this, "code");
18
- __publicField$4(this, "data");
17
+ __publicField$5(this, "code");
18
+ __publicField$5(this, "data");
19
19
  this.code = err.code;
20
20
  this.data = err.data;
21
21
  if (err.stack) {
@@ -323,12 +323,8 @@ function getRpcResponseDefinition(rpcName, procedure) {
323
323
  return name;
324
324
  }
325
325
  function registerRpc(router, path, procedure, opts) {
326
- let responseValidator;
327
- try {
328
- responseValidator = procedure.response ? a.compile(procedure.response) : void 0;
329
- } catch (err) {
330
- console.error("ERROR COMPILING VALIDATOR", err);
331
- }
326
+ const paramValidator = procedure.params ? getSchemaValidator(procedure.name, "params", procedure.params) : void 0;
327
+ const responseValidator = procedure.response ? getSchemaValidator(procedure.name, "response", procedure.response) : void 0;
332
328
  const httpMethod = procedure.method ?? "post";
333
329
  const handler = eventHandler(async (event) => {
334
330
  event.context.rpcName = procedure.name;
@@ -348,7 +344,8 @@ function registerRpc(router, path, procedure, opts) {
348
344
  await validateRpcRequestInput(
349
345
  event,
350
346
  httpMethod,
351
- procedure.params
347
+ procedure.params,
348
+ paramValidator
352
349
  );
353
350
  }
354
351
  const response = await procedure.handler(
@@ -411,7 +408,7 @@ function registerRpc(router, path, procedure, opts) {
411
408
  break;
412
409
  }
413
410
  }
414
- async function validateRpcRequestInput(event, httpMethod, schema) {
411
+ async function validateRpcRequestInput(event, httpMethod, schema, validator) {
415
412
  switch (httpMethod) {
416
413
  case "get": {
417
414
  const parsedParams = await getValidatedQuery(
@@ -450,8 +447,8 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
450
447
  message: `Invalid request body. Expected object. Got undefined.`
451
448
  });
452
449
  }
453
- const parsedParams = a.safeParse(schema, body);
454
- if (!parsedParams.success) {
450
+ const parsedParams = validator.safeParse(body);
451
+ if (!parsedParams?.success) {
455
452
  const errorParts = [];
456
453
  for (const err of parsedParams.error.errors) {
457
454
  const errPath = err.instancePath.split("/");
@@ -472,11 +469,22 @@ async function validateRpcRequestInput(event, httpMethod, schema) {
472
469
  }
473
470
  }
474
471
  }
472
+ function getSchemaValidator(rpcName, type, schema) {
473
+ try {
474
+ if (isAdaptedSchema(schema)) {
475
+ return validatorFromAdaptedSchema(schema);
476
+ }
477
+ return a.compile(schema);
478
+ } catch (err) {
479
+ console.error(`Error compiling ${type} validator for ${rpcName}`);
480
+ return void 0;
481
+ }
482
+ }
475
483
 
476
- var __defProp$3 = Object.defineProperty;
477
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
478
- var __publicField$3 = (obj, key, value) => {
479
- __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
484
+ var __defProp$4 = Object.defineProperty;
485
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
486
+ var __publicField$4 = (obj, key, value) => {
487
+ __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
480
488
  return value;
481
489
  };
482
490
  function defineEventStreamRpc(config) {
@@ -492,14 +500,14 @@ function isEventStreamRpc(input) {
492
500
  }
493
501
  class EventStreamConnection {
494
502
  constructor(event, opts) {
495
- __publicField$3(this, "lastEventId");
496
- __publicField$3(this, "validationErrors");
497
- __publicField$3(this, "validator");
498
- __publicField$3(this, "serializer");
503
+ __publicField$4(this, "lastEventId");
504
+ __publicField$4(this, "validationErrors");
505
+ __publicField$4(this, "validator");
506
+ __publicField$4(this, "serializer");
499
507
  // for some reason Rollup cannot output DTS when this is set to NodeJS.Timeout
500
- __publicField$3(this, "pingInterval");
501
- __publicField$3(this, "pingIntervalMs");
502
- __publicField$3(this, "eventStream");
508
+ __publicField$4(this, "pingInterval");
509
+ __publicField$4(this, "pingIntervalMs");
510
+ __publicField$4(this, "eventStream");
503
511
  this.eventStream = createEventStream(event);
504
512
  this.lastEventId = getHeader(event, "Last-Event-Id");
505
513
  this.pingIntervalMs = opts.pingInterval ?? 6e4;
@@ -579,12 +587,8 @@ class EventStreamConnection {
579
587
  }
580
588
  }
581
589
  function registerEventStreamRpc(router, path, procedure, opts) {
582
- let responseValidator;
583
- try {
584
- responseValidator = procedure.response ? a.compile(procedure.response) : void 0;
585
- } catch (err) {
586
- console.error("ERROR COMPILING VALIDATOR", err);
587
- }
590
+ const paramValidator = procedure.params ? getSchemaValidator(procedure.name, "params", procedure.params) : void 0;
591
+ const responseValidator = procedure.response ? getSchemaValidator(procedure.name, "response", procedure.response) : void 0;
588
592
  const httpMethod = procedure.method ?? "get";
589
593
  const handler = eventHandler(async (event) => {
590
594
  event.context.rpcName = procedure.name;
@@ -604,7 +608,8 @@ function registerEventStreamRpc(router, path, procedure, opts) {
604
608
  await validateRpcRequestInput(
605
609
  event,
606
610
  httpMethod,
607
- procedure.params
611
+ procedure.params,
612
+ paramValidator
608
613
  );
609
614
  }
610
615
  const stream = new EventStreamConnection(event, {
@@ -779,29 +784,53 @@ function handleRoute(router, method, route, opts) {
779
784
  }
780
785
  }
781
786
 
787
+ var __defProp$3 = Object.defineProperty;
788
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
789
+ var __publicField$3 = (obj, key, value) => {
790
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
791
+ return value;
792
+ };
793
+ class ArriRouter {
794
+ constructor(routePrefix = "") {
795
+ __publicField$3(this, "routes", []);
796
+ __publicField$3(this, "definitions", {});
797
+ __publicField$3(this, "prefix");
798
+ this.prefix = routePrefix;
799
+ }
800
+ route(route) {
801
+ route.path = `${this.prefix}${route.path}`;
802
+ this.routes.push(route);
803
+ }
804
+ registerDefinitions(models) {
805
+ for (const key of Object.keys(models)) {
806
+ this.definitions[key] = models[key];
807
+ }
808
+ }
809
+ getRoutes() {
810
+ return this.routes;
811
+ }
812
+ getDefinitions() {
813
+ return this.definitions;
814
+ }
815
+ }
816
+
782
817
  var __defProp$2 = Object.defineProperty;
783
818
  var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
784
819
  var __publicField$2 = (obj, key, value) => {
785
820
  __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
786
821
  return value;
787
822
  };
788
- class ArriRouter {
789
- constructor() {
823
+ class ArriService {
824
+ constructor(name) {
825
+ __publicField$2(this, "name");
790
826
  __publicField$2(this, "procedures", []);
791
- __publicField$2(this, "routes", []);
792
827
  __publicField$2(this, "definitions", {});
828
+ this.name = name;
793
829
  }
794
- rpc(procedure) {
795
- procedure.transport = "http";
796
- this.procedures.push(procedure);
797
- }
798
- wsRpc(procedure) {
799
- procedure.transport = "ws";
830
+ rpc(name, procedure) {
831
+ procedure.name = `${this.name}.${name}`;
800
832
  this.procedures.push(procedure);
801
833
  }
802
- route(route) {
803
- this.routes.push(route);
804
- }
805
834
  registerDefinitions(models) {
806
835
  for (const key of Object.keys(models)) {
807
836
  this.definitions[key] = models[key];
@@ -810,13 +839,17 @@ class ArriRouter {
810
839
  getProcedures() {
811
840
  return this.procedures;
812
841
  }
813
- getRoutes() {
814
- return this.routes;
815
- }
816
842
  getDefinitions() {
817
843
  return this.definitions;
818
844
  }
819
845
  }
846
+ function defineService(name, procedures) {
847
+ const service = new ArriService(name);
848
+ for (const key of Object.keys(procedures ?? {})) {
849
+ service.rpc(key, procedures[key]);
850
+ }
851
+ return service;
852
+ }
820
853
 
821
854
  var __defProp$1 = Object.defineProperty;
822
855
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -998,14 +1031,21 @@ class ArriApp {
998
1031
  if (!opts.disableDefinitionRoute) {
999
1032
  this.h3Router.get(
1000
1033
  this.definitionPath,
1001
- eventHandler(() => this.getAppDefinition())
1034
+ eventHandler((event) => {
1035
+ setResponseHeader(
1036
+ event,
1037
+ "Content-Type",
1038
+ "application/json"
1039
+ );
1040
+ return this.getAppDefinition();
1041
+ })
1002
1042
  );
1003
1043
  }
1004
1044
  if (!opts.disableDefaultRoute) {
1005
1045
  this.route({
1006
1046
  method: ["get", "head"],
1007
1047
  path: "/",
1008
- handler: (_) => {
1048
+ handler: async (_) => {
1009
1049
  const response = {
1010
1050
  title: this.appInfo?.title ?? "Arri-RPC Server",
1011
1051
  description: this.appInfo?.description ?? "This server utilizes Arri-RPC. Visit the schema path to see all of the available procedures.",
@@ -1028,7 +1068,14 @@ class ArriApp {
1028
1068
  if (process.env.ARRI_DEV_MODE === "true") {
1029
1069
  this.h3Router.get(
1030
1070
  DEV_DEFINITION_ENDPOINT,
1031
- eventHandler(() => this.getAppDefinition())
1071
+ eventHandler((event) => {
1072
+ setResponseHeader(
1073
+ event,
1074
+ "Content-Type",
1075
+ "application/json"
1076
+ );
1077
+ return this.getAppDefinition();
1078
+ })
1032
1079
  );
1033
1080
  }
1034
1081
  this.h3Router.use(
@@ -1055,23 +1102,27 @@ class ArriApp {
1055
1102
  for (const route of input.getRoutes()) {
1056
1103
  this.route(route);
1057
1104
  }
1105
+ this.registerDefinitions(input.getDefinitions());
1106
+ return;
1107
+ }
1108
+ if (typeof input === "object" && input instanceof ArriService) {
1058
1109
  for (const rpc of input.getProcedures()) {
1059
- if (rpc.transport === "http") {
1060
- this.rpc(rpc);
1061
- } else {
1062
- this.wsRpc(rpc);
1063
- }
1110
+ this.rpc(rpc.name, rpc);
1064
1111
  }
1065
1112
  this.registerDefinitions(input.getDefinitions());
1066
1113
  return;
1067
1114
  }
1068
1115
  this._middlewares.push(input);
1069
1116
  }
1070
- rpc(procedure) {
1071
- procedure.transport = "http";
1117
+ rpc(name, procedure) {
1118
+ procedure.name = name;
1072
1119
  const p = procedure;
1073
1120
  const path = p.path ?? getRpcPath(p.name, this._rpcRoutePrefix);
1074
- this._procedures[p.name] = createHttpRpcDefinition(p.name, path, p);
1121
+ if (p.transport === "http") {
1122
+ this._procedures[p.name] = createHttpRpcDefinition(p.name, path, p);
1123
+ } else if (p.transport === "ws") {
1124
+ this._procedures[p.name] = createWsRpcDefinition(p.name, path, p);
1125
+ }
1075
1126
  if (isRpcParamSchema(p.params)) {
1076
1127
  const paramName = getRpcParamName(p.name, p);
1077
1128
  if (paramName) {
@@ -1084,8 +1135,19 @@ class ArriApp {
1084
1135
  this._definitions[responseName] = p.response;
1085
1136
  }
1086
1137
  }
1087
- if (isEventStreamRpc(p)) {
1088
- registerEventStreamRpc(this.h3Router, path, p, {
1138
+ if (p.transport === "http") {
1139
+ if (isEventStreamRpc(p)) {
1140
+ registerEventStreamRpc(this.h3Router, path, p, {
1141
+ middleware: this._middlewares,
1142
+ onRequest: this._onRequest,
1143
+ onError: this._onError,
1144
+ onAfterResponse: this._onAfterResponse,
1145
+ onBeforeResponse: this._onBeforeResponse,
1146
+ debug: this._debug
1147
+ });
1148
+ return;
1149
+ }
1150
+ registerRpc(this.h3Router, path, p, {
1089
1151
  middleware: this._middlewares,
1090
1152
  onRequest: this._onRequest,
1091
1153
  onError: this._onError,
@@ -1095,37 +1157,9 @@ class ArriApp {
1095
1157
  });
1096
1158
  return;
1097
1159
  }
1098
- registerRpc(this.h3Router, path, p, {
1099
- middleware: this._middlewares,
1100
- onRequest: this._onRequest,
1101
- onError: this._onError,
1102
- onAfterResponse: this._onAfterResponse,
1103
- onBeforeResponse: this._onBeforeResponse,
1104
- debug: this._debug
1105
- });
1106
- }
1107
- wsRpc(procedure) {
1108
- procedure.transport = "ws";
1109
- const p = procedure;
1110
- const path = procedure.path ?? getRpcPath(procedure.name, this._rpcRoutePrefix);
1111
- this._procedures[procedure.name] = createWsRpcDefinition(
1112
- procedure.name,
1113
- path,
1114
- p
1115
- );
1116
- if (isRpcParamSchema(procedure.params)) {
1117
- const paramName = getRpcParamName(procedure.name, p);
1118
- if (paramName) {
1119
- this._definitions[paramName] = procedure.params;
1120
- }
1121
- }
1122
- if (isRpcParamSchema(procedure.response)) {
1123
- const responseName = getRpcResponseName(procedure.name, p);
1124
- if (responseName) {
1125
- this._definitions[responseName] = procedure.response;
1126
- }
1160
+ if (p.transport === "ws") {
1161
+ registerWebsocketRpc(this.h3Router, path, p);
1127
1162
  }
1128
- registerWebsocketRpc(this.h3Router, path, p);
1129
1163
  }
1130
1164
  route(route) {
1131
1165
  registerRoute(this.h3Router, route, {
@@ -1159,4 +1193,4 @@ class ArriApp {
1159
1193
 
1160
1194
  const defineMiddleware = (middleware) => middleware;
1161
1195
 
1162
- export { ArriApp, ArriRouter, ArriServerError, ArriServerErrorResponse, EventStreamConnection, WsPeer, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isEventStreamRpc, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
1196
+ export { ArriApp, ArriRouter, ArriServerError, ArriServerErrorResponse, ArriService, EventStreamConnection, WsPeer, createAppDefinition, createHttpRpcDefinition, createWsRpcDefinition, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, defineService, defineWebsocketRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, getSchemaValidator, handleH3Error, handleRoute, isEventStreamRpc, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, registerWebsocketRpc, validateRpcRequestInput };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arrirpc/server",
3
- "version": "0.55.0",
3
+ "version": "0.57.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -28,12 +28,12 @@
28
28
  "scule": "^1.3.0",
29
29
  "source-map-support": "^0.5.21",
30
30
  "uncrypto": "^0.1.3",
31
- "@arrirpc/codegen-dart": "0.55.0",
32
- "@arrirpc/codegen-ts": "0.55.0",
33
- "@arrirpc/codegen-utils": "0.55.0",
34
- "@arrirpc/codegen-kotlin": "0.55.0",
35
- "@arrirpc/schema": "0.55.0",
36
- "arri": "0.55.0"
31
+ "@arrirpc/codegen-dart": "0.57.0",
32
+ "@arrirpc/codegen-kotlin": "0.57.0",
33
+ "@arrirpc/codegen-ts": "0.57.0",
34
+ "@arrirpc/codegen-utils": "0.57.0",
35
+ "@arrirpc/schema": "0.57.0",
36
+ "arri": "0.57.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "bun-types": "^1.1.20"