@stacksjs/router 0.70.44 → 0.70.53
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/LICENSE.md +21 -0
- package/dist/api-shape.d.ts +24 -0
- package/dist/encrypted-session-store.d.ts +19 -0
- package/dist/error-handler.d.ts +10 -4
- package/dist/index.d.ts +57 -11
- package/dist/index.js +33 -32
- package/dist/middleware.d.ts +1 -0
- package/dist/path-sanitize.d.ts +64 -0
- package/dist/request-augmentation.d.ts +67 -0
- package/dist/request-context.d.ts +32 -9
- package/dist/route-loader.d.ts +1 -1
- package/dist/route-types.d.ts +12 -0
- package/dist/security-headers.d.ts +20 -0
- package/dist/session-factory.d.ts +57 -0
- package/dist/signed-url.d.ts +50 -0
- package/dist/stacks-router.d.ts +93 -0
- package/package.json +11 -11
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Open Web Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*`,
|
|
2
|
+
* not `application/json`). This predicate fixes that asymmetry by making
|
|
3
|
+
* JSON the default unless the client explicitly opts into HTML.
|
|
4
|
+
*/
|
|
5
|
+
export declare function isApiRequest(req: Request | { headers: Headers }): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* "Is this request JSON-shaped?" — the single source of truth used across
|
|
8
|
+
* the framework to decide JSON vs HTML for responses (errors, primitives,
|
|
9
|
+
* empty results) and to widen request-body parsing to every JSON variant.
|
|
10
|
+
*
|
|
11
|
+
* The historical bug was scattered ad-hoc checks: `error-handler` looked at
|
|
12
|
+
* `Accept`, `formatResult` ignored the request entirely, `parseRequestBody`
|
|
13
|
+
* did `contentType.includes('application/json')` so `application/vnd.api+json`
|
|
14
|
+
* went unparsed. Centralizing the decision here means a future tweak (e.g.,
|
|
15
|
+
* treating an `apiResponse: true` route group as always-JSON) lands in one
|
|
16
|
+
* place and every response path picks it up.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Matches `application/json` plus any RFC-6838 structured-suffix subtype:
|
|
20
|
+
* `application/vnd.api+json`, `application/ld+json`, `application/hal+json`,
|
|
21
|
+
* `application/problem+json`, etc. Case-insensitive; tolerates a trailing
|
|
22
|
+
* `;` (for `;charset=utf-8`) or end-of-string.
|
|
23
|
+
*/
|
|
24
|
+
export declare const JSON_CONTENT_TYPE: unknown;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SessionData, SessionStore } from '@stacksjs/bun-router';
|
|
2
|
+
export declare interface EncryptedSessionStoreOptions {
|
|
3
|
+
appKey?: string
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Wrap a bun-router `SessionStore<SessionData>` so all writes are
|
|
7
|
+
* encrypted on the way in and decrypted on the way out. Drop-in
|
|
8
|
+
* replacement for any of the built-in stores.
|
|
9
|
+
*/
|
|
10
|
+
export declare class EncryptedSessionStore implements SessionStore<SessionData> {
|
|
11
|
+
constructor(inner: SessionStore<SessionData>, opts?: EncryptedSessionStoreOptions);
|
|
12
|
+
set(sid: string, session: SessionData, ttl?: number): Promise<void>;
|
|
13
|
+
touch(sid: string, session: SessionData, ttl?: number): Promise<void>;
|
|
14
|
+
get(sid: string): Promise<SessionData | null>;
|
|
15
|
+
destroy(sid: string): Promise<void>;
|
|
16
|
+
all(): Promise<Record<string, SessionData>>;
|
|
17
|
+
length(): Promise<number>;
|
|
18
|
+
clear(): Promise<void>;
|
|
19
|
+
}
|
package/dist/error-handler.d.ts
CHANGED
|
@@ -10,12 +10,18 @@ import type { EnhancedRequest } from '@stacksjs/bun-router';
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function trackQuery(query: string, time?: number, connection?: string): void;
|
|
12
12
|
/**
|
|
13
|
-
* Snapshot of query shape counts
|
|
14
|
-
* action ran a single query for `posts`
|
|
13
|
+
* Snapshot of query shape counts for the active request. Useful for
|
|
14
|
+
* tests asserting that an action ran a single query for `posts`
|
|
15
|
+
* instead of one-per-user.
|
|
15
16
|
*/
|
|
16
17
|
export declare function getQueryShapeCounts(): ReadonlyMap<string, number>;
|
|
17
18
|
/**
|
|
18
|
-
*
|
|
19
|
+
* Reset query tracking for the active scope.
|
|
20
|
+
*
|
|
21
|
+
* Inside a request, this clears the per-request tracking object — but
|
|
22
|
+
* the object is also auto-collected when the request goes out of scope,
|
|
23
|
+
* so the explicit call is mainly useful for tests that re-use a single
|
|
24
|
+
* request. Outside a request, this clears the process-wide fallback.
|
|
19
25
|
*/
|
|
20
26
|
export declare function clearTrackedQueries(): void;
|
|
21
27
|
/**
|
|
@@ -41,7 +47,7 @@ export declare function createErrorResponse(error: Error, request: Request | Enh
|
|
|
41
47
|
* validation middleware leaks out as a 500 with an Ignition error page —
|
|
42
48
|
* which is what we used to ship for `GET /api/me` without a token.
|
|
43
49
|
*/
|
|
44
|
-
export declare function createMiddlewareErrorResponse(error: Error & { statusCode?: number, status?: number }, request: Request | EnhancedRequest): Promise<Response>;
|
|
50
|
+
export declare function createMiddlewareErrorResponse(error: Error & { statusCode?: number, status?: number, headers?: Record<string, string> }, request: Request | EnhancedRequest): Promise<Response>;
|
|
45
51
|
/**
|
|
46
52
|
* Create a validation error response
|
|
47
53
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
+
import './request-augmentation';
|
|
2
|
+
// Re-export the augmentation types so userland can refer to the marker
|
|
3
|
+
// surface explicitly when needed.
|
|
4
|
+
export type { StacksRequestExtensions, StacksRequestMacros, StacksRequestMarkers } from './request-augmentation';
|
|
1
5
|
export type { MiddlewareConfig, Request } from './middleware';
|
|
2
|
-
// Export route registry types
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
// Export route registry types — owned here rather than in app/Routes.ts
|
|
7
|
+
// so the path doesn't depend on a 5-level relative reach across the
|
|
8
|
+
// framework defaults tree (stacksjs/stacks#1863, T-10).
|
|
9
|
+
export type { RouteDefinition, RouteRegistry } from './route-types';
|
|
10
|
+
export type { PathParamRejection, SanitizePathParamOptions } from './path-sanitize';
|
|
11
|
+
export type { StreamOptions } from './stacks-router';
|
|
12
|
+
export type { SignedUrlOptions, SignedUrlVerifyResult } from './signed-url';
|
|
13
|
+
export type { EncryptedSessionStoreOptions } from './encrypted-session-store';
|
|
14
|
+
export type {
|
|
15
|
+
RedisClient,
|
|
16
|
+
SessionConfig,
|
|
17
|
+
SessionData,
|
|
18
|
+
SessionStore,
|
|
19
|
+
StacksSessionConfig,
|
|
20
|
+
} from './session-factory';
|
|
12
21
|
// Re-export everything from bun-router (includes response factory)
|
|
13
22
|
export * from '@stacksjs/bun-router';
|
|
14
23
|
// Export Stacks-specific action resolver and URL helper
|
|
15
|
-
export { clearMiddlewareCache, createStacksRouter, installMiddlewareHotReload, route, serve, serverResponse, url } from './stacks-router';
|
|
24
|
+
export { assertRouteMiddlewareResolvable, clearMiddlewareCache, createStacksRouter, findUnresolvableRouteMiddleware, installMiddlewareHotReload, route, serve, serverResponse, url } from './stacks-router';
|
|
16
25
|
// Export request context helpers
|
|
17
26
|
export { cacheRequestQuery, getCurrentRequest, getTraceId, request, runWithRequest, setCurrentRequest, withTraceId } from './request-context';
|
|
18
27
|
// Export Middleware class for defining route middleware
|
|
@@ -31,5 +40,42 @@ export {
|
|
|
31
40
|
} from './error-handler';
|
|
32
41
|
// Export route introspection helpers
|
|
33
42
|
export { listRegisteredRoutes, routeParams } from './stacks-router';
|
|
43
|
+
// Export JSON-vs-HTML negotiation predicate so userland can short-circuit
|
|
44
|
+
// the same decision the framework makes in formatResult / error-handler.
|
|
45
|
+
export { isApiRequest, JSON_CONTENT_TYPE } from './api-shape';
|
|
34
46
|
// Export action-level rate limiting helpers
|
|
35
47
|
export { rateLimit, rateLimitStatus, clearRateLimit } from './rate-limit';
|
|
48
|
+
// Export path-param sanitization helper (stacksjs/stacks#1870 R-12).
|
|
49
|
+
// Defense-in-depth for actions that interpolate route params into
|
|
50
|
+
// filesystem paths; the helper enforces no-traversal / no-absolute /
|
|
51
|
+
// no-null-byte / length ceiling at a single chokepoint.
|
|
52
|
+
export { PathParamError, safePathParam, sanitizePathParam } from './path-sanitize';
|
|
53
|
+
// Export the streaming-response helper for SSE / NDJSON / chunked
|
|
54
|
+
// binary returns (stacksjs/stacks#1870 R-4). Actions can return
|
|
55
|
+
// `stream(asyncGen, { type: 'sse' })` and the router pipes it back
|
|
56
|
+
// with the right Content-Type + no-cache headers.
|
|
57
|
+
export { stream } from './stacks-router';
|
|
58
|
+
// Signed-URL helpers — HMAC over the URL + optional expiry so single-
|
|
59
|
+
// use links (email verify, password reset, unsubscribe) can be handed
|
|
60
|
+
// out without long-lived bearer tokens. Pair `signedUrl(...)` with the
|
|
61
|
+
// `signed` middleware (or call `verifySignedUrl(req.url)` directly).
|
|
62
|
+
// See stacksjs/stacks#1870 R-7.
|
|
63
|
+
export { signedUrl, signUrl, verifySignedUrl, verifySignedUrlMiddleware } from './signed-url';
|
|
64
|
+
// Encryption-at-rest wrapper for any bun-router SessionStore
|
|
65
|
+
// (stacksjs/stacks#1878 Se-4). Opt-in: wrap your existing store
|
|
66
|
+
// instance so session payloads are AES-GCM encrypted via APP_KEY
|
|
67
|
+
// before being persisted.
|
|
68
|
+
export { EncryptedSessionStore } from './encrypted-session-store';
|
|
69
|
+
// Session driver factory (stacksjs/stacks#1889, F-2 from #1874).
|
|
70
|
+
// Builds a SessionStore from the Stacks config — picks the right
|
|
71
|
+
// driver from `config.session.driver`, optionally wraps with
|
|
72
|
+
// EncryptedSessionStore. Re-exports all four bun-router store
|
|
73
|
+
// classes so callers can assemble custom stacks manually too.
|
|
74
|
+
export {
|
|
75
|
+
createSessionStore,
|
|
76
|
+
createStacksSessionStore,
|
|
77
|
+
DatabaseSessionStore,
|
|
78
|
+
FileSessionStore,
|
|
79
|
+
MemorySessionStore,
|
|
80
|
+
RedisSessionStore,
|
|
81
|
+
} from './session-factory';
|