arri 0.12.8 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -3
- package/dist/cli.cjs +88 -130
- package/dist/cli.mjs +88 -130
- package/dist/index.cjs +9 -1
- package/dist/index.d.cts +114 -38
- package/dist/index.d.mts +114 -38
- package/dist/index.d.ts +114 -38
- package/dist/index.mjs +1 -1
- package/dist/shared/{arri.4d91d9b0.mjs → arri.28516ef9.mjs} +353 -102
- package/dist/shared/{arri.fa32b1ba.cjs → arri.2eb37786.cjs} +359 -100
- package/package.json +11 -9
package/dist/cli.mjs
CHANGED
|
@@ -8,9 +8,10 @@ import { loadConfig } from 'c12';
|
|
|
8
8
|
import consola, { createConsola } from 'consola';
|
|
9
9
|
import * as esbuild from 'esbuild';
|
|
10
10
|
import { build as build$1 } from 'esbuild';
|
|
11
|
+
import { replace } from 'esbuild-plugin-replace';
|
|
11
12
|
import path from 'pathe';
|
|
12
13
|
import prettier from 'prettier';
|
|
13
|
-
import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.
|
|
14
|
+
import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.28516ef9.mjs';
|
|
14
15
|
import { globby } from 'globby';
|
|
15
16
|
import { camelCase, kebabCase } from 'scule';
|
|
16
17
|
import { dartClientGenerator } from 'arri-codegen-dart';
|
|
@@ -21,10 +22,11 @@ import Degit from 'degit';
|
|
|
21
22
|
import 'h3';
|
|
22
23
|
import 'arri-validate';
|
|
23
24
|
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
25
|
+
const GEN_APP_FILE = "__arri_app.js";
|
|
26
|
+
const GEN_SERVER_ENTRY_FILE = "__arri_server.js";
|
|
27
|
+
const OUT_APP_FILE = "app.js";
|
|
28
|
+
const OUT_SERVER_ENTRY = "server.js";
|
|
29
|
+
const OUT_CODEGEN = "codegen.js";
|
|
28
30
|
async function setupWorkingDir(config) {
|
|
29
31
|
const arriDir = path.resolve(config.rootDir, config.buildDir);
|
|
30
32
|
const outDir = path.resolve(config.rootDir, ".output");
|
|
@@ -37,12 +39,15 @@ async function setupWorkingDir(config) {
|
|
|
37
39
|
await fs.mkdir(arriDir);
|
|
38
40
|
await fs.mkdir(outDir);
|
|
39
41
|
}
|
|
40
|
-
async function
|
|
42
|
+
async function createAppWithRoutesModule(config) {
|
|
43
|
+
const appModule = path.resolve(config.rootDir, config.srcDir, config.entry);
|
|
44
|
+
const appImportParts = path.relative(path.resolve(config.rootDir, config.srcDir), appModule).split(".");
|
|
45
|
+
appImportParts.pop();
|
|
41
46
|
const routes = [];
|
|
42
47
|
const existingRoutes = [];
|
|
43
48
|
await Promise.all(
|
|
44
49
|
config.procedureGlobPatterns.map(async (pattern) => {
|
|
45
|
-
const results = await
|
|
50
|
+
const results = await getFsRouteBatch(pattern, config);
|
|
46
51
|
for (const result of results) {
|
|
47
52
|
if (!existingRoutes.includes(result.name)) {
|
|
48
53
|
routes.push(result);
|
|
@@ -53,22 +58,29 @@ async function createRoutesModule(config) {
|
|
|
53
58
|
);
|
|
54
59
|
routes.sort((a, b) => a.name < b.name ? -1 : 1);
|
|
55
60
|
const module = await prettier.format(
|
|
56
|
-
|
|
61
|
+
`import app from './${appImportParts.join(".")}';
|
|
62
|
+
${routes.map(
|
|
57
63
|
(route) => `import ${route.importName} from '${route.importPath}';`
|
|
58
64
|
).join("\n")}
|
|
59
65
|
const routes = [${routes.map(
|
|
60
66
|
(route) => `{ id: '${route.name}', route: ${route.importName} }`
|
|
61
67
|
).join(",\n")}
|
|
62
68
|
];
|
|
63
|
-
|
|
69
|
+
for(const route of routes) {
|
|
70
|
+
app.rpc({
|
|
71
|
+
name: route.id,
|
|
72
|
+
...route.route,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export default app`,
|
|
64
76
|
{ parser: "typescript", tabWidth: 4 }
|
|
65
77
|
);
|
|
66
78
|
await fs.writeFile(
|
|
67
|
-
path.resolve(config.rootDir, config.buildDir,
|
|
79
|
+
path.resolve(config.rootDir, config.buildDir, GEN_APP_FILE),
|
|
68
80
|
module
|
|
69
81
|
);
|
|
70
82
|
}
|
|
71
|
-
async function
|
|
83
|
+
async function getFsRouteBatch(globPattern, config) {
|
|
72
84
|
if (!config.procedureDir) {
|
|
73
85
|
return [];
|
|
74
86
|
}
|
|
@@ -174,19 +186,15 @@ async function startBuild(config, skipCodeGen = false) {
|
|
|
174
186
|
logger$2.log("Bundling server....");
|
|
175
187
|
await setupWorkingDir(config);
|
|
176
188
|
await Promise.all([
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
189
|
+
createAppWithRoutesModule(config),
|
|
190
|
+
createServerEntryFile(config),
|
|
191
|
+
createCodegenEntryFile(config),
|
|
192
|
+
transpileFiles(config)
|
|
180
193
|
]);
|
|
181
|
-
await
|
|
182
|
-
await bundleFiles(config);
|
|
194
|
+
await bundleAppEntry(config);
|
|
183
195
|
logger$2.log("Finished bundling");
|
|
184
196
|
const clientCount = config.clientGenerators.length;
|
|
185
|
-
const codegenModule = path.resolve(
|
|
186
|
-
config.rootDir,
|
|
187
|
-
".output",
|
|
188
|
-
CODEGEN_OUTPUT
|
|
189
|
-
);
|
|
197
|
+
const codegenModule = path.resolve(config.rootDir, ".output", OUT_CODEGEN);
|
|
190
198
|
if (!skipCodeGen) {
|
|
191
199
|
logger$2.log("Generating Arri app definition (__definition.json)");
|
|
192
200
|
execSync(`node ${codegenModule}`, { env: process.env });
|
|
@@ -213,48 +221,18 @@ async function startBuild(config, skipCodeGen = false) {
|
|
|
213
221
|
logger$2.log("Cleaning up files");
|
|
214
222
|
await fs.rm(codegenModule);
|
|
215
223
|
logger$2.success(
|
|
216
|
-
`Build finished! You can start your server by running "node .output/${
|
|
224
|
+
`Build finished! You can start your server by running "node .output/${OUT_SERVER_ENTRY}"`
|
|
217
225
|
);
|
|
218
226
|
}
|
|
219
|
-
async function
|
|
220
|
-
|
|
221
|
-
await build$1({
|
|
222
|
-
...config.esbuild,
|
|
223
|
-
entryPoints: [
|
|
224
|
-
path.resolve(
|
|
225
|
-
config.rootDir,
|
|
226
|
-
config.buildDir,
|
|
227
|
-
DEFAULT_CODEGEN_FILE
|
|
228
|
-
)
|
|
229
|
-
],
|
|
230
|
-
platform: config.esbuild.platform ?? "node",
|
|
231
|
-
target: config.esbuild.target ?? "node20",
|
|
232
|
-
packages: "external",
|
|
233
|
-
bundle: true,
|
|
234
|
-
format: "esm",
|
|
235
|
-
sourcemap: false,
|
|
236
|
-
minifyWhitespace: false,
|
|
237
|
-
banner: {
|
|
238
|
-
js: `import { createRequire as topLevelCreateRequire } from 'module';
|
|
239
|
-
const require = topLevelCreateRequire(import.meta.url);`
|
|
240
|
-
},
|
|
241
|
-
outfile: path.resolve(config.rootDir, ".output", CODEGEN_OUTPUT)
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
let buildEntry = path.resolve(
|
|
227
|
+
async function bundleAppEntry(config, allowCodegen = true) {
|
|
228
|
+
const appEntry = path.resolve(
|
|
245
229
|
config.rootDir,
|
|
246
230
|
config.buildDir,
|
|
247
|
-
|
|
231
|
+
GEN_APP_FILE
|
|
248
232
|
);
|
|
249
|
-
if (config.buildEntry) {
|
|
250
|
-
const parts = config.buildEntry.split(".");
|
|
251
|
-
parts.pop();
|
|
252
|
-
const mergedParts = `${parts.join(".")}.js`;
|
|
253
|
-
buildEntry = path.resolve(config.rootDir, config.buildDir, mergedParts);
|
|
254
|
-
}
|
|
255
233
|
await build$1({
|
|
256
234
|
...config.esbuild,
|
|
257
|
-
entryPoints: [
|
|
235
|
+
entryPoints: [appEntry],
|
|
258
236
|
platform: config.esbuild.platform ?? "node",
|
|
259
237
|
target: config.esbuild.target ?? "node20",
|
|
260
238
|
bundle: true,
|
|
@@ -267,11 +245,34 @@ const require = topLevelCreateRequire(import.meta.url);`
|
|
|
267
245
|
const require = topLevelCreateRequire(import.meta.url);`
|
|
268
246
|
},
|
|
269
247
|
allowOverwrite: true,
|
|
270
|
-
outfile: path.resolve(config.rootDir, ".output",
|
|
248
|
+
outfile: path.resolve(config.rootDir, ".output", OUT_APP_FILE)
|
|
271
249
|
});
|
|
272
250
|
}
|
|
273
|
-
async function
|
|
274
|
-
if (config.
|
|
251
|
+
async function createServerEntryFile(config) {
|
|
252
|
+
if (config.serverEntry) {
|
|
253
|
+
const buildEntry = path.resolve(
|
|
254
|
+
config.rootDir,
|
|
255
|
+
config.srcDir,
|
|
256
|
+
config.serverEntry
|
|
257
|
+
);
|
|
258
|
+
await build$1({
|
|
259
|
+
...config.esbuild,
|
|
260
|
+
entryPoints: [buildEntry],
|
|
261
|
+
platform: config.esbuild.platform ?? "node",
|
|
262
|
+
target: config.esbuild.target ?? "node20",
|
|
263
|
+
bundle: false,
|
|
264
|
+
packages: "external",
|
|
265
|
+
format: "esm",
|
|
266
|
+
sourcemap: true,
|
|
267
|
+
minifyWhitespace: true,
|
|
268
|
+
banner: {
|
|
269
|
+
js: `import { createRequire as topLevelCreateRequire } from 'module';
|
|
270
|
+
const require = topLevelCreateRequire(import.meta.url);`
|
|
271
|
+
},
|
|
272
|
+
plugins: [replace({ "virtual:arri/app": "./app.js" })],
|
|
273
|
+
allowOverwrite: true,
|
|
274
|
+
outfile: path.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY)
|
|
275
|
+
});
|
|
275
276
|
return;
|
|
276
277
|
}
|
|
277
278
|
const appModule = path.resolve(config.rootDir, config.srcDir, config.entry);
|
|
@@ -279,34 +280,18 @@ async function createBuildEntryModule(config) {
|
|
|
279
280
|
appImportParts.pop();
|
|
280
281
|
const virtualEntry = `import { toNodeListener } from 'arri';
|
|
281
282
|
import { listen } from 'listhen';
|
|
282
|
-
import
|
|
283
|
-
import app from './${appImportParts.join(".")}.js';
|
|
284
|
-
|
|
285
|
-
for (const route of routes) {
|
|
286
|
-
app.rpc({
|
|
287
|
-
name: route.id,
|
|
288
|
-
method: route.route.method,
|
|
289
|
-
params: route.route.params,
|
|
290
|
-
response: route.route.response,
|
|
291
|
-
handler: route.route.handler,
|
|
292
|
-
postHandler: route.route.postHandler,
|
|
293
|
-
});
|
|
294
|
-
}
|
|
283
|
+
import app from './${OUT_APP_FILE}';
|
|
295
284
|
|
|
296
285
|
void listen(toNodeListener(app.h3App), {
|
|
297
286
|
port: process.env.PORT ?? ${config.port},
|
|
298
287
|
public: true,
|
|
299
288
|
});`;
|
|
300
289
|
await fs.writeFile(
|
|
301
|
-
path.resolve(
|
|
302
|
-
config.rootDir,
|
|
303
|
-
config.buildDir,
|
|
304
|
-
DEFAULT_SERVER_ENTRY_FILE
|
|
305
|
-
),
|
|
290
|
+
path.resolve(config.rootDir, ".output", GEN_SERVER_ENTRY_FILE),
|
|
306
291
|
virtualEntry
|
|
307
292
|
);
|
|
308
293
|
}
|
|
309
|
-
async function
|
|
294
|
+
async function createCodegenEntryFile(config) {
|
|
310
295
|
const appModule = path.resolve(config.rootDir, config.srcDir, config.entry);
|
|
311
296
|
const appImportParts = path.relative(path.resolve(config.rootDir, config.srcDir), appModule).split(".");
|
|
312
297
|
appImportParts.pop();
|
|
@@ -314,20 +299,7 @@ async function createBuildCodegenModule(config) {
|
|
|
314
299
|
`
|
|
315
300
|
import { writeFileSync } from 'node:fs';
|
|
316
301
|
import path from 'pathe';
|
|
317
|
-
import app from './${
|
|
318
|
-
import routes from './routes.js';
|
|
319
|
-
|
|
320
|
-
for (const route of routes) {
|
|
321
|
-
app.rpc({
|
|
322
|
-
name: route.id,
|
|
323
|
-
method: route.route.method,
|
|
324
|
-
path: route.route.path,
|
|
325
|
-
params: route.route.params,
|
|
326
|
-
response: route.route.response,
|
|
327
|
-
handler: route.route.handler,
|
|
328
|
-
postHandler: route.route.postHandler,
|
|
329
|
-
});
|
|
330
|
-
}
|
|
302
|
+
import app from './${OUT_APP_FILE}';
|
|
331
303
|
|
|
332
304
|
const __dirname = new URL(".", import.meta.url).pathname;
|
|
333
305
|
const def = app.getAppDefinition();
|
|
@@ -338,7 +310,7 @@ async function createBuildCodegenModule(config) {
|
|
|
338
310
|
{ tabWidth: 4, parser: "typescript" }
|
|
339
311
|
);
|
|
340
312
|
await fs.writeFile(
|
|
341
|
-
path.resolve(config.rootDir,
|
|
313
|
+
path.resolve(config.rootDir, ".output", OUT_CODEGEN),
|
|
342
314
|
virtualModule
|
|
343
315
|
);
|
|
344
316
|
}
|
|
@@ -440,26 +412,26 @@ const dev = defineCommand({
|
|
|
440
412
|
await startDevServer(config);
|
|
441
413
|
}
|
|
442
414
|
});
|
|
443
|
-
const startListener = (config, showQr = false) => listenAndWatch(
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
qr: showQr
|
|
450
|
-
}
|
|
451
|
-
);
|
|
415
|
+
const startListener = (config, showQr = false) => listenAndWatch(path.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY), {
|
|
416
|
+
public: true,
|
|
417
|
+
port: config.port,
|
|
418
|
+
logger: logger$1,
|
|
419
|
+
qr: showQr
|
|
420
|
+
});
|
|
452
421
|
async function bundleFilesContext(config) {
|
|
422
|
+
const serverContent = `import app from './${OUT_APP_FILE}';
|
|
423
|
+
|
|
424
|
+
export default app.h3App;`;
|
|
425
|
+
await fs.writeFile(
|
|
426
|
+
path.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY),
|
|
427
|
+
serverContent
|
|
428
|
+
);
|
|
453
429
|
return await esbuild.context({
|
|
454
430
|
...config.esbuild,
|
|
455
431
|
entryPoints: [
|
|
456
|
-
path.resolve(
|
|
457
|
-
config.rootDir,
|
|
458
|
-
config.buildDir,
|
|
459
|
-
DEFAULT_SERVER_ENTRY_FILE
|
|
460
|
-
)
|
|
432
|
+
path.resolve(config.rootDir, config.buildDir, GEN_APP_FILE)
|
|
461
433
|
],
|
|
462
|
-
outfile: path.resolve(config.rootDir, ".output",
|
|
434
|
+
outfile: path.resolve(config.rootDir, ".output", OUT_APP_FILE),
|
|
463
435
|
format: "esm",
|
|
464
436
|
bundle: true,
|
|
465
437
|
sourcemap: true,
|
|
@@ -471,8 +443,11 @@ async function bundleFilesContext(config) {
|
|
|
471
443
|
async function startDevServer(config) {
|
|
472
444
|
await setupWorkingDir(config);
|
|
473
445
|
let fileWatcher;
|
|
474
|
-
await Promise.all([
|
|
475
|
-
|
|
446
|
+
await Promise.all([
|
|
447
|
+
createEntryModule(config),
|
|
448
|
+
createAppWithRoutesModule(config),
|
|
449
|
+
transpileFiles(config)
|
|
450
|
+
]);
|
|
476
451
|
const bundleFiles = await bundleFilesContext(config);
|
|
477
452
|
await bundleFiles.rebuild();
|
|
478
453
|
const listener = await startListener(config, true);
|
|
@@ -510,7 +485,7 @@ async function startDevServer(config) {
|
|
|
510
485
|
if (event === "add" || event === "addDir") {
|
|
511
486
|
return;
|
|
512
487
|
}
|
|
513
|
-
await
|
|
488
|
+
await createAppWithRoutesModule(config);
|
|
514
489
|
let bundleCreated = false;
|
|
515
490
|
try {
|
|
516
491
|
logger$1.log(
|
|
@@ -563,28 +538,11 @@ async function createEntryModule(config) {
|
|
|
563
538
|
appImportParts.pop();
|
|
564
539
|
const virtualEntry = `import { toNodeListener } from 'h3';
|
|
565
540
|
import { listen } from 'listhen';
|
|
566
|
-
import
|
|
567
|
-
import app from './${appImportParts.join(".")}';
|
|
568
|
-
|
|
569
|
-
for (const route of routes) {
|
|
570
|
-
app.rpc({
|
|
571
|
-
name: route.id,
|
|
572
|
-
method: route.route.method,
|
|
573
|
-
path: route.route.path,
|
|
574
|
-
params: route.route.params,
|
|
575
|
-
response: route.route.response,
|
|
576
|
-
handler: route.route.handler,
|
|
577
|
-
postHandler: route.route.postHandler,
|
|
578
|
-
});
|
|
579
|
-
}
|
|
541
|
+
import app from './${GEN_APP_FILE}';
|
|
580
542
|
|
|
581
543
|
export default app.h3App;`;
|
|
582
544
|
await fs.writeFile(
|
|
583
|
-
path.resolve(
|
|
584
|
-
config.rootDir,
|
|
585
|
-
config.buildDir,
|
|
586
|
-
DEFAULT_SERVER_ENTRY_FILE
|
|
587
|
-
),
|
|
545
|
+
path.resolve(config.rootDir, config.buildDir, GEN_SERVER_ENTRY_FILE),
|
|
588
546
|
virtualEntry
|
|
589
547
|
);
|
|
590
548
|
}
|
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.2eb37786.cjs');
|
|
4
4
|
const h3 = require('h3');
|
|
5
5
|
require('arri-validate');
|
|
6
6
|
require('arri-codegen-utils');
|
|
@@ -13,24 +13,32 @@ exports.ArriRouter = config.ArriRouter;
|
|
|
13
13
|
exports.DEV_DEFINITION_ENDPOINT = config.DEV_DEFINITION_ENDPOINT;
|
|
14
14
|
exports.DEV_ENDPOINT_ROOT = config.DEV_ENDPOINT_ROOT;
|
|
15
15
|
exports.ErrorResponse = config.ErrorResponse;
|
|
16
|
+
exports.EventStreamConnection = config.EventStreamConnection;
|
|
16
17
|
exports.createRpcDefinition = config.createRpcDefinition;
|
|
17
18
|
exports.defaultConfig = config.defaultConfig;
|
|
18
19
|
exports.defineConfig = config.defineConfig;
|
|
19
20
|
exports.defineError = config.defineError;
|
|
21
|
+
exports.defineEventStreamRpc = config.defineEventStreamRpc;
|
|
20
22
|
exports.defineRoute = config.defineRoute;
|
|
21
23
|
exports.defineRpc = config.defineRpc;
|
|
22
24
|
exports.errorResponseFromValidationErrors = config.errorResponseFromValidationErrors;
|
|
25
|
+
exports.formatSse = config.formatSse;
|
|
26
|
+
exports.formatSseList = config.formatSseList;
|
|
23
27
|
exports.getRpcParamName = config.getRpcParamName;
|
|
24
28
|
exports.getRpcPath = config.getRpcPath;
|
|
25
29
|
exports.getRpcResponseName = config.getRpcResponseName;
|
|
26
30
|
exports.handleH3Error = config.handleH3Error;
|
|
27
31
|
exports.handleRoute = config.handleRoute;
|
|
28
32
|
exports.isArriConfig = config.isArriConfig;
|
|
33
|
+
exports.isEventStreamRpc = config.isEventStreamRpc;
|
|
29
34
|
exports.isResolvedArriConfig = config.isResolvedArriConfig;
|
|
30
35
|
exports.isRpc = config.isRpc;
|
|
31
36
|
exports.isRpcParamSchema = config.isRpcParamSchema;
|
|
37
|
+
exports.registerEventStreamRpc = config.registerEventStreamRpc;
|
|
32
38
|
exports.registerRoute = config.registerRoute;
|
|
33
39
|
exports.registerRpc = config.registerRpc;
|
|
40
|
+
exports.setSseHeaders = config.setSseHeaders;
|
|
41
|
+
exports.validateRpcRequestInput = config.validateRpcRequestInput;
|
|
34
42
|
exports.defineMiddleware = defineMiddleware;
|
|
35
43
|
Object.keys(h3).forEach(function (k) {
|
|
36
44
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = h3[k];
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { HttpMethod, RpcHttpMethod, RpcDefinition, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
|
|
2
|
-
import { AObjectSchema, ASchema, InferType,
|
|
3
|
-
import { H3EventContext, H3Event, Router,
|
|
1
|
+
import { HttpMethod, RpcHttpMethod, RpcDefinition, SchemaFormProperties, SchemaFormDiscriminator, SchemaFormValues, AppDefinition, ClientGenerator } from 'arri-codegen-utils';
|
|
2
|
+
import { AObjectSchema, ASchema, InferType, a, ValidationError, ARecordSchema, ADiscriminatorSchema } from 'arri-validate';
|
|
3
|
+
import { H3EventContext, H3Event, Router, H3Error, App } from 'h3';
|
|
4
4
|
export * from 'h3';
|
|
5
5
|
import { BuildOptions } from 'esbuild';
|
|
6
6
|
|
|
@@ -44,20 +44,103 @@ type RouteOptions = Pick<ArriOptions, "onAfterResponse" | "onBeforeResponse" | "
|
|
|
44
44
|
declare function registerRoute(router: Router, route: ArriRoute<any>, opts: RouteOptions): void;
|
|
45
45
|
declare function handleRoute(router: Router, method: HttpMethod, route: ArriRoute<any>, opts: RouteOptions): void;
|
|
46
46
|
|
|
47
|
+
declare const ErrorResponse: AObjectSchema<{
|
|
48
|
+
statusCode: number;
|
|
49
|
+
statusMessage: string;
|
|
50
|
+
stack?: string | undefined;
|
|
51
|
+
data?: any;
|
|
52
|
+
}, false>;
|
|
53
|
+
type ErrorResponse = a.infer<typeof ErrorResponse>;
|
|
54
|
+
declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ErrorResponse, "statusCode" | "stack">> & {
|
|
55
|
+
stack?: string;
|
|
56
|
+
}): H3Error;
|
|
57
|
+
declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
|
|
58
|
+
type StatusCode = number | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
59
|
+
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"]): Promise<void>;
|
|
60
|
+
|
|
61
|
+
declare function setSseHeaders(event: H3Event): void;
|
|
62
|
+
declare function defineEventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: Omit<EventStreamRpc<TParams, TResponse>, "isEventStream">): EventStreamRpc<TParams, TResponse>;
|
|
63
|
+
declare function isEventStreamRpc(input: unknown): input is EventStreamRpc<any, any>;
|
|
64
|
+
interface EventStreamRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Omit<Rpc<true, TParams, TResponse>, "handler" | "postHandler"> {
|
|
65
|
+
isEventStream: true;
|
|
66
|
+
handler: EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
|
|
67
|
+
}
|
|
68
|
+
type EventStreamRpcHandler<TParams, TResponse> = (context: EventStreamRpcHandlerContext<TParams, TResponse>, event: EventStreamRpcEvent<TParams, TResponse>) => void | Promise<void>;
|
|
69
|
+
interface EventStreamRpcEvent<TParams, TResponse> extends RpcEvent<TParams> {
|
|
70
|
+
connection: EventStreamConnection<TResponse>;
|
|
71
|
+
}
|
|
72
|
+
interface EventStreamRpcHandlerContext<TParams = any, TResponse = any> extends RpcHandlerContext<TParams> {
|
|
73
|
+
connection: EventStreamConnection<TResponse>;
|
|
74
|
+
}
|
|
75
|
+
interface EventStreamConnectionOptions<TData> {
|
|
76
|
+
serializer: (input: TData) => string;
|
|
77
|
+
pingInterval?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A server sent event
|
|
81
|
+
*/
|
|
82
|
+
interface Sse {
|
|
83
|
+
id?: string;
|
|
84
|
+
event?: string;
|
|
85
|
+
data: string;
|
|
86
|
+
}
|
|
87
|
+
declare function formatSse({ id, data, event }: Sse): string;
|
|
88
|
+
declare function formatSseList(events: Sse[]): string;
|
|
89
|
+
declare class EventStreamConnection<TData> {
|
|
90
|
+
lastEventId: string | undefined;
|
|
91
|
+
private readonly writable;
|
|
92
|
+
private readonly readable;
|
|
93
|
+
private readonly writer;
|
|
94
|
+
private readonly encoder;
|
|
95
|
+
private readonly serializer;
|
|
96
|
+
private readonly h3Event;
|
|
97
|
+
private pingInterval;
|
|
98
|
+
private readonly pingIntervalMs;
|
|
99
|
+
constructor(event: H3Event, opts: EventStreamConnectionOptions<TData>);
|
|
100
|
+
/**
|
|
101
|
+
* Start sending the event stream to the client
|
|
102
|
+
*/
|
|
103
|
+
start(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Publish a new event. Events published with this hook will trigger the `onData()` hooks of any connected clients.
|
|
106
|
+
*/
|
|
107
|
+
push(data: TData[], eventId?: string): Promise<void>;
|
|
108
|
+
push(data: TData, eventId?: string): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Publish an error event. This will trigger the `onError` hooks of any connected clients.
|
|
111
|
+
*/
|
|
112
|
+
pushError(error: ErrorResponse, eventId?: string): Promise<void>;
|
|
113
|
+
private publishEvents;
|
|
114
|
+
private publishEvent;
|
|
115
|
+
private cleanup;
|
|
116
|
+
/**
|
|
117
|
+
* Tell clients that the stream has ended and close the connection.
|
|
118
|
+
*/
|
|
119
|
+
end(): Promise<void>;
|
|
120
|
+
on(event: "disconnect", callback: () => any): void;
|
|
121
|
+
on(event: "end", callback: () => any): void;
|
|
122
|
+
}
|
|
123
|
+
declare function registerEventStreamRpc(router: Router, path: string, procedure: EventStreamRpc<any, any> & {
|
|
124
|
+
name: string;
|
|
125
|
+
}, opts: RouteOptions): void;
|
|
126
|
+
|
|
47
127
|
type RpcParamSchema<TObjectInner = any, TRecordInner extends ASchema = any, TDiscriminatorInner = any> = AObjectSchema<TObjectInner> | ARecordSchema<TRecordInner> | ADiscriminatorSchema<TDiscriminatorInner>;
|
|
48
128
|
declare function isRpcParamSchema(input: unknown): input is RpcParamSchema;
|
|
49
|
-
interface
|
|
50
|
-
|
|
129
|
+
interface NamedRpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> extends Rpc<TIsEventStream, TParams, TResponse> {
|
|
130
|
+
name: string;
|
|
131
|
+
}
|
|
132
|
+
interface Rpc<TIsEventStream extends boolean = false, TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined = undefined> {
|
|
51
133
|
method?: RpcHttpMethod;
|
|
52
134
|
path?: string;
|
|
135
|
+
description?: string;
|
|
53
136
|
params: TParams;
|
|
54
137
|
response: TResponse;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
name: string;
|
|
138
|
+
isEventStream?: TIsEventStream;
|
|
139
|
+
pingInterval?: TIsEventStream extends true ? number : undefined;
|
|
140
|
+
handler: TIsEventStream extends true ? EventStreamRpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined> : RpcHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : void>;
|
|
141
|
+
postHandler?: TIsEventStream extends true ? undefined : RpcPostHandler<TParams extends RpcParamSchema ? InferType<TParams> : undefined, TResponse extends RpcParamSchema ? InferType<TResponse> : undefined>;
|
|
60
142
|
}
|
|
143
|
+
type HttpRpc<TParams extends RpcParamSchema | undefined, TResponse extends RpcParamSchema | undefined> = Omit<Rpc<false, TParams, TResponse>, "isEventStream">;
|
|
61
144
|
type HandlerContext = Record<string, any>;
|
|
62
145
|
interface RpcHandlerContext<TParams = undefined> extends HandlerContext, Omit<H3EventContext, "params"> {
|
|
63
146
|
rpcName: string;
|
|
@@ -72,31 +155,37 @@ interface RpcEvent<TParams = undefined> extends Omit<H3Event, "context"> {
|
|
|
72
155
|
interface RpcPostEvent<TParams = undefined, TResponse = undefined> extends Omit<H3Event, "context"> {
|
|
73
156
|
context: RpcPostHandlerContext<TParams, TResponse>;
|
|
74
157
|
}
|
|
75
|
-
type
|
|
76
|
-
type
|
|
77
|
-
declare function isRpc(input:
|
|
78
|
-
declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config:
|
|
79
|
-
declare function createRpcDefinition(rpcName: string, httpPath: string, procedure:
|
|
158
|
+
type RpcHandler<TParams, TResponse> = (context: RpcHandlerContext<TParams>, event: RpcEvent<TParams>) => TResponse | Promise<TResponse>;
|
|
159
|
+
type RpcPostHandler<TParams, TResponse> = (context: RpcPostHandlerContext<TParams, TResponse>, event: RpcPostEvent<TParams, TResponse>) => any;
|
|
160
|
+
declare function isRpc(input: unknown): input is Rpc<any, any>;
|
|
161
|
+
declare function defineRpc<TParams extends RpcParamSchema | undefined = undefined, TResponse extends RpcParamSchema | undefined | never = undefined>(config: HttpRpc<TParams, TResponse>): Rpc<false, TParams, TResponse>;
|
|
162
|
+
declare function createRpcDefinition(rpcName: string, httpPath: string, procedure: Rpc<any, any, any>): RpcDefinition;
|
|
80
163
|
declare function getRpcPath(rpcName: string, prefix?: string): string;
|
|
81
|
-
declare function getRpcParamName(rpcName: string, procedure:
|
|
82
|
-
declare function getRpcResponseName(rpcName: string, procedure:
|
|
83
|
-
declare function registerRpc(router: Router, path: string, procedure:
|
|
164
|
+
declare function getRpcParamName(rpcName: string, procedure: Rpc<any, any, any>): string | undefined;
|
|
165
|
+
declare function getRpcResponseName(rpcName: string, procedure: Rpc<any, any, any>): string | undefined;
|
|
166
|
+
declare function registerRpc(router: Router, path: string, procedure: NamedRpc<any, any, any>, opts: RouteOptions): void;
|
|
167
|
+
declare function validateRpcRequestInput(event: H3Event, httpMethod: RpcHttpMethod, schema: ASchema): Promise<void>;
|
|
84
168
|
|
|
85
169
|
interface ArriRouterBase {
|
|
86
|
-
rpc: <TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure:
|
|
170
|
+
rpc: <TIsEventStream extends boolean, TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>) => void;
|
|
87
171
|
route: <TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>) => void;
|
|
172
|
+
registerModels: (models: ModelMap) => void;
|
|
88
173
|
}
|
|
89
174
|
declare class ArriRouter implements ArriRouterBase {
|
|
90
175
|
private readonly procedures;
|
|
91
176
|
private readonly routes;
|
|
92
|
-
|
|
177
|
+
private readonly models;
|
|
178
|
+
rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>): void;
|
|
93
179
|
route<TPath extends string, TQuery extends AObjectSchema<any, any> = any, TBody extends ASchema<any> = any, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
|
|
94
|
-
|
|
180
|
+
registerModels(models: ModelMap): void;
|
|
181
|
+
getProcedures(): NamedRpc<any, any, any>[];
|
|
95
182
|
getRoutes(): ArriRoute<any, any, any, any>[];
|
|
183
|
+
getModels(): ModelMap;
|
|
96
184
|
}
|
|
97
185
|
|
|
98
186
|
declare const DEV_ENDPOINT_ROOT = "/__arri_dev__";
|
|
99
187
|
declare const DEV_DEFINITION_ENDPOINT = "/__arri_dev__/__definition";
|
|
188
|
+
type ModelMap = Record<string, SchemaFormProperties | SchemaFormDiscriminator | SchemaFormValues>;
|
|
100
189
|
declare class ArriApp implements ArriRouterBase {
|
|
101
190
|
__isArri__: boolean;
|
|
102
191
|
readonly h3App: App;
|
|
@@ -113,8 +202,9 @@ declare class ArriApp implements ArriRouterBase {
|
|
|
113
202
|
private readonly onError;
|
|
114
203
|
constructor(opts?: ArriOptions);
|
|
115
204
|
use(input: Middleware | ArriRouter): void;
|
|
116
|
-
rpc<TParams extends AObjectSchema<any, any> | undefined, TResponse extends AObjectSchema<any, any> | undefined>(procedure:
|
|
205
|
+
rpc<TIsEventStream extends boolean = false, TParams extends AObjectSchema<any, any> | undefined = undefined, TResponse extends AObjectSchema<any, any> | undefined = undefined>(procedure: NamedRpc<TIsEventStream, TParams, TResponse>): void;
|
|
117
206
|
route<TPath extends string, TQuery extends AObjectSchema<any, any>, TBody extends ASchema<any>, TResponse = any>(route: ArriRoute<TPath, TQuery, TBody, TResponse>): void;
|
|
207
|
+
registerModels(models: ModelMap): void;
|
|
118
208
|
getAppDefinition(): AppDefinition;
|
|
119
209
|
}
|
|
120
210
|
interface ArriOptions {
|
|
@@ -135,24 +225,10 @@ interface ArriOptions {
|
|
|
135
225
|
onError?: (error: H3Error, event: MiddlewareEvent) => void | Promise<void>;
|
|
136
226
|
}
|
|
137
227
|
|
|
138
|
-
declare const ErrorResponse: AObjectSchema<{
|
|
139
|
-
statusCode: number;
|
|
140
|
-
statusMessage: string;
|
|
141
|
-
stack?: string | undefined;
|
|
142
|
-
data?: any;
|
|
143
|
-
}, false>;
|
|
144
|
-
type ErrorResponse = a.infer<typeof ErrorResponse>;
|
|
145
|
-
declare function defineError(statusCode: StatusCode, input?: Partial<Omit<ErrorResponse, "statusCode" | "stack">> & {
|
|
146
|
-
stack?: string;
|
|
147
|
-
}): H3Error;
|
|
148
|
-
declare function errorResponseFromValidationErrors(errors: ValidationError["errors"], prefixText?: string): H3Error;
|
|
149
|
-
type StatusCode = number | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
|
|
150
|
-
declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOptions["onError"]): Promise<void>;
|
|
151
|
-
|
|
152
228
|
interface ArriConfig {
|
|
153
229
|
port: number;
|
|
154
230
|
entry: string;
|
|
155
|
-
|
|
231
|
+
serverEntry?: string;
|
|
156
232
|
rootDir?: string;
|
|
157
233
|
srcDir?: string;
|
|
158
234
|
procedureDir?: string | false;
|
|
@@ -170,4 +246,4 @@ type ResolvedArriConfig = Required<ArriConfig>;
|
|
|
170
246
|
declare const defaultConfig: Required<ArriConfig>;
|
|
171
247
|
declare function defineConfig(config: ArriConfig): ResolvedArriConfig;
|
|
172
248
|
|
|
173
|
-
export { ArriApp, type ArriConfig, type
|
|
249
|
+
export { ArriApp, type ArriConfig, type ArriOptions, type ArriRoute, ArriRouter, type ArriRouterBase, DEV_DEFINITION_ENDPOINT, DEV_ENDPOINT_ROOT, ErrorResponse, EventStreamConnection, type EventStreamConnectionOptions, type EventStreamRpc, type EventStreamRpcEvent, type EventStreamRpcHandler, type EventStreamRpcHandlerContext, type ExtractParam, type ExtractParams, type HandlerContext, type HttpRpc, type Middleware, type MiddlewareEvent, type MiddlewareEventContext, type ModelMap, type NamedRpc, type PostRouteEvent, type PostRouteEventContext, type ResolvedArriConfig, type RouteEvent, type RouteEventContext, type RouteOptions, type Rpc, type RpcEvent, type RpcHandler, type RpcHandlerContext, type RpcParamSchema, type RpcPostEvent, type RpcPostHandler, type RpcPostHandlerContext, type Sse, type StatusCode, createRpcDefinition, defaultConfig, defineConfig, defineError, defineEventStreamRpc, defineMiddleware, defineRoute, defineRpc, errorResponseFromValidationErrors, formatSse, formatSseList, getRpcParamName, getRpcPath, getRpcResponseName, handleH3Error, handleRoute, isArriConfig, isEventStreamRpc, isResolvedArriConfig, isRpc, isRpcParamSchema, registerEventStreamRpc, registerRoute, registerRpc, setSseHeaders, validateRpcRequestInput };
|