@hyperspan/framework 0.2.0 → 0.3.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/build.ts +1 -1
- package/dist/server.js +84 -64
- package/package.json +3 -3
- package/src/server.ts +131 -97
package/build.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { build } from 'bun';
|
|
2
2
|
|
|
3
3
|
const entrypoints = ['./src/server.ts', './src/assets.ts'];
|
|
4
|
-
const external = ['@hyperspan/html'
|
|
4
|
+
const external = ['@hyperspan/html'];
|
|
5
5
|
const outdir = './dist';
|
|
6
6
|
const target = 'node';
|
|
7
7
|
const splitting = true;
|
package/dist/server.js
CHANGED
|
@@ -1833,6 +1833,7 @@ function createConfig(config) {
|
|
|
1833
1833
|
}
|
|
1834
1834
|
function createRoute(handler) {
|
|
1835
1835
|
let _handlers = {};
|
|
1836
|
+
let _middleware = [];
|
|
1836
1837
|
if (handler) {
|
|
1837
1838
|
_handlers["GET"] = handler;
|
|
1838
1839
|
}
|
|
@@ -1858,34 +1859,52 @@ function createRoute(handler) {
|
|
|
1858
1859
|
_handlers["PATCH"] = handler2;
|
|
1859
1860
|
return api;
|
|
1860
1861
|
},
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1862
|
+
middleware(middleware) {
|
|
1863
|
+
_middleware = middleware;
|
|
1864
|
+
return api;
|
|
1865
|
+
},
|
|
1866
|
+
_getRouteHandlers() {
|
|
1867
|
+
return [
|
|
1868
|
+
..._middleware,
|
|
1869
|
+
async (context) => {
|
|
1870
|
+
const method = context.req.method.toUpperCase();
|
|
1871
|
+
try {
|
|
1872
|
+
const handler2 = _handlers[method];
|
|
1873
|
+
if (!handler2) {
|
|
1874
|
+
throw new HTTPException(405, { message: "Method not allowed" });
|
|
1875
|
+
}
|
|
1876
|
+
const routeContent = await handler2(context);
|
|
1877
|
+
if (routeContent instanceof Response) {
|
|
1878
|
+
return routeContent;
|
|
1879
|
+
}
|
|
1880
|
+
const userIsBot = isbot(context.req.header("User-Agent"));
|
|
1881
|
+
const streamOpt = context.req.query("__nostream");
|
|
1882
|
+
const streamingEnabled = !userIsBot && (streamOpt !== undefined ? streamOpt : true);
|
|
1883
|
+
if (isHSHtml(routeContent)) {
|
|
1884
|
+
if (streamingEnabled) {
|
|
1885
|
+
return new StreamResponse(renderStream(routeContent));
|
|
1886
|
+
} else {
|
|
1887
|
+
const output = await renderAsync(routeContent);
|
|
1888
|
+
return context.html(output);
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
if (routeContent instanceof Response) {
|
|
1892
|
+
return routeContent;
|
|
1893
|
+
}
|
|
1894
|
+
return context.text(String(routeContent));
|
|
1895
|
+
} catch (e) {
|
|
1896
|
+
!IS_PROD && console.error(e);
|
|
1897
|
+
return await showErrorReponse(context, e);
|
|
1898
|
+
}
|
|
1880
1899
|
}
|
|
1881
|
-
|
|
1882
|
-
return context.text(String(routeContent));
|
|
1900
|
+
];
|
|
1883
1901
|
}
|
|
1884
1902
|
};
|
|
1885
1903
|
return api;
|
|
1886
1904
|
}
|
|
1887
1905
|
function createAPIRoute(handler) {
|
|
1888
1906
|
let _handlers = {};
|
|
1907
|
+
let _middleware = [];
|
|
1889
1908
|
if (handler) {
|
|
1890
1909
|
_handlers["GET"] = handler;
|
|
1891
1910
|
}
|
|
@@ -1911,30 +1930,46 @@ function createAPIRoute(handler) {
|
|
|
1911
1930
|
_handlers["PATCH"] = handler2;
|
|
1912
1931
|
return api;
|
|
1913
1932
|
},
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1933
|
+
middleware(middleware) {
|
|
1934
|
+
_middleware = middleware;
|
|
1935
|
+
return api;
|
|
1936
|
+
},
|
|
1937
|
+
_getRouteHandlers() {
|
|
1938
|
+
return [
|
|
1939
|
+
..._middleware,
|
|
1940
|
+
async (context) => {
|
|
1941
|
+
const method = context.req.method.toUpperCase();
|
|
1942
|
+
const handler2 = _handlers[method];
|
|
1943
|
+
if (!handler2) {
|
|
1944
|
+
return context.json({
|
|
1945
|
+
meta: { success: false, dtResponse: new Date },
|
|
1946
|
+
data: {},
|
|
1947
|
+
error: {
|
|
1948
|
+
message: "Method not allowed"
|
|
1949
|
+
}
|
|
1950
|
+
}, { status: 405 });
|
|
1951
|
+
}
|
|
1952
|
+
try {
|
|
1953
|
+
const response = await handler2(context);
|
|
1954
|
+
if (response instanceof Response) {
|
|
1955
|
+
return response;
|
|
1956
|
+
}
|
|
1957
|
+
return context.json({ meta: { success: true, dtResponse: new Date }, data: response }, { status: 200 });
|
|
1958
|
+
} catch (err) {
|
|
1959
|
+
const e = err;
|
|
1960
|
+
!IS_PROD && console.error(e);
|
|
1961
|
+
return context.json({
|
|
1962
|
+
meta: { success: false, dtResponse: new Date },
|
|
1963
|
+
data: {},
|
|
1964
|
+
error: {
|
|
1965
|
+
message: e.message,
|
|
1966
|
+
stack: IS_PROD ? undefined : e.stack?.split(`
|
|
1934
1967
|
`)
|
|
1968
|
+
}
|
|
1969
|
+
}, { status: 500 });
|
|
1935
1970
|
}
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1971
|
+
}
|
|
1972
|
+
];
|
|
1938
1973
|
}
|
|
1939
1974
|
};
|
|
1940
1975
|
return api;
|
|
@@ -1950,13 +1985,10 @@ function getRunnableRoute(route) {
|
|
|
1950
1985
|
if (kind === "object" && "default" in route) {
|
|
1951
1986
|
return getRunnableRoute(route.default);
|
|
1952
1987
|
}
|
|
1953
|
-
throw new Error(
|
|
1988
|
+
throw new Error(`Route not runnable. Use "export default createRoute()" to create a Hyperspan route. Exported methods found were: ${Object.keys(route).join(", ")}`);
|
|
1954
1989
|
}
|
|
1955
1990
|
function isRunnableRoute(route) {
|
|
1956
|
-
return typeof route === "object" && "
|
|
1957
|
-
}
|
|
1958
|
-
function createLayout(layout) {
|
|
1959
|
-
return layout;
|
|
1991
|
+
return typeof route === "object" && "_getRouteHandlers" in route;
|
|
1960
1992
|
}
|
|
1961
1993
|
async function showErrorReponse(context, err) {
|
|
1962
1994
|
const output = render(html`
|
|
@@ -2009,20 +2041,8 @@ async function buildRoutes(config) {
|
|
|
2009
2041
|
return routes;
|
|
2010
2042
|
}
|
|
2011
2043
|
function createRouteFromModule(RouteModule) {
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
try {
|
|
2015
|
-
const runnableRoute = getRunnableRoute(RouteModule);
|
|
2016
|
-
const content = await runnableRoute.run(reqMethod, context);
|
|
2017
|
-
if (content instanceof Response) {
|
|
2018
|
-
return content;
|
|
2019
|
-
}
|
|
2020
|
-
return context.text(String(content));
|
|
2021
|
-
} catch (e) {
|
|
2022
|
-
console.error(e);
|
|
2023
|
-
return await showErrorReponse(context, e);
|
|
2024
|
-
}
|
|
2025
|
-
};
|
|
2044
|
+
const route = getRunnableRoute(RouteModule);
|
|
2045
|
+
return route._getRouteHandlers();
|
|
2026
2046
|
}
|
|
2027
2047
|
async function createServer(config) {
|
|
2028
2048
|
await Promise.all([buildClientJS(), buildClientCSS()]);
|
|
@@ -2035,7 +2055,8 @@ async function createServer(config) {
|
|
|
2035
2055
|
const fullRouteFile = join(CWD, route.file);
|
|
2036
2056
|
const routePattern = normalizePath(route.route);
|
|
2037
2057
|
routeMap.push({ route: routePattern, file: route.file });
|
|
2038
|
-
|
|
2058
|
+
const routeHandlers = createRouteFromModule(await import(fullRouteFile));
|
|
2059
|
+
app.all(routePattern, ...routeHandlers);
|
|
2039
2060
|
}
|
|
2040
2061
|
if (routeMap.length === 0) {
|
|
2041
2062
|
app.get("/", (context) => {
|
|
@@ -2101,7 +2122,6 @@ export {
|
|
|
2101
2122
|
createRouteFromModule,
|
|
2102
2123
|
createRoute,
|
|
2103
2124
|
createReadableStreamFromAsyncGenerator,
|
|
2104
|
-
createLayout,
|
|
2105
2125
|
createConfig,
|
|
2106
2126
|
createAPIRoute,
|
|
2107
2127
|
buildRoutes,
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperspan/framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Hyperspan Web Framework",
|
|
5
|
-
"main": "dist/server.
|
|
5
|
+
"main": "dist/server.ts",
|
|
6
6
|
"types": "src/server.ts",
|
|
7
7
|
"public": true,
|
|
8
8
|
"publishConfig": {
|
|
@@ -63,6 +63,6 @@
|
|
|
63
63
|
"@hyperspan/html": "^0.1.7",
|
|
64
64
|
"hono": "^4.7.10",
|
|
65
65
|
"isbot": "^5.1.28",
|
|
66
|
-
"zod": "^3.25.
|
|
66
|
+
"zod": "^3.25.42"
|
|
67
67
|
}
|
|
68
68
|
}
|
package/src/server.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { buildClientJS, buildClientCSS } from './assets';
|
|
|
6
6
|
import { Hono, type Context } from 'hono';
|
|
7
7
|
import { serveStatic } from 'hono/bun';
|
|
8
8
|
import { HTTPException } from 'hono/http-exception';
|
|
9
|
+
import type { HandlerResponse, MiddlewareHandler } from 'hono/types';
|
|
9
10
|
|
|
10
11
|
export const IS_PROD = process.env.NODE_ENV === 'production';
|
|
11
12
|
const CWD = process.cwd();
|
|
@@ -15,8 +16,7 @@ const CWD = process.cwd();
|
|
|
15
16
|
*/
|
|
16
17
|
export type THSResponseTypes = HSHtml | Response | string | null;
|
|
17
18
|
export type THSRouteHandler = (context: Context) => THSResponseTypes | Promise<THSResponseTypes>;
|
|
18
|
-
export type
|
|
19
|
-
export type THSAPIRouteHandler = (context: Context) => THSResponseTypes | Promise<THSResponseTypes>;
|
|
19
|
+
export type THSAPIRouteHandler = (context: Context) => Promise<any> | any;
|
|
20
20
|
|
|
21
21
|
export type THSRoute = {
|
|
22
22
|
_kind: 'hsRoute';
|
|
@@ -25,7 +25,18 @@ export type THSRoute = {
|
|
|
25
25
|
put: (handler: THSRouteHandler) => THSRoute;
|
|
26
26
|
delete: (handler: THSRouteHandler) => THSRoute;
|
|
27
27
|
patch: (handler: THSRouteHandler) => THSRoute;
|
|
28
|
-
|
|
28
|
+
middleware: (middleware: Array<MiddlewareHandler>) => THSRoute;
|
|
29
|
+
_getRouteHandlers: () => Array<MiddlewareHandler | ((context: Context) => HandlerResponse<any>)>;
|
|
30
|
+
};
|
|
31
|
+
export type THSAPIRoute = {
|
|
32
|
+
_kind: 'hsAPIRoute';
|
|
33
|
+
get: (handler: THSAPIRouteHandler) => THSAPIRoute;
|
|
34
|
+
post: (handler: THSAPIRouteHandler) => THSAPIRoute;
|
|
35
|
+
put: (handler: THSAPIRouteHandler) => THSAPIRoute;
|
|
36
|
+
delete: (handler: THSAPIRouteHandler) => THSAPIRoute;
|
|
37
|
+
patch: (handler: THSAPIRouteHandler) => THSAPIRoute;
|
|
38
|
+
middleware: (middleware: Array<MiddlewareHandler>) => THSAPIRoute;
|
|
39
|
+
_getRouteHandlers: () => Array<MiddlewareHandler | ((context: Context) => HandlerResponse<any>)>;
|
|
29
40
|
};
|
|
30
41
|
|
|
31
42
|
export function createConfig(config: THSServerConfig): THSServerConfig {
|
|
@@ -38,6 +49,7 @@ export function createConfig(config: THSServerConfig): THSServerConfig {
|
|
|
38
49
|
*/
|
|
39
50
|
export function createRoute(handler?: THSRouteHandler): THSRoute {
|
|
40
51
|
let _handlers: Record<string, THSRouteHandler> = {};
|
|
52
|
+
let _middleware: Array<MiddlewareHandler> = [];
|
|
41
53
|
|
|
42
54
|
if (handler) {
|
|
43
55
|
_handlers['GET'] = handler;
|
|
@@ -65,37 +77,57 @@ export function createRoute(handler?: THSRouteHandler): THSRoute {
|
|
|
65
77
|
_handlers['PATCH'] = handler;
|
|
66
78
|
return api;
|
|
67
79
|
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
80
|
+
middleware(middleware: Array<MiddlewareHandler>) {
|
|
81
|
+
_middleware = middleware;
|
|
82
|
+
return api;
|
|
83
|
+
},
|
|
84
|
+
_getRouteHandlers() {
|
|
85
|
+
return [
|
|
86
|
+
..._middleware,
|
|
87
|
+
async (context: Context) => {
|
|
88
|
+
const method = context.req.method.toUpperCase();
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const handler = _handlers[method];
|
|
92
|
+
if (!handler) {
|
|
93
|
+
throw new HTTPException(405, { message: 'Method not allowed' });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const routeContent = await handler(context);
|
|
97
|
+
|
|
98
|
+
// Return Response if returned from route handler
|
|
99
|
+
if (routeContent instanceof Response) {
|
|
100
|
+
return routeContent;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// @TODO: Move this to config or something...
|
|
104
|
+
const userIsBot = isbot(context.req.header('User-Agent'));
|
|
105
|
+
const streamOpt = context.req.query('__nostream');
|
|
106
|
+
const streamingEnabled = !userIsBot && (streamOpt !== undefined ? streamOpt : true);
|
|
107
|
+
|
|
108
|
+
// Render HSHtml if returned from route handler
|
|
109
|
+
if (isHSHtml(routeContent)) {
|
|
110
|
+
if (streamingEnabled) {
|
|
111
|
+
return new StreamResponse(renderStream(routeContent as HSHtml)) as Response;
|
|
112
|
+
} else {
|
|
113
|
+
const output = await renderAsync(routeContent as HSHtml);
|
|
114
|
+
return context.html(output);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Return custom Response if returned from route handler
|
|
119
|
+
if (routeContent instanceof Response) {
|
|
120
|
+
return routeContent;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Return unknown content - not specifically handled above
|
|
124
|
+
return context.text(String(routeContent));
|
|
125
|
+
} catch (e) {
|
|
126
|
+
!IS_PROD && console.error(e);
|
|
127
|
+
return await showErrorReponse(context, e as Error);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
];
|
|
99
131
|
},
|
|
100
132
|
};
|
|
101
133
|
|
|
@@ -106,14 +138,15 @@ export function createRoute(handler?: THSRouteHandler): THSRoute {
|
|
|
106
138
|
* Create new API Route
|
|
107
139
|
* API Route handlers should return a JSON object or a Response
|
|
108
140
|
*/
|
|
109
|
-
export function createAPIRoute(handler?: THSAPIRouteHandler):
|
|
141
|
+
export function createAPIRoute(handler?: THSAPIRouteHandler): THSAPIRoute {
|
|
110
142
|
let _handlers: Record<string, THSAPIRouteHandler> = {};
|
|
143
|
+
let _middleware: Array<MiddlewareHandler> = [];
|
|
111
144
|
|
|
112
145
|
if (handler) {
|
|
113
146
|
_handlers['GET'] = handler;
|
|
114
147
|
}
|
|
115
148
|
|
|
116
|
-
const api:
|
|
149
|
+
const api: THSAPIRoute = {
|
|
117
150
|
_kind: 'hsRoute',
|
|
118
151
|
get(handler: THSAPIRouteHandler) {
|
|
119
152
|
_handlers['GET'] = handler;
|
|
@@ -135,39 +168,59 @@ export function createAPIRoute(handler?: THSAPIRouteHandler): THSRoute {
|
|
|
135
168
|
_handlers['PATCH'] = handler;
|
|
136
169
|
return api;
|
|
137
170
|
},
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
171
|
+
middleware(middleware: Array<MiddlewareHandler>) {
|
|
172
|
+
_middleware = middleware;
|
|
173
|
+
return api;
|
|
174
|
+
},
|
|
175
|
+
_getRouteHandlers() {
|
|
176
|
+
return [
|
|
177
|
+
..._middleware,
|
|
178
|
+
async (context: Context) => {
|
|
179
|
+
const method = context.req.method.toUpperCase();
|
|
180
|
+
const handler = _handlers[method];
|
|
181
|
+
|
|
182
|
+
if (!handler) {
|
|
183
|
+
return context.json(
|
|
184
|
+
{
|
|
185
|
+
meta: { success: false, dtResponse: new Date() },
|
|
186
|
+
data: {},
|
|
187
|
+
error: {
|
|
188
|
+
message: 'Method not allowed',
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{ status: 405 }
|
|
192
|
+
);
|
|
193
|
+
}
|
|
150
194
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
195
|
+
try {
|
|
196
|
+
const response = await handler(context);
|
|
197
|
+
|
|
198
|
+
if (response instanceof Response) {
|
|
199
|
+
return response;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return context.json(
|
|
203
|
+
{ meta: { success: true, dtResponse: new Date() }, data: response },
|
|
204
|
+
{ status: 200 }
|
|
205
|
+
);
|
|
206
|
+
} catch (err) {
|
|
207
|
+
const e = err as Error;
|
|
208
|
+
!IS_PROD && console.error(e);
|
|
209
|
+
|
|
210
|
+
return context.json(
|
|
211
|
+
{
|
|
212
|
+
meta: { success: false, dtResponse: new Date() },
|
|
213
|
+
data: {},
|
|
214
|
+
error: {
|
|
215
|
+
message: e.message,
|
|
216
|
+
stack: IS_PROD ? undefined : e.stack?.split('\n'),
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
{ status: 500 }
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
];
|
|
171
224
|
},
|
|
172
225
|
};
|
|
173
226
|
|
|
@@ -199,21 +252,13 @@ export function getRunnableRoute(route: unknown): THSRoute {
|
|
|
199
252
|
|
|
200
253
|
// No route -> error
|
|
201
254
|
throw new Error(
|
|
202
|
-
|
|
255
|
+
`Route not runnable. Use "export default createRoute()" to create a Hyperspan route. Exported methods found were: ${Object.keys(route as {}).join(', ')}`
|
|
203
256
|
);
|
|
204
257
|
}
|
|
205
258
|
|
|
206
259
|
export function isRunnableRoute(route: unknown): boolean {
|
|
207
260
|
// @ts-ignore
|
|
208
|
-
return typeof route === 'object' && '
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Create a layout for a Hyperspan app. Passthrough for now.
|
|
213
|
-
* Future intent is to be able to conditionally render a layout for full page content vs. partial content.
|
|
214
|
-
*/
|
|
215
|
-
export function createLayout<T>(layout: (props: T) => HSHtml | Promise<HSHtml>) {
|
|
216
|
-
return layout;
|
|
261
|
+
return typeof route === 'object' && '_getRouteHandlers' in route;
|
|
217
262
|
}
|
|
218
263
|
|
|
219
264
|
/**
|
|
@@ -305,24 +350,11 @@ export async function buildRoutes(config: THSServerConfig): Promise<THSRouteMap[
|
|
|
305
350
|
/**
|
|
306
351
|
* Run route from file
|
|
307
352
|
*/
|
|
308
|
-
export function createRouteFromModule(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const runnableRoute = getRunnableRoute(RouteModule);
|
|
314
|
-
const content = await runnableRoute.run(reqMethod, context);
|
|
315
|
-
|
|
316
|
-
if (content instanceof Response) {
|
|
317
|
-
return content;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return context.text(String(content));
|
|
321
|
-
} catch (e) {
|
|
322
|
-
console.error(e);
|
|
323
|
-
return await showErrorReponse(context, e as Error);
|
|
324
|
-
}
|
|
325
|
-
};
|
|
353
|
+
export function createRouteFromModule(
|
|
354
|
+
RouteModule: any
|
|
355
|
+
): Array<MiddlewareHandler | ((context: Context) => HandlerResponse<any>)> {
|
|
356
|
+
const route = getRunnableRoute(RouteModule);
|
|
357
|
+
return route._getRouteHandlers();
|
|
326
358
|
}
|
|
327
359
|
|
|
328
360
|
/**
|
|
@@ -349,7 +381,8 @@ export async function createServer(config: THSServerConfig): Promise<Hono> {
|
|
|
349
381
|
routeMap.push({ route: routePattern, file: route.file });
|
|
350
382
|
|
|
351
383
|
// Import route
|
|
352
|
-
|
|
384
|
+
const routeHandlers = createRouteFromModule(await import(fullRouteFile));
|
|
385
|
+
app.all(routePattern, ...routeHandlers);
|
|
353
386
|
}
|
|
354
387
|
|
|
355
388
|
// Help route if no routes found
|
|
@@ -386,6 +419,7 @@ export async function createServer(config: THSServerConfig): Promise<Hono> {
|
|
|
386
419
|
);
|
|
387
420
|
|
|
388
421
|
app.notFound((context) => {
|
|
422
|
+
// @TODO: Add a custom 404 route
|
|
389
423
|
return context.text('Not... found?', { status: 404 });
|
|
390
424
|
});
|
|
391
425
|
|