@curveball/core
Advanced tools
Comparing version 0.18.0 to 0.19.0
@@ -75,2 +75,13 @@ /// <reference types="node" /> | ||
buildContextFromHttp(req: NodeHttpRequest, res: NodeHttpResponse): Context; | ||
private _origin?; | ||
/** | ||
* The public base url of the application. | ||
* | ||
* This can be auto-detected, but will often be wrong when your server is | ||
* running behind a reverse proxy or load balancer. | ||
* | ||
* To provide this, set the process.env.PUBLIC_URI property. | ||
*/ | ||
get origin(): string; | ||
set origin(baseUrl: string); | ||
} |
@@ -89,4 +89,4 @@ "use strict"; | ||
wss.on('connection', async (ws, req) => { | ||
const request = new request_1.default(req); | ||
const response = new memory_response_1.default(); | ||
const request = new request_1.default(req, this.origin); | ||
const response = new memory_response_1.default(this.origin); | ||
const context = new context_1.Context(request, response); | ||
@@ -137,4 +137,4 @@ context.webSocket = ws; | ||
this.wss.on('connection', async (ws, req) => { | ||
const request = new request_1.default(req); | ||
const response = new memory_response_1.default(); | ||
const request = new request_1.default(req, this.origin); | ||
const response = new memory_response_1.default(this.origin); | ||
const context = new context_1.Context(request, response); | ||
@@ -152,3 +152,3 @@ context.webSocket = ws; | ||
if (typeof arg1 === 'string') { | ||
request = new memory_request_1.default(arg1, path, headers, body); | ||
request = new memory_request_1.default(arg1, path, this.origin, headers, body); | ||
} | ||
@@ -158,3 +158,3 @@ else { | ||
} | ||
const context = new context_1.Context(request, new memory_response_1.default()); | ||
const context = new context_1.Context(request, new memory_response_1.default(this.origin)); | ||
try { | ||
@@ -164,3 +164,2 @@ await this.handle(context); | ||
catch (err) { | ||
// eslint-disable-next-line no-console | ||
console.error(err); | ||
@@ -186,7 +185,31 @@ if (this.listenerCount('error')) { | ||
buildContextFromHttp(req, res) { | ||
const context = new context_1.Context(new request_1.default(req), new response_1.default(res)); | ||
const context = new context_1.Context(new request_1.default(req, this.origin), new response_1.default(res, this.origin)); | ||
return context; | ||
} | ||
/** | ||
* The public base url of the application. | ||
* | ||
* This can be auto-detected, but will often be wrong when your server is | ||
* running behind a reverse proxy or load balancer. | ||
* | ||
* To provide this, set the process.env.PUBLIC_URI property. | ||
*/ | ||
get origin() { | ||
if (this._origin) { | ||
return this._origin; | ||
} | ||
if (process.env.CURVEBALL_ORIGIN) { | ||
return process.env.CURVEBALL_ORIGIN; | ||
} | ||
if (process.env.PUBLIC_URI) { | ||
return new URL(process.env.PUBLIC_URI).origin; | ||
} | ||
const port = process.env.PORT ? +process.env.PORT : 80; | ||
return 'http://localhost' + (port !== 80 ? ':' + port : ''); | ||
} | ||
set origin(baseUrl) { | ||
this._origin = new URL(baseUrl).origin; | ||
} | ||
} | ||
exports.default = Application; | ||
//# sourceMappingURL=application.js.map |
@@ -39,2 +39,3 @@ import { Middleware } from './application'; | ||
get path(): string; | ||
get absoluteUrl(): string; | ||
/** | ||
@@ -41,0 +42,0 @@ * HTTP method |
@@ -23,2 +23,5 @@ "use strict"; | ||
} | ||
get absoluteUrl() { | ||
return this.request.absoluteUrl; | ||
} | ||
/** | ||
@@ -25,0 +28,0 @@ * HTTP method |
@@ -15,3 +15,3 @@ /// <reference types="node" /> | ||
body: T; | ||
constructor(method: string, requestTarget: string, headers?: HeadersInterface | HeadersObject, body?: any); | ||
constructor(method: string, requestTarget: string, origin: string, headers?: HeadersInterface | HeadersObject, body?: any, absoluteUrl?: string); | ||
/** | ||
@@ -18,0 +18,0 @@ * Internal representation of body. |
@@ -8,5 +8,5 @@ "use strict"; | ||
class MemoryRequest extends request_1.Request { | ||
constructor(method, requestTarget, headers, body = null) { | ||
super(method, requestTarget); | ||
if ((headers === null || headers === void 0 ? void 0 : headers.get) !== undefined) { | ||
constructor(method, requestTarget, origin, headers, body = null, absoluteUrl) { | ||
super(method, requestTarget, origin); | ||
if (headers?.get !== undefined) { | ||
this.headers = headers; | ||
@@ -13,0 +13,0 @@ } |
import { Headers } from './headers'; | ||
import { Response, Body } from './response'; | ||
export declare class MemoryResponse<T = Body> extends Response<T> { | ||
constructor(); | ||
constructor(origin: string); | ||
/** | ||
@@ -6,0 +6,0 @@ * An object containing all headers. |
@@ -7,4 +7,4 @@ "use strict"; | ||
class MemoryResponse extends response_1.Response { | ||
constructor() { | ||
super(); | ||
constructor(origin) { | ||
super(origin); | ||
this.headers = new headers_1.Headers(); | ||
@@ -11,0 +11,0 @@ this.status = 200; |
@@ -10,3 +10,3 @@ /// <reference types="node" /> | ||
private inner; | ||
constructor(inner: NodeHttpRequest); | ||
constructor(inner: NodeHttpRequest, origin: string); | ||
/** | ||
@@ -38,2 +38,7 @@ * This function returns the request body. | ||
* proxy, and the X-Forwarded-For header should be used instead. | ||
* | ||
* If trustProxy is not set, it defaults to false unless the | ||
* CURVEBALL_TRUSTPROXY environment variable is set. Using an environment | ||
* variable is a good idea for this as having a proxy may be environment | ||
* dependent. | ||
*/ | ||
@@ -40,0 +45,0 @@ ip(trustProxy?: boolean): string; |
@@ -8,4 +8,4 @@ "use strict"; | ||
class NodeRequest extends request_1.default { | ||
constructor(inner) { | ||
super(inner.method, inner.url); | ||
constructor(inner, origin) { | ||
super(inner.method, inner.url, origin); | ||
this.inner = inner; | ||
@@ -42,5 +42,10 @@ // @ts-expect-error ignoring that headers might be undefined | ||
* proxy, and the X-Forwarded-For header should be used instead. | ||
* | ||
* If trustProxy is not set, it defaults to false unless the | ||
* CURVEBALL_TRUSTPROXY environment variable is set. Using an environment | ||
* variable is a good idea for this as having a proxy may be environment | ||
* dependent. | ||
*/ | ||
ip(trustProxy = false) { | ||
if (trustProxy) { | ||
if (trustProxy ?? process.env.CURVEBALL_TRUSTPROXY) { | ||
const forwardedForHeader = this.headers.get('X-Forwarded-For'); | ||
@@ -47,0 +52,0 @@ if (forwardedForHeader) { |
@@ -10,3 +10,3 @@ import { Middleware } from '../application'; | ||
private explicitStatus; | ||
constructor(inner: NodeHttpResponse); | ||
constructor(inner: NodeHttpResponse, origin: string); | ||
/** | ||
@@ -73,3 +73,9 @@ * List of HTTP Headers | ||
redirect(status: number, address: string): void; | ||
/** | ||
* Public base URL | ||
* | ||
* This will be used to determine the absoluteUrl | ||
*/ | ||
readonly origin: string; | ||
} | ||
export default NodeResponse; |
@@ -15,3 +15,3 @@ "use strict"; | ||
class NodeResponse { | ||
constructor(inner) { | ||
constructor(inner, origin) { | ||
// The default response status is 404. | ||
@@ -24,2 +24,3 @@ this.inner = inner; | ||
this.explicitStatus = false; | ||
this.origin = origin; | ||
} | ||
@@ -121,3 +122,3 @@ /** | ||
} | ||
const pushCtx = new context_1.Context(new memory_request_1.default('GET', '|||DELIBERATELY_INVALID|||'), new memory_response_1.default()); | ||
const pushCtx = new context_1.Context(new memory_request_1.default('GET', '|||DELIBERATELY_INVALID|||', this.origin), new memory_response_1.default(this.origin)); | ||
await (0, application_1.invokeMiddlewares)(pushCtx, [callback]); | ||
@@ -124,0 +125,0 @@ if (pushCtx.request.requestTarget === '|||DELIBERATELY_INVALID|||') { |
@@ -9,3 +9,3 @@ /// <reference types="node" /> | ||
export declare abstract class Request<T = unknown> { | ||
constructor(method: string, requestTarget: string); | ||
constructor(method: string, requestTarget: string, origin: string); | ||
/** | ||
@@ -144,3 +144,17 @@ * List of HTTP Headers | ||
prefer(preference: 'transclude'): string | false; | ||
/** | ||
* Returns the absolute url for this request. | ||
* | ||
* This may not always be correct, because it's based on a best guess. | ||
* If you have a reverse proxy in front of your curveball server, you may | ||
* need to provide a 'origin' argument when constructing the server. | ||
*/ | ||
get absoluteUrl(): string; | ||
/** | ||
* Public base URL | ||
* | ||
* This will be used to determine the absoluteUrl | ||
*/ | ||
readonly origin: string; | ||
} | ||
export default Request; |
@@ -12,6 +12,7 @@ "use strict"; | ||
class Request { | ||
constructor(method, requestTarget) { | ||
constructor(method, requestTarget, origin) { | ||
this.method = method; | ||
this.requestTarget = requestTarget; | ||
this.headers = new headers_1.Headers(); | ||
this.origin = origin; | ||
} | ||
@@ -96,2 +97,12 @@ /** | ||
} | ||
/** | ||
* Returns the absolute url for this request. | ||
* | ||
* This may not always be correct, because it's based on a best guess. | ||
* If you have a reverse proxy in front of your curveball server, you may | ||
* need to provide a 'origin' argument when constructing the server. | ||
*/ | ||
get absoluteUrl() { | ||
return this.origin + this.requestTarget; | ||
} | ||
} | ||
@@ -98,0 +109,0 @@ exports.Request = Request; |
@@ -10,3 +10,3 @@ /// <reference types="node" /> | ||
export declare abstract class Response<T = Body> { | ||
constructor(); | ||
constructor(origin: string); | ||
/** | ||
@@ -65,3 +65,9 @@ * List of HTTP Headers | ||
redirect(status: number, address: string): void; | ||
/** | ||
* Public base URL | ||
* | ||
* This will be used to determine the absoluteUrl | ||
*/ | ||
readonly origin: string; | ||
} | ||
export default Response; |
@@ -10,5 +10,6 @@ "use strict"; | ||
class Response { | ||
constructor() { | ||
constructor(origin) { | ||
this.headers = new headers_1.Headers(); | ||
this.status = 200; | ||
this.origin = origin; | ||
} | ||
@@ -15,0 +16,0 @@ /** |
{ | ||
"name": "@curveball/core", | ||
"version": "0.18.0", | ||
"version": "0.19.0", | ||
"description": "Curveball is a framework writting in Typescript for Node.js", | ||
@@ -41,3 +41,3 @@ "main": "dist/index.js", | ||
"@types/mocha": "^9.0.0", | ||
"@types/node": "^12.20.12", | ||
"@types/node": "^14.18.14", | ||
"@types/node-fetch": "^2.5.8", | ||
@@ -70,3 +70,3 @@ "@types/sinon": "^10.0.6", | ||
"engines": { | ||
"node": ">=9.4" | ||
"node": ">=14.4" | ||
}, | ||
@@ -73,0 +73,0 @@ "mocha": { |
@@ -264,2 +264,6 @@ Curveball | ||
result. | ||
* `origin` - Sets the 'origin' for the application. This is used to determine | ||
absolute URIs. You can set the `origin` directly on the application, but | ||
you can also set a `CURVEBALL_ORIGIN` environment variable. If nothing is | ||
set this value will default to `http://localhost`. | ||
@@ -287,2 +291,3 @@ | ||
`Location` header. | ||
* `absoluteUrl` - The absolute URL for the request. | ||
@@ -312,4 +317,11 @@ | ||
`hal+json` and `json`. | ||
* `origin` - The 'origin' for the request, for example: | ||
`http://my-api:8008`. | ||
* `absoluteUrl` - The absolute URL for the request. | ||
* `ip()` - Returns the ip address of the client. This may be ipv4 or ipv6. | ||
If `CURVEBALL_TRUSTPROXY` is set in the environment and truthy, this will | ||
use the information from the `X-Forwarded-For` header (if available). | ||
### The Response interface | ||
@@ -334,3 +346,6 @@ | ||
`Location` header. | ||
* `origin` - The 'origin' for the request, for example: | ||
`http://my-api:8008`. | ||
### The Headers interface | ||
@@ -337,0 +352,0 @@ |
@@ -125,4 +125,4 @@ import { isHttpError } from '@curveball/http-errors'; | ||
const request = new NodeRequest(req); | ||
const response = new MemoryResponse(); | ||
const request = new NodeRequest(req, this.origin); | ||
const response = new MemoryResponse(this.origin); | ||
const context = new Context(request, response); | ||
@@ -184,4 +184,4 @@ | ||
this.wss.on('connection', async(ws, req) => { | ||
const request = new NodeRequest(req); | ||
const response = new MemoryResponse(); | ||
const request = new NodeRequest(req, this.origin); | ||
const response = new MemoryResponse(this.origin); | ||
const context = new Context(request, response); | ||
@@ -218,3 +218,3 @@ | ||
if (typeof arg1 === 'string') { | ||
request = new MemoryRequest(arg1, path!, headers, body); | ||
request = new MemoryRequest(arg1, path!, this.origin, headers, body); | ||
} else { | ||
@@ -224,3 +224,3 @@ request = arg1; | ||
const context = new Context(request, new MemoryResponse()); | ||
const context = new Context(request, new MemoryResponse(this.origin)); | ||
@@ -230,3 +230,2 @@ try { | ||
} catch (err: any) { | ||
// eslint-disable-next-line no-console | ||
console.error(err); | ||
@@ -255,3 +254,6 @@ if (this.listenerCount('error')) { | ||
): Context { | ||
const context = new Context(new NodeRequest(req), new NodeResponse(res)); | ||
const context = new Context( | ||
new NodeRequest(req, this.origin), | ||
new NodeResponse(res, this.origin) | ||
); | ||
@@ -261,2 +263,37 @@ return context; | ||
private _origin?: string; | ||
/** | ||
* The public base url of the application. | ||
* | ||
* This can be auto-detected, but will often be wrong when your server is | ||
* running behind a reverse proxy or load balancer. | ||
* | ||
* To provide this, set the process.env.PUBLIC_URI property. | ||
*/ | ||
get origin(): string { | ||
if (this._origin) { | ||
return this._origin; | ||
} | ||
if (process.env.CURVEBALL_ORIGIN) { | ||
return process.env.CURVEBALL_ORIGIN; | ||
} | ||
if (process.env.PUBLIC_URI) { | ||
return new URL(process.env.PUBLIC_URI).origin; | ||
} | ||
const port = process.env.PORT ? +process.env.PORT : 80; | ||
return 'http://localhost' + (port!==80?':' + port : ''); | ||
} | ||
set origin(baseUrl: string) { | ||
this._origin = new URL(baseUrl).origin; | ||
} | ||
} |
@@ -56,2 +56,9 @@ import { Middleware } from './application'; | ||
get absoluteUrl(): string { | ||
return this.request.absoluteUrl; | ||
} | ||
/** | ||
@@ -58,0 +65,0 @@ * HTTP method |
@@ -18,5 +18,5 @@ import { Readable } from 'stream'; | ||
constructor(method: string, requestTarget: string, headers?: HeadersInterface | HeadersObject, body: any = null) { | ||
constructor(method: string, requestTarget: string, origin: string, headers?: HeadersInterface | HeadersObject, body: any = null, absoluteUrl?: string) { | ||
super(method, requestTarget); | ||
super(method, requestTarget, origin); | ||
if (headers?.get !== undefined) { | ||
@@ -23,0 +23,0 @@ this.headers = headers as HeadersInterface; |
@@ -6,5 +6,5 @@ import { Headers } from './headers'; | ||
constructor() { | ||
constructor(origin: string) { | ||
super(); | ||
super(origin); | ||
this.headers = new Headers(); | ||
@@ -11,0 +11,0 @@ this.status = 200; |
@@ -14,5 +14,5 @@ import * as rawBody from 'raw-body'; | ||
constructor(inner: NodeHttpRequest) { | ||
constructor(inner: NodeHttpRequest, origin: string) { | ||
super(inner.method!, inner.url!); | ||
super(inner.method!, inner.url!, origin); | ||
this.inner = inner; | ||
@@ -76,6 +76,11 @@ // @ts-expect-error ignoring that headers might be undefined | ||
* proxy, and the X-Forwarded-For header should be used instead. | ||
* | ||
* If trustProxy is not set, it defaults to false unless the | ||
* CURVEBALL_TRUSTPROXY environment variable is set. Using an environment | ||
* variable is a good idea for this as having a proxy may be environment | ||
* dependent. | ||
*/ | ||
ip(trustProxy: boolean = false): string { | ||
if (trustProxy) { | ||
if (trustProxy ?? process.env.CURVEBALL_TRUSTPROXY) { | ||
const forwardedForHeader = this.headers.get('X-Forwarded-For'); | ||
@@ -82,0 +87,0 @@ if (forwardedForHeader) { |
@@ -20,3 +20,3 @@ import * as http from 'http'; | ||
constructor(inner: NodeHttpResponse) { | ||
constructor(inner: NodeHttpResponse, origin: string) { | ||
@@ -31,2 +31,3 @@ // The default response status is 404. | ||
this.explicitStatus = false; | ||
this.origin = origin; | ||
@@ -154,4 +155,4 @@ } | ||
const pushCtx = new Context( | ||
new MemoryRequest('GET', '|||DELIBERATELY_INVALID|||'), | ||
new MemoryResponse() | ||
new MemoryRequest('GET', '|||DELIBERATELY_INVALID|||', this.origin), | ||
new MemoryResponse(this.origin) | ||
); | ||
@@ -238,4 +239,11 @@ | ||
/** | ||
* Public base URL | ||
* | ||
* This will be used to determine the absoluteUrl | ||
*/ | ||
readonly origin: string; | ||
} | ||
export default NodeResponse; |
@@ -16,6 +16,7 @@ import * as accepts from 'accepts'; | ||
constructor(method: string, requestTarget: string) { | ||
constructor(method: string, requestTarget: string, origin: string) { | ||
this.method = method; | ||
this.requestTarget = requestTarget; | ||
this.headers = new Headers(); | ||
this.origin = origin; | ||
} | ||
@@ -214,4 +215,23 @@ | ||
/** | ||
* Returns the absolute url for this request. | ||
* | ||
* This may not always be correct, because it's based on a best guess. | ||
* If you have a reverse proxy in front of your curveball server, you may | ||
* need to provide a 'origin' argument when constructing the server. | ||
*/ | ||
get absoluteUrl(): string { | ||
return this.origin + this.requestTarget; | ||
} | ||
/** | ||
* Public base URL | ||
* | ||
* This will be used to determine the absoluteUrl | ||
*/ | ||
readonly origin: string; | ||
} | ||
export default Request; |
@@ -21,6 +21,7 @@ import { Middleware } from './application'; | ||
constructor() { | ||
constructor(origin: string) { | ||
this.headers = new Headers(); | ||
this.status = 200; | ||
this.origin = origin; | ||
@@ -138,4 +139,10 @@ } | ||
/** | ||
* Public base URL | ||
* | ||
* This will be used to determine the absoluteUrl | ||
*/ | ||
readonly origin: string; | ||
} | ||
export default Response; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
182295
77
4240
396
7