arri 0.13.0 → 0.16.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/README.md +75 -3
- package/dist/cli.cjs +16 -8
- package/dist/cli.mjs +16 -8
- package/dist/index.cjs +9 -1
- package/dist/index.d.cts +118 -37
- package/dist/index.d.mts +118 -37
- package/dist/index.d.ts +118 -37
- package/dist/index.mjs +1 -1
- package/dist/shared/{arri.165b8604.cjs → arri.beaf548c.cjs} +361 -100
- package/dist/shared/{arri.cc0da87a.mjs → arri.ff70fe08.mjs} +355 -102
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -149,7 +149,9 @@ Setup your npm scripts:
|
|
|
149
149
|
|
|
150
150
|
## Usage
|
|
151
151
|
|
|
152
|
-
###
|
|
152
|
+
### Creating Procedures
|
|
153
|
+
|
|
154
|
+
#### File Based Routing
|
|
153
155
|
|
|
154
156
|
Arri RPC comes with an optional file based router that will automatically register functions in the `./procedures` directory that end with the `.rpc.ts` file extension.
|
|
155
157
|
|
|
@@ -184,7 +186,7 @@ export default defineRpc({
|
|
|
184
186
|
});
|
|
185
187
|
```
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
##### Customizing the File Based Router
|
|
188
190
|
|
|
189
191
|
```ts
|
|
190
192
|
export default defineConfig({
|
|
@@ -194,7 +196,7 @@ export default defineConfig({
|
|
|
194
196
|
});
|
|
195
197
|
```
|
|
196
198
|
|
|
197
|
-
|
|
199
|
+
#### Manual Routing
|
|
198
200
|
|
|
199
201
|
```ts
|
|
200
202
|
// using the app instance
|
|
@@ -208,6 +210,76 @@ router.rpc('sayHello', {...})
|
|
|
208
210
|
app.use(router)
|
|
209
211
|
```
|
|
210
212
|
|
|
213
|
+
#### Creating Event Stream Procedures
|
|
214
|
+
|
|
215
|
+
Event stream procedures make use of [Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) to stream events to clients.
|
|
216
|
+
|
|
217
|
+
Normal events will have the event type `message`. Error events will have the event type `error`, and a `done` event will be sent when closing the connection. Additionally the `EventStreamConnection` will periodically since a `ping` event to keep the connection alive
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
/// standard event ///
|
|
221
|
+
id: string | undefined;
|
|
222
|
+
event: "message";
|
|
223
|
+
data: Response; // whatever you have specified as the response serialized to json
|
|
224
|
+
|
|
225
|
+
/// error event ///
|
|
226
|
+
id: string | undefined;
|
|
227
|
+
event: "error";
|
|
228
|
+
data: ArriRequestError; // serialized to json
|
|
229
|
+
|
|
230
|
+
/// done event ///
|
|
231
|
+
event: "done";
|
|
232
|
+
data: "this stream has ended";
|
|
233
|
+
|
|
234
|
+
/// ping event ///
|
|
235
|
+
event: "ping";
|
|
236
|
+
data: "";
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
##### Example Usage:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
// procedures/users/watchUser.rpc.ts
|
|
243
|
+
export default defineEventStreamRpc({
|
|
244
|
+
params: a.object({
|
|
245
|
+
userId: a.string(),
|
|
246
|
+
}),
|
|
247
|
+
response: a.object({
|
|
248
|
+
id: a.string(),
|
|
249
|
+
name: a.string(),
|
|
250
|
+
createdAt: a.timestamp(),
|
|
251
|
+
updatedAt: a.timestamp(),
|
|
252
|
+
}),
|
|
253
|
+
handler({ params, connection }) {
|
|
254
|
+
// send a message every second
|
|
255
|
+
const interval = setInterval(async () => {
|
|
256
|
+
await connection.push({
|
|
257
|
+
id: "1",
|
|
258
|
+
name: "John Doe",
|
|
259
|
+
createdAt: new Date(),
|
|
260
|
+
updatedAt: new Date(),
|
|
261
|
+
});
|
|
262
|
+
}, 1000);
|
|
263
|
+
// cleanup when the client disconnects
|
|
264
|
+
connection.on("disconnect", () => {
|
|
265
|
+
clearInterval(interval);
|
|
266
|
+
});
|
|
267
|
+
// start streaming events to the client
|
|
268
|
+
connection.start();
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### EventStreamConnection methods
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
connection.push(data: Data, eventId?: string)
|
|
277
|
+
connection.pushError(error: ArriRequestError, eventId?: string)
|
|
278
|
+
connection.start()
|
|
279
|
+
connection.end()
|
|
280
|
+
connection.on(e: 'disconnect' | 'end', callback: () => any)
|
|
281
|
+
```
|
|
282
|
+
|
|
211
283
|
### Adding Non-RPC Routes
|
|
212
284
|
|
|
213
285
|
You can also add generic endpoints for instances when a message-based RPC endpoint doesn't fit.
|
package/dist/cli.cjs
CHANGED
|
@@ -12,7 +12,7 @@ const esbuild = require('esbuild');
|
|
|
12
12
|
const esbuildPluginReplace = require('esbuild-plugin-replace');
|
|
13
13
|
const path = require('pathe');
|
|
14
14
|
const prettier = require('prettier');
|
|
15
|
-
const config = require('./shared/arri.
|
|
15
|
+
const config = require('./shared/arri.beaf548c.cjs');
|
|
16
16
|
const globby = require('globby');
|
|
17
17
|
const scule = require('scule');
|
|
18
18
|
const arriCodegenDart = require('arri-codegen-dart');
|
|
@@ -93,11 +93,7 @@ async function createAppWithRoutesModule(config) {
|
|
|
93
93
|
for(const route of routes) {
|
|
94
94
|
app.rpc({
|
|
95
95
|
name: route.id,
|
|
96
|
-
|
|
97
|
-
params: route.route.params,
|
|
98
|
-
response: route.route.response,
|
|
99
|
-
handler: route.route.handler,
|
|
100
|
-
postHandler: route.route.postHandler,
|
|
96
|
+
...route.route,
|
|
101
97
|
});
|
|
102
98
|
}
|
|
103
99
|
export default app`,
|
|
@@ -306,6 +302,12 @@ const require = topLevelCreateRequire(import.meta.url);`
|
|
|
306
302
|
const appModule = path__default.resolve(config.rootDir, config.srcDir, config.entry);
|
|
307
303
|
const appImportParts = path__default.relative(path__default.resolve(config.rootDir, config.srcDir), appModule).split(".");
|
|
308
304
|
appImportParts.pop();
|
|
305
|
+
let httpsString = ``;
|
|
306
|
+
if (config.https === true) {
|
|
307
|
+
httpsString = `https: true,`;
|
|
308
|
+
} else if (typeof config.https === "object") {
|
|
309
|
+
httpsString = `https: { cert: '${config.https.cert}', key: '${config.https.key}', passphrase: ${config.https.passphrase ? `'${config.https.passphrase}'` : "undefined"}},`;
|
|
310
|
+
}
|
|
309
311
|
const virtualEntry = `import { toNodeListener } from 'arri';
|
|
310
312
|
import { listen } from 'listhen';
|
|
311
313
|
import app from './${OUT_APP_FILE}';
|
|
@@ -313,6 +315,7 @@ import app from './${OUT_APP_FILE}';
|
|
|
313
315
|
void listen(toNodeListener(app.h3App), {
|
|
314
316
|
port: process.env.PORT ?? ${config.port},
|
|
315
317
|
public: true,
|
|
318
|
+
${httpsString}
|
|
316
319
|
});`;
|
|
317
320
|
await fs__default.writeFile(
|
|
318
321
|
path__default.resolve(config.rootDir, ".output", GEN_SERVER_ENTRY_FILE),
|
|
@@ -444,7 +447,8 @@ const startListener = (config, showQr = false) => listhen.listenAndWatch(path__d
|
|
|
444
447
|
public: true,
|
|
445
448
|
port: config.port,
|
|
446
449
|
logger: logger$1,
|
|
447
|
-
qr: showQr
|
|
450
|
+
qr: showQr,
|
|
451
|
+
https: config.https
|
|
448
452
|
});
|
|
449
453
|
async function bundleFilesContext(config) {
|
|
450
454
|
const serverContent = `import app from './${OUT_APP_FILE}';
|
|
@@ -540,8 +544,12 @@ async function startDevServer(config) {
|
|
|
540
544
|
}
|
|
541
545
|
async function generateClients(config$1) {
|
|
542
546
|
try {
|
|
547
|
+
const protocol = config$1.https === true || typeof config$1.https === "object" ? "https" : "http";
|
|
548
|
+
if (protocol === "https") {
|
|
549
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
550
|
+
}
|
|
543
551
|
const result = await ofetch.ofetch(
|
|
544
|
-
|
|
552
|
+
`${protocol}://127.0.0.1:${config$1.port}${config.DEV_DEFINITION_ENDPOINT}`
|
|
545
553
|
);
|
|
546
554
|
if (!arriCodegenUtils.isAppDefinition(result)) {
|
|
547
555
|
return;
|
package/dist/cli.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { build as build$1 } from 'esbuild';
|
|
|
11
11
|
import { replace } from 'esbuild-plugin-replace';
|
|
12
12
|
import path from 'pathe';
|
|
13
13
|
import prettier from 'prettier';
|
|
14
|
-
import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.
|
|
14
|
+
import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.ff70fe08.mjs';
|
|
15
15
|
import { globby } from 'globby';
|
|
16
16
|
import { camelCase, kebabCase } from 'scule';
|
|
17
17
|
import { dartClientGenerator } from 'arri-codegen-dart';
|
|
@@ -69,11 +69,7 @@ async function createAppWithRoutesModule(config) {
|
|
|
69
69
|
for(const route of routes) {
|
|
70
70
|
app.rpc({
|
|
71
71
|
name: route.id,
|
|
72
|
-
|
|
73
|
-
params: route.route.params,
|
|
74
|
-
response: route.route.response,
|
|
75
|
-
handler: route.route.handler,
|
|
76
|
-
postHandler: route.route.postHandler,
|
|
72
|
+
...route.route,
|
|
77
73
|
});
|
|
78
74
|
}
|
|
79
75
|
export default app`,
|
|
@@ -282,6 +278,12 @@ const require = topLevelCreateRequire(import.meta.url);`
|
|
|
282
278
|
const appModule = path.resolve(config.rootDir, config.srcDir, config.entry);
|
|
283
279
|
const appImportParts = path.relative(path.resolve(config.rootDir, config.srcDir), appModule).split(".");
|
|
284
280
|
appImportParts.pop();
|
|
281
|
+
let httpsString = ``;
|
|
282
|
+
if (config.https === true) {
|
|
283
|
+
httpsString = `https: true,`;
|
|
284
|
+
} else if (typeof config.https === "object") {
|
|
285
|
+
httpsString = `https: { cert: '${config.https.cert}', key: '${config.https.key}', passphrase: ${config.https.passphrase ? `'${config.https.passphrase}'` : "undefined"}},`;
|
|
286
|
+
}
|
|
285
287
|
const virtualEntry = `import { toNodeListener } from 'arri';
|
|
286
288
|
import { listen } from 'listhen';
|
|
287
289
|
import app from './${OUT_APP_FILE}';
|
|
@@ -289,6 +291,7 @@ import app from './${OUT_APP_FILE}';
|
|
|
289
291
|
void listen(toNodeListener(app.h3App), {
|
|
290
292
|
port: process.env.PORT ?? ${config.port},
|
|
291
293
|
public: true,
|
|
294
|
+
${httpsString}
|
|
292
295
|
});`;
|
|
293
296
|
await fs.writeFile(
|
|
294
297
|
path.resolve(config.rootDir, ".output", GEN_SERVER_ENTRY_FILE),
|
|
@@ -420,7 +423,8 @@ const startListener = (config, showQr = false) => listenAndWatch(path.resolve(co
|
|
|
420
423
|
public: true,
|
|
421
424
|
port: config.port,
|
|
422
425
|
logger: logger$1,
|
|
423
|
-
qr: showQr
|
|
426
|
+
qr: showQr,
|
|
427
|
+
https: config.https
|
|
424
428
|
});
|
|
425
429
|
async function bundleFilesContext(config) {
|
|
426
430
|
const serverContent = `import app from './${OUT_APP_FILE}';
|
|
@@ -516,8 +520,12 @@ async function startDevServer(config) {
|
|
|
516
520
|
}
|
|
517
521
|
async function generateClients(config) {
|
|
518
522
|
try {
|
|
523
|
+
const protocol = config.https === true || typeof config.https === "object" ? "https" : "http";
|
|
524
|
+
if (protocol === "https") {
|
|
525
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
526
|
+
}
|
|
519
527
|
const result = await ofetch(
|
|
520
|
-
|
|
528
|
+
`${protocol}://127.0.0.1:${config.port}${DEV_DEFINITION_ENDPOINT}`
|
|
521
529
|
);
|
|
522
530
|
if (!isAppDefinition(result)) {
|
|
523
531
|
return;
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const config = require('./shared/arri.
|
|
3
|
+
const config = require('./shared/arri.beaf548c.cjs');
|
|
4
4
|
const h3 = require('h3');
|
|
5
5
|
require('arri-validate');
|
|
6
6
|
require('arri-codegen-utils');
|
|
@@ -13,24 +13,32 @@ exports.ArriRouter = config.ArriRouter;
|
|
|
13
13
|
exports.DEV_DEFINITION_ENDPOINT = config.DEV_DEFINITION_ENDPOINT;
|
|
14
14
|
exports.DEV_ENDPOINT_ROOT = config.DEV_ENDPOINT_ROOT;
|
|
15
15
|
exports.ErrorResponse = config.ErrorResponse;
|
|
16
|
+
exports.EventStreamConnection = config.EventStreamConnection;
|
|
16
17
|
exports.createRpcDefinition = config.createRpcDefinition;
|
|
17
18
|
exports.defaultConfig = config.defaultConfig;
|
|
18
19
|
exports.defineConfig = config.defineConfig;
|
|
19
20
|
exports.defineError = config.defineError;
|
|
21
|
+
exports.defineEventStreamRpc = config.defineEventStreamRpc;
|
|
20
22
|
exports.defineRoute = config.defineRoute;
|
|
21
23
|
exports.defineRpc = config.defineRpc;
|
|
22
24
|
exports.errorResponseFromValidationErrors = config.errorResponseFromValidationErrors;
|
|
25
|
+
exports.formatSse = config.formatSse;
|
|
26
|
+
exports.formatSseList = config.formatSseList;
|
|
23
27
|
exports.getRpcParamName = config.getRpcParamName;
|
|
24
28
|
exports.getRpcPath = config.getRpcPath;
|
|
25
29
|
exports.getRpcResponseName = config.getRpcResponseName;
|
|
26
30
|
exports.handleH3Error = config.handleH3Error;
|
|
27
31
|
exports.handleRoute = config.handleRoute;
|
|
28
32
|
exports.isArriConfig = config.isArriConfig;
|
|
33
|
+
exports.isEventStreamRpc = config.isEventStreamRpc;
|
|
29
34
|
exports.isResolvedArriConfig = config.isResolvedArriConfig;
|
|
30
35
|
exports.isRpc = config.isRpc;
|
|
31
36
|
exports.isRpcParamSchema = config.isRpcParamSchema;
|
|
37
|
+
exports.registerEventStreamRpc = config.registerEventStreamRpc;
|
|
32
38
|
exports.registerRoute = config.registerRoute;
|
|
33
39
|
exports.registerRpc = config.registerRpc;
|
|
40
|
+
exports.setSseHeaders = config.setSseHeaders;
|
|
41
|
+
exports.validateRpcRequestInput = config.validateRpcRequestInput;
|
|
34
42
|
exports.defineMiddleware = defineMiddleware;
|
|
35
43
|
Object.keys(h3).forEach(function (k) {
|
|
36
44
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = h3[k];
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { HttpMethod, RpcHttpMethod, RpcDefinition, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
|
|
2
|
-
import { AObjectSchema, ASchema, InferType,
|
|
3
|
-
import { H3EventContext, H3Event, Router,
|
|
1
|
+
import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
|
|
2
|
+
import { AObjectSchema, ASchema, InferType, a, ValidationError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
|
|
3
|
+
import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
5
|
import { BuildOptions } from 'esbuild';
|
|
6
6
|
|
|
@@ -44,20 +44,103 @@ type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "
|
|
|
44
44
|
declare function registerRoute(router: Router, route: ArriRoute<any>, opts: RouteOptions): void;
|
|
45
45
|
declare function handleRoute(router: Router, method: HttpMethod, route: ArriRoute<any>, opts: RouteOptions): void;
|
|
46
46
|
|
|
47
|
+
declare const ErrorResponse: AObjectSchema<{
|
|
48
|
+
statusCode: number;
|
|
49
|
+
statusMessage: string;
|
|
50
|
+
stack?: string | undefined;
|
|
51
|
+
data?: any;
|
|
52
|
+
}, false>;
|
|
53
|
+
type ErrorResponse = a.infer<typeof ErrorResponse>;
|
|
54
|
+
declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ErrorResponse, "statusCode" | "stack">> & {
|
|
55
|
+
stack?: string;
|
|
56
|
+
}): H3Error;
|
|
57
|
+
declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
|
|
58
|
+
type StatusCode = number | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
59
|
+
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"]): Promise<void>;
|
|
60
|
+
|
|
61
|
+
declare function setSseHeaders(event: H3Event): void;
|
|
62
|
+
declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream">): EventStreamRpc<TParams, TResponse>;
|
|
63
|
+
declare function isEventStreamRpc(input: unknown): input is EventStreamRpc<any, any>;
|
|
64
|
+
interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<Rpc<true, TParams, TResponse>, "handler" | "postHandler"> {
|
|
65
|
+
isEventStream: true;
|
|
66
|
+
handler: EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
|
|
67
|
+
}
|
|
68
|
+
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event: EventStreamRpcEvent<TParams, TResponse>) => void | Promise<void>;
|
|
69
|
+
interface EventStreamRpcEvent<TParams, TResponse> extends RpcEvent<TParams> {
|
|
70
|
+
connection: EventStreamConnection<TResponse>;
|
|
71
|
+
}
|
|
72
|
+
interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends RpcHandlerContext<TParams> {
|
|
73
|
+
connection: EventStreamConnection<TResponse>;
|
|
74
|
+
}
|
|
75
|
+
interface EventStreamConnectionOptions<TData> {
|
|
76
|
+
serializer: (input: TData) => string;
|
|
77
|
+
pingInterval?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A server sent event
|
|
81
|
+
*/
|
|
82
|
+
interface Sse {
|
|
83
|
+
id?: string;
|
|
84
|
+
event?: string;
|
|
85
|
+
data: string;
|
|
86
|
+
}
|
|
87
|
+
declare function formatSse({ id, data, event }: Sse): string;
|
|
88
|
+
declare function formatSseList(events: Sse[]): string;
|
|
89
|
+
declare class EventStreamConnection<TData> {
|
|
90
|
+
lastEventId: string | undefined;
|
|
91
|
+
private readonly writable;
|
|
92
|
+
private readonly readable;
|
|
93
|
+
private readonly writer;
|
|
94
|
+
private readonly encoder;
|
|
95
|
+
private readonly serializer;
|
|
96
|
+
private readonly h3Event;
|
|
97
|
+
private pingInterval;
|
|
98
|
+
private readonly pingIntervalMs;
|
|
99
|
+
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
100
|
+
/**
|
|
101
|
+
* Start sending the event stream to the client
|
|
102
|
+
*/
|
|
103
|
+
start(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Publish a new event. Events published with this hook will trigger the `onData()` hooks of any connected clients.
|
|
106
|
+
*/
|
|
107
|
+
push(data: TData[], eventId?: string): Promise<void>;
|
|
108
|
+
push(data: TData, eventId?: string): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Publish an error event. This will trigger the `onError` hooks of any connected clients.
|
|
111
|
+
*/
|
|
112
|
+
pushError(error: ErrorResponse, eventId?: string): Promise<void>;
|
|
113
|
+
private publishEvents;
|
|
114
|
+
private publishEvent;
|
|
115
|
+
private cleanup;
|
|
116
|
+
/**
|
|
117
|
+
* Tell clients that the stream has ended and close the connection.
|
|
118
|
+
*/
|
|
119
|
+
end(): Promise<void>;
|
|
120
|
+
on(event: "disconnect", callback: () => any): void;
|
|
121
|
+
on(event: "end", callback: () => any): void;
|
|
122
|
+
}
|
|
123
|
+
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
124
|
+
name: string;
|
|
125
|
+
}, opts: RouteOptions): void;
|
|
126
|
+
|
|
47
127
|
type RpcParamSchema<TObjectInner = any, TRecordInner extends ASchema = any, TDiscriminatorInner = any> = AObjectSchema<TObjectInner> | ARecordSchema<TRecordInner> | ADiscriminatorSchema<TDiscriminatorInner>;
|
|
48
128
|
declare function isRpcParamSchema(input: unknown): input is RpcParamSchema;
|
|
49
|
-
interface
|
|
50
|
-
|
|
129
|
+
interface NamedRpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Rpc<TIsEventStream, TParams, TResponse> {
|
|
130
|
+
name: string;
|
|
131
|
+
}
|
|
132
|
+
interface Rpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> {
|
|
51
133
|
method?: RpcHttpMethod;
|
|
52
134
|
path?: string;
|
|
135
|
+
description?: string;
|
|
53
136
|
params: TParams;
|
|
54
137
|
response: TResponse;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
name: string;
|
|
138
|
+
isEventStream?: TIsEventStream;
|
|
139
|
+
pingInterval?: TIsEventStream extends true ? number : undefined;
|
|
140
|
+
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>;
|
|
141
|
+
postHandler?: TIsEventStream extends true ? undefined : RpcPostHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
|
|
60
142
|
}
|
|
143
|
+
type HttpRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined> = Omit<Rpc<false, TParams, TResponse>, "isEventStream">;
|
|
61
144
|
type HandlerContext = Record<string, any>;
|
|
62
145
|
interface RpcHandlerContext<TParams = undefined> extends HandlerContext, Omit<H3EventContext, "params"> {
|
|
63
146
|
rpcName: string;
|
|
@@ -72,31 +155,37 @@ interface RpcEvent<TParams = undefined> extends Omit<H3Event, "context"> {
|
|
|
72
155
|
interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<H3Event, "context"> {
|
|
73
156
|
context: RpcPostHandlerContext<TParams, TResponse>;
|
|
74
157
|
}
|
|
75
|
-
type
|
|
76
|
-
type
|
|
77
|
-
declare function isRpc(input:
|
|
78
|
-
declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config:
|
|
79
|
-
declare function createRpcDefinition(rpcName: string, httpPath: string, procedure:
|
|
158
|
+
type RpcHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
|
|
159
|
+
type RpcPostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
|
|
160
|
+
declare function isRpc(input: unknown): input is Rpc<any, any>;
|
|
161
|
+
declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: HttpRpc<TParams, TResponse>): Rpc<false, TParams, TResponse>;
|
|
162
|
+
declare function createRpcDefinition(rpcName: string, httpPath: string, procedure: Rpc<any, any, any>): RpcDefinition;
|
|
80
163
|
declare function getRpcPath(rpcName: string, prefix?: string): string;
|
|
81
|
-
declare function getRpcParamName(rpcName: string, procedure:
|
|
82
|
-
declare function getRpcResponseName(rpcName: string, procedure:
|
|
83
|
-
declare function registerRpc(router: Router, path: string, procedure:
|
|
164
|
+
declare function getRpcParamName(rpcName: string, procedure: Rpc<any, any, any>): string | undefined;
|
|
165
|
+
declare function getRpcResponseName(rpcName: string, procedure: Rpc<any, any, any>): string | undefined;
|
|
166
|
+
declare function registerRpc(router: Router, path: string, procedure: NamedRpc<any, any, any>, opts: RouteOptions): void;
|
|
167
|
+
declare function validateRpcRequestInput(event: H3Event, httpMethod: RpcHttpMethod, schema: ASchema): Promise<void>;
|
|
84
168
|
|
|
85
169
|
interface ArriRouterBase {
|
|
86
|
-
rpc: <TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure:
|
|
170
|
+
rpc: <TIsEventStream extends boolean, TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>) => void;
|
|
87
171
|
route: <TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>) => void;
|
|
172
|
+
registerModels: (models: ModelMap) => void;
|
|
88
173
|
}
|
|
89
174
|
declare class ArriRouter implements ArriRouterBase {
|
|
90
175
|
private readonly procedures;
|
|
91
176
|
private readonly routes;
|
|
92
|
-
|
|
177
|
+
private readonly models;
|
|
178
|
+
rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>): void;
|
|
93
179
|
route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
|
|
94
|
-
|
|
180
|
+
registerModels(models: ModelMap): void;
|
|
181
|
+
getProcedures(): NamedRpc<any, any, any>[];
|
|
95
182
|
getRoutes(): ArriRoute<any, any, any, any>[];
|
|
183
|
+
getModels(): ModelMap;
|
|
96
184
|
}
|
|
97
185
|
|
|
98
186
|
declare const DEV_ENDPOINT_ROOT = "/__arri_dev__";
|
|
99
187
|
declare const DEV_DEFINITION_ENDPOINT = "/__arri_dev__/__definition";
|
|
188
|
+
type ModelMap = Record<string, SchemaFormProperties | SchemaFormDiscriminator | SchemaFormValues>;
|
|
100
189
|
declare class ArriApp implements ArriRouterBase {
|
|
101
190
|
__isArri__: boolean;
|
|
102
191
|
readonly h3App: App;
|
|
@@ -113,8 +202,9 @@ declare class ArriApp implements ArriRouterBase {
|
|
|
113
202
|
private readonly onError;
|
|
114
203
|
constructor(opts?: ArriOptions);
|
|
115
204
|
use(input: Middleware | ArriRouter): void;
|
|
116
|
-
rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure:
|
|
205
|
+
rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>): void;
|
|
117
206
|
route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
|
|
207
|
+
registerModels(models: ModelMap): void;
|
|
118
208
|
getAppDefinition(): AppDefinition;
|
|
119
209
|
}
|
|
120
210
|
interface ArriOptions {
|
|
@@ -135,20 +225,6 @@ interface ArriOptions {
|
|
|
135
225
|
onError?: (error: H3Error, event: MiddlewareEvent) => void | Promise<void>;
|
|
136
226
|
}
|
|
137
227
|
|
|
138
|
-
declare const ErrorResponse: AObjectSchema<{
|
|
139
|
-
statusCode: number;
|
|
140
|
-
statusMessage: string;
|
|
141
|
-
stack?: string | undefined;
|
|
142
|
-
data?: any;
|
|
143
|
-
}, false>;
|
|
144
|
-
type ErrorResponse = a.infer<typeof ErrorResponse>;
|
|
145
|
-
declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ErrorResponse, "statusCode" | "stack">> & {
|
|
146
|
-
stack?: string;
|
|
147
|
-
}): H3Error;
|
|
148
|
-
declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
|
|
149
|
-
type StatusCode = number | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
150
|
-
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"]): Promise<void>;
|
|
151
|
-
|
|
152
228
|
interface ArriConfig {
|
|
153
229
|
port: number;
|
|
154
230
|
entry: string;
|
|
@@ -163,6 +239,11 @@ interface ArriConfig {
|
|
|
163
239
|
clientGenerators?: Array<ClientGenerator<any>>;
|
|
164
240
|
buildDir?: string;
|
|
165
241
|
esbuild?: Omit<BuildOptions, "outfile" | "outdir" | "entryNames" | "entryPoints">;
|
|
242
|
+
https?: {
|
|
243
|
+
cert: string;
|
|
244
|
+
key: string;
|
|
245
|
+
passphrase?: string;
|
|
246
|
+
} | boolean;
|
|
166
247
|
}
|
|
167
248
|
declare function isArriConfig(input: unknown): input is ArriConfig;
|
|
168
249
|
declare function isResolvedArriConfig(input: unknown): input is ResolvedArriConfig;
|
|
@@ -170,4 +251,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
|
|
|
170
251
|
declare const defaultConfig: Required<ArriConfig>;
|
|
171
252
|
declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
|
|
172
253
|
|
|
173
|
-
export { ArriApp, type ArriConfig, type
|
|
254
|
+
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcEvent, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HandlerContext, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ModelMap, type NamedRpc, type PostRouteEvent, type PostRouteEventContext, type ResolvedArriConfig, type RouteEvent, type RouteEventContext, type RouteOptions, type Rpc, type RpcEvent, type RpcHandler, type RpcHandlerContext, type RpcParamSchema, type RpcPostEvent, type RpcPostHandler, type RpcPostHandlerContext, type Sse, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, errorResponseFromValidationErrors, formatSse, formatSseList, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isEventStreamRpc, isResolvedArriConfig, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, setSseHeaders, validateRpcRequestInput };
|