Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fluvial

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fluvial - npm Package Compare versions

Comparing version 0.1.0-alpha.5 to 0.1.0-alpha.6

13

dist/index.js

@@ -79,7 +79,10 @@ import { createSecureServer, createServer, } from 'node:http2';

if (!this.server) {
if (this.invokedOptions.ssl &&
((this.invokedOptions.ssl.certificatePath || this.invokedOptions.ssl.certificate) &&
if (!this.invokedOptions.ssl) {
this.server = createServer(this.mainHandler);
}
else if (this.invokedOptions.ssl &&
(((this.invokedOptions.ssl.certificatePath || this.invokedOptions.ssl.certificate) &&
(this.invokedOptions.ssl.key || this.invokedOptions.ssl.keyPath)) ||
((this.invokedOptions.ssl.pfx || this.invokedOptions.ssl.pfxPath) &&
this.invokedOptions.ssl.passphrase)) {
((this.invokedOptions.ssl.pfx || this.invokedOptions.ssl.pfxPath) &&
this.invokedOptions.ssl.passphrase))) {
if (this.invokedOptions.ssl.pfx || this.invokedOptions.ssl.pfxPath) {

@@ -107,3 +110,3 @@ this.server = createSecureServer({

else {
this.server = createServer(this.mainHandler);
throw Error('An unknown error occurred; please review the creation of the application');
}

@@ -110,0 +113,0 @@ }

@@ -14,3 +14,2 @@ /// <reference types="node" />

readonly headers: Readonly<IncomingHttpHeaders>;
readonly rawHeaders: Readonly<string[]>;
readonly payload: any;

@@ -25,7 +24,9 @@ readonly rawRequest: Http2ServerRequest | IncomingMessage;

readonly rawRequest: IncomingMessage;
readonly httpVersion: '1.1';
}
interface Http2Request extends BaseRequest {
readonly rawRequest: Http2ServerRequest;
readonly httpVersion: '2.0';
}
type Request = Http1Request | Http2Request;
export type { Request, };

@@ -14,3 +14,2 @@ import { constants } from 'node:http2';

const headers = Object.freeze(Object.assign({}, rawRequest.headers));
const rawHeaders = Object.freeze(rawRequest.rawHeaders.slice());
Object.defineProperty(req, 'params', { get() { return params; } });

@@ -22,3 +21,2 @@ Object.defineProperty(req, 'query', { get() { return query; } });

Object.defineProperty(req, 'hash', { get() { return url.hash; } });
Object.defineProperty(req, 'rawHeaders', { get() { rawHeaders; } });
return req;

@@ -25,0 +23,0 @@ }

@@ -21,25 +21,28 @@ /// <reference types="node" />

status(statusCode: number): void;
/** getter for the current eventSource value (default: false) */
asEventSource(): boolean;
/** setter for the eventSource value */
asEventSource(bool: boolean): void;
/** pass-thru for http2Stream.write */
write(data: string | Buffer): void;
/** pass-thru for http2Stream.end */
end(data?: string | Buffer): void;
/** the simplest way to respond with or without data */
/** DEFAULT MODE ONLY: the simplest way to respond with or without data */
send(data?: any): void;
/** ideal for object data to be consumed in a browser */
json(data: object): void;
/** DEFAULT MODE ONLY: pass-thru for http2Stream.end */
end(data?: string | Buffer): void;
/** EVENT STREAM MODE ONLY: when the response is set as an event stream, this sends the event; errors otherwise */
sendEvent(data?: object | string): void;
/** ideal for needing to respond with files */
stream(stream: Readable, options?: SendStreamOptions): Promise<void>;
stream(stream: Readable): void;
}
interface Http1Response extends BaseResponse {
httpVersion: '1.1';
readonly httpVersion: '1.1';
readonly rawResponse: ServerResponse;
}
interface Http2Response extends BaseResponse {
httpVersion: '2.0';
readonly httpVersion: '2.0';
readonly rawResponse: Http2ServerResponse;
}
type Response = Http1Response | Http2Response;
interface SendStreamOptions {
noCache: boolean;
}
export type { Response, };

@@ -0,1 +1,2 @@

import { randomUUID } from 'node:crypto';
import { constants } from 'node:http2';

@@ -14,3 +15,3 @@ import { Readable } from 'node:stream';

},
ownKeys(target) {
ownKeys() {
return rawResponse.getHeaderNames();

@@ -29,7 +30,3 @@ },

Object.defineProperty(res, 'httpVersion', { get() { return rawResponse.req.httpVersion; } });
Object.defineProperty(res, 'rawResponse', {
get() {
return rawResponse;
},
});
Object.defineProperty(res, 'rawResponse', { get() { return rawResponse; } });
Object.defineProperty(res, 'headers', {

@@ -42,2 +39,3 @@ get() {

res._status = 200;
res._eventSource = false;
return res;

@@ -59,4 +57,29 @@ }

}
if (this.rawResponse.headersSent) {
throw TypeError('An attempt to set the status code failed because the response headers have already been sent');
}
this._status = statusCode;
},
asEventSource(value) {
if (typeof value != 'boolean') {
return this._eventSource;
}
if (value) {
this._eventSourceId = randomUUID();
// "connection" is only necessary for http/1.x responses and are ignored by Node for http/2 responses
this.headers['connection'] = 'keep-alive';
this.headers['content-type'] = 'text/event-stream';
this.headers['cache-control'] = 'no-cache';
}
else if (this._eventSourceId) {
if (this.headers['connection'] == 'keep-alive') {
this.headers['connection'] = undefined;
}
if (this.headers['content-type'] == 'text/event-stream') {
this.headers['content-type'] = undefined;
}
this._eventSourceId = null;
}
this._eventSource = value;
},
write(data) {

@@ -66,7 +89,13 @@ this.rawResponse.write(data);

end(data) {
if (this._eventSource) {
throw TypeError('An attempt to close the response stream failed because the response is set up to be an event source and only clients are allowed to close such streams');
}
this.rawResponse.end(data);
},
send(data) {
if (this._eventSource) {
throw TypeError('An attempt to send a singular response failed because the response is set up to be an event source; use sendEvent instead');
}
if (this.responseSent) {
throw TypeError('attempted to send another response though the response stream is closed');
throw TypeError('An attempt to send a response failed because the response stream is closed');
}

@@ -98,6 +127,27 @@ if (data instanceof Readable) {

},
sendEvent(event) {
if (!this._eventSource) {
throw TypeError('An attempt to send an event failed because this response is not set up to be an event source; must use the asEventSource() setter first');
}
if (this.rawResponse.headersSent && this.rawResponse.closed) {
throw TypeError('An attempt to send an event failed because the stream is currently closed');
}
if (!this.rawResponse.headersSent) {
if (this.httpVersion == '1.1') {
this.rawResponse.writeHead(this._status, {
...this.headers
});
}
else {
this.rawResponse.stream.respond({
[constants.HTTP2_HEADER_STATUS]: this._status,
...this.headers,
});
}
}
const preparedData = typeof event == 'string' ? event : JSON.stringify(event);
this.rawResponse.write('id: ' + this._eventSourceId + '\n' +
'data: ' + preparedData + '\n\n');
},
json(data) {
if (this.responseSent) {
throw TypeError('attempted to send another response though the response stream is closed');
}
if (data && typeof data != 'object') {

@@ -109,15 +159,3 @@ throw TypeError('An attempt to send a response as JSON failed as the response was not an object or array');

}
if (this.httpVersion == '1.1') {
this.rawResponse.writeHead(this._status);
}
else {
this.rawResponse.stream.respond({
...this.headers,
[constants.HTTP2_HEADER_STATUS]: this._status,
});
}
if (data) {
this.rawResponse.write(data);
}
this.rawResponse.end();
this.send(data);
},

@@ -124,0 +162,0 @@ async stream(sourceStream) {

@@ -83,3 +83,3 @@ import { type PathString, type PathMatcher } from './path-matching.js';

interface RequestHandler {
(req: Request, res: Response): void | 'next' | Promise<void | 'next'>;
(req: Request, res: Response): void | 'next' | 'route' | Promise<void | 'next' | 'route'>;
}

@@ -86,0 +86,0 @@ /**

@@ -142,2 +142,5 @@ import { getRouteParams, getQueryParams, } from './path-matching.js';

for (const handler of handlers) {
if (handlerState.end) {
break;
}
try {

@@ -155,3 +158,3 @@ if (typeof handler == 'function') {

}
if (!latestResult) {
if (latestResult != 'next') {
handlerState.end = true;

@@ -175,2 +178,8 @@ if (handlerState.error) {

}
if (latestResult == 'route') {
latestResult = 'next';
}
else if (latestResult != 'next') {
latestResult = undefined;
}
}

@@ -177,0 +186,0 @@ if (handlerState.error) {

{
"name": "fluvial",
"version": "0.1.0-alpha.5",
"version": "0.1.0-alpha.6",
"description": "Fluvial: A light http/2 server framework, similar to Express",

@@ -48,4 +48,5 @@ "main": "dist/index.js",

"test": "vitest",
"test:coverage": "pnpm test --coverage"
"test:coverage": "pnpm test --coverage",
"prepublish": "pnpm test && pnpm compile"
}
}

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc