arri 0.1.0-beta.3 → 0.1.0-beta.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/dist/cli.cjs CHANGED
@@ -11,7 +11,7 @@ const consola = require('consola');
11
11
  const esbuild = require('esbuild');
12
12
  const path = require('pathe');
13
13
  const prettier = require('prettier');
14
- const config = require('./shared/arri.406d936a.cjs');
14
+ const config = require('./shared/arri.ab9313ca.cjs');
15
15
  const globby = require('globby');
16
16
  const scule = require('scule');
17
17
  const arriCodegenDart = require('arri-codegen-dart');
@@ -263,6 +263,7 @@ async function bundleFiles(config, allowCodegen = true) {
263
263
  js: `import { createRequire as topLevelCreateRequire } from 'module';
264
264
  const require = topLevelCreateRequire(import.meta.url);`
265
265
  },
266
+ allowOverwrite: true,
266
267
  outdir: path__default.resolve(config.rootDir, ".output")
267
268
  });
268
269
  }
@@ -309,6 +310,7 @@ async function createBuildCodegenModule(config) {
309
310
  app.rpc({
310
311
  name: route.id,
311
312
  method: route.route.method,
313
+ path: route.route.path,
312
314
  params: route.route.params,
313
315
  response: route.route.response,
314
316
  handler: route.route.handler,
@@ -549,6 +551,7 @@ for (const route of routes) {
549
551
  app.rpc({
550
552
  name: route.id,
551
553
  method: route.route.method,
554
+ path: route.route.path,
552
555
  params: route.route.params,
553
556
  response: route.route.response,
554
557
  handler: route.route.handler,
package/dist/cli.mjs CHANGED
@@ -10,7 +10,7 @@ import * as esbuild from 'esbuild';
10
10
  import { build as build$1 } from 'esbuild';
11
11
  import path from 'pathe';
12
12
  import prettier from 'prettier';
13
- import { m as defaultConfig, l as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.8539c7bd.mjs';
13
+ import { m as defaultConfig, l as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.b5addda0.mjs';
14
14
  import { globby } from 'globby';
15
15
  import { camelCase, kebabCase } from 'scule';
16
16
  import { dartClientGenerator } from 'arri-codegen-dart';
@@ -242,6 +242,7 @@ async function bundleFiles(config, allowCodegen = true) {
242
242
  js: `import { createRequire as topLevelCreateRequire } from 'module';
243
243
  const require = topLevelCreateRequire(import.meta.url);`
244
244
  },
245
+ allowOverwrite: true,
245
246
  outdir: path.resolve(config.rootDir, ".output")
246
247
  });
247
248
  }
@@ -288,6 +289,7 @@ async function createBuildCodegenModule(config) {
288
289
  app.rpc({
289
290
  name: route.id,
290
291
  method: route.route.method,
292
+ path: route.route.path,
291
293
  params: route.route.params,
292
294
  response: route.route.response,
293
295
  handler: route.route.handler,
@@ -528,6 +530,7 @@ for (const route of routes) {
528
530
  app.rpc({
529
531
  name: route.id,
530
532
  method: route.route.method,
533
+ path: route.route.path,
531
534
  params: route.route.params,
532
535
  response: route.route.response,
533
536
  handler: route.route.handler,
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const config = require('./shared/arri.406d936a.cjs');
3
+ const config = require('./shared/arri.ab9313ca.cjs');
4
4
  const h3 = require('h3');
5
5
  require('arri-validate');
6
6
  require('arri-codegen-utils');
package/dist/index.d.cts CHANGED
@@ -1,28 +1,44 @@
1
1
  import { HttpMethod, RpcDefinition, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
2
  import * as arri_validate from 'arri-validate';
3
- import { AObjectSchema, InferType, a, ValidationError } from 'arri-validate';
4
- import { H3Event, H3EventContext, Router, App, H3Error } from 'h3';
3
+ import { AObjectSchema, ASchema, InferType, a, ValidationError } from 'arri-validate';
4
+ import { H3EventContext, H3Event, Router, App, H3Error } from 'h3';
5
5
  export * from 'h3';
6
6
  import { BuildOptions } from 'esbuild';
7
7
 
8
- type Middleware = (event: H3Event) => void | Promise<void>;
8
+ interface MiddlewareEventContext extends H3EventContext {
9
+ rpcName?: string;
10
+ }
11
+ interface MiddlewareEvent extends H3Event {
12
+ context: MiddlewareEventContext;
13
+ }
14
+ type Middleware = (event: MiddlewareEvent) => void | Promise<void>;
9
15
  declare const defineMiddleware: (middleware: Middleware) => Middleware;
10
16
  type ExtractParam$1<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
11
17
  type ExtractParams$1<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam$1<Segment, ExtractParams$1<Rest>> : ExtractParam$1<Path, {}>;
12
18
 
13
19
  type ExtractParam<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
14
20
  type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam<Segment, ExtractParams<Rest>> : ExtractParam<Path, {}>;
15
- interface RouteEventContext<TPath extends string> extends H3EventContext {
21
+ interface RouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3EventContext {
16
22
  params: ExtractParams<TPath>;
23
+ query: TQuery;
24
+ body: TBody;
17
25
  }
18
- interface RouteEvent<TPath extends string> extends H3Event {
19
- context: RouteEventContext<TPath>;
26
+ interface RouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3Event {
27
+ context: RouteEventContext<TPath, TQuery, TBody>;
28
+ }
29
+ interface PostRouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends RouteEventContext<TPath, TQuery, TBody> {
30
+ response: TResponse;
20
31
  }
21
- interface ArriRoute<TPath extends string> {
32
+ interface PostRouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends H3Event {
33
+ context: PostRouteEventContext<TPath, TQuery, TBody, TResponse>;
34
+ }
35
+ interface ArriRoute<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any> {
22
36
  path: TPath;
23
37
  method: HttpMethod | HttpMethod[];
24
- handler: (event: RouteEvent<TPath>) => any;
25
- postHandler?: (event: RouteEvent<TPath>) => any;
38
+ query?: TQuery;
39
+ body?: TBody;
40
+ handler: (event: RouteEvent<TPath, InferType<TQuery>, InferType<TBody>>) => TResponse;
41
+ postHandler?: (event: PostRouteEvent<TPath, InferType<TQuery>, InferType<TBody>, Awaited<TResponse>>) => any;
26
42
  }
27
43
  type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "onError" | "onRequest"> & {
28
44
  middleware: Middleware[];
@@ -31,6 +47,7 @@ type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "
31
47
  interface ArriProcedure<TParams extends AObjectSchema | undefined, TResponse extends AObjectSchema | undefined> {
32
48
  description?: string;
33
49
  method?: HttpMethod;
50
+ path?: string;
34
51
  params: TParams;
35
52
  response: TResponse;
36
53
  handler: ArriProcedureHandler<TParams extends AObjectSchema ? InferType<TParams> : undefined, TResponse extends AObjectSchema ? InferType<TResponse> : void>;
@@ -41,32 +58,39 @@ interface ArriNamedProcedure<TParams extends AObjectSchema | undefined, TRespons
41
58
  }
42
59
  type HandlerContext = Record<string, any>;
43
60
  interface RpcHandlerContext<TParams = undefined> extends HandlerContext, Omit<H3EventContext, "params"> {
61
+ rpcName: string;
44
62
  params: TParams;
45
63
  }
46
64
  interface RpcPostHandlerContext<TParams = undefined, TResponse = undefined> extends RpcHandlerContext<TParams> {
47
65
  response: TResponse;
48
66
  }
49
- type ArriProcedureHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: H3Event) => TResponse | Promise<TResponse>;
50
- type ArriProcedurePostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: H3Event) => any;
67
+ interface RpcEvent<TParams = undefined> extends Omit<H3Event, "context"> {
68
+ context: RpcHandlerContext<TParams>;
69
+ }
70
+ interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<H3Event, "context"> {
71
+ context: RpcPostHandlerContext<TParams, TResponse>;
72
+ }
73
+ type ArriProcedureHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
74
+ type ArriProcedurePostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
51
75
  declare function isRpc(input: any): input is ArriProcedure<any, any>;
52
76
  declare function defineRpc<TParams extends AObjectSchema | undefined = undefined, TResponse extends AObjectSchema | undefined | never = undefined>(config: ArriProcedure<TParams, TResponse>): ArriProcedure<TParams, TResponse>;
53
77
  declare function createRpcDefinition(rpcName: string, httpPath: string, procedure: ArriProcedure<any, any>): RpcDefinition;
54
78
  declare function getRpcPath(rpcName: string, prefix?: string): string;
55
79
  declare function getRpcParamName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
56
80
  declare function getRpcResponseName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
57
- declare function registerRpc(router: Router, path: string, procedure: ArriProcedure<any, any>, opts: RouteOptions): void;
81
+ declare function registerRpc(router: Router, path: string, procedure: ArriNamedProcedure<any, any>, opts: RouteOptions): void;
58
82
 
59
83
  interface ArriRouterBase {
60
84
  rpc: <TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>) => void;
61
- route: <TPath extends string>(route: ArriRoute<TPath>) => void;
85
+ route: <TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>) => void;
62
86
  }
63
87
  declare class ArriRouter implements ArriRouterBase {
64
88
  private readonly procedures;
65
89
  private readonly routes;
66
90
  rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>): void;
67
- route<TPath extends string>(route: ArriRoute<TPath>): void;
91
+ route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
68
92
  getProcedures(): ArriNamedProcedure<any, any>[];
69
- getRoutes(): ArriRoute<any>[];
93
+ getRoutes(): ArriRoute<any, any, any, any>[];
70
94
  }
71
95
 
72
96
  declare const DEV_ENDPOINT_ROOT = "/__arri_dev__";
@@ -88,7 +112,7 @@ declare class ArriApp implements ArriRouterBase {
88
112
  constructor(opts?: ArriOptions);
89
113
  use(input: Middleware | ArriRouter): void;
90
114
  rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>): void;
91
- route<TPath extends string>(route: ArriRoute<TPath>): void;
115
+ route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
92
116
  getAppDefinition(): AppDefinition;
93
117
  }
94
118
  interface ArriOptions {
@@ -103,10 +127,10 @@ interface ArriOptions {
103
127
  * This parameters also takes the rpcRoutePrefix option into account
104
128
  */
105
129
  rpcDefinitionPath?: string;
106
- onRequest?: (event: H3Event) => void | Promise<void>;
107
- onAfterResponse?: (event: H3Event) => void | Promise<void>;
108
- onBeforeResponse?: (event: H3Event) => void | Promise<void>;
109
- onError?: (error: H3Error, event: H3Event) => void | Promise<void>;
130
+ onRequest?: (event: MiddlewareEvent) => void | Promise<void>;
131
+ onAfterResponse?: (event: MiddlewareEvent) => void | Promise<void>;
132
+ onBeforeResponse?: (event: MiddlewareEvent) => void | Promise<void>;
133
+ onError?: (error: H3Error, event: MiddlewareEvent) => void | Promise<void>;
110
134
  }
111
135
 
112
136
  declare const ErrorResponse: arri_validate.AObjectSchema<{
@@ -143,4 +167,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
143
167
  declare const defaultConfig: Required<ArriConfig>;
144
168
  declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
145
169
 
146
- export { ArriApp, type ArriConfig, type ArriNamedProcedure, type ArriOptions, type ArriProcedure, type ArriProcedureHandler, type ArriProcedurePostHandler, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, type ExtractParam$1 as ExtractParam, type ExtractParams$1 as ExtractParams, type HandlerContext, type Middleware, type ResolvedArriConfig, type RpcHandlerContext, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineMiddleware, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, isArriConfig, isResolvedArriConfig, isRpc, registerRpc };
170
+ export { ArriApp, type ArriConfig, type ArriNamedProcedure, type ArriOptions, type ArriProcedure, type ArriProcedureHandler, type ArriProcedurePostHandler, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, type ExtractParam$1 as ExtractParam, type ExtractParams$1 as ExtractParams, type HandlerContext, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ResolvedArriConfig, type RpcEvent, type RpcHandlerContext, type RpcPostEvent, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineMiddleware, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, isArriConfig, isResolvedArriConfig, isRpc, registerRpc };
package/dist/index.d.mts CHANGED
@@ -1,28 +1,44 @@
1
1
  import { HttpMethod, RpcDefinition, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
2
  import * as arri_validate from 'arri-validate';
3
- import { AObjectSchema, InferType, a, ValidationError } from 'arri-validate';
4
- import { H3Event, H3EventContext, Router, App, H3Error } from 'h3';
3
+ import { AObjectSchema, ASchema, InferType, a, ValidationError } from 'arri-validate';
4
+ import { H3EventContext, H3Event, Router, App, H3Error } from 'h3';
5
5
  export * from 'h3';
6
6
  import { BuildOptions } from 'esbuild';
7
7
 
8
- type Middleware = (event: H3Event) => void | Promise<void>;
8
+ interface MiddlewareEventContext extends H3EventContext {
9
+ rpcName?: string;
10
+ }
11
+ interface MiddlewareEvent extends H3Event {
12
+ context: MiddlewareEventContext;
13
+ }
14
+ type Middleware = (event: MiddlewareEvent) => void | Promise<void>;
9
15
  declare const defineMiddleware: (middleware: Middleware) => Middleware;
10
16
  type ExtractParam$1<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
11
17
  type ExtractParams$1<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam$1<Segment, ExtractParams$1<Rest>> : ExtractParam$1<Path, {}>;
12
18
 
13
19
  type ExtractParam<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
14
20
  type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam<Segment, ExtractParams<Rest>> : ExtractParam<Path, {}>;
15
- interface RouteEventContext<TPath extends string> extends H3EventContext {
21
+ interface RouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3EventContext {
16
22
  params: ExtractParams<TPath>;
23
+ query: TQuery;
24
+ body: TBody;
17
25
  }
18
- interface RouteEvent<TPath extends string> extends H3Event {
19
- context: RouteEventContext<TPath>;
26
+ interface RouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3Event {
27
+ context: RouteEventContext<TPath, TQuery, TBody>;
28
+ }
29
+ interface PostRouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends RouteEventContext<TPath, TQuery, TBody> {
30
+ response: TResponse;
20
31
  }
21
- interface ArriRoute<TPath extends string> {
32
+ interface PostRouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends H3Event {
33
+ context: PostRouteEventContext<TPath, TQuery, TBody, TResponse>;
34
+ }
35
+ interface ArriRoute<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any> {
22
36
  path: TPath;
23
37
  method: HttpMethod | HttpMethod[];
24
- handler: (event: RouteEvent<TPath>) => any;
25
- postHandler?: (event: RouteEvent<TPath>) => any;
38
+ query?: TQuery;
39
+ body?: TBody;
40
+ handler: (event: RouteEvent<TPath, InferType<TQuery>, InferType<TBody>>) => TResponse;
41
+ postHandler?: (event: PostRouteEvent<TPath, InferType<TQuery>, InferType<TBody>, Awaited<TResponse>>) => any;
26
42
  }
27
43
  type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "onError" | "onRequest"> & {
28
44
  middleware: Middleware[];
@@ -31,6 +47,7 @@ type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "
31
47
  interface ArriProcedure<TParams extends AObjectSchema | undefined, TResponse extends AObjectSchema | undefined> {
32
48
  description?: string;
33
49
  method?: HttpMethod;
50
+ path?: string;
34
51
  params: TParams;
35
52
  response: TResponse;
36
53
  handler: ArriProcedureHandler<TParams extends AObjectSchema ? InferType<TParams> : undefined, TResponse extends AObjectSchema ? InferType<TResponse> : void>;
@@ -41,32 +58,39 @@ interface ArriNamedProcedure<TParams extends AObjectSchema | undefined, TRespons
41
58
  }
42
59
  type HandlerContext = Record<string, any>;
43
60
  interface RpcHandlerContext<TParams = undefined> extends HandlerContext, Omit<H3EventContext, "params"> {
61
+ rpcName: string;
44
62
  params: TParams;
45
63
  }
46
64
  interface RpcPostHandlerContext<TParams = undefined, TResponse = undefined> extends RpcHandlerContext<TParams> {
47
65
  response: TResponse;
48
66
  }
49
- type ArriProcedureHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: H3Event) => TResponse | Promise<TResponse>;
50
- type ArriProcedurePostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: H3Event) => any;
67
+ interface RpcEvent<TParams = undefined> extends Omit<H3Event, "context"> {
68
+ context: RpcHandlerContext<TParams>;
69
+ }
70
+ interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<H3Event, "context"> {
71
+ context: RpcPostHandlerContext<TParams, TResponse>;
72
+ }
73
+ type ArriProcedureHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
74
+ type ArriProcedurePostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
51
75
  declare function isRpc(input: any): input is ArriProcedure<any, any>;
52
76
  declare function defineRpc<TParams extends AObjectSchema | undefined = undefined, TResponse extends AObjectSchema | undefined | never = undefined>(config: ArriProcedure<TParams, TResponse>): ArriProcedure<TParams, TResponse>;
53
77
  declare function createRpcDefinition(rpcName: string, httpPath: string, procedure: ArriProcedure<any, any>): RpcDefinition;
54
78
  declare function getRpcPath(rpcName: string, prefix?: string): string;
55
79
  declare function getRpcParamName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
56
80
  declare function getRpcResponseName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
57
- declare function registerRpc(router: Router, path: string, procedure: ArriProcedure<any, any>, opts: RouteOptions): void;
81
+ declare function registerRpc(router: Router, path: string, procedure: ArriNamedProcedure<any, any>, opts: RouteOptions): void;
58
82
 
59
83
  interface ArriRouterBase {
60
84
  rpc: <TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>) => void;
61
- route: <TPath extends string>(route: ArriRoute<TPath>) => void;
85
+ route: <TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>) => void;
62
86
  }
63
87
  declare class ArriRouter implements ArriRouterBase {
64
88
  private readonly procedures;
65
89
  private readonly routes;
66
90
  rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>): void;
67
- route<TPath extends string>(route: ArriRoute<TPath>): void;
91
+ route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
68
92
  getProcedures(): ArriNamedProcedure<any, any>[];
69
- getRoutes(): ArriRoute<any>[];
93
+ getRoutes(): ArriRoute<any, any, any, any>[];
70
94
  }
71
95
 
72
96
  declare const DEV_ENDPOINT_ROOT = "/__arri_dev__";
@@ -88,7 +112,7 @@ declare class ArriApp implements ArriRouterBase {
88
112
  constructor(opts?: ArriOptions);
89
113
  use(input: Middleware | ArriRouter): void;
90
114
  rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>): void;
91
- route<TPath extends string>(route: ArriRoute<TPath>): void;
115
+ route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
92
116
  getAppDefinition(): AppDefinition;
93
117
  }
94
118
  interface ArriOptions {
@@ -103,10 +127,10 @@ interface ArriOptions {
103
127
  * This parameters also takes the rpcRoutePrefix option into account
104
128
  */
105
129
  rpcDefinitionPath?: string;
106
- onRequest?: (event: H3Event) => void | Promise<void>;
107
- onAfterResponse?: (event: H3Event) => void | Promise<void>;
108
- onBeforeResponse?: (event: H3Event) => void | Promise<void>;
109
- onError?: (error: H3Error, event: H3Event) => void | Promise<void>;
130
+ onRequest?: (event: MiddlewareEvent) => void | Promise<void>;
131
+ onAfterResponse?: (event: MiddlewareEvent) => void | Promise<void>;
132
+ onBeforeResponse?: (event: MiddlewareEvent) => void | Promise<void>;
133
+ onError?: (error: H3Error, event: MiddlewareEvent) => void | Promise<void>;
110
134
  }
111
135
 
112
136
  declare const ErrorResponse: arri_validate.AObjectSchema<{
@@ -143,4 +167,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
143
167
  declare const defaultConfig: Required<ArriConfig>;
144
168
  declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
145
169
 
146
- export { ArriApp, type ArriConfig, type ArriNamedProcedure, type ArriOptions, type ArriProcedure, type ArriProcedureHandler, type ArriProcedurePostHandler, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, type ExtractParam$1 as ExtractParam, type ExtractParams$1 as ExtractParams, type HandlerContext, type Middleware, type ResolvedArriConfig, type RpcHandlerContext, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineMiddleware, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, isArriConfig, isResolvedArriConfig, isRpc, registerRpc };
170
+ export { ArriApp, type ArriConfig, type ArriNamedProcedure, type ArriOptions, type ArriProcedure, type ArriProcedureHandler, type ArriProcedurePostHandler, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, type ExtractParam$1 as ExtractParam, type ExtractParams$1 as ExtractParams, type HandlerContext, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ResolvedArriConfig, type RpcEvent, type RpcHandlerContext, type RpcPostEvent, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineMiddleware, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, isArriConfig, isResolvedArriConfig, isRpc, registerRpc };
package/dist/index.d.ts CHANGED
@@ -1,28 +1,44 @@
1
1
  import { HttpMethod, RpcDefinition, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
2
2
  import * as arri_validate from 'arri-validate';
3
- import { AObjectSchema, InferType, a, ValidationError } from 'arri-validate';
4
- import { H3Event, H3EventContext, Router, App, H3Error } from 'h3';
3
+ import { AObjectSchema, ASchema, InferType, a, ValidationError } from 'arri-validate';
4
+ import { H3EventContext, H3Event, Router, App, H3Error } from 'h3';
5
5
  export * from 'h3';
6
6
  import { BuildOptions } from 'esbuild';
7
7
 
8
- type Middleware = (event: H3Event) => void | Promise<void>;
8
+ interface MiddlewareEventContext extends H3EventContext {
9
+ rpcName?: string;
10
+ }
11
+ interface MiddlewareEvent extends H3Event {
12
+ context: MiddlewareEventContext;
13
+ }
14
+ type Middleware = (event: MiddlewareEvent) => void | Promise<void>;
9
15
  declare const defineMiddleware: (middleware: Middleware) => Middleware;
10
16
  type ExtractParam$1<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
11
17
  type ExtractParams$1<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam$1<Segment, ExtractParams$1<Rest>> : ExtractParam$1<Path, {}>;
12
18
 
13
19
  type ExtractParam<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
14
20
  type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam<Segment, ExtractParams<Rest>> : ExtractParam<Path, {}>;
15
- interface RouteEventContext<TPath extends string> extends H3EventContext {
21
+ interface RouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3EventContext {
16
22
  params: ExtractParams<TPath>;
23
+ query: TQuery;
24
+ body: TBody;
17
25
  }
18
- interface RouteEvent<TPath extends string> extends H3Event {
19
- context: RouteEventContext<TPath>;
26
+ interface RouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3Event {
27
+ context: RouteEventContext<TPath, TQuery, TBody>;
28
+ }
29
+ interface PostRouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends RouteEventContext<TPath, TQuery, TBody> {
30
+ response: TResponse;
20
31
  }
21
- interface ArriRoute<TPath extends string> {
32
+ interface PostRouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends H3Event {
33
+ context: PostRouteEventContext<TPath, TQuery, TBody, TResponse>;
34
+ }
35
+ interface ArriRoute<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any> {
22
36
  path: TPath;
23
37
  method: HttpMethod | HttpMethod[];
24
- handler: (event: RouteEvent<TPath>) => any;
25
- postHandler?: (event: RouteEvent<TPath>) => any;
38
+ query?: TQuery;
39
+ body?: TBody;
40
+ handler: (event: RouteEvent<TPath, InferType<TQuery>, InferType<TBody>>) => TResponse;
41
+ postHandler?: (event: PostRouteEvent<TPath, InferType<TQuery>, InferType<TBody>, Awaited<TResponse>>) => any;
26
42
  }
27
43
  type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "onError" | "onRequest"> & {
28
44
  middleware: Middleware[];
@@ -31,6 +47,7 @@ type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "
31
47
  interface ArriProcedure<TParams extends AObjectSchema | undefined, TResponse extends AObjectSchema | undefined> {
32
48
  description?: string;
33
49
  method?: HttpMethod;
50
+ path?: string;
34
51
  params: TParams;
35
52
  response: TResponse;
36
53
  handler: ArriProcedureHandler<TParams extends AObjectSchema ? InferType<TParams> : undefined, TResponse extends AObjectSchema ? InferType<TResponse> : void>;
@@ -41,32 +58,39 @@ interface ArriNamedProcedure<TParams extends AObjectSchema | undefined, TRespons
41
58
  }
42
59
  type HandlerContext = Record<string, any>;
43
60
  interface RpcHandlerContext<TParams = undefined> extends HandlerContext, Omit<H3EventContext, "params"> {
61
+ rpcName: string;
44
62
  params: TParams;
45
63
  }
46
64
  interface RpcPostHandlerContext<TParams = undefined, TResponse = undefined> extends RpcHandlerContext<TParams> {
47
65
  response: TResponse;
48
66
  }
49
- type ArriProcedureHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: H3Event) => TResponse | Promise<TResponse>;
50
- type ArriProcedurePostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: H3Event) => any;
67
+ interface RpcEvent<TParams = undefined> extends Omit<H3Event, "context"> {
68
+ context: RpcHandlerContext<TParams>;
69
+ }
70
+ interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<H3Event, "context"> {
71
+ context: RpcPostHandlerContext<TParams, TResponse>;
72
+ }
73
+ type ArriProcedureHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
74
+ type ArriProcedurePostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
51
75
  declare function isRpc(input: any): input is ArriProcedure<any, any>;
52
76
  declare function defineRpc<TParams extends AObjectSchema | undefined = undefined, TResponse extends AObjectSchema | undefined | never = undefined>(config: ArriProcedure<TParams, TResponse>): ArriProcedure<TParams, TResponse>;
53
77
  declare function createRpcDefinition(rpcName: string, httpPath: string, procedure: ArriProcedure<any, any>): RpcDefinition;
54
78
  declare function getRpcPath(rpcName: string, prefix?: string): string;
55
79
  declare function getRpcParamName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
56
80
  declare function getRpcResponseName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
57
- declare function registerRpc(router: Router, path: string, procedure: ArriProcedure<any, any>, opts: RouteOptions): void;
81
+ declare function registerRpc(router: Router, path: string, procedure: ArriNamedProcedure<any, any>, opts: RouteOptions): void;
58
82
 
59
83
  interface ArriRouterBase {
60
84
  rpc: <TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>) => void;
61
- route: <TPath extends string>(route: ArriRoute<TPath>) => void;
85
+ route: <TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>) => void;
62
86
  }
63
87
  declare class ArriRouter implements ArriRouterBase {
64
88
  private readonly procedures;
65
89
  private readonly routes;
66
90
  rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>): void;
67
- route<TPath extends string>(route: ArriRoute<TPath>): void;
91
+ route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
68
92
  getProcedures(): ArriNamedProcedure<any, any>[];
69
- getRoutes(): ArriRoute<any>[];
93
+ getRoutes(): ArriRoute<any, any, any, any>[];
70
94
  }
71
95
 
72
96
  declare const DEV_ENDPOINT_ROOT = "/__arri_dev__";
@@ -88,7 +112,7 @@ declare class ArriApp implements ArriRouterBase {
88
112
  constructor(opts?: ArriOptions);
89
113
  use(input: Middleware | ArriRouter): void;
90
114
  rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: ArriNamedProcedure<TParams, TResponse>): void;
91
- route<TPath extends string>(route: ArriRoute<TPath>): void;
115
+ route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
92
116
  getAppDefinition(): AppDefinition;
93
117
  }
94
118
  interface ArriOptions {
@@ -103,10 +127,10 @@ interface ArriOptions {
103
127
  * This parameters also takes the rpcRoutePrefix option into account
104
128
  */
105
129
  rpcDefinitionPath?: string;
106
- onRequest?: (event: H3Event) => void | Promise<void>;
107
- onAfterResponse?: (event: H3Event) => void | Promise<void>;
108
- onBeforeResponse?: (event: H3Event) => void | Promise<void>;
109
- onError?: (error: H3Error, event: H3Event) => void | Promise<void>;
130
+ onRequest?: (event: MiddlewareEvent) => void | Promise<void>;
131
+ onAfterResponse?: (event: MiddlewareEvent) => void | Promise<void>;
132
+ onBeforeResponse?: (event: MiddlewareEvent) => void | Promise<void>;
133
+ onError?: (error: H3Error, event: MiddlewareEvent) => void | Promise<void>;
110
134
  }
111
135
 
112
136
  declare const ErrorResponse: arri_validate.AObjectSchema<{
@@ -143,4 +167,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
143
167
  declare const defaultConfig: Required<ArriConfig>;
144
168
  declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
145
169
 
146
- export { ArriApp, type ArriConfig, type ArriNamedProcedure, type ArriOptions, type ArriProcedure, type ArriProcedureHandler, type ArriProcedurePostHandler, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, type ExtractParam$1 as ExtractParam, type ExtractParams$1 as ExtractParams, type HandlerContext, type Middleware, type ResolvedArriConfig, type RpcHandlerContext, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineMiddleware, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, isArriConfig, isResolvedArriConfig, isRpc, registerRpc };
170
+ export { ArriApp, type ArriConfig, type ArriNamedProcedure, type ArriOptions, type ArriProcedure, type ArriProcedureHandler, type ArriProcedurePostHandler, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, type ExtractParam$1 as ExtractParam, type ExtractParams$1 as ExtractParams, type HandlerContext, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ResolvedArriConfig, type RpcEvent, type RpcHandlerContext, type RpcPostEvent, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineMiddleware, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, isArriConfig, isResolvedArriConfig, isRpc, registerRpc };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ArriApp, o as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse, c as createRpcDefinition, m as defaultConfig, n as defineConfig, f as defineError, d as defineRpc, h as errorResponseFromValidationErrors, b as getRpcParamName, g as getRpcPath, e as getRpcResponseName, j as handleH3Error, k as isArriConfig, l as isResolvedArriConfig, i as isRpc, r as registerRpc } from './shared/arri.8539c7bd.mjs';
1
+ export { A as ArriApp, o as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse, c as createRpcDefinition, m as defaultConfig, n as defineConfig, f as defineError, d as defineRpc, h as errorResponseFromValidationErrors, b as getRpcParamName, g as getRpcPath, e as getRpcResponseName, j as handleH3Error, k as isArriConfig, l as isResolvedArriConfig, i as isRpc, r as registerRpc } from './shared/arri.b5addda0.mjs';
2
2
  export * from 'h3';
3
3
  import 'arri-validate';
4
4
  import 'arri-codegen-utils';
@@ -272,10 +272,10 @@ function getRpcResponseDefinition(rpcName, procedure) {
272
272
  return name;
273
273
  }
274
274
  function registerRpc(router, path, procedure, opts) {
275
- const paramValidator = procedure.params ? arriValidate.a.compile(procedure.params) : void 0;
276
275
  const responseValidator = procedure.response ? arriValidate.a.compile(procedure.response) : void 0;
277
276
  const httpMethod = procedure.method ?? "post";
278
277
  const handler = h3.eventHandler(async (event) => {
278
+ event.context.rpcName = procedure.name;
279
279
  if (h3.isPreflightRequest(event)) {
280
280
  return "ok";
281
281
  }
@@ -288,7 +288,7 @@ function registerRpc(router, path, procedure, opts) {
288
288
  await m(event);
289
289
  }
290
290
  }
291
- if (arriValidate.isAObjectSchema(procedure.params) && paramValidator) {
291
+ if (arriValidate.isAObjectSchema(procedure.params)) {
292
292
  switch (httpMethod) {
293
293
  case "get":
294
294
  case "head": {
@@ -328,7 +328,10 @@ function registerRpc(router, path, procedure, opts) {
328
328
  statusMessage: `Invalid request body. Expected object. Got undefined.`
329
329
  });
330
330
  }
331
- const parsedParams = paramValidator.safeParse(body);
331
+ const parsedParams = arriValidate.a.safeParse(
332
+ procedure.params,
333
+ body
334
+ );
332
335
  if (!parsedParams.success) {
333
336
  const errorParts = [];
334
337
  for (const err of parsedParams.error.errors) {
@@ -367,21 +370,8 @@ function registerRpc(router, path, procedure, opts) {
367
370
  responseValidator?.serialize(response) ?? JSON.stringify(response)
368
371
  );
369
372
  } else {
370
- await h3.send(
371
- event,
372
- response ?? `<!doctype html>
373
- <html lang="en">
374
- <head>
375
- <meta charset="UTF-8" />
376
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
377
- <title>Empty Response</title>
378
- </head>
379
- <body>
380
- nothing to see here
381
- </body>
382
- </html>
383
- `
384
- );
373
+ h3.setResponseHeader(event, "Content-Type", "application/json");
374
+ await h3.send(event, `{}`);
385
375
  }
386
376
  if (opts.onAfterResponse) {
387
377
  await opts.onAfterResponse(event);
@@ -453,6 +443,9 @@ function registerRoute(router, route, opts) {
453
443
  }
454
444
  function handleRoute(router, method, route, opts) {
455
445
  const handler = h3.defineEventHandler(async (event) => {
446
+ if (h3.isPreflightRequest(event)) {
447
+ return "ok";
448
+ }
456
449
  try {
457
450
  if (opts.onRequest) {
458
451
  await opts.onRequest(event);
@@ -462,6 +455,55 @@ function handleRoute(router, method, route, opts) {
462
455
  await m(event);
463
456
  }
464
457
  }
458
+ if (route.query) {
459
+ const query = h3.getQuery(event);
460
+ const parsedQuery = arriValidate.a.safeCoerce(route.query, query);
461
+ if (!parsedQuery.success) {
462
+ const errParts = [];
463
+ for (const err of parsedQuery.error.errors) {
464
+ const errPath = err.instancePath.split("/");
465
+ errPath.shift();
466
+ const propName = errPath.join(".");
467
+ if (!errParts.includes(propName)) {
468
+ errParts.push(propName);
469
+ }
470
+ }
471
+ const message = `Missing or invalid url query parameters: [${errParts.join(
472
+ ", "
473
+ )}]`;
474
+ throw defineError(400, {
475
+ statusMessage: message
476
+ });
477
+ }
478
+ event.context.query = parsedQuery.value;
479
+ }
480
+ const notAllowedBodyMethods = [
481
+ "GET",
482
+ "HEAD",
483
+ "CONNECT",
484
+ "OPTIONS"
485
+ ];
486
+ if (route.body && !notAllowedBodyMethods.includes(event.method)) {
487
+ const body = await h3.readRawBody(event);
488
+ const parsedBody = arriValidate.a.safeParse(route.body, body);
489
+ if (!parsedBody.success) {
490
+ const errorParts = [];
491
+ for (const err of parsedBody.error.errors) {
492
+ const errPath = err.instancePath.split("/");
493
+ errPath.shift();
494
+ if (!errorParts.includes(errPath.join("."))) {
495
+ errorParts.push(errPath.join("."));
496
+ }
497
+ }
498
+ throw defineError(400, {
499
+ statusMessage: `Invalid request body. Affected properties [${errorParts.join(
500
+ ", "
501
+ )}]`,
502
+ data: parsedBody.error
503
+ });
504
+ }
505
+ event.context.body = parsedBody.value;
506
+ }
465
507
  const response = await route.handler(event);
466
508
  event.context.response = response;
467
509
  if (!event.handled) {
@@ -484,6 +526,7 @@ function handleRoute(router, method, route, opts) {
484
526
  } catch (err) {
485
527
  await handleH3Error(err, event, opts.onError);
486
528
  }
529
+ return "";
487
530
  });
488
531
  switch (method) {
489
532
  case "get":
@@ -534,6 +577,7 @@ class ArriApp {
534
577
  this.h3App = h3.createApp({
535
578
  debug: opts?.debug
536
579
  });
580
+ this.onRequest = opts.onRequest;
537
581
  this.onError = opts.onError;
538
582
  this.onAfterResponse = opts.onAfterResponse;
539
583
  this.onBeforeResponse = opts.onBeforeResponse;
@@ -556,6 +600,9 @@ class ArriApp {
556
600
  h3.setResponseStatus(event, 404);
557
601
  const error = defineError(404);
558
602
  try {
603
+ if (this.onRequest) {
604
+ await this.onRequest(event);
605
+ }
559
606
  if (this.middlewares.length) {
560
607
  for (const m of this.middlewares) {
561
608
  await m(event);
@@ -590,7 +637,7 @@ class ArriApp {
590
637
  this.middlewares.push(input);
591
638
  }
592
639
  rpc(procedure) {
593
- const path = getRpcPath(procedure.name, this.rpcRoutePrefix);
640
+ const path = procedure.path ?? getRpcPath(procedure.name, this.rpcRoutePrefix);
594
641
  this.procedures[procedure.name] = createRpcDefinition(
595
642
  procedure.name,
596
643
  path,
@@ -610,6 +657,7 @@ class ArriApp {
610
657
  }
611
658
  registerRpc(this.h3Router, path, procedure, {
612
659
  middleware: this.middlewares,
660
+ onRequest: this.onRequest,
613
661
  onError: this.onError,
614
662
  onAfterResponse: this.onAfterResponse,
615
663
  onBeforeResponse: this.onBeforeResponse
@@ -618,6 +666,7 @@ class ArriApp {
618
666
  route(route) {
619
667
  registerRoute(this.h3Router, route, {
620
668
  middleware: this.middlewares,
669
+ onRequest: this.onRequest,
621
670
  onError: this.onError,
622
671
  onAfterResponse: this.onAfterResponse,
623
672
  onBeforeResponse: this.onBeforeResponse
@@ -628,8 +677,7 @@ class ArriApp {
628
677
  arriSchemaVersion: "0.0.2",
629
678
  info: this.appInfo,
630
679
  procedures: {},
631
- models: this.models,
632
- errors: ErrorResponse
680
+ models: this.models
633
681
  };
634
682
  for (const key of Object.keys(this.procedures)) {
635
683
  const rpc = this.procedures[key];
@@ -1,5 +1,5 @@
1
1
  import { a, isAObjectSchema } from 'arri-validate';
2
- import { createError, isError, setResponseStatus, send, eventHandler, isPreflightRequest, readRawBody, getValidatedQuery, setResponseHeader, defineEventHandler, setHeader, createRouter, createApp, sendError } from 'h3';
2
+ import { createError, isError, setResponseStatus, send, eventHandler, isPreflightRequest, readRawBody, getValidatedQuery, setResponseHeader, defineEventHandler, getQuery, setHeader, createRouter, createApp, sendError } from 'h3';
3
3
  import { isHttpMethod, removeDisallowedChars } from 'arri-codegen-utils';
4
4
  import { kebabCase, pascalCase } from 'scule';
5
5
 
@@ -270,10 +270,10 @@ function getRpcResponseDefinition(rpcName, procedure) {
270
270
  return name;
271
271
  }
272
272
  function registerRpc(router, path, procedure, opts) {
273
- const paramValidator = procedure.params ? a.compile(procedure.params) : void 0;
274
273
  const responseValidator = procedure.response ? a.compile(procedure.response) : void 0;
275
274
  const httpMethod = procedure.method ?? "post";
276
275
  const handler = eventHandler(async (event) => {
276
+ event.context.rpcName = procedure.name;
277
277
  if (isPreflightRequest(event)) {
278
278
  return "ok";
279
279
  }
@@ -286,7 +286,7 @@ function registerRpc(router, path, procedure, opts) {
286
286
  await m(event);
287
287
  }
288
288
  }
289
- if (isAObjectSchema(procedure.params) && paramValidator) {
289
+ if (isAObjectSchema(procedure.params)) {
290
290
  switch (httpMethod) {
291
291
  case "get":
292
292
  case "head": {
@@ -326,7 +326,10 @@ function registerRpc(router, path, procedure, opts) {
326
326
  statusMessage: `Invalid request body. Expected object. Got undefined.`
327
327
  });
328
328
  }
329
- const parsedParams = paramValidator.safeParse(body);
329
+ const parsedParams = a.safeParse(
330
+ procedure.params,
331
+ body
332
+ );
330
333
  if (!parsedParams.success) {
331
334
  const errorParts = [];
332
335
  for (const err of parsedParams.error.errors) {
@@ -365,21 +368,8 @@ function registerRpc(router, path, procedure, opts) {
365
368
  responseValidator?.serialize(response) ?? JSON.stringify(response)
366
369
  );
367
370
  } else {
368
- await send(
369
- event,
370
- response ?? `<!doctype html>
371
- <html lang="en">
372
- <head>
373
- <meta charset="UTF-8" />
374
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
375
- <title>Empty Response</title>
376
- </head>
377
- <body>
378
- nothing to see here
379
- </body>
380
- </html>
381
- `
382
- );
371
+ setResponseHeader(event, "Content-Type", "application/json");
372
+ await send(event, `{}`);
383
373
  }
384
374
  if (opts.onAfterResponse) {
385
375
  await opts.onAfterResponse(event);
@@ -451,6 +441,9 @@ function registerRoute(router, route, opts) {
451
441
  }
452
442
  function handleRoute(router, method, route, opts) {
453
443
  const handler = defineEventHandler(async (event) => {
444
+ if (isPreflightRequest(event)) {
445
+ return "ok";
446
+ }
454
447
  try {
455
448
  if (opts.onRequest) {
456
449
  await opts.onRequest(event);
@@ -460,6 +453,55 @@ function handleRoute(router, method, route, opts) {
460
453
  await m(event);
461
454
  }
462
455
  }
456
+ if (route.query) {
457
+ const query = getQuery(event);
458
+ const parsedQuery = a.safeCoerce(route.query, query);
459
+ if (!parsedQuery.success) {
460
+ const errParts = [];
461
+ for (const err of parsedQuery.error.errors) {
462
+ const errPath = err.instancePath.split("/");
463
+ errPath.shift();
464
+ const propName = errPath.join(".");
465
+ if (!errParts.includes(propName)) {
466
+ errParts.push(propName);
467
+ }
468
+ }
469
+ const message = `Missing or invalid url query parameters: [${errParts.join(
470
+ ", "
471
+ )}]`;
472
+ throw defineError(400, {
473
+ statusMessage: message
474
+ });
475
+ }
476
+ event.context.query = parsedQuery.value;
477
+ }
478
+ const notAllowedBodyMethods = [
479
+ "GET",
480
+ "HEAD",
481
+ "CONNECT",
482
+ "OPTIONS"
483
+ ];
484
+ if (route.body && !notAllowedBodyMethods.includes(event.method)) {
485
+ const body = await readRawBody(event);
486
+ const parsedBody = a.safeParse(route.body, body);
487
+ if (!parsedBody.success) {
488
+ const errorParts = [];
489
+ for (const err of parsedBody.error.errors) {
490
+ const errPath = err.instancePath.split("/");
491
+ errPath.shift();
492
+ if (!errorParts.includes(errPath.join("."))) {
493
+ errorParts.push(errPath.join("."));
494
+ }
495
+ }
496
+ throw defineError(400, {
497
+ statusMessage: `Invalid request body. Affected properties [${errorParts.join(
498
+ ", "
499
+ )}]`,
500
+ data: parsedBody.error
501
+ });
502
+ }
503
+ event.context.body = parsedBody.value;
504
+ }
463
505
  const response = await route.handler(event);
464
506
  event.context.response = response;
465
507
  if (!event.handled) {
@@ -482,6 +524,7 @@ function handleRoute(router, method, route, opts) {
482
524
  } catch (err) {
483
525
  await handleH3Error(err, event, opts.onError);
484
526
  }
527
+ return "";
485
528
  });
486
529
  switch (method) {
487
530
  case "get":
@@ -532,6 +575,7 @@ class ArriApp {
532
575
  this.h3App = createApp({
533
576
  debug: opts?.debug
534
577
  });
578
+ this.onRequest = opts.onRequest;
535
579
  this.onError = opts.onError;
536
580
  this.onAfterResponse = opts.onAfterResponse;
537
581
  this.onBeforeResponse = opts.onBeforeResponse;
@@ -554,6 +598,9 @@ class ArriApp {
554
598
  setResponseStatus(event, 404);
555
599
  const error = defineError(404);
556
600
  try {
601
+ if (this.onRequest) {
602
+ await this.onRequest(event);
603
+ }
557
604
  if (this.middlewares.length) {
558
605
  for (const m of this.middlewares) {
559
606
  await m(event);
@@ -588,7 +635,7 @@ class ArriApp {
588
635
  this.middlewares.push(input);
589
636
  }
590
637
  rpc(procedure) {
591
- const path = getRpcPath(procedure.name, this.rpcRoutePrefix);
638
+ const path = procedure.path ?? getRpcPath(procedure.name, this.rpcRoutePrefix);
592
639
  this.procedures[procedure.name] = createRpcDefinition(
593
640
  procedure.name,
594
641
  path,
@@ -608,6 +655,7 @@ class ArriApp {
608
655
  }
609
656
  registerRpc(this.h3Router, path, procedure, {
610
657
  middleware: this.middlewares,
658
+ onRequest: this.onRequest,
611
659
  onError: this.onError,
612
660
  onAfterResponse: this.onAfterResponse,
613
661
  onBeforeResponse: this.onBeforeResponse
@@ -616,6 +664,7 @@ class ArriApp {
616
664
  route(route) {
617
665
  registerRoute(this.h3Router, route, {
618
666
  middleware: this.middlewares,
667
+ onRequest: this.onRequest,
619
668
  onError: this.onError,
620
669
  onAfterResponse: this.onAfterResponse,
621
670
  onBeforeResponse: this.onBeforeResponse
@@ -626,8 +675,7 @@ class ArriApp {
626
675
  arriSchemaVersion: "0.0.2",
627
676
  info: this.appInfo,
628
677
  procedures: {},
629
- models: this.models,
630
- errors: ErrorResponse
678
+ models: this.models
631
679
  };
632
680
  for (const key of Object.keys(this.procedures)) {
633
681
  const rpc = this.procedures[key];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arri",
3
- "version": "0.1.0-beta.3",
3
+ "version": "0.1.0-beta.5",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -22,7 +22,7 @@
22
22
  "chokidar": "^3.5.3",
23
23
  "citty": "^0.1.4",
24
24
  "consola": "^3.2.3",
25
- "esbuild": "^0.19.3",
25
+ "esbuild": "^0.19.4",
26
26
  "globby": "^13.2.2",
27
27
  "h3": "^1.8.2",
28
28
  "jiti": "^1.20.0",
@@ -31,12 +31,12 @@
31
31
  "pathe": "^1.1.1",
32
32
  "prettier": "^3.0.3",
33
33
  "scule": "^1.0.0",
34
- "arri-validate": "0.1.0-beta.3",
35
- "arri-codegen-ts": "0.1.0-beta.3",
36
- "arri-codegen-utils": "0.1.0-beta.3",
37
- "arri-codegen-dart": "0.1.0-beta.3"
34
+ "arri-codegen-dart": "0.1.0-beta.5",
35
+ "arri-codegen-utils": "0.1.0-beta.5",
36
+ "arri-validate": "0.1.0-beta.5",
37
+ "arri-codegen-ts": "0.1.0-beta.5"
38
38
  },
39
39
  "devDependencies": {
40
- "bun-types": "^1.0.3"
40
+ "bun-types": "^1.0.5"
41
41
  }
42
42
  }