oc-fastify-server-adapter 0.1.3 → 0.1.4
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/index.d.ts +14 -0
- package/dist/index.js +22 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -100,6 +100,20 @@ export interface FastifyServerAdapterOptions {
|
|
|
100
100
|
host?: string;
|
|
101
101
|
port?: number | string;
|
|
102
102
|
trustProxy?: boolean | string | string[] | number;
|
|
103
|
+
/**
|
|
104
|
+
* When enabled, Fastify treats `/foo` and `/foo/` as the same route, matching
|
|
105
|
+
* Express' default (non-strict) trailing-slash behavior. This is convenient
|
|
106
|
+
* for incoming requests that include a trailing slash, but it is slightly less
|
|
107
|
+
* performant than Fastify's native routing and requires OC to deduplicate
|
|
108
|
+
* routes that only differ by a trailing slash.
|
|
109
|
+
*
|
|
110
|
+
* Defaults to `false` to keep Fastify's faster native routing. OC's own routes
|
|
111
|
+
* never rely on trailing slashes, so the default is safe for the built-in
|
|
112
|
+
* registry endpoints.
|
|
113
|
+
*
|
|
114
|
+
* @default false
|
|
115
|
+
*/
|
|
116
|
+
ignoreTrailingSlash?: boolean;
|
|
103
117
|
}
|
|
104
118
|
export type HttpServerAdapterFactory<TOptions = unknown, TNative = unknown> = {
|
|
105
119
|
(options?: unknown): HttpServerAdapter<TNative>;
|
package/dist/index.js
CHANGED
|
@@ -28,15 +28,19 @@ class FastifyHttpServerAdapter {
|
|
|
28
28
|
bodyInflationRegistered = false;
|
|
29
29
|
bodyLimit = defaultBodyLimit;
|
|
30
30
|
host;
|
|
31
|
+
ignoreTrailingSlash;
|
|
32
|
+
registeredRoutes = new Set();
|
|
31
33
|
routes = [];
|
|
32
34
|
optionsRoutesRegistered = false;
|
|
33
35
|
constructor(options = {}) {
|
|
34
36
|
this.host = options.host;
|
|
37
|
+
this.ignoreTrailingSlash = options.ignoreTrailingSlash ?? false;
|
|
35
38
|
this.app = (0, fastify_1.default)({
|
|
36
39
|
bodyLimit: this.bodyLimit,
|
|
37
40
|
exposeHeadRoutes: true,
|
|
38
41
|
logger: false,
|
|
39
42
|
routerOptions: {
|
|
43
|
+
ignoreTrailingSlash: this.ignoreTrailingSlash,
|
|
40
44
|
querystringParser: (str) => (0, node_querystring_1.parse)(str)
|
|
41
45
|
},
|
|
42
46
|
trustProxy: options.trustProxy
|
|
@@ -156,6 +160,18 @@ class FastifyHttpServerAdapter {
|
|
|
156
160
|
}
|
|
157
161
|
route(method, routePath, id, handlers) {
|
|
158
162
|
const url = toFastifyRoutePath(routePath);
|
|
163
|
+
// With `ignoreTrailingSlash` enabled Fastify treats `/foo` and `/foo/` as
|
|
164
|
+
// the same route and throws on duplicate registrations. Deduplicate so a
|
|
165
|
+
// consumer registering both variants does not crash the server. When the
|
|
166
|
+
// option is disabled the two paths are distinct routes, so we let Fastify
|
|
167
|
+
// register both.
|
|
168
|
+
if (this.ignoreTrailingSlash) {
|
|
169
|
+
const routeKey = `${method}:${stripTrailingSlash(url)}`;
|
|
170
|
+
if (this.registeredRoutes.has(routeKey)) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
this.registeredRoutes.add(routeKey);
|
|
174
|
+
}
|
|
159
175
|
this.routes.push({ method, path: url });
|
|
160
176
|
this.app.route({
|
|
161
177
|
bodyLimit: this.bodyLimit,
|
|
@@ -506,10 +522,13 @@ function isFastifyAdapterOptions(options) {
|
|
|
506
522
|
const port = candidate.port;
|
|
507
523
|
const host = candidate.host;
|
|
508
524
|
const trustProxy = candidate.trustProxy;
|
|
525
|
+
const ignoreTrailingSlash = candidate.ignoreTrailingSlash;
|
|
509
526
|
return ((typeof port === 'undefined' ||
|
|
510
527
|
typeof port === 'number' ||
|
|
511
528
|
typeof port === 'string') &&
|
|
512
529
|
(typeof host === 'undefined' || typeof host === 'string') &&
|
|
530
|
+
(typeof ignoreTrailingSlash === 'undefined' ||
|
|
531
|
+
typeof ignoreTrailingSlash === 'boolean') &&
|
|
513
532
|
(typeof trustProxy === 'undefined' ||
|
|
514
533
|
typeof trustProxy === 'boolean' ||
|
|
515
534
|
typeof trustProxy === 'string' ||
|
|
@@ -520,6 +539,9 @@ function isFastifyAdapterOptions(options) {
|
|
|
520
539
|
function toFastifyRoutePath(routePath) {
|
|
521
540
|
return routePath.replace(/\*[A-Za-z0-9_]+/g, '*');
|
|
522
541
|
}
|
|
542
|
+
function stripTrailingSlash(value) {
|
|
543
|
+
return value !== '/' && value.endsWith('/') ? value.slice(0, -1) : value;
|
|
544
|
+
}
|
|
523
545
|
function routePathMatches(routePath, pathname) {
|
|
524
546
|
if (routePath === pathname) {
|
|
525
547
|
return true;
|