orpc-file-based-router 0.0.1 → 0.0.2
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 +4 -5
- package/dist/index.cjs +20 -16
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +20 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,12 +16,11 @@ yarn add orpc-file-based-router
|
|
|
16
16
|
// generator.ts
|
|
17
17
|
import { generateRouter } from 'orpc-file-based-router'
|
|
18
18
|
|
|
19
|
-
const routesDir = './routes'
|
|
20
|
-
const outputFile = './router.ts'
|
|
19
|
+
const routesDir = new URL('./routes', import.meta.url).pathname
|
|
20
|
+
const outputFile = new URL('./router.ts', import.meta.url).pathname
|
|
21
|
+
const router = await generateRouter(routesDir, outputFile)
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
.then(() => console.log('Router generated successfully'))
|
|
24
|
-
.catch(console.error)
|
|
23
|
+
const handler = new RPCHandler(router)
|
|
25
24
|
```
|
|
26
25
|
|
|
27
26
|
### File Structure Example
|
package/dist/index.cjs
CHANGED
|
@@ -32,37 +32,38 @@ async function generateRouter(routesDir, outputFile) {
|
|
|
32
32
|
routesDir
|
|
33
33
|
);
|
|
34
34
|
const exports = await generateRoutes(files);
|
|
35
|
-
const importPaths = exports.map((x) => path.relative(path.dirname(outputFile), routesDir).concat(x.
|
|
36
|
-
const
|
|
37
|
-
return {
|
|
38
|
-
|
|
39
|
-
routePath: x.routePath
|
|
40
|
-
};
|
|
41
|
-
}));
|
|
35
|
+
const importPaths = exports.map((x) => path.relative(path.dirname(outputFile), routesDir).concat(x.path));
|
|
36
|
+
const content = buildRouter(exports, (r, e) => {
|
|
37
|
+
return `${e}.route({ path: '${r.path}' })`;
|
|
38
|
+
});
|
|
42
39
|
let routerContent = `// This file is auto-generated
|
|
43
40
|
|
|
44
41
|
`;
|
|
45
42
|
routerContent += importPaths.map((x, i) => `import { ${Object.keys(exports[i].exports).join(", ")} } from "./${x}"`).join("\n");
|
|
46
43
|
routerContent += "\n\nexport const router = ";
|
|
47
|
-
routerContent += JSON.stringify(
|
|
44
|
+
routerContent += JSON.stringify(content, null, 2).replace(/"/g, "");
|
|
48
45
|
node_fs.writeFileSync(path.join(outputFile), routerContent);
|
|
46
|
+
const router = buildRouter(exports, (r, e) => {
|
|
47
|
+
return r.exports[e].route({ path: `${r.path}` });
|
|
48
|
+
});
|
|
49
|
+
return router;
|
|
49
50
|
}
|
|
50
51
|
function buildRoutePath(parsedFile) {
|
|
51
52
|
const directory = parsedFile.dir === parsedFile.root ? "" : parsedFile.dir;
|
|
52
53
|
const name = parsedFile.name.startsWith("index") ? parsedFile.name.replace("index", "") : `/${parsedFile.name}`;
|
|
53
54
|
return directory + name;
|
|
54
55
|
}
|
|
55
|
-
function buildRouter(
|
|
56
|
+
function buildRouter(routes, mapper) {
|
|
56
57
|
const router = {};
|
|
57
|
-
for (const
|
|
58
|
-
const segments =
|
|
58
|
+
for (const route of routes) {
|
|
59
|
+
const segments = route.path.replace(/\{\w+\}/g, "").replace(/\/\//g, "/").split("/").filter(Boolean);
|
|
59
60
|
let current = router;
|
|
60
61
|
for (let i = 0; i < segments.length; i++) {
|
|
61
62
|
const segment = segments[i];
|
|
62
63
|
if (i === segments.length - 1) {
|
|
63
64
|
current[segment] = current[segment] || {};
|
|
64
|
-
for (const exp
|
|
65
|
-
current[segment][exp] =
|
|
65
|
+
for (const exp in route.exports) {
|
|
66
|
+
current[segment][exp] = mapper(route, exp);
|
|
66
67
|
}
|
|
67
68
|
} else {
|
|
68
69
|
current[segment] = current[segment] || {};
|
|
@@ -75,7 +76,7 @@ function buildRouter(inputs) {
|
|
|
75
76
|
function simplifyRouter(router) {
|
|
76
77
|
const simplifiedRouter = {};
|
|
77
78
|
for (const key in router) {
|
|
78
|
-
if (typeof router[key] === "string") {
|
|
79
|
+
if (typeof router[key] === "string" || isORPCProcedure(router, key)) {
|
|
79
80
|
simplifiedRouter[key] = router[key];
|
|
80
81
|
} else if (typeof router[key] === "object" && isSingleLeaf(router[key])) {
|
|
81
82
|
const childKey = Object.keys(router[key])[0];
|
|
@@ -86,9 +87,12 @@ function simplifyRouter(router) {
|
|
|
86
87
|
}
|
|
87
88
|
return simplifiedRouter;
|
|
88
89
|
}
|
|
90
|
+
function isORPCProcedure(obj, key) {
|
|
91
|
+
return "~orpc" in obj[key];
|
|
92
|
+
}
|
|
89
93
|
function isSingleLeaf(obj) {
|
|
90
94
|
const keys = Object.keys(obj);
|
|
91
|
-
return keys.length === 1
|
|
95
|
+
return keys.length === 1;
|
|
92
96
|
}
|
|
93
97
|
const isCjs = () => typeof module !== "undefined" && !!module?.exports;
|
|
94
98
|
const IS_ESM = !isCjs();
|
|
@@ -101,7 +105,7 @@ async function generateRoutes(files) {
|
|
|
101
105
|
const exports = await import(MODULE_IMPORT_PREFIX + path__default.join(file.path, file.name));
|
|
102
106
|
routes.push({
|
|
103
107
|
exports,
|
|
104
|
-
routePath
|
|
108
|
+
path: routePath
|
|
105
109
|
});
|
|
106
110
|
}
|
|
107
111
|
return routes;
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -26,37 +26,38 @@ async function generateRouter(routesDir, outputFile) {
|
|
|
26
26
|
routesDir
|
|
27
27
|
);
|
|
28
28
|
const exports = await generateRoutes(files);
|
|
29
|
-
const importPaths = exports.map((x) => relative(dirname(outputFile), routesDir).concat(x.
|
|
30
|
-
const
|
|
31
|
-
return {
|
|
32
|
-
|
|
33
|
-
routePath: x.routePath
|
|
34
|
-
};
|
|
35
|
-
}));
|
|
29
|
+
const importPaths = exports.map((x) => relative(dirname(outputFile), routesDir).concat(x.path));
|
|
30
|
+
const content = buildRouter(exports, (r, e) => {
|
|
31
|
+
return `${e}.route({ path: '${r.path}' })`;
|
|
32
|
+
});
|
|
36
33
|
let routerContent = `// This file is auto-generated
|
|
37
34
|
|
|
38
35
|
`;
|
|
39
36
|
routerContent += importPaths.map((x, i) => `import { ${Object.keys(exports[i].exports).join(", ")} } from "./${x}"`).join("\n");
|
|
40
37
|
routerContent += "\n\nexport const router = ";
|
|
41
|
-
routerContent += JSON.stringify(
|
|
38
|
+
routerContent += JSON.stringify(content, null, 2).replace(/"/g, "");
|
|
42
39
|
writeFileSync(join(outputFile), routerContent);
|
|
40
|
+
const router = buildRouter(exports, (r, e) => {
|
|
41
|
+
return r.exports[e].route({ path: `${r.path}` });
|
|
42
|
+
});
|
|
43
|
+
return router;
|
|
43
44
|
}
|
|
44
45
|
function buildRoutePath(parsedFile) {
|
|
45
46
|
const directory = parsedFile.dir === parsedFile.root ? "" : parsedFile.dir;
|
|
46
47
|
const name = parsedFile.name.startsWith("index") ? parsedFile.name.replace("index", "") : `/${parsedFile.name}`;
|
|
47
48
|
return directory + name;
|
|
48
49
|
}
|
|
49
|
-
function buildRouter(
|
|
50
|
+
function buildRouter(routes, mapper) {
|
|
50
51
|
const router = {};
|
|
51
|
-
for (const
|
|
52
|
-
const segments =
|
|
52
|
+
for (const route of routes) {
|
|
53
|
+
const segments = route.path.replace(/\{\w+\}/g, "").replace(/\/\//g, "/").split("/").filter(Boolean);
|
|
53
54
|
let current = router;
|
|
54
55
|
for (let i = 0; i < segments.length; i++) {
|
|
55
56
|
const segment = segments[i];
|
|
56
57
|
if (i === segments.length - 1) {
|
|
57
58
|
current[segment] = current[segment] || {};
|
|
58
|
-
for (const exp
|
|
59
|
-
current[segment][exp] =
|
|
59
|
+
for (const exp in route.exports) {
|
|
60
|
+
current[segment][exp] = mapper(route, exp);
|
|
60
61
|
}
|
|
61
62
|
} else {
|
|
62
63
|
current[segment] = current[segment] || {};
|
|
@@ -69,7 +70,7 @@ function buildRouter(inputs) {
|
|
|
69
70
|
function simplifyRouter(router) {
|
|
70
71
|
const simplifiedRouter = {};
|
|
71
72
|
for (const key in router) {
|
|
72
|
-
if (typeof router[key] === "string") {
|
|
73
|
+
if (typeof router[key] === "string" || isORPCProcedure(router, key)) {
|
|
73
74
|
simplifiedRouter[key] = router[key];
|
|
74
75
|
} else if (typeof router[key] === "object" && isSingleLeaf(router[key])) {
|
|
75
76
|
const childKey = Object.keys(router[key])[0];
|
|
@@ -80,9 +81,12 @@ function simplifyRouter(router) {
|
|
|
80
81
|
}
|
|
81
82
|
return simplifiedRouter;
|
|
82
83
|
}
|
|
84
|
+
function isORPCProcedure(obj, key) {
|
|
85
|
+
return "~orpc" in obj[key];
|
|
86
|
+
}
|
|
83
87
|
function isSingleLeaf(obj) {
|
|
84
88
|
const keys = Object.keys(obj);
|
|
85
|
-
return keys.length === 1
|
|
89
|
+
return keys.length === 1;
|
|
86
90
|
}
|
|
87
91
|
const isCjs = () => typeof module !== "undefined" && !!module?.exports;
|
|
88
92
|
const IS_ESM = !isCjs();
|
|
@@ -95,7 +99,7 @@ async function generateRoutes(files) {
|
|
|
95
99
|
const exports = await import(MODULE_IMPORT_PREFIX + path.join(file.path, file.name));
|
|
96
100
|
routes.push({
|
|
97
101
|
exports,
|
|
98
|
-
routePath
|
|
102
|
+
path: routePath
|
|
99
103
|
});
|
|
100
104
|
}
|
|
101
105
|
return routes;
|
package/package.json
CHANGED