@nextrush/types 4.0.0-beta.0 → 4.0.0-beta.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/dist/index.d.ts +123 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -159,6 +159,32 @@ type ContentTypeValue = (typeof ContentType)[keyof typeof ContentType];
|
|
|
159
159
|
* This enables runtime-specific optimizations while maintaining a unified API.
|
|
160
160
|
*/
|
|
161
161
|
type Runtime = 'node' | 'bun' | 'deno' | 'deno-deploy' | 'cloudflare-workers' | 'vercel-edge' | 'edge' | 'unknown';
|
|
162
|
+
/**
|
|
163
|
+
* Named serverless/edge deployment platform, orthogonal to {@link Runtime}.
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* `Runtime` answers "which JS engine" (node/bun/deno/edge); `PlatformId`
|
|
167
|
+
* answers "which vendor platform" (Lambda, GCF, Azure, Cloudflare Workers,
|
|
168
|
+
* Vercel Edge, Netlify Edge) — two independent questions that `Runtime`
|
|
169
|
+
* conflating would make into one. Exposed as `ctx.platform` alongside the
|
|
170
|
+
* unchanged `ctx.runtime`.
|
|
171
|
+
*
|
|
172
|
+
* @see RFC-026
|
|
173
|
+
*/
|
|
174
|
+
type PlatformId = 'lambda' | 'gcf' | 'azure' | 'cloudflare-workers' | 'vercel-edge' | 'netlify-edge';
|
|
175
|
+
/**
|
|
176
|
+
* Proxy-trust specification for client-IP resolution (RFC-030, SEC-01).
|
|
177
|
+
*
|
|
178
|
+
* @remarks
|
|
179
|
+
* `false` trusts nothing — the direct socket peer is always `ctx.ip`.
|
|
180
|
+
* A `number` trusts exactly that many proxy hops, selecting the
|
|
181
|
+
* corresponding `X-Forwarded-For` entry counting from the right rather than
|
|
182
|
+
* the client-authored leftmost entry. A `string[]` of CIDR ranges/literal
|
|
183
|
+
* IPs trusts only a direct peer (and every hop it names) falling inside the
|
|
184
|
+
* set. `true` and `0` are rejected at boot — see `resolveClientIp` in
|
|
185
|
+
* `@nextrush/runtime`.
|
|
186
|
+
*/
|
|
187
|
+
type ProxyTrust = false | number | string[];
|
|
162
188
|
/**
|
|
163
189
|
* Runtime feature capabilities
|
|
164
190
|
*
|
|
@@ -181,6 +207,10 @@ interface RuntimeCapabilities {
|
|
|
181
207
|
cryptoSubtle: boolean;
|
|
182
208
|
/** Supports Web Workers / Worker Threads */
|
|
183
209
|
workers: boolean;
|
|
210
|
+
/** Supports TLS (HTTPS) — the runtime can terminate TLS connections */
|
|
211
|
+
secureServing: boolean;
|
|
212
|
+
/** Supports HTTP/2 negotiation via ALPN (requires secureServing) */
|
|
213
|
+
http2: boolean;
|
|
184
214
|
}
|
|
185
215
|
/**
|
|
186
216
|
* Runtime information object
|
|
@@ -466,11 +496,26 @@ interface Context {
|
|
|
466
496
|
*/
|
|
467
497
|
readonly url: string;
|
|
468
498
|
/**
|
|
469
|
-
* Request path without query string
|
|
499
|
+
* Request path without query string, canonicalized by the router (case
|
|
500
|
+
* folded per `caseSensitive`, structurally normalized) — the value the
|
|
501
|
+
* router actually matched on, and the one path-based policy middleware
|
|
502
|
+
* should compare against instead of hand-rolling its own normalization
|
|
503
|
+
* (RFC-029). See {@link originalPath} for the untouched raw target.
|
|
470
504
|
* @example '/users/123'
|
|
471
505
|
* @readonly
|
|
472
506
|
*/
|
|
473
507
|
readonly path: string;
|
|
508
|
+
/**
|
|
509
|
+
* The raw request target as received, before router canonicalization —
|
|
510
|
+
* still query-string-free, but not case-folded or structurally normalized.
|
|
511
|
+
* Optional: populated once the router's dispatch middleware runs; absent
|
|
512
|
+
* (or equal to {@link path}) when no router has run yet, or when a caller
|
|
513
|
+
* constructs a `Context` directly (e.g. a test double) without one. Prefer
|
|
514
|
+
* `path` for any security- or routing-relevant comparison (RFC-029).
|
|
515
|
+
* @example '/Users/123' when a request for '/USERS/123' matched '/users/:id'
|
|
516
|
+
* @readonly
|
|
517
|
+
*/
|
|
518
|
+
readonly originalPath?: string;
|
|
474
519
|
/**
|
|
475
520
|
* Parsed query string parameters
|
|
476
521
|
* @example { include: 'posts', limit: '10' }
|
|
@@ -713,6 +758,25 @@ interface Context {
|
|
|
713
758
|
* ```
|
|
714
759
|
*/
|
|
715
760
|
readonly runtime: Runtime;
|
|
761
|
+
/**
|
|
762
|
+
* Named deployment platform, when known — orthogonal to {@link runtime}.
|
|
763
|
+
*
|
|
764
|
+
* @remarks
|
|
765
|
+
* `undefined` on adapters/runtimes with no named platform to report (e.g.
|
|
766
|
+
* plain Node.js, Bun, Deno). On `@nextrush/adapter-edge` and
|
|
767
|
+
* `@nextrush/adapter-serverless`, set when the platform is detectable
|
|
768
|
+
* (Cloudflare Workers, Vercel Edge, Netlify Edge) or explicitly known by
|
|
769
|
+
* the Tier-1 handler that built this context (AWS Lambda, Google Cloud
|
|
770
|
+
* Functions, Azure Functions).
|
|
771
|
+
*
|
|
772
|
+
* @example
|
|
773
|
+
* ```typescript
|
|
774
|
+
* if (ctx.platform === 'lambda') {
|
|
775
|
+
* // AWS Lambda-specific behavior
|
|
776
|
+
* }
|
|
777
|
+
* ```
|
|
778
|
+
*/
|
|
779
|
+
readonly platform: PlatformId | undefined;
|
|
716
780
|
/**
|
|
717
781
|
* Body source for cross-runtime body reading
|
|
718
782
|
*
|
|
@@ -1576,4 +1640,61 @@ interface RouteParam {
|
|
|
1576
1640
|
pattern?: RegExp;
|
|
1577
1641
|
}
|
|
1578
1642
|
|
|
1579
|
-
|
|
1643
|
+
/**
|
|
1644
|
+
* @nextrush/types - Security Audit Contribution Contract
|
|
1645
|
+
*
|
|
1646
|
+
* `core` cannot import `@nextrush/{cors,static,cookies,errors}` (lower
|
|
1647
|
+
* packages never import from higher ones — `architecture.instructions.md`),
|
|
1648
|
+
* so `Application` cannot inspect a middleware instance's configuration
|
|
1649
|
+
* directly. This contract lets a middleware factory (`cors()`, `serveStatic()`,
|
|
1650
|
+
* `cookies()`, `errorHandler()`, …) optionally attach a boot-time check to the
|
|
1651
|
+
* `Middleware` function it already returns from `app.use()` — the same
|
|
1652
|
+
* "contribute via a well-known symbol, the owner collects it later" shape as
|
|
1653
|
+
* {@link ROUTE_METADATA}, applied to production-safety auditing instead of
|
|
1654
|
+
* route documentation (RFC gates this in `docs/RFC/` under the
|
|
1655
|
+
* `security-boundaries` capability's boot-audit requirement).
|
|
1656
|
+
*
|
|
1657
|
+
* @packageDocumentation
|
|
1658
|
+
*/
|
|
1659
|
+
|
|
1660
|
+
/**
|
|
1661
|
+
* Well-known symbol by which a middleware factory contributes a security
|
|
1662
|
+
* audit check to the `Middleware` function it returns. `Application.use()`
|
|
1663
|
+
* reads this symbol off every registered middleware and collects any checks
|
|
1664
|
+
* present; `app.ready()` runs the collected set once, in production only.
|
|
1665
|
+
*
|
|
1666
|
+
* `Symbol.for` (global registry) matches {@link ROUTE_METADATA}'s choice, so
|
|
1667
|
+
* identity holds even across duplicate package instances.
|
|
1668
|
+
*/
|
|
1669
|
+
declare const SECURITY_AUDIT: unique symbol;
|
|
1670
|
+
/**
|
|
1671
|
+
* The outcome of one security audit check.
|
|
1672
|
+
*
|
|
1673
|
+
* - `ok` — configuration is safe; nothing is reported.
|
|
1674
|
+
* - `warn` — configuration is unsafe but has a legitimate use; logged once,
|
|
1675
|
+
* never blocks boot.
|
|
1676
|
+
* - `throw` — configuration has no legitimate production use; boot fails.
|
|
1677
|
+
*/
|
|
1678
|
+
type SecurityAuditVerdict = {
|
|
1679
|
+
readonly level: 'ok';
|
|
1680
|
+
} | {
|
|
1681
|
+
readonly level: 'warn';
|
|
1682
|
+
readonly message: string;
|
|
1683
|
+
} | {
|
|
1684
|
+
readonly level: 'throw';
|
|
1685
|
+
readonly message: string;
|
|
1686
|
+
};
|
|
1687
|
+
/**
|
|
1688
|
+
* A middleware's self-reported boot-time safety check, invoked only when the
|
|
1689
|
+
* application is booting in production. Pure and synchronous — a check
|
|
1690
|
+
* inspects configuration already closed over at construction time, never I/O.
|
|
1691
|
+
*/
|
|
1692
|
+
type SecurityAuditCheck = () => SecurityAuditVerdict;
|
|
1693
|
+
/** A middleware function carrying a {@link SecurityAuditCheck} contribution. */
|
|
1694
|
+
interface SecurityAudited {
|
|
1695
|
+
readonly [SECURITY_AUDIT]: SecurityAuditCheck;
|
|
1696
|
+
}
|
|
1697
|
+
/** A registered middleware, optionally carrying a security audit contribution. */
|
|
1698
|
+
type AuditableMiddleware = Middleware & Partial<SecurityAudited>;
|
|
1699
|
+
|
|
1700
|
+
export { type AdapterContext, type AdapterContextFactory, type AuditableMiddleware, type BaseStreamWriter, type BodySource, type BodySourceOptions, type ClassProvider, type CommonHttpMethod, type Constructor, type Container, ContentType, type ContentTypeValue, type Context, type ContextOptions, type ContextState, type Extension, type ExtensionContext, type ExtensionHost, type FactoryProvider, type FetchAdapter, type FetchContext, type FetchHandler, type FetchHandlerOptions, HTTP_METHODS, type HandlerOptions, type HttpMethod, HttpStatus, type HttpStatusCode, type IncomingHeaders, type InferOutput, type Logger, type MetadataContribution, type Middleware, type NDJSONStreamWriter, type Next, type NodeStreamLike, type OutgoingHeaders, type ParsedBody, type PlatformId, type Provider, type ProxyTrust, type QueryParams, ROUTE_METADATA, type RawHttp, type RegisterOptions, type ResponseBody, type Route, type RouteDefinition, type RouteEntry, type RouteHandler, type RouteMatch, type RouteMetaMarker, type RouteMetadata, type RouteParam, type RouteParams, type RoutePattern, type Router, type RouterOptions, type Runtime, type RuntimeCapabilities, type RuntimeInfo, SECURITY_AUDIT, type SSEEvent, type SSEStreamWriter, type Scope, type SecurityAuditCheck, type SecurityAuditVerdict, type SecurityAudited, type ServerAdapter, type ServerAddress, type ServerHandle, type ServiceOptions, type StandardSchemaIssue, type StandardSchemaPathSegment, type StandardSchemaProps, type StandardSchemaResult, type StandardSchemaV1, type StreamRun, type StreamSource, type TextStreamWriter, type Token, type ValueProvider, type WebStreamLike };
|
package/dist/index.js
CHANGED
|
@@ -76,6 +76,9 @@ var ContentType = {
|
|
|
76
76
|
// src/route-metadata.ts
|
|
77
77
|
var ROUTE_METADATA = /* @__PURE__ */ Symbol.for("nextrush.route.metadata");
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
// src/security-audit.ts
|
|
80
|
+
var SECURITY_AUDIT = /* @__PURE__ */ Symbol.for("nextrush.security.audit");
|
|
81
|
+
|
|
82
|
+
export { ContentType, HTTP_METHODS, HttpStatus, ROUTE_METADATA, SECURITY_AUDIT };
|
|
80
83
|
//# sourceMappingURL=index.js.map
|
|
81
84
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http.ts","../src/route-metadata.ts"],"names":[],"mappings":";AAyCO,IAAM,YAAA,GAAe;AAAA,EAC1B,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF;AAuBO,IAAM,UAAA,GAAa;AAAA;AAAA,EAExB,EAAA,EAAI,GAAA;AAAA,EACJ,OAAA,EAAS,GAAA;AAAA,EACT,QAAA,EAAU,GAAA;AAAA,EACV,UAAA,EAAY,GAAA;AAAA;AAAA,EAGZ,iBAAA,EAAmB,GAAA;AAAA,EACnB,KAAA,EAAO,GAAA;AAAA,EACP,SAAA,EAAW,GAAA;AAAA,EACX,YAAA,EAAc,GAAA;AAAA,EACd,kBAAA,EAAoB,GAAA;AAAA,EACpB,kBAAA,EAAoB,GAAA;AAAA;AAAA,EAGpB,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,gBAAA,EAAkB,GAAA;AAAA,EAClB,SAAA,EAAW,GAAA;AAAA,EACX,SAAA,EAAW,GAAA;AAAA,EACX,kBAAA,EAAoB,GAAA;AAAA,EACpB,cAAA,EAAgB,GAAA;AAAA,EAChB,mBAAA,EAAqB,GAAA;AAAA,EACrB,eAAA,EAAiB,GAAA;AAAA,EACjB,QAAA,EAAU,GAAA;AAAA,EACV,IAAA,EAAM,GAAA;AAAA,EACN,eAAA,EAAiB,GAAA;AAAA,EACjB,mBAAA,EAAqB,GAAA;AAAA,EACrB,iBAAA,EAAmB,GAAA;AAAA,EACnB,YAAA,EAAc,GAAA;AAAA,EACd,sBAAA,EAAwB,GAAA;AAAA,EACxB,qBAAA,EAAuB,GAAA;AAAA,EACvB,kBAAA,EAAoB,GAAA;AAAA,EACpB,WAAA,EAAa,GAAA;AAAA,EACb,oBAAA,EAAsB,GAAA;AAAA,EACtB,MAAA,EAAQ,GAAA;AAAA,EACR,iBAAA,EAAmB,GAAA;AAAA,EACnB,SAAA,EAAW,GAAA;AAAA,EACX,gBAAA,EAAkB,GAAA;AAAA,EAClB,qBAAA,EAAuB,GAAA;AAAA,EACvB,iBAAA,EAAmB,GAAA;AAAA,EACnB,+BAAA,EAAiC,GAAA;AAAA,EACjC,6BAAA,EAA+B,GAAA;AAAA;AAAA,EAG/B,qBAAA,EAAuB,GAAA;AAAA,EACvB,eAAA,EAAiB,GAAA;AAAA,EACjB,WAAA,EAAa,GAAA;AAAA,EACb,mBAAA,EAAqB,GAAA;AAAA,EACrB,eAAA,EAAiB,GAAA;AAAA,EACjB,0BAAA,EAA4B,GAAA;AAAA,EAC5B,uBAAA,EAAyB,GAAA;AAAA,EACzB,oBAAA,EAAsB,GAAA;AAAA,EACtB,aAAA,EAAe,GAAA;AAAA,EACf,YAAA,EAAc,GAAA;AAAA,EACd,qBAAA,EAAuB;AACzB;AAqFO,IAAM,WAAA,GAAc;AAAA,EACzB,IAAA,EAAM,kBAAA;AAAA,EACN,IAAA,EAAM,WAAA;AAAA,EACN,IAAA,EAAM,YAAA;AAAA,EACN,GAAA,EAAK,iBAAA;AAAA,EACL,IAAA,EAAM,mCAAA;AAAA,EACN,SAAA,EAAW,qBAAA;AAAA,EACX,YAAA,EAAc;AAChB;;;ACnMO,IAAM,cAAA,mBAAgC,MAAA,CAAO,GAAA,CAAI,yBAAyB","file":"index.js","sourcesContent":["/**\n * @nextrush/types - HTTP Type Definitions\n *\n * Core HTTP types used across the NextRush framework.\n * These types provide a clean abstraction over HTTP primitives,\n * designed to work across multiple runtimes (Node.js, Bun, Deno, Edge).\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// HTTP Method Types\n// ============================================================================\n\n/**\n * Standard HTTP methods supported by NextRush\n */\nexport type HttpMethod =\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'DELETE'\n | 'PATCH'\n | 'HEAD'\n | 'OPTIONS'\n | 'TRACE'\n | 'CONNECT';\n\n/**\n * Common HTTP methods for convenience\n */\nexport type CommonHttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\n/**\n * HTTP methods as readonly tuple for iteration.\n *\n * Note: TRACE and CONNECT are intentionally excluded from this constant.\n * - TRACE enables Cross-Site Tracing (XST) attacks and is disabled by most servers.\n * - CONNECT is used for HTTP tunneling (proxies) and is not relevant to application routing.\n * Both remain in the `HttpMethod` type for completeness (e.g., custom proxy adapters).\n */\nexport const HTTP_METHODS = [\n 'GET',\n 'POST',\n 'PUT',\n 'DELETE',\n 'PATCH',\n 'HEAD',\n 'OPTIONS',\n] as const satisfies readonly HttpMethod[];\n\n// ============================================================================\n// HTTP Headers Types\n// ============================================================================\n\n/**\n * Incoming request headers (read-only)\n */\nexport type IncomingHeaders = Readonly<Record<string, string | string[] | undefined>>;\n\n/**\n * Outgoing response headers (writable)\n */\nexport type OutgoingHeaders = Record<string, string | number | string[]>;\n\n// ============================================================================\n// HTTP Status Codes\n// ============================================================================\n\n/**\n * HTTP status codes\n */\nexport const HttpStatus = {\n // 2xx Success\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n\n // 3xx Redirection\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // 4xx Client Errors\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n PROXY_AUTH_REQUIRED: 407,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n LENGTH_REQUIRED: 411,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n EXPECTATION_FAILED: 417,\n IM_A_TEAPOT: 418,\n UNPROCESSABLE_ENTITY: 422,\n LOCKED: 423,\n FAILED_DEPENDENCY: 424,\n TOO_EARLY: 425,\n UPGRADE_REQUIRED: 426,\n PRECONDITION_REQUIRED: 428,\n TOO_MANY_REQUESTS: 429,\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n\n // 5xx Server Errors\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n VARIANT_ALSO_NEGOTIATES: 506,\n INSUFFICIENT_STORAGE: 507,\n LOOP_DETECTED: 508,\n NOT_EXTENDED: 510,\n NETWORK_AUTH_REQUIRED: 511,\n} as const;\n\nexport type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus];\n\n// ============================================================================\n// Request/Response Body Types\n// ============================================================================\n\n/**\n * Supported request body types after parsing\n */\nexport type ParsedBody =\n | string\n | Uint8Array\n | Record<string, unknown>\n | unknown[]\n | null\n | undefined;\n\n/**\n * Supported response body types\n *\n * @remarks\n * Uses structural stream interfaces to avoid coupling to any\n * specific runtime (Node.js, Bun, Deno, Edge).\n * Uint8Array and ArrayBuffer provide Web API compatibility.\n */\nexport type ResponseBody =\n | string\n | Uint8Array\n | ArrayBuffer\n | NodeStreamLike\n | WebStreamLike\n | Record<string, unknown>\n | unknown[]\n | null\n | undefined;\n\n// ============================================================================\n// Cross-Runtime Stream Types\n// ============================================================================\n\n/**\n * Structural interface for Node.js-compatible readable streams.\n * Matches Node.js `Readable` and `IncomingMessage` without importing `@types/node`.\n */\nexport interface NodeStreamLike {\n pipe(destination: unknown): unknown;\n}\n\n/**\n * Structural interface for Web API ReadableStreams.\n * Matches the global `ReadableStream<Uint8Array>` without requiring DOM lib types.\n */\nexport interface WebStreamLike {\n getReader(): unknown;\n readonly locked: boolean;\n}\n\n// ============================================================================\n// Raw HTTP Access Types\n// ============================================================================\n\n/**\n * Raw HTTP objects - generic to support multiple runtimes\n *\n * For Node.js: RawHttp<IncomingMessage, ServerResponse>\n * For Bun: RawHttp<Request, Response>\n * For Edge: RawHttp<Request, ResponseInit>\n *\n * @typeParam TReq - Raw request type for the runtime\n * @typeParam TRes - Raw response type for the runtime\n */\nexport interface RawHttp<TReq = unknown, TRes = unknown> {\n readonly req: TReq;\n readonly res: TRes;\n}\n\n// ============================================================================\n// Content Type Helpers\n// ============================================================================\n\n/**\n * Common content types\n */\nexport const ContentType = {\n JSON: 'application/json',\n HTML: 'text/html',\n TEXT: 'text/plain',\n XML: 'application/xml',\n FORM: 'application/x-www-form-urlencoded',\n MULTIPART: 'multipart/form-data',\n OCTET_STREAM: 'application/octet-stream',\n} as const;\n\nexport type ContentTypeValue = (typeof ContentType)[keyof typeof ContentType];\n","/**\n * @nextrush/types - Route Metadata Contracts\n *\n * `RouteDefinition` is the single source of truth for what a route *is and\n * means*. The router collects it once at registration; renderers\n * (`@nextrush/openapi`, and later SDK/Postman/RPC generators) read it. The\n * router itself is renderer-agnostic — it stores raw schemas and generic\n * metadata, never OpenAPI shapes.\n *\n * See docs/RFC/request-data/002-route-metadata.md.\n *\n * @packageDocumentation\n */\n\nimport type { Middleware } from './context';\nimport type { HttpMethod } from './http';\nimport type { StandardSchemaV1 } from './standard-schema';\n\n/**\n * Well-known symbol by which anything — a middleware function (e.g. `validate()`)\n * or a pure marker (e.g. `endpoint()`) — contributes metadata to the route it is\n * registered on. The router reads this symbol off every route entry at\n * registration and merges the contributions.\n *\n * `Symbol.for` (global registry) is used so the identity holds even across\n * duplicate package instances.\n */\nexport const ROUTE_METADATA: unique symbol = Symbol.for('nextrush.route.metadata');\n\n/** A partial metadata contribution; contributions merge in registration order. */\nexport type MetadataContribution = Partial<RouteMetadata>;\n\n/**\n * A pure-metadata marker carried in a route's argument list. Not a middleware —\n * it has no runtime behavior and never enters the executed chain.\n */\nexport interface RouteMetaMarker {\n readonly [ROUTE_METADATA]: MetadataContribution;\n}\n\n/** An entry in a route's argument list: behavior (`Middleware`) or pure metadata (a marker). */\nexport type RouteEntry = Middleware | RouteMetaMarker;\n\n/**\n * Generic, renderer-agnostic description of a route's request/response shapes\n * and documentation facts. Every field is a fact any renderer needs; no\n * renderer-specific artifacts (e.g. OpenAPI `operationId`) live here.\n */\nexport interface RouteMetadata {\n /** Request shapes — contributed by `validate()`; never hand-written on the golden path. */\n readonly request?: {\n readonly body?: StandardSchemaV1;\n readonly query?: StandardSchemaV1;\n readonly params?: StandardSchemaV1;\n };\n /** Response shapes by numeric status — contributed by `endpoint()`. */\n readonly responses?: Readonly<Record<number, StandardSchemaV1>>;\n readonly summary?: string;\n readonly description?: string;\n readonly tags?: readonly string[];\n readonly deprecated?: boolean;\n /** Cross-renderer intent — an `'internal'` route is excluded from public specs/SDKs. */\n readonly visibility?: 'public' | 'internal';\n}\n\n/**\n * The canonical description of a registered endpoint, produced by the router\n * and consumed by renderers.\n */\nexport interface RouteDefinition {\n /**\n * Canonical route key — `${METHOD} ${pathPattern}` (e.g. `\"GET /users/:id\"`),\n * the key the router uses internally. Deterministic and stable across\n * restarts, but it encodes the path, so it changes if the path or a param\n * name changes — a key, not a rename-stable opaque id.\n */\n readonly key: string;\n readonly method: HttpMethod;\n /** Full, mount/prefix-resolved path pattern. */\n readonly path: string;\n readonly metadata?: RouteMetadata;\n /**\n * `true` when this entry represents an any-method route (registered via\n * `router.all()` / `@All()`), matching every standard HTTP method under a\n * single introspection row rather than one row per method (T016). `method`\n * is still a real `HttpMethod` value for structural compatibility with\n * existing consumers that read `.method` unconditionally — check this flag\n * first when the distinction matters (e.g. an OpenAPI renderer expanding\n * one row into per-verb operations). Absent (`undefined`) for every\n * ordinary single-method route.\n */\n readonly isAnyMethod?: boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/http.ts","../src/route-metadata.ts","../src/security-audit.ts"],"names":[],"mappings":";AAyCO,IAAM,YAAA,GAAe;AAAA,EAC1B,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF;AAuBO,IAAM,UAAA,GAAa;AAAA;AAAA,EAExB,EAAA,EAAI,GAAA;AAAA,EACJ,OAAA,EAAS,GAAA;AAAA,EACT,QAAA,EAAU,GAAA;AAAA,EACV,UAAA,EAAY,GAAA;AAAA;AAAA,EAGZ,iBAAA,EAAmB,GAAA;AAAA,EACnB,KAAA,EAAO,GAAA;AAAA,EACP,SAAA,EAAW,GAAA;AAAA,EACX,YAAA,EAAc,GAAA;AAAA,EACd,kBAAA,EAAoB,GAAA;AAAA,EACpB,kBAAA,EAAoB,GAAA;AAAA;AAAA,EAGpB,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,gBAAA,EAAkB,GAAA;AAAA,EAClB,SAAA,EAAW,GAAA;AAAA,EACX,SAAA,EAAW,GAAA;AAAA,EACX,kBAAA,EAAoB,GAAA;AAAA,EACpB,cAAA,EAAgB,GAAA;AAAA,EAChB,mBAAA,EAAqB,GAAA;AAAA,EACrB,eAAA,EAAiB,GAAA;AAAA,EACjB,QAAA,EAAU,GAAA;AAAA,EACV,IAAA,EAAM,GAAA;AAAA,EACN,eAAA,EAAiB,GAAA;AAAA,EACjB,mBAAA,EAAqB,GAAA;AAAA,EACrB,iBAAA,EAAmB,GAAA;AAAA,EACnB,YAAA,EAAc,GAAA;AAAA,EACd,sBAAA,EAAwB,GAAA;AAAA,EACxB,qBAAA,EAAuB,GAAA;AAAA,EACvB,kBAAA,EAAoB,GAAA;AAAA,EACpB,WAAA,EAAa,GAAA;AAAA,EACb,oBAAA,EAAsB,GAAA;AAAA,EACtB,MAAA,EAAQ,GAAA;AAAA,EACR,iBAAA,EAAmB,GAAA;AAAA,EACnB,SAAA,EAAW,GAAA;AAAA,EACX,gBAAA,EAAkB,GAAA;AAAA,EAClB,qBAAA,EAAuB,GAAA;AAAA,EACvB,iBAAA,EAAmB,GAAA;AAAA,EACnB,+BAAA,EAAiC,GAAA;AAAA,EACjC,6BAAA,EAA+B,GAAA;AAAA;AAAA,EAG/B,qBAAA,EAAuB,GAAA;AAAA,EACvB,eAAA,EAAiB,GAAA;AAAA,EACjB,WAAA,EAAa,GAAA;AAAA,EACb,mBAAA,EAAqB,GAAA;AAAA,EACrB,eAAA,EAAiB,GAAA;AAAA,EACjB,0BAAA,EAA4B,GAAA;AAAA,EAC5B,uBAAA,EAAyB,GAAA;AAAA,EACzB,oBAAA,EAAsB,GAAA;AAAA,EACtB,aAAA,EAAe,GAAA;AAAA,EACf,YAAA,EAAc,GAAA;AAAA,EACd,qBAAA,EAAuB;AACzB;AAqFO,IAAM,WAAA,GAAc;AAAA,EACzB,IAAA,EAAM,kBAAA;AAAA,EACN,IAAA,EAAM,WAAA;AAAA,EACN,IAAA,EAAM,YAAA;AAAA,EACN,GAAA,EAAK,iBAAA;AAAA,EACL,IAAA,EAAM,mCAAA;AAAA,EACN,SAAA,EAAW,qBAAA;AAAA,EACX,YAAA,EAAc;AAChB;;;ACnMO,IAAM,cAAA,mBAAgC,MAAA,CAAO,GAAA,CAAI,yBAAyB;;;ACC1E,IAAM,cAAA,mBAAgC,MAAA,CAAO,GAAA,CAAI,yBAAyB","file":"index.js","sourcesContent":["/**\n * @nextrush/types - HTTP Type Definitions\n *\n * Core HTTP types used across the NextRush framework.\n * These types provide a clean abstraction over HTTP primitives,\n * designed to work across multiple runtimes (Node.js, Bun, Deno, Edge).\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// HTTP Method Types\n// ============================================================================\n\n/**\n * Standard HTTP methods supported by NextRush\n */\nexport type HttpMethod =\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'DELETE'\n | 'PATCH'\n | 'HEAD'\n | 'OPTIONS'\n | 'TRACE'\n | 'CONNECT';\n\n/**\n * Common HTTP methods for convenience\n */\nexport type CommonHttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\n/**\n * HTTP methods as readonly tuple for iteration.\n *\n * Note: TRACE and CONNECT are intentionally excluded from this constant.\n * - TRACE enables Cross-Site Tracing (XST) attacks and is disabled by most servers.\n * - CONNECT is used for HTTP tunneling (proxies) and is not relevant to application routing.\n * Both remain in the `HttpMethod` type for completeness (e.g., custom proxy adapters).\n */\nexport const HTTP_METHODS = [\n 'GET',\n 'POST',\n 'PUT',\n 'DELETE',\n 'PATCH',\n 'HEAD',\n 'OPTIONS',\n] as const satisfies readonly HttpMethod[];\n\n// ============================================================================\n// HTTP Headers Types\n// ============================================================================\n\n/**\n * Incoming request headers (read-only)\n */\nexport type IncomingHeaders = Readonly<Record<string, string | string[] | undefined>>;\n\n/**\n * Outgoing response headers (writable)\n */\nexport type OutgoingHeaders = Record<string, string | number | string[]>;\n\n// ============================================================================\n// HTTP Status Codes\n// ============================================================================\n\n/**\n * HTTP status codes\n */\nexport const HttpStatus = {\n // 2xx Success\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n\n // 3xx Redirection\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // 4xx Client Errors\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n PROXY_AUTH_REQUIRED: 407,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n LENGTH_REQUIRED: 411,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n EXPECTATION_FAILED: 417,\n IM_A_TEAPOT: 418,\n UNPROCESSABLE_ENTITY: 422,\n LOCKED: 423,\n FAILED_DEPENDENCY: 424,\n TOO_EARLY: 425,\n UPGRADE_REQUIRED: 426,\n PRECONDITION_REQUIRED: 428,\n TOO_MANY_REQUESTS: 429,\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n\n // 5xx Server Errors\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n VARIANT_ALSO_NEGOTIATES: 506,\n INSUFFICIENT_STORAGE: 507,\n LOOP_DETECTED: 508,\n NOT_EXTENDED: 510,\n NETWORK_AUTH_REQUIRED: 511,\n} as const;\n\nexport type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus];\n\n// ============================================================================\n// Request/Response Body Types\n// ============================================================================\n\n/**\n * Supported request body types after parsing\n */\nexport type ParsedBody =\n | string\n | Uint8Array\n | Record<string, unknown>\n | unknown[]\n | null\n | undefined;\n\n/**\n * Supported response body types\n *\n * @remarks\n * Uses structural stream interfaces to avoid coupling to any\n * specific runtime (Node.js, Bun, Deno, Edge).\n * Uint8Array and ArrayBuffer provide Web API compatibility.\n */\nexport type ResponseBody =\n | string\n | Uint8Array\n | ArrayBuffer\n | NodeStreamLike\n | WebStreamLike\n | Record<string, unknown>\n | unknown[]\n | null\n | undefined;\n\n// ============================================================================\n// Cross-Runtime Stream Types\n// ============================================================================\n\n/**\n * Structural interface for Node.js-compatible readable streams.\n * Matches Node.js `Readable` and `IncomingMessage` without importing `@types/node`.\n */\nexport interface NodeStreamLike {\n pipe(destination: unknown): unknown;\n}\n\n/**\n * Structural interface for Web API ReadableStreams.\n * Matches the global `ReadableStream<Uint8Array>` without requiring DOM lib types.\n */\nexport interface WebStreamLike {\n getReader(): unknown;\n readonly locked: boolean;\n}\n\n// ============================================================================\n// Raw HTTP Access Types\n// ============================================================================\n\n/**\n * Raw HTTP objects - generic to support multiple runtimes\n *\n * For Node.js: RawHttp<IncomingMessage, ServerResponse>\n * For Bun: RawHttp<Request, Response>\n * For Edge: RawHttp<Request, ResponseInit>\n *\n * @typeParam TReq - Raw request type for the runtime\n * @typeParam TRes - Raw response type for the runtime\n */\nexport interface RawHttp<TReq = unknown, TRes = unknown> {\n readonly req: TReq;\n readonly res: TRes;\n}\n\n// ============================================================================\n// Content Type Helpers\n// ============================================================================\n\n/**\n * Common content types\n */\nexport const ContentType = {\n JSON: 'application/json',\n HTML: 'text/html',\n TEXT: 'text/plain',\n XML: 'application/xml',\n FORM: 'application/x-www-form-urlencoded',\n MULTIPART: 'multipart/form-data',\n OCTET_STREAM: 'application/octet-stream',\n} as const;\n\nexport type ContentTypeValue = (typeof ContentType)[keyof typeof ContentType];\n","/**\n * @nextrush/types - Route Metadata Contracts\n *\n * `RouteDefinition` is the single source of truth for what a route *is and\n * means*. The router collects it once at registration; renderers\n * (`@nextrush/openapi`, and later SDK/Postman/RPC generators) read it. The\n * router itself is renderer-agnostic — it stores raw schemas and generic\n * metadata, never OpenAPI shapes.\n *\n * See docs/RFC/request-data/002-route-metadata.md.\n *\n * @packageDocumentation\n */\n\nimport type { Middleware } from './context';\nimport type { HttpMethod } from './http';\nimport type { StandardSchemaV1 } from './standard-schema';\n\n/**\n * Well-known symbol by which anything — a middleware function (e.g. `validate()`)\n * or a pure marker (e.g. `endpoint()`) — contributes metadata to the route it is\n * registered on. The router reads this symbol off every route entry at\n * registration and merges the contributions.\n *\n * `Symbol.for` (global registry) is used so the identity holds even across\n * duplicate package instances.\n */\nexport const ROUTE_METADATA: unique symbol = Symbol.for('nextrush.route.metadata');\n\n/** A partial metadata contribution; contributions merge in registration order. */\nexport type MetadataContribution = Partial<RouteMetadata>;\n\n/**\n * A pure-metadata marker carried in a route's argument list. Not a middleware —\n * it has no runtime behavior and never enters the executed chain.\n */\nexport interface RouteMetaMarker {\n readonly [ROUTE_METADATA]: MetadataContribution;\n}\n\n/** An entry in a route's argument list: behavior (`Middleware`) or pure metadata (a marker). */\nexport type RouteEntry = Middleware | RouteMetaMarker;\n\n/**\n * Generic, renderer-agnostic description of a route's request/response shapes\n * and documentation facts. Every field is a fact any renderer needs; no\n * renderer-specific artifacts (e.g. OpenAPI `operationId`) live here.\n */\nexport interface RouteMetadata {\n /** Request shapes — contributed by `validate()`; never hand-written on the golden path. */\n readonly request?: {\n readonly body?: StandardSchemaV1;\n readonly query?: StandardSchemaV1;\n readonly params?: StandardSchemaV1;\n };\n /** Response shapes by numeric status — contributed by `endpoint()`. */\n readonly responses?: Readonly<Record<number, StandardSchemaV1>>;\n readonly summary?: string;\n readonly description?: string;\n readonly tags?: readonly string[];\n readonly deprecated?: boolean;\n /** Cross-renderer intent — an `'internal'` route is excluded from public specs/SDKs. */\n readonly visibility?: 'public' | 'internal';\n}\n\n/**\n * The canonical description of a registered endpoint, produced by the router\n * and consumed by renderers.\n */\nexport interface RouteDefinition {\n /**\n * Canonical route key — `${METHOD} ${pathPattern}` (e.g. `\"GET /users/:id\"`),\n * the key the router uses internally. Deterministic and stable across\n * restarts, but it encodes the path, so it changes if the path or a param\n * name changes — a key, not a rename-stable opaque id.\n */\n readonly key: string;\n readonly method: HttpMethod;\n /** Full, mount/prefix-resolved path pattern. */\n readonly path: string;\n readonly metadata?: RouteMetadata;\n /**\n * `true` when this entry represents an any-method route (registered via\n * `router.all()` / `@All()`), matching every standard HTTP method under a\n * single introspection row rather than one row per method (T016). `method`\n * is still a real `HttpMethod` value for structural compatibility with\n * existing consumers that read `.method` unconditionally — check this flag\n * first when the distinction matters (e.g. an OpenAPI renderer expanding\n * one row into per-verb operations). Absent (`undefined`) for every\n * ordinary single-method route.\n */\n readonly isAnyMethod?: boolean;\n}\n","/**\n * @nextrush/types - Security Audit Contribution Contract\n *\n * `core` cannot import `@nextrush/{cors,static,cookies,errors}` (lower\n * packages never import from higher ones — `architecture.instructions.md`),\n * so `Application` cannot inspect a middleware instance's configuration\n * directly. This contract lets a middleware factory (`cors()`, `serveStatic()`,\n * `cookies()`, `errorHandler()`, …) optionally attach a boot-time check to the\n * `Middleware` function it already returns from `app.use()` — the same\n * \"contribute via a well-known symbol, the owner collects it later\" shape as\n * {@link ROUTE_METADATA}, applied to production-safety auditing instead of\n * route documentation (RFC gates this in `docs/RFC/` under the\n * `security-boundaries` capability's boot-audit requirement).\n *\n * @packageDocumentation\n */\n\nimport type { Middleware } from './context';\n\n/**\n * Well-known symbol by which a middleware factory contributes a security\n * audit check to the `Middleware` function it returns. `Application.use()`\n * reads this symbol off every registered middleware and collects any checks\n * present; `app.ready()` runs the collected set once, in production only.\n *\n * `Symbol.for` (global registry) matches {@link ROUTE_METADATA}'s choice, so\n * identity holds even across duplicate package instances.\n */\nexport const SECURITY_AUDIT: unique symbol = Symbol.for('nextrush.security.audit');\n\n/**\n * The outcome of one security audit check.\n *\n * - `ok` — configuration is safe; nothing is reported.\n * - `warn` — configuration is unsafe but has a legitimate use; logged once,\n * never blocks boot.\n * - `throw` — configuration has no legitimate production use; boot fails.\n */\nexport type SecurityAuditVerdict =\n | { readonly level: 'ok' }\n | { readonly level: 'warn'; readonly message: string }\n | { readonly level: 'throw'; readonly message: string };\n\n/**\n * A middleware's self-reported boot-time safety check, invoked only when the\n * application is booting in production. Pure and synchronous — a check\n * inspects configuration already closed over at construction time, never I/O.\n */\nexport type SecurityAuditCheck = () => SecurityAuditVerdict;\n\n/** A middleware function carrying a {@link SecurityAuditCheck} contribution. */\nexport interface SecurityAudited {\n readonly [SECURITY_AUDIT]: SecurityAuditCheck;\n}\n\n/** A registered middleware, optionally carrying a security audit contribution. */\nexport type AuditableMiddleware = Middleware & Partial<SecurityAudited>;\n"]}
|