@gracile/engine 0.7.0-next.0 → 0.7.0-next.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/dist/build/static.d.ts.map +1 -1
- package/dist/build/static.js +6 -1
- package/dist/dev/dev.d.ts.map +1 -1
- package/dist/dev/dev.js +23 -16
- package/dist/dev/vite-logger.d.ts +2 -0
- package/dist/dev/vite-logger.d.ts.map +1 -0
- package/dist/dev/vite-logger.js +2 -0
- package/dist/errors/create-vite-better-error.d.ts +6 -0
- package/dist/errors/create-vite-better-error.d.ts.map +1 -0
- package/dist/errors/create-vite-better-error.js +27 -0
- package/dist/errors/errors-data.d.ts +81 -0
- package/dist/errors/errors-data.d.ts.map +1 -0
- package/dist/errors/errors-data.js +98 -0
- package/dist/errors/errors.d.ts +22 -0
- package/dist/errors/errors.d.ts.map +1 -0
- package/dist/errors/errors.js +122 -0
- package/dist/errors/pages.d.ts +4 -0
- package/dist/errors/pages.d.ts.map +1 -0
- package/dist/errors/pages.js +135 -0
- package/dist/logging/messages.d.ts +2 -0
- package/dist/logging/messages.d.ts.map +1 -0
- package/dist/logging/messages.js +6 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +33 -5
- package/dist/render/route-template.d.ts.map +1 -1
- package/dist/render/route-template.js +37 -9
- package/dist/routes/collect.d.ts +2 -1
- package/dist/routes/collect.d.ts.map +1 -1
- package/dist/routes/collect.js +13 -9
- package/dist/routes/load-module.d.ts +1 -1
- package/dist/routes/load-module.d.ts.map +1 -1
- package/dist/routes/load-module.js +31 -5
- package/dist/routes/match.d.ts +1 -1
- package/dist/routes/match.d.ts.map +1 -1
- package/dist/routes/match.js +24 -10
- package/dist/routes/route.d.ts +1 -1
- package/dist/routes/route.d.ts.map +1 -1
- package/dist/routes/route.js +14 -12
- package/dist/server/adapters/hono.d.ts +5 -2
- package/dist/server/adapters/hono.d.ts.map +1 -1
- package/dist/server/adapters/hono.js +9 -3
- package/dist/server/adapters/node.d.ts +4 -2
- package/dist/server/adapters/node.d.ts.map +1 -1
- package/dist/server/adapters/node.js +24 -9
- package/dist/server/request.d.ts +4 -1
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +44 -42
- package/dist/server/utils.d.ts.map +1 -1
- package/dist/server/utils.js +2 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vite/plugins/build-routes.d.ts.map +1 -1
- package/dist/vite/plugins/build-routes.js +5 -3
- package/dist/vite/plugins/virtual-routes.d.ts.map +1 -1
- package/dist/vite/plugins/virtual-routes.js +3 -2
- package/package.json +5 -4
- package/dist/assertions.d.ts +0 -13
- package/dist/assertions.d.ts.map +0 -1
- package/dist/assertions.js +0 -45
- package/dist/errors/templates.d.ts +0 -3
- package/dist/errors/templates.d.ts.map +0 -1
- package/dist/errors/templates.js +0 -69
package/dist/plugin.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import { createLogger } from '@gracile/internal-utils/logger/helpers';
|
|
3
|
+
import { getVersion } from '@gracile/internal-utils/version';
|
|
4
|
+
import { betterErrors } from '@gracile-labs/better-errors/plugin';
|
|
3
5
|
import { rename, rm } from 'fs/promises';
|
|
4
6
|
import c from 'picocolors';
|
|
5
7
|
import { build, createServer } from 'vite';
|
|
@@ -31,6 +33,7 @@ let isClientBuilt = false;
|
|
|
31
33
|
// This `any[]` AND with a plugin -array- makes ESLint and TS shut up.
|
|
32
34
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
35
|
export const gracile = (config) => {
|
|
36
|
+
const logger = createLogger();
|
|
34
37
|
const outputMode = config?.output || 'static';
|
|
35
38
|
const clientAssets = {};
|
|
36
39
|
const routes = new Map();
|
|
@@ -49,6 +52,9 @@ export const gracile = (config) => {
|
|
|
49
52
|
// enabled: gracileConfig?.pages?.premises?.expose || false,
|
|
50
53
|
});
|
|
51
54
|
return [
|
|
55
|
+
betterErrors({
|
|
56
|
+
overlayImportPath: '@gracile/gracile/_internals/vite-custom-overlay',
|
|
57
|
+
}),
|
|
52
58
|
// {
|
|
53
59
|
// name: 'gracile-routes-codegen',
|
|
54
60
|
// // watchChange(change) {
|
|
@@ -74,14 +80,19 @@ export const gracile = (config) => {
|
|
|
74
80
|
// return null;
|
|
75
81
|
// },
|
|
76
82
|
// },
|
|
77
|
-
virtualRoutesForClient,
|
|
78
83
|
{
|
|
79
84
|
name: 'vite-plugin-gracile-serve-middleware',
|
|
80
85
|
apply: 'serve',
|
|
81
|
-
config() {
|
|
86
|
+
config(_, env) {
|
|
87
|
+
if (env.isPreview)
|
|
88
|
+
return null;
|
|
82
89
|
return {
|
|
83
90
|
// NOTE: Supresses message: `Could not auto-determine entry point from rollupOptions or html files…`
|
|
91
|
+
// FIXME: It's not working when reloading the Vite config.
|
|
92
|
+
// Is user config, putting `optimizeDeps: { include: [] }` solve this.
|
|
84
93
|
optimizeDeps: { include: [] },
|
|
94
|
+
// NOTE: Useful? It breaks preview (expected)
|
|
95
|
+
appType: 'custom',
|
|
85
96
|
// resolve: {
|
|
86
97
|
// conditions: ['development'],
|
|
87
98
|
// },
|
|
@@ -102,7 +113,7 @@ export const gracile = (config) => {
|
|
|
102
113
|
// ) as {
|
|
103
114
|
// version: number;
|
|
104
115
|
// };
|
|
105
|
-
const version =
|
|
116
|
+
const version = getVersion();
|
|
106
117
|
logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile')))}` +
|
|
107
118
|
` ${c.dim(`~`)} ${c.green(`v${version ?? 'X'}`)}`);
|
|
108
119
|
// ---
|
|
@@ -111,14 +122,28 @@ export const gracile = (config) => {
|
|
|
111
122
|
vite: server,
|
|
112
123
|
gracileConfig,
|
|
113
124
|
});
|
|
125
|
+
logger.info(c.dim('Vite development server is starting…'), {
|
|
126
|
+
timestamp: true,
|
|
127
|
+
});
|
|
128
|
+
server.watcher.on('ready', () => {
|
|
129
|
+
setTimeout(() => {
|
|
130
|
+
logger.info('');
|
|
131
|
+
logger.info(c.green('Watching for file changes…'), {
|
|
132
|
+
timestamp: true,
|
|
133
|
+
});
|
|
134
|
+
logger.info('');
|
|
135
|
+
}, 100);
|
|
136
|
+
// s
|
|
137
|
+
});
|
|
114
138
|
return () => {
|
|
115
139
|
server.middlewares.use((req, res, next) => {
|
|
116
140
|
const locals = config?.dev?.locals?.({ nodeRequest: req });
|
|
117
|
-
Promise.resolve(nodeAdapter(handler)(req, res, locals)).catch((error) => next(error));
|
|
141
|
+
Promise.resolve(nodeAdapter(handler, { logger })(req, res, locals)).catch((error) => next(error));
|
|
118
142
|
});
|
|
119
143
|
};
|
|
120
144
|
},
|
|
121
145
|
},
|
|
146
|
+
virtualRoutesForClient,
|
|
122
147
|
{
|
|
123
148
|
name: 'vite-plugin-gracile-build',
|
|
124
149
|
apply: 'build',
|
|
@@ -224,6 +249,9 @@ export const gracile = (config) => {
|
|
|
224
249
|
return `
|
|
225
250
|
import { routeAssets, routeImports, routes } from 'gracile:routes';
|
|
226
251
|
import { createGracileHandler } from '@gracile/gracile/_internals/server-runtime';
|
|
252
|
+
import { createLogger } from '@gracile/gracile/_internals/logger';
|
|
253
|
+
|
|
254
|
+
createLogger();
|
|
227
255
|
|
|
228
256
|
export const handler = createGracileHandler({
|
|
229
257
|
root: process.cwd(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-template.d.ts","sourceRoot":"","sources":["../../src/render/route-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route-template.d.ts","sourceRoot":"","sources":["../../src/render/route-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAO1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,KAAK,CAAC,MAAM,oBAAoB,CAAC;AAa7C,eAAO,MAAM,gBAAgB,QACkC,CAAC;AAEhE,eAAO,MAAM,cAAc,QAA2B,CAAC;AAEvD,wBAAsB,mBAAmB,CAAC,EACzC,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,WAAW,EACX,UAAU,EACV,OAAO,GACP,EAAE;IACF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,CAAC,CAqNhE"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
|
+
import * as assert from '@gracile/internal-utils/assertions';
|
|
2
3
|
import { html } from '@gracile/internal-utils/dummy-literals';
|
|
3
4
|
import { render as renderLitSsr } from '@lit-labs/ssr';
|
|
4
5
|
import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
|
|
5
|
-
import {
|
|
6
|
+
import { GracileError, GracileErrorData, TemplateError, } from '../errors/errors.js';
|
|
6
7
|
import { PAGE_ASSETS_MARKER, SSR_OUTLET_MARKER } from './markers.js';
|
|
7
8
|
async function* concatStreams(...readables) {
|
|
8
9
|
// eslint-disable-next-line no-restricted-syntax
|
|
@@ -16,6 +17,9 @@ async function* concatStreams(...readables) {
|
|
|
16
17
|
export const REGEX_TAG_SCRIPT = /\s?<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script\s*>\s?/gi;
|
|
17
18
|
export const REGEX_TAG_LINK = /\s?<link\b[^>]*?>\s?/gi;
|
|
18
19
|
export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAssets, serverMode, docOnly, }) {
|
|
20
|
+
const location = {
|
|
21
|
+
file: routeInfos.foundRoute.filePath,
|
|
22
|
+
};
|
|
19
23
|
if (!routeInfos.routeModule.document && !routeInfos.routeModule.template)
|
|
20
24
|
return { output: null, document: null };
|
|
21
25
|
// MARK: Context
|
|
@@ -27,8 +31,12 @@ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAs
|
|
|
27
31
|
// MARK: Fragment
|
|
28
32
|
if (!routeInfos.routeModule.document && routeInfos.routeModule.template) {
|
|
29
33
|
const fragmentOutput = await Promise.resolve(routeInfos.routeModule.template?.(context));
|
|
30
|
-
if (isLitTemplate(fragmentOutput) === false)
|
|
31
|
-
throw
|
|
34
|
+
if (assert.isLitTemplate(fragmentOutput) === false)
|
|
35
|
+
throw new GracileError({
|
|
36
|
+
...GracileErrorData.InvalidRouteDocument,
|
|
37
|
+
message: GracileErrorData.InvalidRouteDocument.message(location.file),
|
|
38
|
+
// location,
|
|
39
|
+
});
|
|
32
40
|
const fragmentRender = renderLitSsr(fragmentOutput);
|
|
33
41
|
const output = Readable.from(fragmentRender);
|
|
34
42
|
return { output, document: null };
|
|
@@ -36,11 +44,30 @@ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAs
|
|
|
36
44
|
// MARK: Document
|
|
37
45
|
if (!routeInfos.routeModule.document ||
|
|
38
46
|
typeof routeInfos.routeModule.document !== 'function')
|
|
39
|
-
throw new
|
|
47
|
+
throw new GracileError({
|
|
48
|
+
...GracileErrorData.InvalidRouteDocument,
|
|
49
|
+
message: GracileErrorData.InvalidRouteDocument.message(location.file),
|
|
50
|
+
location,
|
|
51
|
+
});
|
|
40
52
|
const baseDocTemplateResult = await Promise.resolve(routeInfos.routeModule.document?.(context));
|
|
41
|
-
if (isLitServerTemplate(baseDocTemplateResult) === false)
|
|
42
|
-
throw new
|
|
43
|
-
|
|
53
|
+
if (assert.isLitServerTemplate(baseDocTemplateResult) === false)
|
|
54
|
+
throw new GracileError({
|
|
55
|
+
...GracileErrorData.InvalidRouteDocumentResult,
|
|
56
|
+
message: GracileErrorData.InvalidRouteDocumentResult.message(location.file),
|
|
57
|
+
location,
|
|
58
|
+
});
|
|
59
|
+
let baseDocRendered;
|
|
60
|
+
// console.log({ ddd: baseDocTemplateResult });
|
|
61
|
+
try {
|
|
62
|
+
baseDocRendered = await collectResult(renderLitSsr(baseDocTemplateResult));
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
throw new TemplateError({
|
|
66
|
+
...GracileErrorData.CouldNotRenderRouteDocument,
|
|
67
|
+
message: GracileErrorData.CouldNotRenderRouteDocument.message(location.file),
|
|
68
|
+
location,
|
|
69
|
+
}, { cause: String(e) });
|
|
70
|
+
}
|
|
44
71
|
// MARK: Sibling assets
|
|
45
72
|
let baseDocRenderedWithAssets = baseDocRendered;
|
|
46
73
|
// If the user doesnt use `pageAssetCustomLocation`, we put this as a fallback
|
|
@@ -62,7 +89,8 @@ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAs
|
|
|
62
89
|
// prettier-ignore
|
|
63
90
|
return html ` <link rel="stylesheet" href="/${path}" />`;
|
|
64
91
|
}
|
|
65
|
-
|
|
92
|
+
// NOTE: Never called (filtered upstream in `collectRoutes`)
|
|
93
|
+
return null;
|
|
66
94
|
})
|
|
67
95
|
.join('\n')}` +
|
|
68
96
|
`<!-- /PAGE ASSETS -->\n `
|
|
@@ -128,7 +156,7 @@ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAs
|
|
|
128
156
|
// );
|
|
129
157
|
// return { output, document: null };
|
|
130
158
|
// }
|
|
131
|
-
if (isLitTemplate(routeOutput) === false)
|
|
159
|
+
if (assert.isLitTemplate(routeOutput) === false)
|
|
132
160
|
throw Error(`Wrong template result for page template ${routeInfos.foundRoute.filePath}.`);
|
|
133
161
|
const renderStream = Readable.from(renderLitSsr(routeOutput));
|
|
134
162
|
const output = Readable.from(concatStreams(baseDocRenderStreamPre, renderStream, baseDocRenderStreamPost));
|
package/dist/routes/collect.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type * as R from './route.js';
|
|
2
|
-
export declare
|
|
2
|
+
export declare const WATCHED_FILES_REGEX: RegExp;
|
|
3
|
+
export declare function collectRoutes(routes: R.RoutesManifest, root: string, excludePatterns?: string[]): Promise<void>;
|
|
3
4
|
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/routes/collect.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/routes/collect.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;AAuDrC,eAAO,MAAM,mBAAmB,QAC+B,CAAC;AAGhE,wBAAsB,aAAa,CAClC,MAAM,EAAE,CAAC,CAAC,cAAc,EACxB,IAAI,EAAE,MAAM,EACZ,eAAe,GAAE,MAAM,EAAO,GAE5B,OAAO,CAAC,IAAI,CAAC,CAoGf"}
|
package/dist/routes/collect.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import { getLogger } from '@gracile/internal-utils/logger/helpers';
|
|
3
3
|
import * as paths from '@gracile/internal-utils/paths';
|
|
4
4
|
import { fdir as Fdir } from 'fdir';
|
|
5
5
|
import c from 'picocolors';
|
|
6
6
|
import { URLPattern } from 'urlpattern-polyfill/urlpattern';
|
|
7
7
|
import { createFilter } from 'vite';
|
|
8
|
-
|
|
8
|
+
import { emptyRoutes } from '../logging/messages.js';
|
|
9
9
|
import { prepareSortableRoutes, routeComparator } from './comparator.js';
|
|
10
10
|
import { REGEXES } from './load-module.js';
|
|
11
|
+
const logger = getLogger();
|
|
11
12
|
function extractRoutePatterns(routeFilePath) {
|
|
12
13
|
const routePathname = routeFilePath.replace(/\.[j|t]s$/, '');
|
|
13
|
-
let pathParts = routePathname.split(
|
|
14
|
+
let pathParts = routePathname.split(paths.isWindows() ? paths.WINDOWS_PATH_SEPARATOR : '/');
|
|
14
15
|
const last = pathParts.at(-1);
|
|
15
|
-
if (
|
|
16
|
-
throw new
|
|
16
|
+
if (last === undefined)
|
|
17
|
+
throw new ReferenceError('Cannot parse file path.');
|
|
17
18
|
if (
|
|
18
19
|
// NOTE: /foo/(foo) => /foo
|
|
19
20
|
/\((.*)\)/.test(last) ||
|
|
@@ -22,9 +23,6 @@ function extractRoutePatterns(routeFilePath) {
|
|
|
22
23
|
pathParts.pop();
|
|
23
24
|
if (pathParts.length === 1 && pathParts.at(0) === 'index')
|
|
24
25
|
pathParts = [];
|
|
25
|
-
// NOTE: Disabled for now, but might be useful later
|
|
26
|
-
// if (pathParts.length === 1 && pathParts.at(0) === '404')
|
|
27
|
-
// pathParts = ['__404'];
|
|
28
26
|
let hasParams = false;
|
|
29
27
|
const pathRelNorm = pathParts.map((pathEntry) => {
|
|
30
28
|
let entry = pathEntry;
|
|
@@ -48,6 +46,7 @@ function extractRoutePatterns(routeFilePath) {
|
|
|
48
46
|
hasParams,
|
|
49
47
|
};
|
|
50
48
|
}
|
|
49
|
+
export const WATCHED_FILES_REGEX = /\/src\/routes\/(.*)\.(ts|js|css|scss|sass|less|styl|stylus)$/;
|
|
51
50
|
// const routes: R.RoutesManifest = new Map<string, R.Route>();
|
|
52
51
|
export async function collectRoutes(routes, root /* vite: ViteDevServer */, excludePatterns = []) {
|
|
53
52
|
routes.clear();
|
|
@@ -69,6 +68,12 @@ export async function collectRoutes(routes, root /* vite: ViteDevServer */, excl
|
|
|
69
68
|
...excludePatterns,
|
|
70
69
|
]);
|
|
71
70
|
const serverEntrypoints = allFilesInRoutes.filter((f) => serverEntrypointsFilter(f));
|
|
71
|
+
if (serverEntrypoints.length === 0) {
|
|
72
|
+
logger.warnOnce(emptyRoutes(), {
|
|
73
|
+
timestamp: true,
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
72
77
|
// MARK: Routes priority order
|
|
73
78
|
// TODO: `prepareSortableRoutes` and `routeComparator` in same function `sortRoutes`
|
|
74
79
|
const serverEntrypointsSorted = prepareSortableRoutes(serverEntrypoints)
|
|
@@ -117,5 +122,4 @@ export async function collectRoutes(routes, root /* vite: ViteDevServer */, excl
|
|
|
117
122
|
route.pageAssets.push(assetPathWithExt);
|
|
118
123
|
});
|
|
119
124
|
});
|
|
120
|
-
return routes;
|
|
121
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-module.d.ts","sourceRoot":"","sources":["../../src/routes/load-module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"load-module.d.ts","sourceRoot":"","sources":["../../src/routes/load-module.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC;AAGhC,eAAO,MAAM,OAAO;;;;;;CASnB,CAAC;AAQF,wBAAsB,sBAAsB,CAAC,EAC5C,IAAI,EACJ,KAAK,EACL,YAAY,GACZ,EAAE;IACF,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,SAAS,CAAC;CAC3C,0BA8CA"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { collectErrorMetadata } from '@gracile-labs/better-errors/dev/utils';
|
|
2
|
+
import { enhanceViteSSRError } from '@gracile-labs/better-errors/dev/vite';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { pathToFileURL } from 'url';
|
|
5
|
+
import {} from 'vite';
|
|
6
|
+
import { GracileError, GracileErrorData } from '../errors/errors.js';
|
|
1
7
|
import * as R from './route.js';
|
|
2
8
|
// const ROUTE_SPREAD = /^\.{3}.+$/;
|
|
3
9
|
export const REGEXES = {
|
|
@@ -9,11 +15,32 @@ export const REGEXES = {
|
|
|
9
15
|
// index: /^(index\.(js|ts)|\((.*)\)\.(js|ts))$/,
|
|
10
16
|
index: /\((.*)\)/,
|
|
11
17
|
};
|
|
18
|
+
const incorrectRouteModuleError = (p) => new GracileError({
|
|
19
|
+
...GracileErrorData.InvalidRouteExport,
|
|
20
|
+
message: GracileErrorData.InvalidRouteExport.message(p),
|
|
21
|
+
});
|
|
12
22
|
export async function loadForeignRouteObject({ vite, route, routeImports, }) {
|
|
13
23
|
// NOTE: Check and assert unknown userland module to correct RouteModule instance (in the engine's realm)
|
|
14
24
|
let unknownRouteModule = null;
|
|
15
|
-
if (vite)
|
|
16
|
-
|
|
25
|
+
if (vite) {
|
|
26
|
+
try {
|
|
27
|
+
unknownRouteModule = await vite.ssrLoadModule(route.filePath /* + 's' */, {});
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
const err = e;
|
|
31
|
+
const filePath = pathToFileURL(join(vite.config.root, route.filePath));
|
|
32
|
+
const rootFolder = pathToFileURL(vite.config.root);
|
|
33
|
+
// NOTE: Maybe it's not required here? But just upstream (safeError…)
|
|
34
|
+
const enhance = enhanceViteSSRError({
|
|
35
|
+
error: err,
|
|
36
|
+
filePath,
|
|
37
|
+
// @ts-expect-error Typings mismatches
|
|
38
|
+
vite,
|
|
39
|
+
});
|
|
40
|
+
const errorWithMetadata = collectErrorMetadata(enhance, rootFolder);
|
|
41
|
+
throw errorWithMetadata;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
17
44
|
else if (routeImports) {
|
|
18
45
|
const ri = routeImports.get(route.pattern.pathname);
|
|
19
46
|
if (ri)
|
|
@@ -22,11 +49,10 @@ export async function loadForeignRouteObject({ vite, route, routeImports, }) {
|
|
|
22
49
|
if (unknownRouteModule === null)
|
|
23
50
|
throw new Error('Cannot find route module.');
|
|
24
51
|
const routeModuleFactory = unknownRouteModule['default'];
|
|
25
|
-
const errorBase = `Incorrect route module ${route.filePath}!`;
|
|
26
52
|
if (typeof routeModuleFactory !== 'function')
|
|
27
|
-
throw
|
|
53
|
+
throw incorrectRouteModuleError(route.filePath);
|
|
28
54
|
const routeModule = routeModuleFactory(R.RouteModule);
|
|
29
55
|
if (routeModule instanceof R.RouteModule === false)
|
|
30
|
-
throw
|
|
56
|
+
throw incorrectRouteModuleError(route.filePath);
|
|
31
57
|
return routeModule;
|
|
32
58
|
}
|
package/dist/routes/match.d.ts
CHANGED
|
@@ -13,6 +13,6 @@ export declare function getRoute(options: {
|
|
|
13
13
|
vite?: ViteDevServer | undefined;
|
|
14
14
|
routes: R.RoutesManifest;
|
|
15
15
|
routeImports?: R.RoutesImports | undefined;
|
|
16
|
-
}): Promise<RouteInfos>;
|
|
16
|
+
}): Promise<RouteInfos | null>;
|
|
17
17
|
export {};
|
|
18
18
|
//# sourceMappingURL=match.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../src/routes/match.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;AAErC,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAoFjD,MAAM,MAAM,UAAU,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACrC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AACF,wBAAsB,QAAQ,CAAC,OAAO,EAAE;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,CAAC,CAAC,cAAc,CAAC;IACzB,YAAY,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,SAAS,CAAC;CAC3C,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../src/routes/match.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;AAErC,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAoFjD,MAAM,MAAM,UAAU,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACrC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AACF,wBAAsB,QAAQ,CAAC,OAAO,EAAE;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,CAAC,CAAC,cAAc,CAAC;IACzB,YAAY,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,SAAS,CAAC;CAC3C,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAiC7B"}
|
package/dist/routes/match.js
CHANGED
|
@@ -15,7 +15,7 @@ function matchRouteFromUrl(url, routes) {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
if (!match || !foundRoute)
|
|
18
|
-
|
|
18
|
+
return null;
|
|
19
19
|
const params = Object.freeze({ ...match.pathname.groups });
|
|
20
20
|
return { match, foundRoute, params, pathname };
|
|
21
21
|
}
|
|
@@ -38,24 +38,38 @@ async function extractStaticPaths(options) {
|
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
if (hasCorrectParams === false)
|
|
41
|
-
throw new Error(
|
|
42
|
-
|
|
41
|
+
// throw new Error(
|
|
42
|
+
// `Incorrect route parameters for \`${options.pathname}\`.\n` +
|
|
43
|
+
// `Check \`staticPaths\` for \`${options.foundRoute.filePath}\`.`,
|
|
44
|
+
// );
|
|
45
|
+
return null;
|
|
43
46
|
return { staticPaths, props };
|
|
44
47
|
}
|
|
45
48
|
export async function getRoute(options) {
|
|
46
|
-
|
|
49
|
+
// throw new GracileError(new Error(`No route matching for ${url}`), {
|
|
50
|
+
// cause: 404,
|
|
51
|
+
// });
|
|
52
|
+
const matchedRoute = matchRouteFromUrl(options.url, options.routes);
|
|
53
|
+
if (!matchedRoute)
|
|
54
|
+
return matchedRoute;
|
|
55
|
+
const { foundRoute, pathname, params } = matchedRoute;
|
|
47
56
|
// TODO: Simplify all the routes things
|
|
48
57
|
const routeModule = await loadForeignRouteObject({
|
|
49
58
|
vite: options.vite,
|
|
50
59
|
route: foundRoute,
|
|
51
60
|
routeImports: options.routeImports,
|
|
52
61
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
let staticPaths = null;
|
|
63
|
+
if (routeModule.staticPaths) {
|
|
64
|
+
staticPaths = await extractStaticPaths({
|
|
65
|
+
routeModule,
|
|
66
|
+
foundRoute,
|
|
67
|
+
pathname,
|
|
68
|
+
params,
|
|
69
|
+
});
|
|
70
|
+
if (!staticPaths)
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
59
73
|
return {
|
|
60
74
|
params,
|
|
61
75
|
props: staticPaths?.props,
|
package/dist/routes/route.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare class RouteModule {
|
|
|
24
24
|
#private;
|
|
25
25
|
get staticPaths(): StaticPathsGeneric | undefined;
|
|
26
26
|
get locals(): {};
|
|
27
|
-
get handler():
|
|
27
|
+
get handler(): HandlerGeneric | undefined;
|
|
28
28
|
get document(): DocumentTemplate<RouteContextGeneric> | undefined;
|
|
29
29
|
get prerender(): boolean | undefined;
|
|
30
30
|
get template(): ((context: RouteContextGeneric) => RouteTemplateResult) | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/routes/route.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAK1C,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,CAAC;AACxC,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AACjE,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,aAAa,CAAC;AAIhD,eAAO,MAAM,aAAa;;;;;;;;;CAShB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG;IAC3B,WAAW,CAAC,EAAE,kBAAkB,CAAmB;IAEnD,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAEhC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;IAEjD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,mBAAmB,CAAC;CACjE,CAAC;AAEF,qBAAa,WAAW;;IAGvB,IAAW,WAAW,mCAErB;IAID,IAAW,MAAM,OAEhB;IAID,IAAW,OAAO
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/routes/route.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/route.js
CHANGED
|
@@ -36,18 +36,20 @@ export class RouteModule {
|
|
|
36
36
|
return this.#template;
|
|
37
37
|
}
|
|
38
38
|
constructor(options) {
|
|
39
|
-
if (typeof options.staticPaths === 'function')
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
// if (typeof options.staticPaths === 'function')
|
|
40
|
+
this.#staticPaths = options.staticPaths;
|
|
41
|
+
// if (
|
|
42
|
+
// (typeof options.handler === 'object' ||
|
|
43
|
+
// typeof options.handler === 'function') &&
|
|
44
|
+
// options.handler
|
|
45
|
+
// )
|
|
46
|
+
this.#handler = options.handler;
|
|
45
47
|
this.#locals = {};
|
|
46
|
-
if (typeof options.template === 'function')
|
|
47
|
-
|
|
48
|
-
if (typeof options.document === 'function')
|
|
49
|
-
|
|
50
|
-
if (typeof options.prerender === 'boolean')
|
|
51
|
-
|
|
48
|
+
// if (typeof options.template === 'function')
|
|
49
|
+
this.#template = options.template;
|
|
50
|
+
// if (typeof options.document === 'function')
|
|
51
|
+
this.#document = options.document;
|
|
52
|
+
// if (typeof options.prerender === 'boolean')
|
|
53
|
+
this.#prerender = options.prerender;
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GracileHandler } from '../request.js';
|
|
1
|
+
import type { AdapterOptions, GracileHandler } from '../request.js';
|
|
2
2
|
export type { GracileHandler };
|
|
3
3
|
export type GracileHonoHandler = (context: {
|
|
4
4
|
req: {
|
|
@@ -6,8 +6,11 @@ export type GracileHonoHandler = (context: {
|
|
|
6
6
|
};
|
|
7
7
|
var: unknown;
|
|
8
8
|
}) => Promise<Response>;
|
|
9
|
+
export interface HonoAdapterOptions extends AdapterOptions {
|
|
10
|
+
}
|
|
9
11
|
/**
|
|
10
12
|
* @param handler - Takes a pre-built Gracile handler from `./dist/server/entrypoint.js`.
|
|
13
|
+
* @param options - If you need more control.
|
|
11
14
|
* @example
|
|
12
15
|
* `/src/server.js`
|
|
13
16
|
* ```js
|
|
@@ -25,7 +28,7 @@ export type GracileHonoHandler = (context: {
|
|
|
25
28
|
* serve(app);
|
|
26
29
|
* ```
|
|
27
30
|
*/
|
|
28
|
-
export declare const honoAdapter: (handler: GracileHandler) => GracileHonoHandler;
|
|
31
|
+
export declare const honoAdapter: (handler: GracileHandler, options?: HonoAdapterOptions) => GracileHonoHandler;
|
|
29
32
|
/**
|
|
30
33
|
*
|
|
31
34
|
* @param root - resolve `dist/client` from this file path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/hono.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/hono.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpE,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE;IAC1C,GAAG,EAAE;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;IACtB,GAAG,EAAE,OAAO,CAAC;CACb,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAExB,MAAM,WAAW,kBAAmB,SAAQ,cAAc;CAEzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,YACb,cAAc,YAAY,kBAAkB,KAAG,kBAmBxD,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,UAK7C;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
// import { logger } from '@gracile/internal-utils/logger';
|
|
2
1
|
import { relative } from 'node:path';
|
|
3
2
|
import { Readable } from 'node:stream';
|
|
4
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { createLogger } from '@gracile/internal-utils/logger/helpers';
|
|
5
|
+
import { GracileError, GracileErrorData } from '../../errors/errors.js';
|
|
5
6
|
import { constants } from '../constants.js';
|
|
6
7
|
/**
|
|
7
8
|
* @param handler - Takes a pre-built Gracile handler from `./dist/server/entrypoint.js`.
|
|
9
|
+
* @param options - If you need more control.
|
|
8
10
|
* @example
|
|
9
11
|
* `/src/server.js`
|
|
10
12
|
* ```js
|
|
@@ -22,7 +24,8 @@ import { constants } from '../constants.js';
|
|
|
22
24
|
* serve(app);
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
|
-
export const honoAdapter = (handler) => async (context) => {
|
|
27
|
+
export const honoAdapter = (handler, options) => async (context) => {
|
|
28
|
+
createLogger(options?.logger);
|
|
26
29
|
const result = await handler(context.req.raw, context.var);
|
|
27
30
|
// TODO: Handle stream abortion as gracefully as with Express.
|
|
28
31
|
if (result?.body) {
|
|
@@ -32,7 +35,10 @@ export const honoAdapter = (handler) => async (context) => {
|
|
|
32
35
|
}
|
|
33
36
|
if (result?.response)
|
|
34
37
|
return result.response;
|
|
35
|
-
throw new
|
|
38
|
+
throw new GracileError({
|
|
39
|
+
...GracileErrorData.InvalidResponseInAdapter,
|
|
40
|
+
message: GracileErrorData.InvalidResponseInAdapter.message('Hono'),
|
|
41
|
+
});
|
|
36
42
|
};
|
|
37
43
|
/**
|
|
38
44
|
*
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
-
import { type GracileHandler } from '../request.js';
|
|
2
|
+
import { type AdapterOptions, type GracileHandler } from '../request.js';
|
|
3
3
|
export type { GracileHandler };
|
|
4
4
|
export type GracileNodeHandler = (req: IncomingMessage, res: ServerResponse, locals?: unknown) => Promise<ServerResponse<IncomingMessage> | null | void>;
|
|
5
|
+
export interface NodeAdapterOptions extends AdapterOptions {
|
|
6
|
+
}
|
|
5
7
|
/**
|
|
6
8
|
* @param handler - Takes a pre-built Gracile handler from `./dist/server/entrypoint.js`.
|
|
7
9
|
* @example
|
|
@@ -20,7 +22,7 @@ export type GracileNodeHandler = (req: IncomingMessage, res: ServerResponse, loc
|
|
|
20
22
|
* const server = app.listen();
|
|
21
23
|
* ```
|
|
22
24
|
*/
|
|
23
|
-
export declare function nodeAdapter(handler: GracileHandler): GracileNodeHandler;
|
|
25
|
+
export declare function nodeAdapter(handler: GracileHandler, options?: NodeAdapterOptions): GracileNodeHandler;
|
|
24
26
|
/**
|
|
25
27
|
* @param root - resolve `dist/client` from this file path.
|
|
26
28
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/node.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/node.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAI5D,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,cAAc,EAEnB,MAAM,eAAe,CAAC;AAoBvB,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,MAAM,MAAM,kBAAkB,GAAG,CAChC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,OAAO,KAEZ,OAAO,CAAC,cAAc,CAAC,eAAe,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;AAE5D,MAAM,WAAW,kBAAmB,SAAQ,cAAc;CAEzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAC1B,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,kBAAkB,GAC1B,kBAAkB,CAoEpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,UAE7C;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Writable } from 'node:stream';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { env } from '@gracile/internal-utils/env';
|
|
4
|
-
import {
|
|
4
|
+
import { createLogger } from '@gracile/internal-utils/logger/helpers';
|
|
5
5
|
import { createServerAdapter } from '@whatwg-node/server';
|
|
6
|
+
import { GracileError, GracileErrorData } from '../../errors/errors.js';
|
|
6
7
|
import { constants } from '../constants.js';
|
|
7
|
-
import { isRedirect } from '../request.js';
|
|
8
|
+
import { isRedirect, } from '../request.js';
|
|
8
9
|
// NOTE: Find a more canonical way to ponyfill the Node HTTP request to standard Request
|
|
9
10
|
// @ts-expect-error Abusing this feature!
|
|
10
11
|
const nodeRequestToStandardRequest = createServerAdapter((request) => request);
|
|
@@ -36,16 +37,28 @@ function standardResponseInitToNodeResponse(responseInit, res) {
|
|
|
36
37
|
* const server = app.listen();
|
|
37
38
|
* ```
|
|
38
39
|
*/
|
|
39
|
-
export function nodeAdapter(handler) {
|
|
40
|
+
export function nodeAdapter(handler, options) {
|
|
40
41
|
return async function nodeHandler(req, res, locals) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const logger = createLogger(options?.logger);
|
|
43
|
+
let webRequest;
|
|
44
|
+
try {
|
|
45
|
+
webRequest = (await Promise.resolve(nodeRequestToStandardRequest.handleNodeRequest(
|
|
46
|
+
// HACK: Exact optional properties
|
|
47
|
+
req)));
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
throw new GracileError({
|
|
51
|
+
...GracileErrorData.InvalidRequestInAdapter,
|
|
52
|
+
message: GracileErrorData.InvalidRequestInAdapter.message('Node'),
|
|
53
|
+
}, {
|
|
54
|
+
cause: e,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
44
57
|
const mergedLocals = {
|
|
45
58
|
...(locals ?? {}),
|
|
46
59
|
...('locals' in res && typeof res.locals === 'object' ? res.locals : {}),
|
|
47
60
|
};
|
|
48
|
-
const result = await handler(
|
|
61
|
+
const result = await handler(webRequest, mergedLocals);
|
|
49
62
|
if (result?.body) {
|
|
50
63
|
standardResponseInitToNodeResponse(result.init, res);
|
|
51
64
|
// NOTE: We can't do similar thing with Hono with just
|
|
@@ -70,9 +83,11 @@ export function nodeAdapter(handler) {
|
|
|
70
83
|
.catch((e) => logger.error(String(e)));
|
|
71
84
|
return piped;
|
|
72
85
|
}
|
|
73
|
-
return null;
|
|
74
86
|
}
|
|
75
|
-
|
|
87
|
+
throw new GracileError({
|
|
88
|
+
...GracileErrorData.InvalidResponseInAdapter,
|
|
89
|
+
message: GracileErrorData.InvalidResponseInAdapter.message('Node'),
|
|
90
|
+
});
|
|
76
91
|
};
|
|
77
92
|
}
|
|
78
93
|
/**
|