arri 0.1.0-beta.0 → 0.1.0-beta.11
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 +161 -5
- package/dist/cli.cjs +15 -14
- package/dist/cli.mjs +15 -14
- package/dist/index.cjs +4 -1
- package/dist/index.d.cts +49 -24
- package/dist/index.d.mts +49 -24
- package/dist/index.d.ts +49 -24
- package/dist/index.mjs +1 -1
- package/dist/shared/{arri.8539c7bd.mjs → arri.121d68e9.mjs} +80 -24
- package/dist/shared/{arri.406d936a.cjs → arri.ed4bd5e1.cjs} +81 -22
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,11 +1,167 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Arri RPC
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Installation
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
```bash
|
|
6
|
+
# npm
|
|
7
|
+
npm install arri arri-validate
|
|
8
|
+
|
|
9
|
+
# pnpm
|
|
10
|
+
pnpm install arri arri-validate
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Setup Example
|
|
14
|
+
|
|
15
|
+
Create an `arri.config.ts` in the project directory
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// arri.config.ts
|
|
19
|
+
import { defineConfig } from "arri";
|
|
20
|
+
import {
|
|
21
|
+
typescriptClientGenerator,
|
|
22
|
+
dartClientGenerator,
|
|
23
|
+
} from "arri/dist/codegen";
|
|
24
|
+
|
|
25
|
+
export default defineConfig({
|
|
26
|
+
entry: "app.ts",
|
|
27
|
+
port: 3000,
|
|
28
|
+
srcDir: "src",
|
|
29
|
+
clientGenerators: [
|
|
30
|
+
typescriptClientGenerator({
|
|
31
|
+
// options
|
|
32
|
+
}),
|
|
33
|
+
dartClientGenerator({
|
|
34
|
+
// options
|
|
35
|
+
}),
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Create an `app.ts` file in the source directory
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// ./src/app.ts
|
|
44
|
+
import { ArriApp } from "arri";
|
|
45
|
+
import { a } from "arri-validate";
|
|
46
|
+
|
|
47
|
+
const app = new ArriApp();
|
|
48
|
+
|
|
49
|
+
app.rpc("sayHello", {
|
|
50
|
+
params: a.object({
|
|
51
|
+
name: a.string(),
|
|
52
|
+
}),
|
|
53
|
+
response: a.object({
|
|
54
|
+
message: a.string(),
|
|
55
|
+
}),
|
|
56
|
+
handler({ params }) {
|
|
57
|
+
return {
|
|
58
|
+
message: `Hello ${params.name}`,
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export default app;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Setup your npm scripts:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"scripts": {
|
|
71
|
+
"dev": "arri dev",
|
|
72
|
+
"build": "arri build"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Start the dev server:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm run dev
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## File Based Routing
|
|
84
|
+
|
|
85
|
+
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.
|
|
86
|
+
|
|
87
|
+
```fs
|
|
88
|
+
|-- src
|
|
89
|
+
|-- procedures
|
|
90
|
+
|-- sayHello.rpc.ts // becomes sayHello()
|
|
91
|
+
|-- users
|
|
92
|
+
|-- getUser.rpc.ts // becomes users.getUser()
|
|
93
|
+
|-- updateUser.rpc.ts // becomes users.updateUser()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Example `.rpc.ts` file
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
// ./src/users/getUser.rpc.ts
|
|
100
|
+
import { defineRpc } from "arri";
|
|
101
|
+
import { a } from "arri-validate";
|
|
102
|
+
|
|
103
|
+
export default defineRpc({
|
|
104
|
+
params: a.object({
|
|
105
|
+
userId: a.string(),
|
|
106
|
+
}),
|
|
107
|
+
response: a.object({
|
|
108
|
+
id: a.string(),
|
|
109
|
+
name: a.string(),
|
|
110
|
+
createdAt: a.timestamp(),
|
|
111
|
+
}),
|
|
112
|
+
handler({ params }) {
|
|
113
|
+
// function body
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Customizing the File Based Router
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
export default defineConfig({
|
|
122
|
+
// rest of config
|
|
123
|
+
procedureDir: "procedures", // change which directory to look for procedures (This is relative to the srcDir)
|
|
124
|
+
procedureGlobPatterns: ["**/*.rpc.ts"], // change the file name glob pattern for finding rpcs
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Adding Non-RPC Endpoints
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
app.route({
|
|
132
|
+
method: "get",
|
|
133
|
+
path: "/hello-world",
|
|
134
|
+
handler(event) {
|
|
135
|
+
return "hello world";
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Creating sub routers
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { ArriApp, ArriRouter } from "arri";
|
|
144
|
+
|
|
145
|
+
const app = new ArriApp();
|
|
146
|
+
const router = new ArriRouter();
|
|
147
|
+
|
|
148
|
+
router.rpc({
|
|
149
|
+
// rpc config
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
router.route({
|
|
153
|
+
// route config
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
app.use(router);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Developing
|
|
160
|
+
|
|
161
|
+
### Building
|
|
6
162
|
|
|
7
163
|
Run `nx build arri-rpc` to build the library.
|
|
8
164
|
|
|
9
|
-
|
|
165
|
+
### Running unit tests
|
|
10
166
|
|
|
11
|
-
Run `nx test arri-rpc` to execute the unit tests via
|
|
167
|
+
Run `nx test arri-rpc` to execute the unit tests via Vitest.
|
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.
|
|
14
|
+
const config = require('./shared/arri.ed4bd5e1.cjs');
|
|
15
15
|
const globby = require('globby');
|
|
16
16
|
const scule = require('scule');
|
|
17
17
|
const arriCodegenDart = require('arri-codegen-dart');
|
|
@@ -142,12 +142,12 @@ const getRpcMetaFromPath = (config, filePath) => {
|
|
|
142
142
|
httpPath: `/${httpParts.join("/")}`
|
|
143
143
|
};
|
|
144
144
|
};
|
|
145
|
-
async function
|
|
145
|
+
async function transpileFiles(config) {
|
|
146
146
|
const outDir = path__default.resolve(config.rootDir, config.buildDir);
|
|
147
147
|
const files = await globby.globby(["**/*.ts"], {
|
|
148
148
|
cwd: path__default.resolve(config.rootDir, config.srcDir)
|
|
149
149
|
});
|
|
150
|
-
|
|
150
|
+
await esbuild__namespace.build({
|
|
151
151
|
entryPoints: [
|
|
152
152
|
...files.map(
|
|
153
153
|
(file) => path__default.resolve(config.rootDir, config.srcDir, file)
|
|
@@ -159,7 +159,6 @@ async function transpileFilesContext(config) {
|
|
|
159
159
|
target: "node18",
|
|
160
160
|
platform: "node"
|
|
161
161
|
});
|
|
162
|
-
return ctx;
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
const build = citty.defineCommand({
|
|
@@ -195,8 +194,7 @@ async function startBuild(config, skipCodeGen = false) {
|
|
|
195
194
|
createBuildEntryModule(config),
|
|
196
195
|
createBuildCodegenModule(config)
|
|
197
196
|
]);
|
|
198
|
-
|
|
199
|
-
await transpile.rebuild();
|
|
197
|
+
await transpileFiles(config);
|
|
200
198
|
await bundleFiles(config);
|
|
201
199
|
logger$1.log("Finished bundling");
|
|
202
200
|
const clientCount = config.clientGenerators.length;
|
|
@@ -224,7 +222,6 @@ async function startBuild(config, skipCodeGen = false) {
|
|
|
224
222
|
logger$1.log(
|
|
225
223
|
`Build finished! You can start your server by running "node .output/server.js"`
|
|
226
224
|
);
|
|
227
|
-
await transpile.dispose();
|
|
228
225
|
}
|
|
229
226
|
async function bundleFiles(config, allowCodegen = true) {
|
|
230
227
|
if (allowCodegen) {
|
|
@@ -263,6 +260,7 @@ async function bundleFiles(config, allowCodegen = true) {
|
|
|
263
260
|
js: `import { createRequire as topLevelCreateRequire } from 'module';
|
|
264
261
|
const require = topLevelCreateRequire(import.meta.url);`
|
|
265
262
|
},
|
|
263
|
+
allowOverwrite: true,
|
|
266
264
|
outdir: path__default.resolve(config.rootDir, ".output")
|
|
267
265
|
});
|
|
268
266
|
}
|
|
@@ -309,6 +307,7 @@ async function createBuildCodegenModule(config) {
|
|
|
309
307
|
app.rpc({
|
|
310
308
|
name: route.id,
|
|
311
309
|
method: route.route.method,
|
|
310
|
+
path: route.route.path,
|
|
312
311
|
params: route.route.params,
|
|
313
312
|
response: route.route.response,
|
|
314
313
|
handler: route.route.handler,
|
|
@@ -427,7 +426,7 @@ const dev = citty.defineCommand({
|
|
|
427
426
|
await startDevServer(config$1);
|
|
428
427
|
}
|
|
429
428
|
});
|
|
430
|
-
const startListener = (config, showQr = false) => listhen.listenAndWatch(path__default.resolve(config.rootDir, ".output", "
|
|
429
|
+
const startListener = (config, showQr = false) => listhen.listenAndWatch(path__default.resolve(config.rootDir, ".output", "server.js"), {
|
|
431
430
|
public: true,
|
|
432
431
|
port: config.port,
|
|
433
432
|
logger,
|
|
@@ -439,7 +438,7 @@ async function bundleFilesContext(config) {
|
|
|
439
438
|
entryPoints: [
|
|
440
439
|
path__default.resolve(config.rootDir, config.buildDir, "entry.js")
|
|
441
440
|
],
|
|
442
|
-
outfile: path__default.resolve(config.rootDir, ".output", "
|
|
441
|
+
outfile: path__default.resolve(config.rootDir, ".output", "server.js"),
|
|
443
442
|
format: "esm",
|
|
444
443
|
bundle: true,
|
|
445
444
|
sourcemap: true,
|
|
@@ -452,9 +451,8 @@ async function startDevServer(config) {
|
|
|
452
451
|
await setupWorkingDir(config);
|
|
453
452
|
let fileWatcher;
|
|
454
453
|
await Promise.all([createRoutesModule(config), createEntryModule(config)]);
|
|
455
|
-
|
|
454
|
+
await transpileFiles(config);
|
|
456
455
|
const bundleFiles = await bundleFilesContext(config);
|
|
457
|
-
await transpileFiles.rebuild();
|
|
458
456
|
await bundleFiles.rebuild();
|
|
459
457
|
const listener = await startListener(config, true);
|
|
460
458
|
setTimeout(async () => {
|
|
@@ -467,7 +465,6 @@ async function startDevServer(config) {
|
|
|
467
465
|
await Promise.allSettled([
|
|
468
466
|
listener.close(),
|
|
469
467
|
fileWatcher?.close(),
|
|
470
|
-
transpileFiles.dispose(),
|
|
471
468
|
bundleFiles.dispose()
|
|
472
469
|
]);
|
|
473
470
|
});
|
|
@@ -488,14 +485,17 @@ async function startDevServer(config) {
|
|
|
488
485
|
ignored: [buildDir, outDir],
|
|
489
486
|
ignoreInitial: true
|
|
490
487
|
});
|
|
491
|
-
fileWatcher.on("all", async (
|
|
488
|
+
fileWatcher.on("all", async (event, file) => {
|
|
489
|
+
if (event === "add" || event === "addDir") {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
492
|
await createRoutesModule(config);
|
|
493
493
|
let bundleCreated = false;
|
|
494
494
|
try {
|
|
495
495
|
logger.log(
|
|
496
496
|
"Change detected. Bundling files and restarting server...."
|
|
497
497
|
);
|
|
498
|
-
await transpileFiles
|
|
498
|
+
await transpileFiles(config);
|
|
499
499
|
await bundleFiles.rebuild();
|
|
500
500
|
bundleCreated = true;
|
|
501
501
|
} catch (err) {
|
|
@@ -549,6 +549,7 @@ for (const route of routes) {
|
|
|
549
549
|
app.rpc({
|
|
550
550
|
name: route.id,
|
|
551
551
|
method: route.route.method,
|
|
552
|
+
path: route.route.path,
|
|
552
553
|
params: route.route.params,
|
|
553
554
|
response: route.route.response,
|
|
554
555
|
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.
|
|
13
|
+
import { m as defaultConfig, l as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.121d68e9.mjs';
|
|
14
14
|
import { globby } from 'globby';
|
|
15
15
|
import { camelCase, kebabCase } from 'scule';
|
|
16
16
|
import { dartClientGenerator } from 'arri-codegen-dart';
|
|
@@ -121,12 +121,12 @@ const getRpcMetaFromPath = (config, filePath) => {
|
|
|
121
121
|
httpPath: `/${httpParts.join("/")}`
|
|
122
122
|
};
|
|
123
123
|
};
|
|
124
|
-
async function
|
|
124
|
+
async function transpileFiles(config) {
|
|
125
125
|
const outDir = path.resolve(config.rootDir, config.buildDir);
|
|
126
126
|
const files = await globby(["**/*.ts"], {
|
|
127
127
|
cwd: path.resolve(config.rootDir, config.srcDir)
|
|
128
128
|
});
|
|
129
|
-
|
|
129
|
+
await esbuild.build({
|
|
130
130
|
entryPoints: [
|
|
131
131
|
...files.map(
|
|
132
132
|
(file) => path.resolve(config.rootDir, config.srcDir, file)
|
|
@@ -138,7 +138,6 @@ async function transpileFilesContext(config) {
|
|
|
138
138
|
target: "node18",
|
|
139
139
|
platform: "node"
|
|
140
140
|
});
|
|
141
|
-
return ctx;
|
|
142
141
|
}
|
|
143
142
|
|
|
144
143
|
const build = defineCommand({
|
|
@@ -174,8 +173,7 @@ async function startBuild(config, skipCodeGen = false) {
|
|
|
174
173
|
createBuildEntryModule(config),
|
|
175
174
|
createBuildCodegenModule(config)
|
|
176
175
|
]);
|
|
177
|
-
|
|
178
|
-
await transpile.rebuild();
|
|
176
|
+
await transpileFiles(config);
|
|
179
177
|
await bundleFiles(config);
|
|
180
178
|
logger$1.log("Finished bundling");
|
|
181
179
|
const clientCount = config.clientGenerators.length;
|
|
@@ -203,7 +201,6 @@ async function startBuild(config, skipCodeGen = false) {
|
|
|
203
201
|
logger$1.log(
|
|
204
202
|
`Build finished! You can start your server by running "node .output/server.js"`
|
|
205
203
|
);
|
|
206
|
-
await transpile.dispose();
|
|
207
204
|
}
|
|
208
205
|
async function bundleFiles(config, allowCodegen = true) {
|
|
209
206
|
if (allowCodegen) {
|
|
@@ -242,6 +239,7 @@ async function bundleFiles(config, allowCodegen = true) {
|
|
|
242
239
|
js: `import { createRequire as topLevelCreateRequire } from 'module';
|
|
243
240
|
const require = topLevelCreateRequire(import.meta.url);`
|
|
244
241
|
},
|
|
242
|
+
allowOverwrite: true,
|
|
245
243
|
outdir: path.resolve(config.rootDir, ".output")
|
|
246
244
|
});
|
|
247
245
|
}
|
|
@@ -288,6 +286,7 @@ async function createBuildCodegenModule(config) {
|
|
|
288
286
|
app.rpc({
|
|
289
287
|
name: route.id,
|
|
290
288
|
method: route.route.method,
|
|
289
|
+
path: route.route.path,
|
|
291
290
|
params: route.route.params,
|
|
292
291
|
response: route.route.response,
|
|
293
292
|
handler: route.route.handler,
|
|
@@ -406,7 +405,7 @@ const dev = defineCommand({
|
|
|
406
405
|
await startDevServer(config);
|
|
407
406
|
}
|
|
408
407
|
});
|
|
409
|
-
const startListener = (config, showQr = false) => listenAndWatch(path.resolve(config.rootDir, ".output", "
|
|
408
|
+
const startListener = (config, showQr = false) => listenAndWatch(path.resolve(config.rootDir, ".output", "server.js"), {
|
|
410
409
|
public: true,
|
|
411
410
|
port: config.port,
|
|
412
411
|
logger,
|
|
@@ -418,7 +417,7 @@ async function bundleFilesContext(config) {
|
|
|
418
417
|
entryPoints: [
|
|
419
418
|
path.resolve(config.rootDir, config.buildDir, "entry.js")
|
|
420
419
|
],
|
|
421
|
-
outfile: path.resolve(config.rootDir, ".output", "
|
|
420
|
+
outfile: path.resolve(config.rootDir, ".output", "server.js"),
|
|
422
421
|
format: "esm",
|
|
423
422
|
bundle: true,
|
|
424
423
|
sourcemap: true,
|
|
@@ -431,9 +430,8 @@ async function startDevServer(config) {
|
|
|
431
430
|
await setupWorkingDir(config);
|
|
432
431
|
let fileWatcher;
|
|
433
432
|
await Promise.all([createRoutesModule(config), createEntryModule(config)]);
|
|
434
|
-
|
|
433
|
+
await transpileFiles(config);
|
|
435
434
|
const bundleFiles = await bundleFilesContext(config);
|
|
436
|
-
await transpileFiles.rebuild();
|
|
437
435
|
await bundleFiles.rebuild();
|
|
438
436
|
const listener = await startListener(config, true);
|
|
439
437
|
setTimeout(async () => {
|
|
@@ -446,7 +444,6 @@ async function startDevServer(config) {
|
|
|
446
444
|
await Promise.allSettled([
|
|
447
445
|
listener.close(),
|
|
448
446
|
fileWatcher?.close(),
|
|
449
|
-
transpileFiles.dispose(),
|
|
450
447
|
bundleFiles.dispose()
|
|
451
448
|
]);
|
|
452
449
|
});
|
|
@@ -467,14 +464,17 @@ async function startDevServer(config) {
|
|
|
467
464
|
ignored: [buildDir, outDir],
|
|
468
465
|
ignoreInitial: true
|
|
469
466
|
});
|
|
470
|
-
fileWatcher.on("all", async (
|
|
467
|
+
fileWatcher.on("all", async (event, file) => {
|
|
468
|
+
if (event === "add" || event === "addDir") {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
471
|
await createRoutesModule(config);
|
|
472
472
|
let bundleCreated = false;
|
|
473
473
|
try {
|
|
474
474
|
logger.log(
|
|
475
475
|
"Change detected. Bundling files and restarting server...."
|
|
476
476
|
);
|
|
477
|
-
await transpileFiles
|
|
477
|
+
await transpileFiles(config);
|
|
478
478
|
await bundleFiles.rebuild();
|
|
479
479
|
bundleCreated = true;
|
|
480
480
|
} catch (err) {
|
|
@@ -528,6 +528,7 @@ for (const route of routes) {
|
|
|
528
528
|
app.rpc({
|
|
529
529
|
name: route.id,
|
|
530
530
|
method: route.route.method,
|
|
531
|
+
path: route.route.path,
|
|
531
532
|
params: route.route.params,
|
|
532
533
|
response: route.route.response,
|
|
533
534
|
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.
|
|
3
|
+
const config = require('./shared/arri.ed4bd5e1.cjs');
|
|
4
4
|
const h3 = require('h3');
|
|
5
5
|
require('arri-validate');
|
|
6
6
|
require('arri-codegen-utils');
|
|
@@ -17,15 +17,18 @@ exports.createRpcDefinition = config.createRpcDefinition;
|
|
|
17
17
|
exports.defaultConfig = config.defaultConfig;
|
|
18
18
|
exports.defineConfig = config.defineConfig;
|
|
19
19
|
exports.defineError = config.defineError;
|
|
20
|
+
exports.defineRoute = config.defineRoute;
|
|
20
21
|
exports.defineRpc = config.defineRpc;
|
|
21
22
|
exports.errorResponseFromValidationErrors = config.errorResponseFromValidationErrors;
|
|
22
23
|
exports.getRpcParamName = config.getRpcParamName;
|
|
23
24
|
exports.getRpcPath = config.getRpcPath;
|
|
24
25
|
exports.getRpcResponseName = config.getRpcResponseName;
|
|
25
26
|
exports.handleH3Error = config.handleH3Error;
|
|
27
|
+
exports.handleRoute = config.handleRoute;
|
|
26
28
|
exports.isArriConfig = config.isArriConfig;
|
|
27
29
|
exports.isResolvedArriConfig = config.isResolvedArriConfig;
|
|
28
30
|
exports.isRpc = config.isRpc;
|
|
31
|
+
exports.registerRoute = config.registerRoute;
|
|
29
32
|
exports.registerRpc = config.registerRpc;
|
|
30
33
|
exports.defineMiddleware = defineMiddleware;
|
|
31
34
|
Object.keys(h3).forEach(function (k) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,36 +1,54 @@
|
|
|
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 {
|
|
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
|
-
|
|
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
|
-
type ExtractParam$1<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
|
|
11
|
-
type ExtractParams$1<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam$1<Segment, ExtractParams$1<Rest>> : ExtractParam$1<Path, {}>;
|
|
12
|
-
|
|
13
16
|
type ExtractParam<Path, NextPart> = Path extends `:${infer Param}` ? Record<Param, string> & NextPart : NextPart;
|
|
14
17
|
type ExtractParams<Path> = Path extends `${infer Segment}/${infer Rest}` ? ExtractParam<Segment, ExtractParams<Rest>> : ExtractParam<Path, {}>;
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
interface RouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3EventContext {
|
|
16
20
|
params: ExtractParams<TPath>;
|
|
21
|
+
query: TQuery;
|
|
22
|
+
body: TBody;
|
|
17
23
|
}
|
|
18
|
-
interface RouteEvent<TPath extends string> extends H3Event {
|
|
19
|
-
context: RouteEventContext<TPath>;
|
|
24
|
+
interface RouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any> extends H3Event {
|
|
25
|
+
context: RouteEventContext<TPath, TQuery, TBody>;
|
|
20
26
|
}
|
|
21
|
-
interface
|
|
27
|
+
interface PostRouteEventContext<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends RouteEventContext<TPath, TQuery, TBody> {
|
|
28
|
+
response: TResponse;
|
|
29
|
+
}
|
|
30
|
+
interface PostRouteEvent<TPath extends string, TQuery extends Record<any, any> = any, TBody = any, TResponse = any> extends H3Event {
|
|
31
|
+
context: PostRouteEventContext<TPath, TQuery, TBody, TResponse>;
|
|
32
|
+
}
|
|
33
|
+
interface ArriRoute<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any> {
|
|
22
34
|
path: TPath;
|
|
23
35
|
method: HttpMethod | HttpMethod[];
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
query?: TQuery;
|
|
37
|
+
body?: TBody;
|
|
38
|
+
handler: (event: RouteEvent<TPath, InferType<TQuery>, InferType<TBody>>) => TResponse;
|
|
39
|
+
postHandler?: (event: PostRouteEvent<TPath, InferType<TQuery>, InferType<TBody>, Awaited<TResponse>>) => any;
|
|
26
40
|
}
|
|
41
|
+
declare function defineRoute<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends AObjectSchema<any, any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): ArriRoute<TPath, TQuery, TBody, TResponse>;
|
|
27
42
|
type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "onError" | "onRequest"> & {
|
|
28
43
|
middleware: Middleware[];
|
|
29
44
|
};
|
|
45
|
+
declare function registerRoute(router: Router, route: ArriRoute<any>, opts: RouteOptions): void;
|
|
46
|
+
declare function handleRoute(router: Router, method: HttpMethod, route: ArriRoute<any>, opts: RouteOptions): void;
|
|
30
47
|
|
|
31
48
|
interface ArriProcedure<TParams extends AObjectSchema | undefined, TResponse extends AObjectSchema | undefined> {
|
|
32
49
|
description?: string;
|
|
33
50
|
method?: HttpMethod;
|
|
51
|
+
path?: string;
|
|
34
52
|
params: TParams;
|
|
35
53
|
response: TResponse;
|
|
36
54
|
handler: ArriProcedureHandler<TParams extends AObjectSchema ? InferType<TParams> : undefined, TResponse extends AObjectSchema ? InferType<TResponse> : void>;
|
|
@@ -41,32 +59,39 @@ interface ArriNamedProcedure<TParams extends AObjectSchema | undefined, TRespons
|
|
|
41
59
|
}
|
|
42
60
|
type HandlerContext = Record<string, any>;
|
|
43
61
|
interface RpcHandlerContext<TParams = undefined> extends HandlerContext, Omit<H3EventContext, "params"> {
|
|
62
|
+
rpcName: string;
|
|
44
63
|
params: TParams;
|
|
45
64
|
}
|
|
46
65
|
interface RpcPostHandlerContext<TParams = undefined, TResponse = undefined> extends RpcHandlerContext<TParams> {
|
|
47
66
|
response: TResponse;
|
|
48
67
|
}
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
interface RpcEvent<TParams = undefined> extends Omit<H3Event, "context"> {
|
|
69
|
+
context: RpcHandlerContext<TParams>;
|
|
70
|
+
}
|
|
71
|
+
interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<H3Event, "context"> {
|
|
72
|
+
context: RpcPostHandlerContext<TParams, TResponse>;
|
|
73
|
+
}
|
|
74
|
+
type ArriProcedureHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
|
|
75
|
+
type ArriProcedurePostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
|
|
51
76
|
declare function isRpc(input: any): input is ArriProcedure<any, any>;
|
|
52
77
|
declare function defineRpc<TParams extends AObjectSchema | undefined = undefined, TResponse extends AObjectSchema | undefined | never = undefined>(config: ArriProcedure<TParams, TResponse>): ArriProcedure<TParams, TResponse>;
|
|
53
78
|
declare function createRpcDefinition(rpcName: string, httpPath: string, procedure: ArriProcedure<any, any>): RpcDefinition;
|
|
54
79
|
declare function getRpcPath(rpcName: string, prefix?: string): string;
|
|
55
80
|
declare function getRpcParamName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
|
|
56
81
|
declare function getRpcResponseName(rpcName: string, procedure: ArriProcedure<any, any>): string | undefined;
|
|
57
|
-
declare function registerRpc(router: Router, path: string, procedure:
|
|
82
|
+
declare function registerRpc(router: Router, path: string, procedure: ArriNamedProcedure<any, any>, opts: RouteOptions): void;
|
|
58
83
|
|
|
59
84
|
interface ArriRouterBase {
|
|
60
85
|
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;
|
|
86
|
+
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
87
|
}
|
|
63
88
|
declare class ArriRouter implements ArriRouterBase {
|
|
64
89
|
private readonly procedures;
|
|
65
90
|
private readonly routes;
|
|
66
91
|
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;
|
|
92
|
+
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
93
|
getProcedures(): ArriNamedProcedure<any, any>[];
|
|
69
|
-
getRoutes(): ArriRoute<any>[];
|
|
94
|
+
getRoutes(): ArriRoute<any, any, any, any>[];
|
|
70
95
|
}
|
|
71
96
|
|
|
72
97
|
declare const DEV_ENDPOINT_ROOT = "/__arri_dev__";
|
|
@@ -88,7 +113,7 @@ declare class ArriApp implements ArriRouterBase {
|
|
|
88
113
|
constructor(opts?: ArriOptions);
|
|
89
114
|
use(input: Middleware | ArriRouter): void;
|
|
90
115
|
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;
|
|
116
|
+
route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
|
|
92
117
|
getAppDefinition(): AppDefinition;
|
|
93
118
|
}
|
|
94
119
|
interface ArriOptions {
|
|
@@ -103,10 +128,10 @@ interface ArriOptions {
|
|
|
103
128
|
* This parameters also takes the rpcRoutePrefix option into account
|
|
104
129
|
*/
|
|
105
130
|
rpcDefinitionPath?: string;
|
|
106
|
-
onRequest?: (event:
|
|
107
|
-
onAfterResponse?: (event:
|
|
108
|
-
onBeforeResponse?: (event:
|
|
109
|
-
onError?: (error: H3Error, event:
|
|
131
|
+
onRequest?: (event: MiddlewareEvent) => void | Promise<void>;
|
|
132
|
+
onAfterResponse?: (event: MiddlewareEvent) => void | Promise<void>;
|
|
133
|
+
onBeforeResponse?: (event: MiddlewareEvent) => void | Promise<void>;
|
|
134
|
+
onError?: (error: H3Error, event: MiddlewareEvent) => void | Promise<void>;
|
|
110
135
|
}
|
|
111
136
|
|
|
112
137
|
declare const ErrorResponse: arri_validate.AObjectSchema<{
|
|
@@ -143,4 +168,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
|
|
|
143
168
|
declare const defaultConfig: Required<ArriConfig>;
|
|
144
169
|
declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
|
|
145
170
|
|
|
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
|
|
171
|
+
export { ArriApp, type ArriConfig, type ArriNamedProcedure, type ArriOptions, type ArriProcedure, type ArriProcedureHandler, type ArriProcedurePostHandler, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, type ExtractParam, type ExtractParams, type HandlerContext, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type PostRouteEvent, type PostRouteEventContext, type ResolvedArriConfig, type RouteEvent, type RouteEventContext, type RouteOptions, type RpcEvent, type RpcHandlerContext, type RpcPostEvent, type RpcPostHandlerContext, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineMiddleware, defineRoute, defineRpc, errorResponseFromValidationErrors, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isResolvedArriConfig, isRpc, registerRoute, registerRpc };
|