jeasx 2.3.1 β 2.4.0
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/CHANGELOG.md +77 -1
- package/env.js +11 -1
- package/esbuild.config.js +5 -27
- package/package.json +3 -4
- package/serverless.js +38 -30
- package/serverless.js.map +2 -2
- package/serverless.ts +68 -45
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,81 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-02-20 - Jeasx 2.4.0 released
|
|
4
|
+
|
|
5
|
+
π This release is both a step forward and a step back: the recently introduced support for MDX has been removed from the core project. Jeasx aims to keep its core as lean as possible, so this change aligns with the project's overall goals. Since MDX is not essential for every Jeasx website or application, it makes sense to move it out of the core.
|
|
6
|
+
|
|
7
|
+
Another key goal of Jeasx is to empower users to implement their own custom solutions in userland, providing the right tools to do so. In short, while MDX remains a fantastic technology for content-driven websites, Jeasx now lets you configure MDX support yourself through a much improved configuration system for its base technologies like esbuild and Fastify.
|
|
8
|
+
|
|
9
|
+
For esbuild, two new configuration options are available: `ESBUILD_SERVER_OPTIONS` and `ESBUILD_BROWSER_OPTIONS`. These can be defined as functions in `.env.js` that return additional configuration settings for esbuild.
|
|
10
|
+
|
|
11
|
+
Why use functions instead of plain objects for the configuration? Because using functions allows configurations to be created lazily - only when needed - which is especially helpful for more complex setups over time.
|
|
12
|
+
|
|
13
|
+
If you want to use MDX with Jeasx, simply run `npm install @mdx-js/esbuild` and add the configuration below to `ESBUILD_SERVER_OPTIONS` in `.env.js`.
|
|
14
|
+
|
|
15
|
+
If you've used `ESBUILD_BROWSER_TARGET` in the past, you have to move this configuration to `ESBUILD_BROWSER_OPTIONS` as shown below.
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
import mdx from "@mdx-js/esbuild";
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
/** @type {() => import("esbuild").BuildOptions} */
|
|
22
|
+
ESBUILD_SERVER_OPTIONS: () => ({
|
|
23
|
+
plugins: [
|
|
24
|
+
mdx({
|
|
25
|
+
development: process.env.NODE_ENV === "development",
|
|
26
|
+
jsxImportSource: "jsx-async-runtime",
|
|
27
|
+
elementAttributeNameCase: "html",
|
|
28
|
+
stylePropertyNameCase: "css"
|
|
29
|
+
})
|
|
30
|
+
]
|
|
31
|
+
}),
|
|
32
|
+
|
|
33
|
+
/** @type {() => import("esbuild").BuildOptions} */
|
|
34
|
+
ESBUILD_BROWSER_OPTIONS: () => ({
|
|
35
|
+
target: ["chrome130", "edge130", "firefox130", "safari18"]
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The existing configuration options for Fastify (such as `FASTIFY_SERVER_OPTIONS`, `FASTIFY_COOKIE_OPTIONS`, `FASTIFY_MULTIPART_OPTIONS`, `FASTIFY_STATIC_OPTIONS`) now require a minor change: they must be defined as functions instead of plain objects.
|
|
41
|
+
|
|
42
|
+
Additionally, you can now customize the fastify server instance using the optional `FASTIFY_SERVER` function. This function receives the created server instance and should return the modified version. This feature is especially useful when integrating existing Fastify plugins like `@fastify/compress`, as demonstrated below.
|
|
43
|
+
|
|
44
|
+
```jsx
|
|
45
|
+
import fastifyCompress from "@fastify/compress";
|
|
46
|
+
|
|
47
|
+
const NODE_ENV_IS_DEVELOPMENT = process.env.NODE_ENV === "development";
|
|
48
|
+
|
|
49
|
+
export default {
|
|
50
|
+
/** @type {(fastify: import("fastify").FastifyInstance) => import("fastify").FastifyInstance} */
|
|
51
|
+
FASTIFY_SERVER: (fastify) => fastify.register(fastifyCompress),
|
|
52
|
+
|
|
53
|
+
/** @type {() => import("fastify").FastifyServerOptions} */
|
|
54
|
+
FASTIFY_SERVER_OPTIONS: () => ({
|
|
55
|
+
disableRequestLogging: NODE_ENV_IS_DEVELOPMENT,
|
|
56
|
+
bodyLimit: 1024 * 1024
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
/** @type {() => import("@fastify/static").FastifyStaticOptions} */
|
|
60
|
+
FASTIFY_STATIC_OPTIONS: () => ({
|
|
61
|
+
immutable: !NODE_ENV_IS_DEVELOPMENT,
|
|
62
|
+
maxAge: NODE_ENV_IS_DEVELOPMENT ? 0 : "365d"
|
|
63
|
+
})
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Another notable change is that the fallback content-type (`text/html`) for routes is now set as late as possible. This means you can return plain JavaScript objects from routes, which will be automatically sent as `application/json` by default - without needing to explicitly specify the content-type in your code. This update brings Jeasx in line with Fastifyβs default behavior.
|
|
68
|
+
|
|
69
|
+
Additionally, you can now define routes directly from simple `*.json` or `*.txt` files - perfect for creating static endpoints like a health check or a `robots.txt` file right in your routes folder.
|
|
70
|
+
|
|
71
|
+
Dependency updates: `@types/node@25.3.0`
|
|
72
|
+
|
|
73
|
+
## 2026-02-12 - Jeasx 2.3.2 released
|
|
74
|
+
|
|
75
|
+
π Upgraded to @types/node@25, enabling seamless development with Node 25 while maintaining compatibility for Node 24 users.
|
|
76
|
+
|
|
77
|
+
Dependency updates: `esbuild@0.27.3`, `@types/node@25.2.3`
|
|
78
|
+
|
|
3
79
|
## 2026-02-04 - Jeasx 2.3.1 released
|
|
4
80
|
|
|
5
81
|
π Just a patch release to update Fastify to fix [CVE-2026-25224](https://github.com/fastify/fastify/security/advisories/GHSA-mrq3-vjjr-p77c).
|
|
@@ -406,7 +482,7 @@ Added two new environment variables (`FASTIFY_DISABLE_REQUEST_LOGGING` and `FAST
|
|
|
406
482
|
|
|
407
483
|
## 2024-12-01 - Jeasx 1.1.0 released
|
|
408
484
|
|
|
409
|
-
π Migrated from dotenv to dotenv-flow, so you can use NODE_ENV-specific .env\* files (like `.env.development`) to configure different environments for production and development. This is useful to disable caching headers (e.g. via `FASTIFY_STATIC_HEADERS`) in development, as Jeasx applies `FASTIFY_STATIC_HEADERS` in development from now on for a more consistent developer
|
|
485
|
+
π Migrated from dotenv to dotenv-flow, so you can use NODE_ENV-specific .env\* files (like `.env.development`) to configure different environments for production and development. This is useful to disable caching headers (e.g. via `FASTIFY_STATIC_HEADERS`) in development, as Jeasx applies `FASTIFY_STATIC_HEADERS` in development from now on for a more consistent developer experience. See updated .env-files in the quickstart-project for an example how to disable caching in development. This is only needed if you have configured `FASTIFY_STATIC_HEADERS` for your existing projects.
|
|
410
486
|
|
|
411
487
|
Bumped default environment variable `ESBUILD_BROWSER_TARGET` to more recent browser versions (e.g. `chrome126, edge126, firefox128, safari17`). If you want to stick with older versions, you can override it via the environment. Learn more about possible values at the esbuild website.
|
|
412
488
|
|
package/env.js
CHANGED
|
@@ -31,7 +31,17 @@ export default async function env() {
|
|
|
31
31
|
const envObject = (await import(envFile)).default;
|
|
32
32
|
Object.entries(envObject).forEach(([key, value]) => {
|
|
33
33
|
try {
|
|
34
|
-
|
|
34
|
+
switch (typeof value) {
|
|
35
|
+
case "string":
|
|
36
|
+
process.env[key] = value;
|
|
37
|
+
break;
|
|
38
|
+
case "function":
|
|
39
|
+
process.env[key] = value.toString();
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
process.env[key] = JSON.stringify(value);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
35
45
|
} catch (error) {
|
|
36
46
|
// JSON.stringify throws TypeError for circular references or BigInts.
|
|
37
47
|
console.error("β", `"${key}" in .env.js throws`, error);
|
package/esbuild.config.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import mdx from "@mdx-js/esbuild";
|
|
2
1
|
import * as esbuild from "esbuild";
|
|
3
2
|
import env from "./env.js";
|
|
4
3
|
|
|
@@ -16,33 +15,15 @@ const BROWSER_PUBLIC_ENV = Object.keys(ENV)
|
|
|
16
15
|
{ "process.env.BROWSER_PUBLIC_BUILD_TIME": BUILD_TIME },
|
|
17
16
|
);
|
|
18
17
|
|
|
19
|
-
const ESBUILD_BROWSER_TARGET = ENV.ESBUILD_BROWSER_TARGET || [
|
|
20
|
-
"chrome130",
|
|
21
|
-
"edge130",
|
|
22
|
-
"firefox130",
|
|
23
|
-
"safari18",
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
const ESBUILD_MDX_PLUGIN = mdx({
|
|
27
|
-
development: process.env.NODE_ENV === "development",
|
|
28
|
-
jsxImportSource: "jsx-async-runtime",
|
|
29
|
-
elementAttributeNameCase: "html",
|
|
30
|
-
stylePropertyNameCase: "css",
|
|
31
|
-
...ENV.ESBUILD_MDX_OPTIONS,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
18
|
/** @type esbuild.BuildOptions[] */
|
|
35
19
|
const buildOptions = [
|
|
36
20
|
{
|
|
37
|
-
entryPoints: ["
|
|
21
|
+
entryPoints: ["src/**/[*].*"],
|
|
38
22
|
define: {
|
|
39
23
|
"process.env.BUILD_TIME": BUILD_TIME,
|
|
40
24
|
},
|
|
41
25
|
minify: process.env.NODE_ENV !== "development",
|
|
42
26
|
logLevel: "info",
|
|
43
|
-
logOverride: {
|
|
44
|
-
"empty-glob": "silent",
|
|
45
|
-
},
|
|
46
27
|
color: true,
|
|
47
28
|
bundle: true,
|
|
48
29
|
sourcemap: process.sourceMapsEnabled,
|
|
@@ -50,16 +31,13 @@ const buildOptions = [
|
|
|
50
31
|
outdir: "dist/server",
|
|
51
32
|
platform: "neutral",
|
|
52
33
|
packages: "external",
|
|
53
|
-
|
|
34
|
+
...ENV.ESBUILD_SERVER_OPTIONS?.(),
|
|
54
35
|
},
|
|
55
36
|
{
|
|
56
|
-
entryPoints: ["
|
|
37
|
+
entryPoints: ["src/**/index.*"],
|
|
57
38
|
define: BROWSER_PUBLIC_ENV,
|
|
58
39
|
minify: process.env.NODE_ENV !== "development",
|
|
59
40
|
logLevel: "info",
|
|
60
|
-
logOverride: {
|
|
61
|
-
"empty-glob": "silent",
|
|
62
|
-
},
|
|
63
41
|
color: true,
|
|
64
42
|
bundle: true,
|
|
65
43
|
sourcemap: process.sourceMapsEnabled,
|
|
@@ -67,7 +45,7 @@ const buildOptions = [
|
|
|
67
45
|
outdir: "dist/browser",
|
|
68
46
|
platform: "browser",
|
|
69
47
|
format: "esm",
|
|
70
|
-
target:
|
|
48
|
+
target: ["chrome130", "edge130", "firefox130", "safari18"],
|
|
71
49
|
external: [
|
|
72
50
|
"*.avif",
|
|
73
51
|
"*.gif",
|
|
@@ -82,7 +60,7 @@ const buildOptions = [
|
|
|
82
60
|
"*.woff",
|
|
83
61
|
"*.woff2",
|
|
84
62
|
],
|
|
85
|
-
|
|
63
|
+
...ENV.ESBUILD_BROWSER_OPTIONS?.(),
|
|
86
64
|
},
|
|
87
65
|
];
|
|
88
66
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jeasx",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Jeasx - the ease of JSX with the power of SSR",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fastify",
|
|
@@ -31,9 +31,8 @@
|
|
|
31
31
|
"@fastify/formbody": "8.0.2",
|
|
32
32
|
"@fastify/multipart": "9.4.0",
|
|
33
33
|
"@fastify/static": "9.0.0",
|
|
34
|
-
"@
|
|
35
|
-
"
|
|
36
|
-
"esbuild": "0.27.2",
|
|
34
|
+
"@types/node": "25.3.0",
|
|
35
|
+
"esbuild": "0.27.3",
|
|
37
36
|
"fastify": "5.7.4",
|
|
38
37
|
"jsx-async-runtime": "2.0.2"
|
|
39
38
|
}
|
package/serverless.js
CHANGED
|
@@ -2,7 +2,7 @@ import fastifyCookie from "@fastify/cookie";
|
|
|
2
2
|
import fastifyFormbody from "@fastify/formbody";
|
|
3
3
|
import fastifyMultipart from "@fastify/multipart";
|
|
4
4
|
import fastifyStatic from "@fastify/static";
|
|
5
|
-
import
|
|
5
|
+
import fastify from "fastify";
|
|
6
6
|
import { jsxToString } from "jsx-async-runtime";
|
|
7
7
|
import { stat } from "node:fs/promises";
|
|
8
8
|
import { freemem } from "node:os";
|
|
@@ -12,33 +12,40 @@ const ENV = await env();
|
|
|
12
12
|
const CWD = process.cwd();
|
|
13
13
|
const NODE_ENV_IS_DEVELOPMENT = process.env.NODE_ENV === "development";
|
|
14
14
|
const JEASX_ROUTE_CACHE_LIMIT = Math.floor(freemem() / 1024 / 1024);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
15
|
+
const FASTIFY_SERVER = ENV.FASTIFY_SERVER ?? ((fastify2) => fastify2);
|
|
16
|
+
var serverless_default = FASTIFY_SERVER(
|
|
17
|
+
fastify({
|
|
18
|
+
logger: true,
|
|
19
|
+
...ENV.FASTIFY_SERVER_OPTIONS?.()
|
|
20
|
+
})
|
|
21
|
+
).register((fastify2) => {
|
|
22
|
+
fastify2.register(fastifyCookie, {
|
|
23
|
+
...ENV.FASTIFY_COOKIE_OPTIONS?.()
|
|
24
|
+
}).register(fastifyFormbody, {
|
|
25
|
+
...ENV.FASTIFY_FORMBODY_OPTIONS?.()
|
|
26
|
+
}).register(fastifyMultipart, {
|
|
27
|
+
attachFieldsToBody: "keyValues",
|
|
28
|
+
...ENV.FASTIFY_MULTIPART_OPTIONS?.()
|
|
29
|
+
}).register(fastifyStatic, {
|
|
30
|
+
root: [["public"], ["dist", "browser"]].map((dir) => join(CWD, ...dir)),
|
|
31
|
+
prefix: "/",
|
|
32
|
+
wildcard: false,
|
|
33
|
+
...ENV.FASTIFY_STATIC_OPTIONS?.()
|
|
34
|
+
}).decorateRequest("route", "").decorateRequest("path", "").addHook("onRequest", async (request) => {
|
|
35
|
+
const index = request.url.indexOf("?");
|
|
36
|
+
request.path = index === -1 ? request.url : request.url.slice(0, index);
|
|
37
|
+
}).all("*", async (request, reply) => {
|
|
38
|
+
try {
|
|
39
|
+
const payload = await handler(request, reply);
|
|
40
|
+
if (reply.getHeader("content-type") === void 0 && (typeof payload === "string" || Buffer.isBuffer(payload))) {
|
|
41
|
+
reply.type("text/html; charset=utf-8");
|
|
42
|
+
}
|
|
43
|
+
return payload;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error("\u274C", error);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
42
49
|
});
|
|
43
50
|
const modules = /* @__PURE__ */ new Map();
|
|
44
51
|
async function handler(request, reply) {
|
|
@@ -79,11 +86,12 @@ async function handler(request, reply) {
|
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
request.route = route;
|
|
82
|
-
response =
|
|
89
|
+
response = // Call functions with request, reply and optional props
|
|
90
|
+
typeof module.default === "function" ? await module.default.call(context, {
|
|
83
91
|
request,
|
|
84
92
|
reply,
|
|
85
93
|
...typeof response === "object" ? response : {}
|
|
86
|
-
});
|
|
94
|
+
}) : module.default;
|
|
87
95
|
if (reply.sent) {
|
|
88
96
|
return;
|
|
89
97
|
} else if (route.endsWith("/[404]")) {
|
package/serverless.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["serverless.ts"],
|
|
4
|
-
"mappings": "AAAA,OAAO,mBAA6C;AACpD,OAAO,qBAAiD;AACxD,OAAO,sBAAmD;AAC1D,OAAO,mBAA6C;AACpD,OAAO,
|
|
5
|
-
"names": []
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["fastify"]
|
|
6
6
|
}
|
package/serverless.ts
CHANGED
|
@@ -2,7 +2,12 @@ import fastifyCookie, { FastifyCookieOptions } from "@fastify/cookie";
|
|
|
2
2
|
import fastifyFormbody, { FastifyFormbodyOptions } from "@fastify/formbody";
|
|
3
3
|
import fastifyMultipart, { FastifyMultipartOptions } from "@fastify/multipart";
|
|
4
4
|
import fastifyStatic, { FastifyStaticOptions } from "@fastify/static";
|
|
5
|
-
import
|
|
5
|
+
import fastify, {
|
|
6
|
+
FastifyInstance,
|
|
7
|
+
FastifyReply,
|
|
8
|
+
FastifyRequest,
|
|
9
|
+
FastifyServerOptions,
|
|
10
|
+
} from "fastify";
|
|
6
11
|
import { jsxToString } from "jsx-async-runtime";
|
|
7
12
|
import { stat } from "node:fs/promises";
|
|
8
13
|
import { freemem } from "node:os";
|
|
@@ -22,44 +27,59 @@ declare module "fastify" {
|
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
...(ENV.
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
30
|
+
// Enhance Fastify server from userland
|
|
31
|
+
const FASTIFY_SERVER = (ENV.FASTIFY_SERVER ?? ((fastify) => fastify)) as (
|
|
32
|
+
fastify: FastifyInstance,
|
|
33
|
+
) => FastifyInstance;
|
|
34
|
+
|
|
35
|
+
// Create and export a Fastify instance
|
|
36
|
+
export default FASTIFY_SERVER(
|
|
37
|
+
fastify({
|
|
38
|
+
logger: true,
|
|
39
|
+
...(ENV.FASTIFY_SERVER_OPTIONS?.() as FastifyServerOptions),
|
|
40
|
+
}),
|
|
41
|
+
)
|
|
42
|
+
// Create encapsulation context
|
|
43
|
+
.register((fastify) => {
|
|
44
|
+
fastify
|
|
45
|
+
.register(fastifyCookie, {
|
|
46
|
+
...(ENV.FASTIFY_COOKIE_OPTIONS?.() as FastifyCookieOptions),
|
|
47
|
+
})
|
|
48
|
+
.register(fastifyFormbody, {
|
|
49
|
+
...(ENV.FASTIFY_FORMBODY_OPTIONS?.() as FastifyFormbodyOptions),
|
|
50
|
+
})
|
|
51
|
+
.register(fastifyMultipart, {
|
|
52
|
+
attachFieldsToBody: "keyValues",
|
|
53
|
+
...(ENV.FASTIFY_MULTIPART_OPTIONS?.() as FastifyMultipartOptions),
|
|
54
|
+
})
|
|
55
|
+
.register(fastifyStatic, {
|
|
56
|
+
root: [["public"], ["dist", "browser"]].map((dir) => join(CWD, ...dir)),
|
|
57
|
+
prefix: "/",
|
|
58
|
+
wildcard: false,
|
|
59
|
+
...(ENV.FASTIFY_STATIC_OPTIONS?.() as FastifyStaticOptions),
|
|
60
|
+
})
|
|
61
|
+
.decorateRequest("route", "")
|
|
62
|
+
.decorateRequest("path", "")
|
|
63
|
+
.addHook("onRequest", async (request) => {
|
|
64
|
+
// Extract path from url
|
|
65
|
+
const index = request.url.indexOf("?");
|
|
66
|
+
request.path = index === -1 ? request.url : request.url.slice(0, index);
|
|
67
|
+
})
|
|
68
|
+
.all("*", async (request: FastifyRequest, reply: FastifyReply) => {
|
|
69
|
+
try {
|
|
70
|
+
const payload = await handler(request, reply);
|
|
71
|
+
if (
|
|
72
|
+
reply.getHeader("content-type") === undefined &&
|
|
73
|
+
(typeof payload === "string" || Buffer.isBuffer(payload))
|
|
74
|
+
) {
|
|
75
|
+
reply.type("text/html; charset=utf-8");
|
|
76
|
+
}
|
|
77
|
+
return payload;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error("β", error);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
63
83
|
});
|
|
64
84
|
|
|
65
85
|
// Cache for resolved route modules, 'null' means no module exists.
|
|
@@ -124,12 +144,15 @@ async function handler(request: FastifyRequest, reply: FastifyReply) {
|
|
|
124
144
|
// Store current route in request
|
|
125
145
|
request.route = route;
|
|
126
146
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
147
|
+
response =
|
|
148
|
+
// Call functions with request, reply and optional props
|
|
149
|
+
typeof module.default === "function"
|
|
150
|
+
? await module.default.call(context, {
|
|
151
|
+
request,
|
|
152
|
+
reply,
|
|
153
|
+
...(typeof response === "object" ? response : {}),
|
|
154
|
+
})
|
|
155
|
+
: module.default; // otherwise return default export
|
|
133
156
|
|
|
134
157
|
if (reply.sent) {
|
|
135
158
|
return;
|