@server/next 0.30.0 → 0.31.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/index.d.ts +9 -7
- package/index.js +84 -85
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -32,6 +32,11 @@ type RouteOptions = {
|
|
|
32
32
|
title?: string;
|
|
33
33
|
description?: string;
|
|
34
34
|
};
|
|
35
|
+
type Route = {
|
|
36
|
+
path: string;
|
|
37
|
+
options: RouteOptions;
|
|
38
|
+
fns: Middleware[];
|
|
39
|
+
};
|
|
35
40
|
type Cookie = {
|
|
36
41
|
value?: string | null;
|
|
37
42
|
path?: string;
|
|
@@ -251,12 +256,11 @@ declare global {
|
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
type Mids<O extends ServerConfig, Path extends string> = Middleware<O, PathToParams<Path>>[];
|
|
254
|
-
type PathOrMiddle<O extends ServerConfig = object> = string | Middleware<O>;
|
|
255
|
-
type FullRoute = [RouterMethod, string, ...Middleware[]][];
|
|
256
259
|
declare class Router<O extends ServerConfig = object> {
|
|
257
|
-
|
|
260
|
+
middleware: Middleware[];
|
|
261
|
+
handlers: Record<Method, Route[]>;
|
|
258
262
|
self(): this;
|
|
259
|
-
handle(method:
|
|
263
|
+
handle(method: Method, pathOrFn?: any, ...rest: any[]): this;
|
|
260
264
|
socket<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
261
265
|
socket<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
262
266
|
socket(...middleware: Middleware<O>[]): this;
|
|
@@ -290,9 +294,7 @@ declare class Router<O extends ServerConfig = object> {
|
|
|
290
294
|
options(...middleware: Middleware<O>[]): this;
|
|
291
295
|
options(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
292
296
|
use(...middleware: Middleware[]): this;
|
|
293
|
-
use(path: string, ...middleware: Middleware[]): this;
|
|
294
297
|
use(router: Router): this;
|
|
295
|
-
use(path: string, router: Router): this;
|
|
296
298
|
}
|
|
297
299
|
declare function router(): Router;
|
|
298
300
|
|
|
@@ -452,4 +454,4 @@ declare class Server<O extends ServerConfig = {}> extends Router<O> {
|
|
|
452
454
|
}
|
|
453
455
|
declare function server<Session extends Record<string, any> = {}, User extends Record<string, any> = {}>(options?: Options): Server<ServerConfig<Session, User>>;
|
|
454
456
|
|
|
455
|
-
export { type AuthOption, type AuthSession, type AuthSettings, type AuthUser, type BasicValue, type Body, type Bucket, type BunEnv, type Context, type Cookie, type CorsSettings, type EventCallback, type ExtractPathParams, type InferParamType, type InlineReply, type KVStore, type LimitOptions, type LogLevel, type Logger, type Method, type Middleware, type Options, type ParamTypeMap, type ParamsToObject, type PathToParams, type Platform, type Provider, type RouteOptions, type RouterMethod, type SecurityOptions, type SecuritySettings, type SerializableValue, Server, type ServerConfig, TypedServerError as ServerError, type Settings, type Strategy, type Time, UploadPipeline, type UploadedFile, cookies, server as default, download, file, headers, json, redirect, router, send, status, type, upload };
|
|
457
|
+
export { type AuthOption, type AuthSession, type AuthSettings, type AuthUser, type BasicValue, type Body, type Bucket, type BunEnv, type Context, type Cookie, type CorsSettings, type EventCallback, type ExtractPathParams, type InferParamType, type InlineReply, type KVStore, type LimitOptions, type LogLevel, type Logger, type Method, type Middleware, type Options, type ParamTypeMap, type ParamsToObject, type PathToParams, type Platform, type Provider, type Route, type RouteOptions, type RouterMethod, type SecurityOptions, type SecuritySettings, type SerializableValue, Server, type ServerConfig, TypedServerError as ServerError, type Settings, type Strategy, type Time, UploadPipeline, type UploadedFile, cookies, server as default, download, file, headers, json, redirect, router, send, status, type, upload };
|
package/index.js
CHANGED
|
@@ -1203,17 +1203,23 @@ function applyCors(res, ctx) {
|
|
|
1203
1203
|
|
|
1204
1204
|
// src/helpers/createWebsocket.ts
|
|
1205
1205
|
function createWebsocket(sockets, handlers) {
|
|
1206
|
+
const run = (event, socket, body) => {
|
|
1207
|
+
const routes = handlers.socket?.filter((r2) => r2.path === event) ?? [];
|
|
1208
|
+
for (const route of routes) {
|
|
1209
|
+
for (const fn of route.fns) {
|
|
1210
|
+
fn({ socket, sockets, body });
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1206
1214
|
return {
|
|
1207
|
-
message:
|
|
1208
|
-
handlers.socket?.filter((s) => s[1] === "message")?.map((s) => s[2]({ socket, sockets, body }));
|
|
1209
|
-
},
|
|
1215
|
+
message: (socket, body) => run("message", socket, body),
|
|
1210
1216
|
open: (socket) => {
|
|
1211
1217
|
sockets.push(socket);
|
|
1212
|
-
|
|
1218
|
+
run("open", socket);
|
|
1213
1219
|
},
|
|
1214
1220
|
close: (socket) => {
|
|
1215
1221
|
sockets.splice(sockets.indexOf(socket), 1);
|
|
1216
|
-
|
|
1222
|
+
run("close", socket);
|
|
1217
1223
|
}
|
|
1218
1224
|
};
|
|
1219
1225
|
}
|
|
@@ -1420,18 +1426,23 @@ function validate(ctx, schema) {
|
|
|
1420
1426
|
}
|
|
1421
1427
|
|
|
1422
1428
|
// src/helpers/handleRequest.ts
|
|
1423
|
-
async function handleRequest(
|
|
1424
|
-
const res = await getResponse(
|
|
1429
|
+
async function handleRequest(app, ctx) {
|
|
1430
|
+
const res = await getResponse(app, ctx);
|
|
1425
1431
|
if (res) ctx.options.log.request(ctx, res);
|
|
1426
1432
|
return res;
|
|
1427
1433
|
}
|
|
1428
|
-
async function getResponse(
|
|
1434
|
+
async function getResponse(app, ctx) {
|
|
1429
1435
|
try {
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1436
|
+
let matched = false;
|
|
1437
|
+
for (const route of app.handlers[ctx.method]) {
|
|
1438
|
+
const params = pathPattern(route.path, ctx.url.pathname || "/");
|
|
1439
|
+
if (!params) continue;
|
|
1440
|
+
matched = true;
|
|
1441
|
+
define(ctx.url, "params", () => params);
|
|
1442
|
+
if (Object.keys(route.options).length) {
|
|
1443
|
+
ctx.options = { ...app.settings, ...route.options };
|
|
1444
|
+
}
|
|
1445
|
+
for (const cb of route.fns) {
|
|
1435
1446
|
if (typeof cb === "function") {
|
|
1436
1447
|
const res = await cb(ctx);
|
|
1437
1448
|
const out = await parseResponse(res, ctx);
|
|
@@ -1440,7 +1451,13 @@ async function getResponse(handlers, ctx) {
|
|
|
1440
1451
|
validate(ctx, cb);
|
|
1441
1452
|
}
|
|
1442
1453
|
}
|
|
1443
|
-
|
|
1454
|
+
break;
|
|
1455
|
+
}
|
|
1456
|
+
if (!matched) {
|
|
1457
|
+
for (const mw of app.middleware) {
|
|
1458
|
+
const out = await parseResponse(await mw(ctx), ctx);
|
|
1459
|
+
if (out) return out;
|
|
1460
|
+
}
|
|
1444
1461
|
}
|
|
1445
1462
|
if (ctx.platform.provider === "netlify") return;
|
|
1446
1463
|
throw new ServerError_default("NOT_FOUND", 404, "Not Found");
|
|
@@ -1934,7 +1951,7 @@ async function favicon(ctx) {
|
|
|
1934
1951
|
return icon ? type("ico").send(icon) : 204;
|
|
1935
1952
|
}
|
|
1936
1953
|
const handled = ctx.app.handlers.get.some(
|
|
1937
|
-
(
|
|
1954
|
+
(route) => pathPattern(route.path, "/favicon.ico")
|
|
1938
1955
|
);
|
|
1939
1956
|
if (handled) return;
|
|
1940
1957
|
return 204;
|
|
@@ -1953,11 +1970,8 @@ var encode = (str = "") => {
|
|
|
1953
1970
|
if (typeof str !== "string") return "";
|
|
1954
1971
|
return str.replace(/[&<>"]/g, (tag) => entities[tag]);
|
|
1955
1972
|
};
|
|
1956
|
-
var getConfig = (
|
|
1957
|
-
const config2 =
|
|
1958
|
-
(r2) => typeof r2 !== "string" && typeof r2 !== "function" && typeof r2 === "object"
|
|
1959
|
-
);
|
|
1960
|
-
if (!config2) return {};
|
|
1973
|
+
var getConfig = (options = {}) => {
|
|
1974
|
+
const config2 = { ...options };
|
|
1961
1975
|
if (config2.tags) {
|
|
1962
1976
|
if (typeof config2.tags === "string") {
|
|
1963
1977
|
config2.tags = config2.tags.split(/\s*,\s*/g);
|
|
@@ -2002,13 +2016,10 @@ var generateOpenApiPaths = (handlers) => {
|
|
|
2002
2016
|
const paths = {};
|
|
2003
2017
|
for (const [method, routes] of Object.entries(handlers)) {
|
|
2004
2018
|
for (const route of routes) {
|
|
2005
|
-
const
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
route.find((p) => typeof p === "object")
|
|
2010
|
-
];
|
|
2011
|
-
const config2 = getConfig(route);
|
|
2019
|
+
const path2 = route.path;
|
|
2020
|
+
const fn = route.fns.find((p) => typeof p === "function");
|
|
2021
|
+
const meta = route.fns.find((p) => typeof p === "object");
|
|
2022
|
+
const config2 = getConfig(route.options);
|
|
2012
2023
|
if (typeof path2 !== "string" || path2 === "*" || path2 === "/docs" || !fn) {
|
|
2013
2024
|
continue;
|
|
2014
2025
|
}
|
|
@@ -2107,7 +2118,7 @@ function preflight(ctx) {
|
|
|
2107
2118
|
if (ctx.method !== "options") return;
|
|
2108
2119
|
if (!ctx.headers["access-control-request-method"]) return;
|
|
2109
2120
|
const handled = ctx.app.handlers.options.some(
|
|
2110
|
-
(
|
|
2121
|
+
(route) => pathPattern(route.path, ctx.url.pathname)
|
|
2111
2122
|
);
|
|
2112
2123
|
if (handled) return;
|
|
2113
2124
|
return 204;
|
|
@@ -2292,7 +2303,7 @@ var Winter = async (app, request, env2) => {
|
|
|
2292
2303
|
if (env2?.upgrade(request)) return;
|
|
2293
2304
|
Object.assign(globalThis.env, env2);
|
|
2294
2305
|
const ctx = await createWinter(request, app, env2);
|
|
2295
|
-
const res = await handleRequest(app
|
|
2306
|
+
const res = await handleRequest(app, ctx);
|
|
2296
2307
|
ctx.events.trigger("finish", { ...ctx, res, end: performance.now() });
|
|
2297
2308
|
return res;
|
|
2298
2309
|
};
|
|
@@ -2301,7 +2312,7 @@ var Node = async (app) => {
|
|
|
2301
2312
|
http.createServer(async (request, response) => {
|
|
2302
2313
|
const ctx = await createNode(request, app);
|
|
2303
2314
|
if ("error" in ctx) throw ctx.error;
|
|
2304
|
-
const out = await handleRequest(app
|
|
2315
|
+
const out = await handleRequest(app, ctx);
|
|
2305
2316
|
response.writeHead(out.status || 200, parseHeaders_default(out.headers));
|
|
2306
2317
|
if (out.body instanceof ReadableStream) {
|
|
2307
2318
|
await iterate(out.body, (chunk) => response.write(chunk));
|
|
@@ -2319,16 +2330,16 @@ var Netlify = async (app, request, context) => {
|
|
|
2319
2330
|
throw new Error("Netlify doesn't exist");
|
|
2320
2331
|
}
|
|
2321
2332
|
const ctx = await createWinter(request, app);
|
|
2322
|
-
const res = await handleRequest(app
|
|
2333
|
+
const res = await handleRequest(app, ctx);
|
|
2323
2334
|
ctx.events.trigger("finish", { ...ctx, res, end: performance.now() });
|
|
2324
2335
|
return res;
|
|
2325
2336
|
};
|
|
2326
2337
|
|
|
2327
2338
|
// src/router.ts
|
|
2328
|
-
function isMiddleware(x) {
|
|
2329
|
-
return typeof x === "function";
|
|
2330
|
-
}
|
|
2331
2339
|
var Router = class _Router {
|
|
2340
|
+
// Cross-cutting middleware added with .use(); they run on every request
|
|
2341
|
+
middleware = [];
|
|
2342
|
+
// Routes per method, each carrying its own (already-flattened) chain of fns
|
|
2332
2343
|
handlers = {
|
|
2333
2344
|
socket: [],
|
|
2334
2345
|
get: [],
|
|
@@ -2344,79 +2355,67 @@ var Router = class _Router {
|
|
|
2344
2355
|
self() {
|
|
2345
2356
|
return this;
|
|
2346
2357
|
}
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2358
|
+
// Registers one route: bakes the current middleware + the route's own
|
|
2359
|
+
// functions into a single flat `fns` list. A plain options object may sit
|
|
2360
|
+
// between the path and the handlers, and it's pulled out here.
|
|
2361
|
+
handle(method, pathOrFn, ...rest) {
|
|
2362
|
+
let path2 = "*";
|
|
2363
|
+
if (typeof pathOrFn === "string") {
|
|
2364
|
+
path2 = pathOrFn;
|
|
2365
|
+
} else if (pathOrFn != null) {
|
|
2366
|
+
rest.unshift(pathOrFn);
|
|
2367
|
+
}
|
|
2368
|
+
let options = {};
|
|
2369
|
+
if (rest[0] != null && typeof rest[0] !== "function") {
|
|
2370
|
+
options = rest.shift();
|
|
2371
|
+
}
|
|
2372
|
+
const base = method === "socket" ? [] : this.middleware;
|
|
2373
|
+
const fns = [...base, ...rest].filter((fn) => fn != null);
|
|
2374
|
+
this.handlers[method].push({ path: path2, options, fns });
|
|
2356
2375
|
return this.self();
|
|
2357
2376
|
}
|
|
2358
2377
|
socket(pathOrMid, optionsOrMid, ...middleware) {
|
|
2359
|
-
|
|
2360
|
-
return this.handle("socket", pathOrMid, optionsOrMid, ...middleware);
|
|
2361
|
-
}
|
|
2362
|
-
return this.handle("socket", pathOrMid, ...middleware);
|
|
2378
|
+
return this.handle("socket", pathOrMid, optionsOrMid, ...middleware);
|
|
2363
2379
|
}
|
|
2364
2380
|
get(pathOrMid, optionsOrMid, ...middleware) {
|
|
2365
|
-
|
|
2366
|
-
return this.handle("get", pathOrMid, optionsOrMid, ...middleware);
|
|
2367
|
-
}
|
|
2368
|
-
return this.handle("get", pathOrMid, ...middleware);
|
|
2381
|
+
return this.handle("get", pathOrMid, optionsOrMid, ...middleware);
|
|
2369
2382
|
}
|
|
2370
2383
|
head(pathOrMid, optionsOrMid, ...middleware) {
|
|
2371
|
-
|
|
2372
|
-
return this.handle("head", pathOrMid, optionsOrMid, ...middleware);
|
|
2373
|
-
}
|
|
2374
|
-
return this.handle("head", pathOrMid, ...middleware);
|
|
2384
|
+
return this.handle("head", pathOrMid, optionsOrMid, ...middleware);
|
|
2375
2385
|
}
|
|
2376
2386
|
post(pathOrMid, optionsOrMid, ...middleware) {
|
|
2377
|
-
|
|
2378
|
-
return this.handle("post", pathOrMid, optionsOrMid, ...middleware);
|
|
2379
|
-
}
|
|
2380
|
-
return this.handle("post", pathOrMid, ...middleware);
|
|
2387
|
+
return this.handle("post", pathOrMid, optionsOrMid, ...middleware);
|
|
2381
2388
|
}
|
|
2382
2389
|
put(pathOrMid, optionsOrMid, ...middleware) {
|
|
2383
|
-
|
|
2384
|
-
return this.handle("put", pathOrMid, optionsOrMid, ...middleware);
|
|
2385
|
-
}
|
|
2386
|
-
return this.handle("put", pathOrMid, ...middleware);
|
|
2390
|
+
return this.handle("put", pathOrMid, optionsOrMid, ...middleware);
|
|
2387
2391
|
}
|
|
2388
2392
|
patch(pathOrMid, optionsOrMid, ...middleware) {
|
|
2389
|
-
|
|
2390
|
-
return this.handle("patch", pathOrMid, optionsOrMid, ...middleware);
|
|
2391
|
-
}
|
|
2392
|
-
return this.handle("patch", pathOrMid, ...middleware);
|
|
2393
|
+
return this.handle("patch", pathOrMid, optionsOrMid, ...middleware);
|
|
2393
2394
|
}
|
|
2394
2395
|
delete(pathOrMid, optionsOrMid, ...middleware) {
|
|
2395
|
-
|
|
2396
|
-
return this.handle("delete", pathOrMid, optionsOrMid, ...middleware);
|
|
2397
|
-
}
|
|
2398
|
-
return this.handle("delete", pathOrMid, ...middleware);
|
|
2396
|
+
return this.handle("delete", pathOrMid, optionsOrMid, ...middleware);
|
|
2399
2397
|
}
|
|
2400
2398
|
options(pathOrMid, optionsOrMid, ...middleware) {
|
|
2401
|
-
|
|
2402
|
-
return this.handle("options", pathOrMid, optionsOrMid, ...middleware);
|
|
2403
|
-
}
|
|
2404
|
-
return this.handle("options", pathOrMid, ...middleware);
|
|
2399
|
+
return this.handle("options", pathOrMid, optionsOrMid, ...middleware);
|
|
2405
2400
|
}
|
|
2406
2401
|
use(...args) {
|
|
2407
|
-
const
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2402
|
+
for (const arg of args) {
|
|
2403
|
+
if (arg instanceof _Router) {
|
|
2404
|
+
for (const m of Object.keys(arg.handlers)) {
|
|
2405
|
+
for (const route of arg.handlers[m]) {
|
|
2406
|
+
const base = m === "socket" ? [] : this.middleware;
|
|
2407
|
+
this.handlers[m].push({
|
|
2408
|
+
path: route.path,
|
|
2409
|
+
options: route.options,
|
|
2410
|
+
fns: [...base, ...route.fns]
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2415
2413
|
}
|
|
2414
|
+
} else {
|
|
2415
|
+
this.middleware.push(arg);
|
|
2416
2416
|
}
|
|
2417
|
-
return this.self();
|
|
2418
2417
|
}
|
|
2419
|
-
return this.
|
|
2418
|
+
return this.self();
|
|
2420
2419
|
}
|
|
2421
2420
|
};
|
|
2422
2421
|
function router() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@server/next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "A fully-fledged web server with routing, file uploads, sessions, static files, schema validation, websockets, testing, etc.",
|
|
5
5
|
"homepage": "https://server-js.com/",
|
|
6
6
|
"repository": "github:franciscop/server-next",
|