@stacksjs/router 0.70.45 → 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 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
+ }
@@ -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. Useful for tests asserting that an
14
- * action ran a single query for `posts` instead of one-per-user.
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
- * Clear tracked queries (e.g., after successful response)
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
- export type { RouteDefinition, RouteRegistry } from '../../../../../app/Routes';
4
- /**
5
- * @stacksjs/router - Stacks Router
6
- *
7
- * A thin wrapper around bun-router that adds Stacks-specific
8
- * action/controller resolution for string-based route handlers.
9
- *
10
- * All routing functionality comes directly from bun-router.
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';