orpc-file-based-router 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -9
- package/dist/index.cjs +16 -11
- package/dist/index.d.cts +10 -3
- package/dist/index.d.mts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.mjs +16 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,10 +9,6 @@ structure, inspired by Next.js and express-file-routing approaches.
|
|
|
9
9
|
- 🔄 **Zero Configuration**: Generate routes automatically based on your directory structure
|
|
10
10
|
- ⚡️ **Development Speed**: Eliminate boilerplate code and reduce maintenance overhead
|
|
11
11
|
- 🔍 **Dynamic Routing**: Support for path parameters using `{param}` syntax in file names
|
|
12
|
-
- 📑 **Index Routes**: Support for index routes via `index.ts` files
|
|
13
|
-
|
|
14
|
-
> ⚠️ **IMPORTANT:** At this time, the plugin's functionality is only guaranteed
|
|
15
|
-
> in nodejs runtime
|
|
16
12
|
|
|
17
13
|
## Quickstart
|
|
18
14
|
|
|
@@ -62,17 +58,18 @@ const router = await createRouter(routesDir);
|
|
|
62
58
|
const handler = new RPCHandler(router);
|
|
63
59
|
|
|
64
60
|
```
|
|
65
|
-
|
|
61
|
+
**Note:** If your environment doesn't support top-level await, just use `lazy` for example in expressjs it could be:
|
|
66
62
|
```typescript
|
|
67
63
|
import { RPCHandler } from "@orpc/server/node";
|
|
68
|
-
import {
|
|
64
|
+
import { lazy, createRouter } from "orpc-file-based-router";
|
|
69
65
|
|
|
70
66
|
const routesDir = new URL("./routes", import.meta.url).pathname;
|
|
71
|
-
|
|
67
|
+
|
|
68
|
+
const router = lazy(() => createRouter(routesDir))
|
|
72
69
|
|
|
73
70
|
app.use('/rpc{/*path}', async (req, res, next) => {
|
|
74
71
|
|
|
75
|
-
const handler = new RPCHandler(await router
|
|
72
|
+
const handler = new RPCHandler(await router());
|
|
76
73
|
|
|
77
74
|
const { matched } = await handler.handle(req, res, {
|
|
78
75
|
prefix: '/rpc',
|
|
@@ -90,7 +87,7 @@ app.use('/rpc{/*path}', async (req, res, next) => {
|
|
|
90
87
|
|
|
91
88
|
For users of the [oRPC client](https://orpc.unnoq.com/docs/client/client-side), we provide automatic configuration generation for enhanced type safety and improved developer experience.
|
|
92
89
|
|
|
93
|
-
1.
|
|
90
|
+
1. You can add this code either directly in your server project (e.g., in server.ts or main.ts) or put it into a separate script (e.g., router-gen.ts).
|
|
94
91
|
|
|
95
92
|
```typescript
|
|
96
93
|
import { generateRouter } from "orpc-file-based-router";
|
|
@@ -102,6 +99,8 @@ generateRouter(routesDir, outputFile);
|
|
|
102
99
|
|
|
103
100
|
2. Generated router is ready to use in client:
|
|
104
101
|
|
|
102
|
+
> ⚠️ If you don't want plugin to generate openapi `route({})` suffix, just set parameter `includeRoute` to `false`
|
|
103
|
+
|
|
105
104
|
```typescript
|
|
106
105
|
// router.ts
|
|
107
106
|
import { me } from "./routes/auth/me";
|
|
@@ -130,6 +129,7 @@ export const router = {
|
|
|
130
129
|
sse: sse.route({ path: "/sse" }),
|
|
131
130
|
};
|
|
132
131
|
|
|
132
|
+
|
|
133
133
|
// lib/orpc.ts
|
|
134
134
|
const client: RouterClient<typeof router> = createORPCClient(link)
|
|
135
135
|
|
|
@@ -142,6 +142,7 @@ When using `generateRouter`, you can provide additional options to customize the
|
|
|
142
142
|
| Field | Type | Required | Default Value | Description |
|
|
143
143
|
|-------------------|----------|--------------|-----------------------|------------------------------------------------------------------------------------------------------------------------------|
|
|
144
144
|
| `importExtension` | string | false | `""`(No extension) | File extension to append to import statements in the generated router. Useful when your build setup requires specific extensions. <br>Example: `.js` → `import { me } from "./routes/auth/me.js"` |
|
|
145
|
+
| `includeRoute` | boolean | false | `true` | When set to true, each route will be wrapped with openapi `.route({ path: '...' })` call |
|
|
145
146
|
|
|
146
147
|
|
|
147
148
|
|
package/dist/index.cjs
CHANGED
|
@@ -36,17 +36,19 @@ async function createRouter(routesDir) {
|
|
|
36
36
|
return r.exports[e].route({ path: `${r.path}` });
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
router = await createRouter(routesDir);
|
|
45
|
-
}
|
|
46
|
-
return router;
|
|
39
|
+
const lazy = (create) => {
|
|
40
|
+
let cache = null;
|
|
41
|
+
const fn = () => {
|
|
42
|
+
if (!cache) {
|
|
43
|
+
cache = Promise.resolve(create());
|
|
47
44
|
}
|
|
45
|
+
return cache;
|
|
48
46
|
};
|
|
49
|
-
|
|
47
|
+
fn.reset = () => {
|
|
48
|
+
cache = null;
|
|
49
|
+
};
|
|
50
|
+
return fn;
|
|
51
|
+
};
|
|
50
52
|
async function generateRouter(routesDir, outputFile, options) {
|
|
51
53
|
const files = walkTree(
|
|
52
54
|
routesDir
|
|
@@ -54,7 +56,10 @@ async function generateRouter(routesDir, outputFile, options) {
|
|
|
54
56
|
const exports = await generateRoutes(files);
|
|
55
57
|
const importPaths = exports.map((x) => path.relative(path.dirname(outputFile), routesDir).concat(x.path));
|
|
56
58
|
const content = buildRouter(exports, (r, e) => {
|
|
57
|
-
|
|
59
|
+
if (options?.includeRoute ?? true) {
|
|
60
|
+
return `${e}.route({ path: '${r.path.replace(/\/{0,1}index$/, "")}' })`;
|
|
61
|
+
}
|
|
62
|
+
return e;
|
|
58
63
|
});
|
|
59
64
|
let routerContent = `// This file is auto-generated
|
|
60
65
|
|
|
@@ -131,6 +136,6 @@ async function generateRoutes(files) {
|
|
|
131
136
|
return routes;
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
exports.cachedRouter = cachedRouter;
|
|
135
139
|
exports.createRouter = createRouter;
|
|
136
140
|
exports.generateRouter = generateRouter;
|
|
141
|
+
exports.lazy = lazy;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare function createRouter(routesDir: string): Promise<Router>;
|
|
2
|
-
declare
|
|
3
|
-
|
|
2
|
+
declare const lazy: <T>(create: () => Promise<T> | T) => {
|
|
3
|
+
(): Promise<T>;
|
|
4
|
+
reset(): void;
|
|
4
5
|
};
|
|
5
6
|
type GeneratorOptions = {
|
|
6
7
|
/**
|
|
@@ -10,8 +11,14 @@ type GeneratorOptions = {
|
|
|
10
11
|
* @default "" (no extension)
|
|
11
12
|
*/
|
|
12
13
|
importExtension?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Include openapi route paths in the generated router.
|
|
16
|
+
* When set to true, each route will have its openapi path
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
includeRoute?: boolean;
|
|
13
20
|
};
|
|
14
21
|
declare function generateRouter(routesDir: string, outputFile: string, options?: GeneratorOptions): Promise<void>;
|
|
15
22
|
type Router = Record<string, any>;
|
|
16
23
|
|
|
17
|
-
export {
|
|
24
|
+
export { createRouter, generateRouter, lazy };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare function createRouter(routesDir: string): Promise<Router>;
|
|
2
|
-
declare
|
|
3
|
-
|
|
2
|
+
declare const lazy: <T>(create: () => Promise<T> | T) => {
|
|
3
|
+
(): Promise<T>;
|
|
4
|
+
reset(): void;
|
|
4
5
|
};
|
|
5
6
|
type GeneratorOptions = {
|
|
6
7
|
/**
|
|
@@ -10,8 +11,14 @@ type GeneratorOptions = {
|
|
|
10
11
|
* @default "" (no extension)
|
|
11
12
|
*/
|
|
12
13
|
importExtension?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Include openapi route paths in the generated router.
|
|
16
|
+
* When set to true, each route will have its openapi path
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
includeRoute?: boolean;
|
|
13
20
|
};
|
|
14
21
|
declare function generateRouter(routesDir: string, outputFile: string, options?: GeneratorOptions): Promise<void>;
|
|
15
22
|
type Router = Record<string, any>;
|
|
16
23
|
|
|
17
|
-
export {
|
|
24
|
+
export { createRouter, generateRouter, lazy };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare function createRouter(routesDir: string): Promise<Router>;
|
|
2
|
-
declare
|
|
3
|
-
|
|
2
|
+
declare const lazy: <T>(create: () => Promise<T> | T) => {
|
|
3
|
+
(): Promise<T>;
|
|
4
|
+
reset(): void;
|
|
4
5
|
};
|
|
5
6
|
type GeneratorOptions = {
|
|
6
7
|
/**
|
|
@@ -10,8 +11,14 @@ type GeneratorOptions = {
|
|
|
10
11
|
* @default "" (no extension)
|
|
11
12
|
*/
|
|
12
13
|
importExtension?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Include openapi route paths in the generated router.
|
|
16
|
+
* When set to true, each route will have its openapi path
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
includeRoute?: boolean;
|
|
13
20
|
};
|
|
14
21
|
declare function generateRouter(routesDir: string, outputFile: string, options?: GeneratorOptions): Promise<void>;
|
|
15
22
|
type Router = Record<string, any>;
|
|
16
23
|
|
|
17
|
-
export {
|
|
24
|
+
export { createRouter, generateRouter, lazy };
|
package/dist/index.mjs
CHANGED
|
@@ -30,17 +30,19 @@ async function createRouter(routesDir) {
|
|
|
30
30
|
return r.exports[e].route({ path: `${r.path}` });
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
router = await createRouter(routesDir);
|
|
39
|
-
}
|
|
40
|
-
return router;
|
|
33
|
+
const lazy = (create) => {
|
|
34
|
+
let cache = null;
|
|
35
|
+
const fn = () => {
|
|
36
|
+
if (!cache) {
|
|
37
|
+
cache = Promise.resolve(create());
|
|
41
38
|
}
|
|
39
|
+
return cache;
|
|
42
40
|
};
|
|
43
|
-
|
|
41
|
+
fn.reset = () => {
|
|
42
|
+
cache = null;
|
|
43
|
+
};
|
|
44
|
+
return fn;
|
|
45
|
+
};
|
|
44
46
|
async function generateRouter(routesDir, outputFile, options) {
|
|
45
47
|
const files = walkTree(
|
|
46
48
|
routesDir
|
|
@@ -48,7 +50,10 @@ async function generateRouter(routesDir, outputFile, options) {
|
|
|
48
50
|
const exports = await generateRoutes(files);
|
|
49
51
|
const importPaths = exports.map((x) => relative(dirname(outputFile), routesDir).concat(x.path));
|
|
50
52
|
const content = buildRouter(exports, (r, e) => {
|
|
51
|
-
|
|
53
|
+
if (options?.includeRoute ?? true) {
|
|
54
|
+
return `${e}.route({ path: '${r.path.replace(/\/{0,1}index$/, "")}' })`;
|
|
55
|
+
}
|
|
56
|
+
return e;
|
|
52
57
|
});
|
|
53
58
|
let routerContent = `// This file is auto-generated
|
|
54
59
|
|
|
@@ -125,4 +130,4 @@ async function generateRoutes(files) {
|
|
|
125
130
|
return routes;
|
|
126
131
|
}
|
|
127
132
|
|
|
128
|
-
export {
|
|
133
|
+
export { createRouter, generateRouter, lazy };
|
package/package.json
CHANGED