4 Commits

Author SHA1 Message Date
bc2fbe14e3 Adding SSL support, release 0.2.3 2018-03-11 15:25:44 -07:00
9fc5d64ceb Adding start/end as static Position
Add the streamPosition constants
Move Projections into the expose classes section
Version 0.2.2
2018-02-19 10:06:33 -08:00
2bdd74e041 Merge pull request #53 from paullucas/master
Upgrade jsdoc to version 3.5.5
2018-02-18 17:03:07 -08:00
fde6ad2e77 Use jsdoc version 3.5.5 2018-02-18 16:50:59 -08:00
9 changed files with 127 additions and 2912 deletions

View File

@ -5,7 +5,6 @@ A port of the EventStore .Net ClientAPI to Node.js
### Missing features:
- Ssl connection
- Set system settings
### Areas to improve
@ -26,9 +25,9 @@ Install using `npm install node-eventstore-client`
- Node.js >= 4.0
- Modules: [long](https://www.npmjs.org/package/long), [protobufjs](https://www.npmjs.org/package/protobufjs), [uuid](https://www.npmjs.org/package/uuid) (installed via `npm install`)
### Install & run an Eventstore on localhost
### Install and run an Eventstore on localhost
See https://eventstore.org/docs/introduction/4.0.2/
See https://eventstore.org/docs/introduction/4.1.0/
*Note: If you are using a version of EventStore prior to 3.9.4, you need to use version 0.1.x of this package `npm install node-eventstore-client@^0.1`.*
@ -115,7 +114,15 @@ To generate a test event, open a separate console and run:
To run the tests it is recommended that you use an in-memory instance of the eventstore so you don't pollute your dev instance.
EventStore.ClusterNode.exe --run-projections=all --memdb
EventStore.ClusterNode.exe --run-projections=all --memdb certificate-file=yourcert.pfx
or
./run-node.sh --run-projections=all --memdb certificate-file=yourcert.p12
For SSL setup see:
https://eventstore.org/docs/server/setting_up_ssl/
or
https://eventstore.org/docs/server/setting_up_ssl_linux/
To execute the tests suites simply run

135
index.d.ts vendored
View File

@ -1,14 +1,15 @@
/// <reference types="node" />
/// <reference types="Long" />
// Expose classes
export class Position {
constructor(commitPosition: number|Long, preparePosition: number|Long);
readonly commitPosition: Long;
readonly preparePosition: Long;
static readonly start: number;
static readonly end: number;
}
// Expose classes
export class UserCredentials {
constructor(username: string, password: string);
readonly username: string;
@ -35,6 +36,57 @@ export class GossipSeed {
readonly hostHeader: string;
}
export interface ProjectionDetails {
readonly coreProcessingTime: number,
readonly version: number,
readonly epoch: number,
readonly effectiveName: string,
readonly writesInProgress: number,
readonly readsInProgress: number,
readonly partitionsCached: number,
readonly status: string,
readonly stateReason: string,
readonly name: string,
readonly mode: string,
readonly position: string,
readonly progress: number,
readonly lastCheckpoint: string,
readonly eventsProcessedAfterRestart: number,
readonly statusUrl: string,
readonly stateUrl: string,
readonly resultUrl: string,
readonly queryUrl: string,
readonly enableCommandUrl: string,
readonly disableCommandUrl: string,
readonly checkpointStatus: string,
readonly bufferedEvents: number,
readonly writePendingEventsBeforeCheckpoint: number,
readonly writePendingEventsAfterCheckpoint: number
}
export class ProjectionsManager {
constructor(log: Logger, httpEndPoint: string, operationTimeout: number);
enable(name: string, userCredentials: UserCredentials): Promise<void>;
disable(name: string, userCredentials: UserCredentials): Promise<void>;
abort(name: string, userCredentials: UserCredentials): Promise<void>;
createOneTime(query: string, userCredentials: UserCredentials): Promise<void>;
createTransient(name: string, query: string, userCredentials: UserCredentials): Promise<void>;
createContinuous(name: string, query: string, trackEmittedStreams: boolean, userCredentials: UserCredentials): Promise<void>;
listAll(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
listOneTime(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
listContinuous(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
getStatus(name: string, userCredentials: UserCredentials): Promise<string>;
getState(name: string, userCredentials: UserCredentials): Promise<string>;
getPartitionState(name: string, partitionId: string, userCredentials: UserCredentials): Promise<string>;
getResult(name: string, userCredentials: UserCredentials): Promise<string>;
getPartitionResult(name: string, partitionId: string, userCredentials: UserCredentials): Promise<string>;
getStatistics(name: string, userCredentials: UserCredentials): Promise<string>;
getQuery(name: string, userCredentials: UserCredentials): Promise<string>;
getState(name: string, userCredentials: UserCredentials): Promise<string>;
updateQuery(name: string, query: string, userCredentials: UserCredentials): Promise<void>;
deleteQuery(name: string, deleteEmittedStreams: boolean, userCredentials: UserCredentials): Promise<void>;
}
// Expose errors
export class WrongExpectedVersionError {
readonly name: string;
@ -59,8 +111,12 @@ export class AccessDeniedError {
readonly transactionId?: Long;
}
// Expose enums/constants
export class ProjectionCommandFailedError {
readonly httpStatusCode: number;
readonly message: string;
}
// Expose enums/constants
export namespace expectedVersion {
const any: number;
const noStream: number;
@ -72,12 +128,17 @@ export namespace positions {
const end: Position;
}
export namespace streamPosition {
const start: number;
const end: number;
}
//TODO
// systemMetadata
// eventReadStatus
// sliceReadStatus
// Expose loggers
export interface Logger {
debug(fmt: string, ...args: any[]): void;
info(fmt: string, ...args: any[]): void;
@ -228,12 +289,12 @@ export interface TcpEndPoint {
}
export interface HeartbeatInfo {
connectionId: string;
remoteEndPoint: TcpEndPoint;
requestSentAt: number;
requestPkgNumber: number;
responseReceivedAt: number;
responsePkgNumber: number;
readonly connectionId: string;
readonly remoteEndPoint: TcpEndPoint;
readonly requestSentAt: number;
readonly requestPkgNumber: number;
readonly responseReceivedAt: number;
readonly responsePkgNumber: number;
}
export interface EventData {
@ -277,7 +338,6 @@ export interface EventStoreNodeConnection {
}
// Expose helper functions
export interface ConnectionSettings {
log?: Logger,
verboseLogging?: boolean,
@ -310,58 +370,7 @@ export interface ConnectionSettings {
gossipTimeout?: number
}
// Expose Helper functions
export function createConnection(settings: ConnectionSettings, endPointOrGossipSeed: string | TcpEndPoint | GossipSeed[], connectionName?: string): EventStoreNodeConnection;
export function createJsonEventData(eventId: string, event: any, metadata?: any, type?: string): EventData;
export function createEventData(eventId: string, type: string, isJson: boolean, data: Buffer, metadata?: Buffer): EventData;
// Projections
export interface ProjectionDetails {
coreProcessingTime: number,
version: number,
epoch: number,
effectiveName: string,
writesInProgress: number,
readsInProgress: number,
partitionsCached: number,
status: string,
stateReason: string,
name: string,
mode: string,
position: string,
progress: number,
lastCheckpoint: string,
eventsProcessedAfterRestart: number,
statusUrl: string,
stateUrl: string,
resultUrl: string,
queryUrl: string,
enableCommandUrl: string,
disableCommandUrl: string,
checkpointStatus: string,
bufferedEvents: number,
writePendingEventsBeforeCheckpoint: number,
writePendingEventsAfterCheckpoint: number
}
export class ProjectionsManager {
constructor(log: Logger, httpEndPoint: string, operationTimeout: number);
enable(name: string, userCredentials: UserCredentials): Promise<void>;
disable(name: string, userCredentials: UserCredentials): Promise<void>;
abort(name: string, userCredentials: UserCredentials): Promise<void>;
createOneTime(query: string, userCredentials: UserCredentials): Promise<void>;
createTransient(name: string, query: string, userCredentials: UserCredentials): Promise<void>;
createContinuous(name: string, query: string, trackEmittedStreams: boolean, userCredentials: UserCredentials): Promise<void>;
listAll(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
listOneTime(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
listContinuous(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
getStatus(name: string, userCredentials: UserCredentials): Promise<string>;
getState(name: string, userCredentials: UserCredentials): Promise<string>;
getPartitionState(name: string, partitionId: string, userCredentials: UserCredentials): Promise<string>;
getResult(name: string, userCredentials: UserCredentials): Promise<string>;
getPartitionResult(name: string, partitionId: string, userCredentials: UserCredentials): Promise<string>;
getStatistics(name: string, userCredentials: UserCredentials): Promise<string>;
getQuery(name: string, userCredentials: UserCredentials): Promise<string>;
getState(name: string, userCredentials: UserCredentials): Promise<string>;
updateQuery(name: string, query: string, userCredentials: UserCredentials): Promise<void>;
deleteQuery(name: string, deleteEmittedStreams: boolean, userCredentials: UserCredentials): Promise<void>;
}

View File

@ -1,6 +1,6 @@
{
"name": "node-eventstore-client",
"version": "0.2.1",
"version": "0.2.3",
"description": "A port of the EventStore .Net ClientAPI to Node.js",
"main": "index.js",
"types": "index.d.ts",
@ -52,7 +52,7 @@
"uuid": "^3.0.1"
},
"devDependencies": {
"jsdoc": "^3.5.3",
"jsdoc": "^3.5.5",
"nodeunit": "^0.11.1",
"webpack": "^3.3.0"
}

View File

@ -4,15 +4,23 @@ var results = require('./results');
const expectedVersion = {
any: -2,
noStream: -1,
emptyStream: -1
emptyStream: -1,
streamExists: -4
};
Object.freeze(expectedVersion);
const positions = {
start: new results.Position(0, 0),
end: new results.Position(-1, -1)
};
Object.freeze(positions);
const streamPosition = {
start: 0,
end: -1
};
Object.freeze(streamPosition);
/**
* Create an EventData object from JavaScript event/metadata that will be serialized as json
* @public
@ -60,6 +68,7 @@ module.exports.ProjectionCommandFailedError = require('./errors/projectionComman
// Expose enums/constants
module.exports.expectedVersion = expectedVersion;
module.exports.positions = positions;
module.exports.streamPosition = streamPosition;
module.exports.systemMetadata = require('./common/systemMetadata');
module.exports.eventReadStatus = results.EventReadStatus;
module.exports.sliceReadStatus = require('./sliceReadStatus');

View File

@ -30,6 +30,8 @@ Position.prototype.toString = function() {
return [this.commitPosition.toString(), this.preparePosition.toString()].join("/");
};
Position.start = new Position(0,0);
Position.end = new Position(-1,-1);
const EventReadStatus = {
Success: 'success',

View File

@ -1,4 +1,5 @@
var net = require('net');
var tls = require('tls');
var createBufferSegment = require('../../common/bufferSegment');
const MaxSendPacketSize = 64 * 1024;
@ -136,11 +137,16 @@ TcpConnection.prototype._closeInternal = function(err, reason) {
};
TcpConnection.createConnectingConnection = function(
log, connectionId, remoteEndPoint, connectionTimeout,
onConnectionEstablished, onConnectionFailed, onConnectionClosed
log, connectionId, remoteEndPoint, ssl, targetHost, validateServer,
connectionTimeout, onConnectionEstablished, onConnectionFailed, onConnectionClosed
) {
var connection = new TcpConnection(log, connectionId, remoteEndPoint, onConnectionClosed);
var socket = net.connect(remoteEndPoint.port, remoteEndPoint.host);
var provider = ssl ? tls : net;
var options = {
servername: targetHost,
rejectUnauthorized: validateServer
};
var socket = provider.connect(remoteEndPoint.port, remoteEndPoint.host, options);
function onError(err) {
if (onConnectionFailed)
onConnectionFailed(connection, err);

View File

@ -38,15 +38,14 @@ function TcpPackageConnection(
this._framer = new LengthPrefixMessageFramer();
this._framer.registerMessageArrivedCallback(this._incomingMessageArrived.bind(this));
//TODO ssl
var self = this;
this._connection = TcpConnection.createConnectingConnection(
log,
connectionId,
remoteEndPoint,
//ssl,
//targetHost,
//validateServer,
ssl,
targetHost,
validateServer,
timeout,
function(tcpConnection) {
log.debug("TcpPackageConnection: connected to [%j, L%j, %s].", tcpConnection.remoteEndPoint, tcpConnection.localEndPoint, connectionId);

View File

@ -72,7 +72,24 @@ module.exports = {
if (err) return test.done(err);
test.done();
}
}*/
}*/,
'Connect to secure tcp endpoint': function(test) {
var conn = client.createConnection({
useSslConnection: true,
targetHost: 'localhost',
validateServer: false
}, 'tcp://localhost:1115');
conn.on('error', function (err) {
test.done(err);
});
conn.connect()
.catch(function (err) {
test.done(err);
});
conn.on('connected', function () {
test.done();
});
}
};
testBase.init(module.exports, false);

2834
yarn.lock

File diff suppressed because it is too large Load Diff