spooder 6.1.95 → 6.2.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/bun.lock +1 -1
- package/package.json +1 -1
- package/src/api.ts +20 -4
package/bun.lock
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"packages": {
|
|
13
13
|
"@types/bun": ["@types/bun@1.3.5", "", { "dependencies": { "bun-types": "1.3.5" } }, "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w=="],
|
|
14
14
|
|
|
15
|
-
"@types/node": ["@types/node@25.0.
|
|
15
|
+
"@types/node": ["@types/node@25.0.7", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-C/er7DlIZgRJO7WtTdYovjIFzGsz0I95UlMyR9anTb4aCpBSRWe5Jc1/RvLKUfzmOxHPGjSE5+63HgLtndxU4w=="],
|
|
16
16
|
|
|
17
17
|
"bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="],
|
|
18
18
|
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -1332,6 +1332,8 @@ export const HTTP_STATUS_CODE = {
|
|
|
1332
1332
|
type HTTP_METHOD = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';
|
|
1333
1333
|
type HTTP_METHODS = HTTP_METHOD|HTTP_METHOD[];
|
|
1334
1334
|
|
|
1335
|
+
type BodylessMethod = 'GET' | 'HEAD';
|
|
1336
|
+
|
|
1335
1337
|
export function http_apply_range(file: BunFile, request: Request): BunFile {
|
|
1336
1338
|
const range_header = request.headers.get('range');
|
|
1337
1339
|
if (range_header !== null) {
|
|
@@ -1384,7 +1386,7 @@ type ErrorHandler = (err: Error, req: Request, url: URL) => Resolvable<Response>
|
|
|
1384
1386
|
type DefaultHandler = (req: Request, status_code: number) => HandlerReturnType;
|
|
1385
1387
|
type StatusCodeHandler = (req: Request) => HandlerReturnType;
|
|
1386
1388
|
|
|
1387
|
-
type JSONRequestHandler = (req: Request, url: URL, json:
|
|
1389
|
+
type JSONRequestHandler<T extends JsonObject | null = JsonObject> = (req: Request, url: URL, json: T) => HandlerReturnType;
|
|
1388
1390
|
|
|
1389
1391
|
export type ServerSentEventClient = {
|
|
1390
1392
|
message: (message: string) => void;
|
|
@@ -1823,10 +1825,20 @@ export function http_serve(port: number, hostname?: string) {
|
|
|
1823
1825
|
log_spooder(`server started on port {${server.port}} (host: {${hostname ?? 'unspecified'}})`);
|
|
1824
1826
|
|
|
1825
1827
|
type ThrottleHandler = {
|
|
1826
|
-
(delta: number, handler: JSONRequestHandler): JSONRequestHandler
|
|
1828
|
+
(delta: number, handler: JSONRequestHandler<JsonObject>): JSONRequestHandler<JsonObject>;
|
|
1829
|
+
(delta: number, handler: JSONRequestHandler<null>): JSONRequestHandler<null>;
|
|
1827
1830
|
(delta: number, handler: RequestHandler): RequestHandler;
|
|
1828
1831
|
};
|
|
1829
1832
|
|
|
1833
|
+
type JsonEndpointHandler = {
|
|
1834
|
+
<M extends BodylessMethod>(path: string, handler: JSONRequestHandler<null>, method: M): void;
|
|
1835
|
+
<M extends BodylessMethod[]>(path: string, handler: JSONRequestHandler<null>, method: M): void;
|
|
1836
|
+
<M extends Exclude<HTTP_METHOD, BodylessMethod>>(path: string, handler: JSONRequestHandler<JsonObject>, method: M): void;
|
|
1837
|
+
<M extends Exclude<HTTP_METHOD, BodylessMethod>[]>(path: string, handler: JSONRequestHandler<JsonObject>, method: M): void;
|
|
1838
|
+
<M extends HTTP_METHOD[]>(path: string, handler: JSONRequestHandler<JsonObject | null>, method: M): void;
|
|
1839
|
+
(path: string, handler: JSONRequestHandler<JsonObject>): void;
|
|
1840
|
+
};
|
|
1841
|
+
|
|
1830
1842
|
return {
|
|
1831
1843
|
/** Register a handler for a specific route. */
|
|
1832
1844
|
route: (path: string, handler: RequestHandler, method: HTTP_METHODS = 'GET'): void => {
|
|
@@ -1853,7 +1865,7 @@ export function http_serve(port: number, hostname?: string) {
|
|
|
1853
1865
|
}) as ThrottleHandler,
|
|
1854
1866
|
|
|
1855
1867
|
/** Register a JSON endpoint with automatic content validation. */
|
|
1856
|
-
json: (path: string, handler: JSONRequestHandler
|
|
1868
|
+
json: ((path: string, handler: JSONRequestHandler<JsonObject | null>, method: HTTP_METHODS = 'POST'): void => {
|
|
1857
1869
|
const json_wrapper: RequestHandler = async (req: Request, url: URL) => {
|
|
1858
1870
|
// handle CORS preflight
|
|
1859
1871
|
if (req.method === 'OPTIONS') {
|
|
@@ -1868,6 +1880,10 @@ export function http_serve(port: number, hostname?: string) {
|
|
|
1868
1880
|
}
|
|
1869
1881
|
|
|
1870
1882
|
try {
|
|
1883
|
+
// GET/HEAD requests don't have bodies, skip validation
|
|
1884
|
+
if (req.method === 'GET' || req.method === 'HEAD')
|
|
1885
|
+
return handler(req, url, null);
|
|
1886
|
+
|
|
1871
1887
|
if (req.headers.get('Content-Type') !== 'application/json')
|
|
1872
1888
|
return 400; // Bad Request
|
|
1873
1889
|
|
|
@@ -1886,7 +1902,7 @@ export function http_serve(port: number, hostname?: string) {
|
|
|
1886
1902
|
|
|
1887
1903
|
const methods: HTTP_METHODS = Array.isArray(method) ? [...method, 'OPTIONS'] : [method, 'OPTIONS'];
|
|
1888
1904
|
routes.push([path.split('/'), json_wrapper, methods]);
|
|
1889
|
-
},
|
|
1905
|
+
}) as JsonEndpointHandler,
|
|
1890
1906
|
|
|
1891
1907
|
/** Unregister a specific route */
|
|
1892
1908
|
unroute: (path: string): void => {
|