arri 0.1.0-beta.0 → 0.1.0-beta.10
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 +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/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 };
|
package/dist/index.d.mts
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 };
|
package/dist/index.d.ts
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 };
|
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.
|
|
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, p as defineRoute, d as defineRpc, h as errorResponseFromValidationErrors, b as getRpcParamName, g as getRpcPath, e as getRpcResponseName, j as handleH3Error, s as handleRoute, k as isArriConfig, l as isResolvedArriConfig, i as isRpc, q as registerRoute, r as registerRpc } from './shared/arri.121d68e9.mjs';
|
|
2
2
|
export * from 'h3';
|
|
3
3
|
import 'arri-validate';
|
|
4
4
|
import 'arri-codegen-utils';
|
|
@@ -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,15 @@ function getRpcResponseDefinition(rpcName, procedure) {
|
|
|
270
270
|
return name;
|
|
271
271
|
}
|
|
272
272
|
function registerRpc(router, path, procedure, opts) {
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
let responseValidator;
|
|
274
|
+
try {
|
|
275
|
+
responseValidator = procedure.response ? a.compile(procedure.response) : void 0;
|
|
276
|
+
} catch (err) {
|
|
277
|
+
console.error("ERROR COMPILING VALIDATOR", err);
|
|
278
|
+
}
|
|
275
279
|
const httpMethod = procedure.method ?? "post";
|
|
276
280
|
const handler = eventHandler(async (event) => {
|
|
281
|
+
event.context.rpcName = procedure.name;
|
|
277
282
|
if (isPreflightRequest(event)) {
|
|
278
283
|
return "ok";
|
|
279
284
|
}
|
|
@@ -286,7 +291,7 @@ function registerRpc(router, path, procedure, opts) {
|
|
|
286
291
|
await m(event);
|
|
287
292
|
}
|
|
288
293
|
}
|
|
289
|
-
if (isAObjectSchema(procedure.params)
|
|
294
|
+
if (isAObjectSchema(procedure.params)) {
|
|
290
295
|
switch (httpMethod) {
|
|
291
296
|
case "get":
|
|
292
297
|
case "head": {
|
|
@@ -326,7 +331,10 @@ function registerRpc(router, path, procedure, opts) {
|
|
|
326
331
|
statusMessage: `Invalid request body. Expected object. Got undefined.`
|
|
327
332
|
});
|
|
328
333
|
}
|
|
329
|
-
const parsedParams =
|
|
334
|
+
const parsedParams = a.safeParse(
|
|
335
|
+
procedure.params,
|
|
336
|
+
body
|
|
337
|
+
);
|
|
330
338
|
if (!parsedParams.success) {
|
|
331
339
|
const errorParts = [];
|
|
332
340
|
for (const err of parsedParams.error.errors) {
|
|
@@ -365,21 +373,8 @@ function registerRpc(router, path, procedure, opts) {
|
|
|
365
373
|
responseValidator?.serialize(response) ?? JSON.stringify(response)
|
|
366
374
|
);
|
|
367
375
|
} else {
|
|
368
|
-
|
|
369
|
-
|
|
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
|
-
);
|
|
376
|
+
setResponseHeader(event, "Content-Type", "application/json");
|
|
377
|
+
await send(event, `{}`);
|
|
383
378
|
}
|
|
384
379
|
if (opts.onAfterResponse) {
|
|
385
380
|
await opts.onAfterResponse(event);
|
|
@@ -440,6 +435,9 @@ class ArriRouter {
|
|
|
440
435
|
}
|
|
441
436
|
}
|
|
442
437
|
|
|
438
|
+
function defineRoute(route) {
|
|
439
|
+
return route;
|
|
440
|
+
}
|
|
443
441
|
function registerRoute(router, route, opts) {
|
|
444
442
|
if (typeof route.method === "string") {
|
|
445
443
|
handleRoute(router, route.method, route, opts);
|
|
@@ -451,6 +449,9 @@ function registerRoute(router, route, opts) {
|
|
|
451
449
|
}
|
|
452
450
|
function handleRoute(router, method, route, opts) {
|
|
453
451
|
const handler = defineEventHandler(async (event) => {
|
|
452
|
+
if (isPreflightRequest(event)) {
|
|
453
|
+
return "ok";
|
|
454
|
+
}
|
|
454
455
|
try {
|
|
455
456
|
if (opts.onRequest) {
|
|
456
457
|
await opts.onRequest(event);
|
|
@@ -460,6 +461,55 @@ function handleRoute(router, method, route, opts) {
|
|
|
460
461
|
await m(event);
|
|
461
462
|
}
|
|
462
463
|
}
|
|
464
|
+
if (route.query) {
|
|
465
|
+
const query = getQuery(event);
|
|
466
|
+
const parsedQuery = a.safeCoerce(route.query, query);
|
|
467
|
+
if (!parsedQuery.success) {
|
|
468
|
+
const errParts = [];
|
|
469
|
+
for (const err of parsedQuery.error.errors) {
|
|
470
|
+
const errPath = err.instancePath.split("/");
|
|
471
|
+
errPath.shift();
|
|
472
|
+
const propName = errPath.join(".");
|
|
473
|
+
if (!errParts.includes(propName)) {
|
|
474
|
+
errParts.push(propName);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
const message = `Missing or invalid url query parameters: [${errParts.join(
|
|
478
|
+
", "
|
|
479
|
+
)}]`;
|
|
480
|
+
throw defineError(400, {
|
|
481
|
+
statusMessage: message
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
event.context.query = parsedQuery.value;
|
|
485
|
+
}
|
|
486
|
+
const notAllowedBodyMethods = [
|
|
487
|
+
"GET",
|
|
488
|
+
"HEAD",
|
|
489
|
+
"CONNECT",
|
|
490
|
+
"OPTIONS"
|
|
491
|
+
];
|
|
492
|
+
if (route.body && !notAllowedBodyMethods.includes(event.method)) {
|
|
493
|
+
const body = await readRawBody(event);
|
|
494
|
+
const parsedBody = a.safeParse(route.body, body);
|
|
495
|
+
if (!parsedBody.success) {
|
|
496
|
+
const errorParts = [];
|
|
497
|
+
for (const err of parsedBody.error.errors) {
|
|
498
|
+
const errPath = err.instancePath.split("/");
|
|
499
|
+
errPath.shift();
|
|
500
|
+
if (!errorParts.includes(errPath.join("."))) {
|
|
501
|
+
errorParts.push(errPath.join("."));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
throw defineError(400, {
|
|
505
|
+
statusMessage: `Invalid request body. Affected properties [${errorParts.join(
|
|
506
|
+
", "
|
|
507
|
+
)}]`,
|
|
508
|
+
data: parsedBody.error
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
event.context.body = parsedBody.value;
|
|
512
|
+
}
|
|
463
513
|
const response = await route.handler(event);
|
|
464
514
|
event.context.response = response;
|
|
465
515
|
if (!event.handled) {
|
|
@@ -482,6 +532,7 @@ function handleRoute(router, method, route, opts) {
|
|
|
482
532
|
} catch (err) {
|
|
483
533
|
await handleH3Error(err, event, opts.onError);
|
|
484
534
|
}
|
|
535
|
+
return "";
|
|
485
536
|
});
|
|
486
537
|
switch (method) {
|
|
487
538
|
case "get":
|
|
@@ -532,6 +583,7 @@ class ArriApp {
|
|
|
532
583
|
this.h3App = createApp({
|
|
533
584
|
debug: opts?.debug
|
|
534
585
|
});
|
|
586
|
+
this.onRequest = opts.onRequest;
|
|
535
587
|
this.onError = opts.onError;
|
|
536
588
|
this.onAfterResponse = opts.onAfterResponse;
|
|
537
589
|
this.onBeforeResponse = opts.onBeforeResponse;
|
|
@@ -554,6 +606,9 @@ class ArriApp {
|
|
|
554
606
|
setResponseStatus(event, 404);
|
|
555
607
|
const error = defineError(404);
|
|
556
608
|
try {
|
|
609
|
+
if (this.onRequest) {
|
|
610
|
+
await this.onRequest(event);
|
|
611
|
+
}
|
|
557
612
|
if (this.middlewares.length) {
|
|
558
613
|
for (const m of this.middlewares) {
|
|
559
614
|
await m(event);
|
|
@@ -588,7 +643,7 @@ class ArriApp {
|
|
|
588
643
|
this.middlewares.push(input);
|
|
589
644
|
}
|
|
590
645
|
rpc(procedure) {
|
|
591
|
-
const path = getRpcPath(procedure.name, this.rpcRoutePrefix);
|
|
646
|
+
const path = procedure.path ?? getRpcPath(procedure.name, this.rpcRoutePrefix);
|
|
592
647
|
this.procedures[procedure.name] = createRpcDefinition(
|
|
593
648
|
procedure.name,
|
|
594
649
|
path,
|
|
@@ -608,6 +663,7 @@ class ArriApp {
|
|
|
608
663
|
}
|
|
609
664
|
registerRpc(this.h3Router, path, procedure, {
|
|
610
665
|
middleware: this.middlewares,
|
|
666
|
+
onRequest: this.onRequest,
|
|
611
667
|
onError: this.onError,
|
|
612
668
|
onAfterResponse: this.onAfterResponse,
|
|
613
669
|
onBeforeResponse: this.onBeforeResponse
|
|
@@ -616,6 +672,7 @@ class ArriApp {
|
|
|
616
672
|
route(route) {
|
|
617
673
|
registerRoute(this.h3Router, route, {
|
|
618
674
|
middleware: this.middlewares,
|
|
675
|
+
onRequest: this.onRequest,
|
|
619
676
|
onError: this.onError,
|
|
620
677
|
onAfterResponse: this.onAfterResponse,
|
|
621
678
|
onBeforeResponse: this.onBeforeResponse
|
|
@@ -626,8 +683,7 @@ class ArriApp {
|
|
|
626
683
|
arriSchemaVersion: "0.0.2",
|
|
627
684
|
info: this.appInfo,
|
|
628
685
|
procedures: {},
|
|
629
|
-
models: this.models
|
|
630
|
-
errors: ErrorResponse
|
|
686
|
+
models: this.models
|
|
631
687
|
};
|
|
632
688
|
for (const key of Object.keys(this.procedures)) {
|
|
633
689
|
const rpc = this.procedures[key];
|
|
@@ -674,4 +730,4 @@ function defineConfig(config) {
|
|
|
674
730
|
};
|
|
675
731
|
}
|
|
676
732
|
|
|
677
|
-
export { ArriApp as A, DEV_ENDPOINT_ROOT as D, ErrorResponse as E, DEV_DEFINITION_ENDPOINT as a, getRpcParamName as b, createRpcDefinition as c, defineRpc as d, getRpcResponseName as e, defineError as f, getRpcPath as g, errorResponseFromValidationErrors as h, isRpc as i, handleH3Error as j, isArriConfig as k, isResolvedArriConfig as l, defaultConfig as m, defineConfig as n, ArriRouter as o, registerRpc as r };
|
|
733
|
+
export { ArriApp as A, DEV_ENDPOINT_ROOT as D, ErrorResponse as E, DEV_DEFINITION_ENDPOINT as a, getRpcParamName as b, createRpcDefinition as c, defineRpc as d, getRpcResponseName as e, defineError as f, getRpcPath as g, errorResponseFromValidationErrors as h, isRpc as i, handleH3Error as j, isArriConfig as k, isResolvedArriConfig as l, defaultConfig as m, defineConfig as n, ArriRouter as o, defineRoute as p, registerRoute as q, registerRpc as r, handleRoute as s };
|
|
@@ -272,10 +272,15 @@ function getRpcResponseDefinition(rpcName, procedure) {
|
|
|
272
272
|
return name;
|
|
273
273
|
}
|
|
274
274
|
function registerRpc(router, path, procedure, opts) {
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
let responseValidator;
|
|
276
|
+
try {
|
|
277
|
+
responseValidator = procedure.response ? arriValidate.a.compile(procedure.response) : void 0;
|
|
278
|
+
} catch (err) {
|
|
279
|
+
console.error("ERROR COMPILING VALIDATOR", err);
|
|
280
|
+
}
|
|
277
281
|
const httpMethod = procedure.method ?? "post";
|
|
278
282
|
const handler = h3.eventHandler(async (event) => {
|
|
283
|
+
event.context.rpcName = procedure.name;
|
|
279
284
|
if (h3.isPreflightRequest(event)) {
|
|
280
285
|
return "ok";
|
|
281
286
|
}
|
|
@@ -288,7 +293,7 @@ function registerRpc(router, path, procedure, opts) {
|
|
|
288
293
|
await m(event);
|
|
289
294
|
}
|
|
290
295
|
}
|
|
291
|
-
if (arriValidate.isAObjectSchema(procedure.params)
|
|
296
|
+
if (arriValidate.isAObjectSchema(procedure.params)) {
|
|
292
297
|
switch (httpMethod) {
|
|
293
298
|
case "get":
|
|
294
299
|
case "head": {
|
|
@@ -328,7 +333,10 @@ function registerRpc(router, path, procedure, opts) {
|
|
|
328
333
|
statusMessage: `Invalid request body. Expected object. Got undefined.`
|
|
329
334
|
});
|
|
330
335
|
}
|
|
331
|
-
const parsedParams =
|
|
336
|
+
const parsedParams = arriValidate.a.safeParse(
|
|
337
|
+
procedure.params,
|
|
338
|
+
body
|
|
339
|
+
);
|
|
332
340
|
if (!parsedParams.success) {
|
|
333
341
|
const errorParts = [];
|
|
334
342
|
for (const err of parsedParams.error.errors) {
|
|
@@ -367,21 +375,8 @@ function registerRpc(router, path, procedure, opts) {
|
|
|
367
375
|
responseValidator?.serialize(response) ?? JSON.stringify(response)
|
|
368
376
|
);
|
|
369
377
|
} else {
|
|
370
|
-
|
|
371
|
-
|
|
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
|
-
);
|
|
378
|
+
h3.setResponseHeader(event, "Content-Type", "application/json");
|
|
379
|
+
await h3.send(event, `{}`);
|
|
385
380
|
}
|
|
386
381
|
if (opts.onAfterResponse) {
|
|
387
382
|
await opts.onAfterResponse(event);
|
|
@@ -442,6 +437,9 @@ class ArriRouter {
|
|
|
442
437
|
}
|
|
443
438
|
}
|
|
444
439
|
|
|
440
|
+
function defineRoute(route) {
|
|
441
|
+
return route;
|
|
442
|
+
}
|
|
445
443
|
function registerRoute(router, route, opts) {
|
|
446
444
|
if (typeof route.method === "string") {
|
|
447
445
|
handleRoute(router, route.method, route, opts);
|
|
@@ -453,6 +451,9 @@ function registerRoute(router, route, opts) {
|
|
|
453
451
|
}
|
|
454
452
|
function handleRoute(router, method, route, opts) {
|
|
455
453
|
const handler = h3.defineEventHandler(async (event) => {
|
|
454
|
+
if (h3.isPreflightRequest(event)) {
|
|
455
|
+
return "ok";
|
|
456
|
+
}
|
|
456
457
|
try {
|
|
457
458
|
if (opts.onRequest) {
|
|
458
459
|
await opts.onRequest(event);
|
|
@@ -462,6 +463,55 @@ function handleRoute(router, method, route, opts) {
|
|
|
462
463
|
await m(event);
|
|
463
464
|
}
|
|
464
465
|
}
|
|
466
|
+
if (route.query) {
|
|
467
|
+
const query = h3.getQuery(event);
|
|
468
|
+
const parsedQuery = arriValidate.a.safeCoerce(route.query, query);
|
|
469
|
+
if (!parsedQuery.success) {
|
|
470
|
+
const errParts = [];
|
|
471
|
+
for (const err of parsedQuery.error.errors) {
|
|
472
|
+
const errPath = err.instancePath.split("/");
|
|
473
|
+
errPath.shift();
|
|
474
|
+
const propName = errPath.join(".");
|
|
475
|
+
if (!errParts.includes(propName)) {
|
|
476
|
+
errParts.push(propName);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const message = `Missing or invalid url query parameters: [${errParts.join(
|
|
480
|
+
", "
|
|
481
|
+
)}]`;
|
|
482
|
+
throw defineError(400, {
|
|
483
|
+
statusMessage: message
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
event.context.query = parsedQuery.value;
|
|
487
|
+
}
|
|
488
|
+
const notAllowedBodyMethods = [
|
|
489
|
+
"GET",
|
|
490
|
+
"HEAD",
|
|
491
|
+
"CONNECT",
|
|
492
|
+
"OPTIONS"
|
|
493
|
+
];
|
|
494
|
+
if (route.body && !notAllowedBodyMethods.includes(event.method)) {
|
|
495
|
+
const body = await h3.readRawBody(event);
|
|
496
|
+
const parsedBody = arriValidate.a.safeParse(route.body, body);
|
|
497
|
+
if (!parsedBody.success) {
|
|
498
|
+
const errorParts = [];
|
|
499
|
+
for (const err of parsedBody.error.errors) {
|
|
500
|
+
const errPath = err.instancePath.split("/");
|
|
501
|
+
errPath.shift();
|
|
502
|
+
if (!errorParts.includes(errPath.join("."))) {
|
|
503
|
+
errorParts.push(errPath.join("."));
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
throw defineError(400, {
|
|
507
|
+
statusMessage: `Invalid request body. Affected properties [${errorParts.join(
|
|
508
|
+
", "
|
|
509
|
+
)}]`,
|
|
510
|
+
data: parsedBody.error
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
event.context.body = parsedBody.value;
|
|
514
|
+
}
|
|
465
515
|
const response = await route.handler(event);
|
|
466
516
|
event.context.response = response;
|
|
467
517
|
if (!event.handled) {
|
|
@@ -484,6 +534,7 @@ function handleRoute(router, method, route, opts) {
|
|
|
484
534
|
} catch (err) {
|
|
485
535
|
await handleH3Error(err, event, opts.onError);
|
|
486
536
|
}
|
|
537
|
+
return "";
|
|
487
538
|
});
|
|
488
539
|
switch (method) {
|
|
489
540
|
case "get":
|
|
@@ -534,6 +585,7 @@ class ArriApp {
|
|
|
534
585
|
this.h3App = h3.createApp({
|
|
535
586
|
debug: opts?.debug
|
|
536
587
|
});
|
|
588
|
+
this.onRequest = opts.onRequest;
|
|
537
589
|
this.onError = opts.onError;
|
|
538
590
|
this.onAfterResponse = opts.onAfterResponse;
|
|
539
591
|
this.onBeforeResponse = opts.onBeforeResponse;
|
|
@@ -556,6 +608,9 @@ class ArriApp {
|
|
|
556
608
|
h3.setResponseStatus(event, 404);
|
|
557
609
|
const error = defineError(404);
|
|
558
610
|
try {
|
|
611
|
+
if (this.onRequest) {
|
|
612
|
+
await this.onRequest(event);
|
|
613
|
+
}
|
|
559
614
|
if (this.middlewares.length) {
|
|
560
615
|
for (const m of this.middlewares) {
|
|
561
616
|
await m(event);
|
|
@@ -590,7 +645,7 @@ class ArriApp {
|
|
|
590
645
|
this.middlewares.push(input);
|
|
591
646
|
}
|
|
592
647
|
rpc(procedure) {
|
|
593
|
-
const path = getRpcPath(procedure.name, this.rpcRoutePrefix);
|
|
648
|
+
const path = procedure.path ?? getRpcPath(procedure.name, this.rpcRoutePrefix);
|
|
594
649
|
this.procedures[procedure.name] = createRpcDefinition(
|
|
595
650
|
procedure.name,
|
|
596
651
|
path,
|
|
@@ -610,6 +665,7 @@ class ArriApp {
|
|
|
610
665
|
}
|
|
611
666
|
registerRpc(this.h3Router, path, procedure, {
|
|
612
667
|
middleware: this.middlewares,
|
|
668
|
+
onRequest: this.onRequest,
|
|
613
669
|
onError: this.onError,
|
|
614
670
|
onAfterResponse: this.onAfterResponse,
|
|
615
671
|
onBeforeResponse: this.onBeforeResponse
|
|
@@ -618,6 +674,7 @@ class ArriApp {
|
|
|
618
674
|
route(route) {
|
|
619
675
|
registerRoute(this.h3Router, route, {
|
|
620
676
|
middleware: this.middlewares,
|
|
677
|
+
onRequest: this.onRequest,
|
|
621
678
|
onError: this.onError,
|
|
622
679
|
onAfterResponse: this.onAfterResponse,
|
|
623
680
|
onBeforeResponse: this.onBeforeResponse
|
|
@@ -628,8 +685,7 @@ class ArriApp {
|
|
|
628
685
|
arriSchemaVersion: "0.0.2",
|
|
629
686
|
info: this.appInfo,
|
|
630
687
|
procedures: {},
|
|
631
|
-
models: this.models
|
|
632
|
-
errors: ErrorResponse
|
|
688
|
+
models: this.models
|
|
633
689
|
};
|
|
634
690
|
for (const key of Object.keys(this.procedures)) {
|
|
635
691
|
const rpc = this.procedures[key];
|
|
@@ -685,13 +741,16 @@ exports.createRpcDefinition = createRpcDefinition;
|
|
|
685
741
|
exports.defaultConfig = defaultConfig;
|
|
686
742
|
exports.defineConfig = defineConfig;
|
|
687
743
|
exports.defineError = defineError;
|
|
744
|
+
exports.defineRoute = defineRoute;
|
|
688
745
|
exports.defineRpc = defineRpc;
|
|
689
746
|
exports.errorResponseFromValidationErrors = errorResponseFromValidationErrors;
|
|
690
747
|
exports.getRpcParamName = getRpcParamName;
|
|
691
748
|
exports.getRpcPath = getRpcPath;
|
|
692
749
|
exports.getRpcResponseName = getRpcResponseName;
|
|
693
750
|
exports.handleH3Error = handleH3Error;
|
|
751
|
+
exports.handleRoute = handleRoute;
|
|
694
752
|
exports.isArriConfig = isArriConfig;
|
|
695
753
|
exports.isResolvedArriConfig = isResolvedArriConfig;
|
|
696
754
|
exports.isRpc = isRpc;
|
|
755
|
+
exports.registerRoute = registerRoute;
|
|
697
756
|
exports.registerRpc = registerRpc;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arri",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.10",
|
|
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.
|
|
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-
|
|
35
|
-
"arri-codegen-ts": "0.1.0-beta.
|
|
36
|
-
"arri-
|
|
37
|
-
"arri-codegen-utils": "0.1.0-beta.
|
|
34
|
+
"arri-validate": "0.1.0-beta.10",
|
|
35
|
+
"arri-codegen-ts": "0.1.0-beta.10",
|
|
36
|
+
"arri-codegen-dart": "0.1.0-beta.10",
|
|
37
|
+
"arri-codegen-utils": "0.1.0-beta.10"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"bun-types": "^1.0.
|
|
40
|
+
"bun-types": "^1.0.5"
|
|
41
41
|
}
|
|
42
42
|
}
|