├── .gitignore
├── test
├── CQRSTest.d.ts
├── mocha.d.ts
├── should.d.ts
├── CQRSTest.ts
└── CQRSTest.js
├── package.json
├── Gruntfile.js
├── README.md
└── lib
├── cqrs-typescript.d.ts
├── async.d.ts
├── node_redis.d.ts
├── cqrs-typescript.ts
├── cqrs-typescript.js
└── node.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/test/CQRSTest.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cqrs-typescript",
3 | "version": "0.0.9",
4 | "description": "A Typescript friendly library for writing event sourcing or CQRS apps.",
5 | "main": "lib/cqrs-typescript.js",
6 | "keywords" : [
7 | "CQRS",
8 | "Event sourcing",
9 | "Typescript"
10 | ],
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/andrewwebber/cqrs-typescript"
14 | },
15 | "scripts": {
16 | "test": "node-debug ./node_modules/grunt-cli/bin/grunt test"
17 | },
18 | "directories" : {
19 | "lib" : "lib",
20 | "test" : "test"
21 | },
22 | "author": "@MrPanigale",
23 | "license": "ISC",
24 | "devDependencies": {
25 | "grunt": "^0.4.5",
26 | "grunt-contrib-jshint": "^0.10.0",
27 | "grunt-contrib-nodeunit": "^0.4.1",
28 | "grunt-contrib-watch": "^0.6.1",
29 | "grunt-mocha-test": "^0.11.0",
30 | "grunt-typescript": "^0.3.7",
31 | "should": "^4.0.4",
32 | "grunt-cli": "~0.1.13"
33 | },
34 | "dependencies": {
35 | "redis": "~0.10.3",
36 | "async": "~0.9.0"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | 'use strict';
3 | // Project configuration
4 | grunt.initConfig({
5 | // Metadata
6 | pkg: grunt.file.readJSON('package.json'),
7 | banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
8 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
9 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
10 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
11 | ' Licensed <%= props.license %> */\n',
12 | // Task configuration
13 | jshint: {
14 | options: {
15 | node: true,
16 | curly: true,
17 | eqeqeq: true,
18 | immed: true,
19 | latedef: true,
20 | newcap: true,
21 | noarg: true,
22 | sub: true,
23 | undef: true,
24 | unused: true,
25 | eqnull: true,
26 | boss: true
27 | },
28 | gruntfile: {
29 | src: 'gruntfile.js'
30 | },
31 | lib_test: {
32 | src: ['lib/**/*.js']
33 | }
34 | },
35 | nodeunit: {
36 | files: ['test/**/*_test.js']
37 | },
38 | watch: {
39 | gruntfile: {
40 | files: '<%= jshint.gruntfile.src %>',
41 | tasks: ['jshint:gruntfile']
42 | },
43 | lib_test: {
44 | files: '<%= jshint.lib_test.src %>',
45 | tasks: ['jshint:lib_test', 'nodeunit']
46 | }
47 | },
48 | typescript : {
49 | development: {
50 | src: ['lib/*.ts', 'test/*.ts'],
51 | options: {
52 | module: 'commonjs',
53 | watch:true,
54 | declaration: true
55 | }
56 | },
57 | test: {
58 | src: ['lib/*.ts', 'test/*.ts'],
59 | options: {
60 | module: 'commonjs',
61 | watch:false,
62 | declaration: true,
63 | comments:true
64 | }
65 | }
66 | },
67 | mochaTest: {
68 | test: {
69 | options: {
70 | reporter: 'spec'
71 | },
72 | src: ['test/**/*.js']
73 | }
74 | }
75 | });
76 |
77 | // These plugins provide necessary tasks
78 | grunt.loadNpmTasks('grunt-contrib-nodeunit');
79 | grunt.loadNpmTasks('grunt-contrib-jshint');
80 | grunt.loadNpmTasks('grunt-contrib-watch');
81 | grunt.loadNpmTasks('grunt-typescript');
82 | grunt.loadNpmTasks('grunt-mocha-test');
83 |
84 | // Default task
85 | grunt.registerTask('default', ['typescript:development']);
86 | grunt.registerTask('ts', ['typescript:development']);
87 | grunt.registerTask('test', ['typescript:test', 'mochaTest']);
88 | };
89 |
--------------------------------------------------------------------------------
/test/mocha.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for mocha 1.17.1
2 | // Project: http://visionmedia.github.io/mocha/
3 | // Definitions by: Kazi Manzur Rashid , otiai10
4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped
5 |
6 | interface Mocha {
7 | // Setup mocha with the given setting options.
8 | setup(options: MochaSetupOptions): Mocha;
9 |
10 | //Run tests and invoke `fn()` when complete.
11 | run(callback?: () => void): void;
12 |
13 | // Set reporter as function
14 | reporter(reporter: () => void): Mocha;
15 |
16 | // Set reporter, defaults to "dot"
17 | reporter(reporter: string): Mocha;
18 |
19 | // Enable growl support.
20 | growl(): Mocha
21 | }
22 |
23 | interface MochaSetupOptions {
24 | //milliseconds to wait before considering a test slow
25 | slow?: number;
26 |
27 | // timeout in milliseconds
28 | timeout?: number;
29 |
30 | // ui name "bdd", "tdd", "exports" etc
31 | ui?: string;
32 |
33 | //array of accepted globals
34 | globals?: any[];
35 |
36 | // reporter instance (function or string), defaults to `mocha.reporters.Dot`
37 | reporter?: any;
38 |
39 | // bail on the first test failure
40 | bail?: Boolean;
41 |
42 | // ignore global leaks
43 | ignoreLeaks?: Boolean;
44 |
45 | // grep string or regexp to filter tests with
46 | grep?: any;
47 | }
48 |
49 | interface MochaDone {
50 | (error?: Error): void;
51 | }
52 |
53 | declare var mocha: Mocha;
54 |
55 | declare var describe : {
56 | (description: string, spec: () => void): void;
57 | only(description: string, spec: () => void): void;
58 | skip(description: string, spec: () => void): void;
59 | timeout(ms: number): void;
60 | }
61 |
62 | // alias for `describe`
63 | declare var context : {
64 | (contextTitle: string, spec: () => void): void;
65 | only(contextTitle: string, spec: () => void): void;
66 | skip(contextTitle: string, spec: () => void): void;
67 | timeout(ms: number): void;
68 | }
69 |
70 | declare var it: {
71 | (expectation: string, assertion?: () => void): void;
72 | (expectation: string, assertion?: (done: MochaDone) => void): void;
73 | only(expectation: string, assertion?: () => void): void;
74 | only(expectation: string, assertion?: (done: MochaDone) => void): void;
75 | skip(expectation: string, assertion?: () => void): void;
76 | skip(expectation: string, assertion?: (done: MochaDone) => void): void;
77 | timeout(ms: number): void;
78 | };
79 |
80 | declare function before(action: () => void): void;
81 |
82 | declare function before(action: (done: MochaDone) => void): void;
83 |
84 | declare function setup(action: () => void): void;
85 |
86 | declare function setup(action: (done: MochaDone) => void): void;
87 |
88 | declare function after(action: () => void): void;
89 |
90 | declare function after(action: (done: MochaDone) => void): void;
91 |
92 | declare function teardown(action: () => void): void;
93 |
94 | declare function teardown(action: (done: MochaDone) => void): void;
95 |
96 | declare function beforeEach(action: () => void): void;
97 |
98 | declare function beforeEach(action: (done: MochaDone) => void): void;
99 |
100 | declare function suiteSetup(action: () => void): void;
101 |
102 | declare function suiteSetup(action: (done: MochaDone) => void): void;
103 |
104 | declare function afterEach(action: () => void): void;
105 |
106 | declare function afterEach(action: (done: MochaDone) => void): void;
107 |
108 | declare function suiteTeardown(action: () => void): void;
109 |
110 | declare function suiteTeardown(action: (done: MochaDone) => void): void;
111 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | cqrs-typescript
2 | ===============
3 |
4 | ###CQRS implementation in typescript.
5 |
6 |
7 |
8 | Components avaliable:
9 | - Event Sourcing
10 | - Interfaces for creating versioned events
11 | - Base classes for creating an event sourced aggregates and raising versioned events
12 | - Command processing
13 | - Interfaces for creating commands
14 | - Command bus for sending events
15 | - Redis based command bus using ['rpoplpush'](http://redis.io/commands/rpoplpush)
16 | - Command handling registry for signing up for command types
17 | - Event processing
18 | - Interfaces for creating events
19 | - Event bus for sending events
20 | - Redis based event bus using ['rpoplpush'](http://redis.io/commands/rpoplpush)
21 | - Event handling registry for signing up for command types
22 |
23 | View the tests for more examples on usage.
24 |
25 | ####Event Sourcing
26 |
27 | ```ts
28 | ///
29 | ///
30 |
31 | import CQRS = require('cqrs-typescript');
32 | import should = require('should');
33 | should.equal('actual', 'actual');
34 |
35 | interface ICreditAccountEvent extends CQRS.IVersionedEvent{
36 | amount:number
37 | }
38 |
39 | interface IDebitAccountEvent extends CQRS.IVersionedEvent{
40 | amount:number
41 | }
42 |
43 | class BankAccount extends CQRS.EventSourced{
44 | constructor(id :string){
45 | super(id);
46 | this.balance = 0;
47 | }
48 |
49 | balance : number;
50 |
51 | credit(amount:number) : void {
52 | this.update({
53 | name: 'CreditAccount',
54 | amount: amount,
55 | version: -1,
56 | sourceId: ''
57 | });
58 | }
59 |
60 | debit(amount:number) : void{
61 | this.update({
62 | name: 'DebitAccount',
63 | amount: amount,
64 | version: -1,
65 | sourceId: ''
66 | });
67 | }
68 |
69 | private onCreditAccount(e : ICreditAccountEvent):void{
70 | this.balance += e.amount;
71 | }
72 |
73 | private onDebitAccount(e : IDebitAccountEvent):void{
74 | this.balance -= e.amount;
75 | }
76 | }
77 |
78 | var account : BankAccount;
79 |
80 | describe('extending from "EventSourced" to create a "bank account"', function() {
81 | it('should be ok to create one once supplying an id ', function() {
82 | account = new BankAccount('1');
83 | });
84 |
85 | it('should be ok to credit the account to 100 by raising an event',function(){
86 | account.credit(100);
87 | account.balance.should.be.exactly(100);
88 | account.getEvents().length.should.be.exactly(1);
89 | account.getVersion().should.be.exactly(1);
90 | });
91 |
92 | it('should be ok to credit the account to 150 by raising an event',function(){
93 | account.credit(50);
94 | account.balance.should.be.exactly(150);
95 | account.getEvents().length.should.be.exactly(2);
96 | account.getVersion().should.be.exactly(2);
97 | });
98 |
99 | it('should be ok to debit the account by 100 by raising an event',function(){
100 | account.debit(100);
101 | account.balance.should.be.exactly(50);
102 | account.getEvents().length.should.be.exactly(3);
103 | account.getVersion().should.be.exactly(3);
104 | });
105 |
106 | it('should be ok to load a bank account from an event stream',function(){
107 | var accountFromEvents = new BankAccount('1');
108 | var events = account.getEvents();
109 | accountFromEvents.loadFromEvents(events);
110 | accountFromEvents.balance.should.be.exactly(account.balance);
111 | accountFromEvents.getVersion().should.be.exactly(account.getVersion());
112 | });
113 | });
114 | ```
115 |
116 | ####Redis based event sourcing repository
117 | ```ts
118 | var account = new BankAccount('2');
119 | account.credit(100);
120 | account.credit(100);
121 | account.debit(50);
122 | account.credit(100);
123 | account.debit(200);
124 | account.balance.should.be.exactly(50);
125 |
126 | var provider = new CQRS.RedisEventSourcedRepository({ host: "127.0.0.1", port:6379});
127 | it('should connect to a specified Redis server',function(done){
128 | provider.connect((error)=>{
129 | should.equal(error, null);
130 | done();
131 | });
132 | });
133 |
134 | it('should be able to persist an event stream for an given aggregate id',function(done){
135 | var events = account.getEvents();
136 | events.length.should.be.exactly(5);
137 | provider.saveEventsByAggregateId(account.getId(),events, (error)=>{
138 | should.equal(error, null);
139 | done();
140 | });
141 | });
142 |
143 | it('should be able to retrieve an event stream by aggregate id and recreate an aggregate instance',function(done){
144 | provider.getEventsByAggregateId(account.getId(),(error, events)=>{
145 | should.equal(error, null);
146 | events.length.should.be.exactly(5);
147 |
148 | var accountFromEvents = new BankAccount(account.getId());
149 | accountFromEvents.loadFromEvents(events);
150 | accountFromEvents.balance.should.be.exactly(account.balance);
151 | done();
152 | });
153 | });
154 | ```
155 |
--------------------------------------------------------------------------------
/lib/cqrs-typescript.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 | import Redis = require('redis');
5 | export interface IEnvelope {
6 | body: T;
7 | correlationId: string;
8 | messageId: string;
9 | TTL?: number;
10 | }
11 | export interface ICommand {
12 | id: string;
13 | name: string;
14 | }
15 | export interface ICommandHandler {
16 | handleCommand(commandToHandle: IEnvelope, callback: (error: any) => void): void;
17 | }
18 | export interface IEvent {
19 | sourceId: string;
20 | name: string;
21 | }
22 | export interface IEventHandler {
23 | handleEvent(eventToHandle: IEnvelope, callback: (error: any) => void): void;
24 | }
25 | export declare class HandlerRegistry implements ICommandHandler, IEventHandler {
26 | constructor();
27 | public commandsRegistry: any;
28 | public eventsRegistry: any;
29 | public registerCommandHandler(commandName: string, commandHandler: ICommandHandler): void;
30 | public registerEventHandler(eventName: string, eventHandler: IEventHandler): void;
31 | public handleCommand(commandToHandle: IEnvelope, callback: (error: any) => void): void;
32 | public handleEvent(eventToHandle: IEnvelope, callback: (error: any) => void): void;
33 | }
34 | export interface IVersionedEvent extends IEvent {
35 | version: number;
36 | }
37 | export interface IEventSourced {
38 | getId(): string;
39 | getVersion(): number;
40 | getEvents(): IVersionedEvent[];
41 | }
42 | export declare class EventSourced implements IEventSourced {
43 | private id;
44 | private version;
45 | private events;
46 | constructor(id: string);
47 | public getId(): string;
48 | public getVersion(): number;
49 | public getEvents(): IVersionedEvent[];
50 | public loadFromEvents(events: IVersionedEvent[]): void;
51 | public update(versionedEvent: IVersionedEvent): void;
52 | }
53 | export declare class RedisResource {
54 | private client;
55 | constructor(options: IRedisConnectionOptions);
56 | public options: IRedisConnectionOptions;
57 | public getClient(): Redis.RedisClient;
58 | public connect(callback: (error: any) => void): void;
59 | }
60 | export declare class RedisCommandReceiver extends RedisResource {
61 | constructor(options: IRedisConnectionOptions, commandReceiver: ICommandHandler);
62 | public commandReceiver: ICommandHandler;
63 | public paused: boolean;
64 | public onConnected(): void;
65 | }
66 | export declare class RedisEventReceiver extends RedisResource {
67 | constructor(options: IRedisConnectionOptions, eventReceiver: IEventHandler);
68 | public eventReceiver: IEventHandler;
69 | public paused: boolean;
70 | public onConnected(): void;
71 | }
72 | export declare class RedisCommandBus extends RedisResource implements ICommandHandler {
73 | constructor(options: IRedisConnectionOptions);
74 | public handleCommand(commandToHandle: IEnvelope, callback: (error: any) => void): void;
75 | }
76 | export declare class RedisEventBus extends RedisResource implements IEventHandler {
77 | constructor(options: IRedisConnectionOptions);
78 | public handleEvent(eventToHandle: IEnvelope, callback: (error: any) => void): void;
79 | }
80 | export interface IEventSourcedRepository {
81 | getEventsByAggregateId(id: string, callback: (error: any, events: IVersionedEvent[]) => void): any;
82 | saveEventsByAggregateId(id: string, events: IVersionedEvent[], callback: (error: any) => void): any;
83 | }
84 | export declare class InMemoryEventSourcedRepository implements IEventSourcedRepository {
85 | private db;
86 | constructor();
87 | public getEventsByAggregateId(id: string, callback: (error: any, events: IVersionedEvent[]) => void): void;
88 | public saveEventsByAggregateId(id: string, events: IVersionedEvent[], callback: (error: any) => void): void;
89 | }
90 | export interface IRedisConnectionOptions {
91 | host: string;
92 | port: number;
93 | }
94 | export declare class EventSourceRepositoryWithNotifications implements IEventSourcedRepository {
95 | constructor(repository: IEventSourcedRepository, onSaveCallback: (id: string, events: IVersionedEvent[]) => void);
96 | public repository: IEventSourcedRepository;
97 | public onSaveCallback: (id: string, events: IVersionedEvent[]) => void;
98 | public getEventsByAggregateId(id: string, callback: (error: any, events: IVersionedEvent[]) => void): void;
99 | public saveEventsByAggregateId(id: string, events: IVersionedEvent[], callback: (error: any) => void): void;
100 | }
101 | export declare class RedisEventSourcedRepository extends RedisResource implements IEventSourcedRepository {
102 | constructor(options: IRedisConnectionOptions);
103 | public getEventsByAggregateId(id: string, callback: (error: any, events: IVersionedEvent[]) => void): void;
104 | public saveEventsByAggregateId(id: string, events: IVersionedEvent[], callback: (error: any) => void): void;
105 | private constructResultsResponse(error, results, callback);
106 | }
107 |
--------------------------------------------------------------------------------
/test/should.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for should.js 3.1.2
2 | // Project: https://github.com/visionmedia/should.js
3 | // Definitions by: Alex Varju , Maxime LUCE
4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped
5 |
6 | interface Object {
7 | should: ShouldAssertion;
8 | }
9 |
10 | interface ShouldAssertion {
11 | // basic grammar
12 | a: ShouldAssertion;
13 | an: ShouldAssertion;
14 | and: ShouldAssertion;
15 | be: ShouldAssertion;
16 | have: ShouldAssertion;
17 | with: ShouldAssertion;
18 | of: ShouldAssertion;
19 | not: ShouldAssertion;
20 |
21 | // validators
22 | arguments: ShouldAssertion;
23 | empty: ShouldAssertion;
24 | ok: ShouldAssertion;
25 | true: ShouldAssertion;
26 | false: ShouldAssertion;
27 | NaN: ShouldAssertion;
28 | Infinity: ShouldAssertion;
29 | Array: ShouldAssertion;
30 | Object: ShouldAssertion;
31 | String: ShouldAssertion;
32 | Boolean: ShouldAssertion;
33 | Number: ShouldAssertion;
34 | Error: ShouldAssertion;
35 | Function: ShouldAssertion;
36 | eql(expected: any, description?: string): ShouldAssertion;
37 | equal(expected: any, description?: string): ShouldAssertion;
38 | within(start: number, finish: number, description?: string): ShouldAssertion;
39 | approximately(value: number, delta: number, description?: string): ShouldAssertion;
40 | type(expected: any, description?: string): ShouldAssertion;
41 | instanceof(constructor: Function, description?: string): ShouldAssertion;
42 | above(n: number, description?: string): ShouldAssertion;
43 | below(n: number, description?: string): ShouldAssertion;
44 | match(other: {}, description?: string): ShouldAssertion;
45 | match(other: (val: any) => any, description?: string): ShouldAssertion;
46 | match(regexp: RegExp, description?: string): ShouldAssertion;
47 | match(other: any, description?: string): ShouldAssertion;
48 | matchEach(other: {}, description?: string): ShouldAssertion;
49 | matchEach(other: (val: any) => any, description?: string): ShouldAssertion;
50 | matchEach(regexp: RegExp, description?: string): ShouldAssertion;
51 | matchEach(other: any, description?: string): ShouldAssertion;
52 | length(n: number, description?: string): ShouldAssertion;
53 | property(name: string, description?: string): ShouldAssertion;
54 | property(name: string, val: any, description?: string): ShouldAssertion;
55 | properties(names: string[]): ShouldAssertion;
56 | properties(name: string): ShouldAssertion;
57 | properties(descriptor: any): ShouldAssertion;
58 | properties(...properties: string[]): ShouldAssertion;
59 | ownProperty(name: string, description?: string): ShouldAssertion;
60 | contain(obj: any): ShouldAssertion;
61 | containEql(obj: any): ShouldAssertion;
62 | containDeep(obj: any): ShouldAssertion;
63 | keys(...allKeys: string[]): ShouldAssertion;
64 | keys(allKeys: string[]): ShouldAssertion;
65 | header(field: string, val?: string): ShouldAssertion;
66 | status(code: number): ShouldAssertion;
67 | json: ShouldAssertion;
68 | html: ShouldAssertion;
69 | startWith(expected: string, message?: any): ShouldAssertion;
70 | endWith(expected: string, message?: any): ShouldAssertion;
71 | throw(message?: any): ShouldAssertion;
72 |
73 | // deprecated
74 | include(obj: any, description?: string): ShouldAssertion;
75 | includeEql(obj: any[], description?: string): ShouldAssertion;
76 |
77 | // aliases
78 | exactly(expected: any, description?: string): ShouldAssertion;
79 | instanceOf(constructor: Function, description?: string): ShouldAssertion;
80 | throwError(message?: any): ShouldAssertion;
81 | lengthOf(n: number, description?: string): ShouldAssertion;
82 | key(key: string): ShouldAssertion;
83 | haveOwnProperty(name: string, description?: string): ShouldAssertion;
84 | greaterThan(n: number, description?: string): ShouldAssertion;
85 | lessThan(n: number, description?: string): ShouldAssertion;
86 | }
87 |
88 | interface ShouldInternal {
89 | // should.js's extras
90 | exist(actual: any): void;
91 | exists(actual: any): void;
92 | not: ShouldInternal;
93 | }
94 |
95 | interface Internal extends ShouldInternal {
96 | (obj: any): ShouldAssertion;
97 |
98 | // node.js's assert functions
99 | fail(actual: any, expected: any, message: string, operator: string): void;
100 | assert(value: any, message: string): void;
101 | ok(value: any, message?: string): void;
102 | equal(actual: any, expected: any, message?: string): void;
103 | notEqual(actual: any, expected: any, message?: string): void;
104 | deepEqual(actual: any, expected: any, message?: string): void;
105 | notDeepEqual(actual: any, expected: any, message?: string): void;
106 | strictEqual(actual: any, expected: any, message?: string): void;
107 | notStrictEqual(actual: any, expected: any, message?: string): void;
108 | throws(block: any, error?: any, message?: string): void;
109 | doesNotThrow(block: any, message?: string): void;
110 | ifError(value: any): void;
111 | inspect(value: any, obj: any): any;
112 | }
113 |
114 | declare var should: Internal;
115 |
116 | declare module "should" {
117 | export = should;
118 | }
119 |
--------------------------------------------------------------------------------
/lib/async.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for Async 0.1.23
2 | // Project: https://github.com/caolan/async
3 | // Definitions by: Boris Yankov
4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped
5 |
6 | interface AsyncMultipleResultsCallback { (err: Error, results: T[]): any; }
7 | interface AsyncSingleResultCallback { (err: Error, result: T): void; }
8 | interface AsyncTimesCallback { (n: number, callback: AsyncMultipleResultsCallback): void; }
9 |
10 | interface AsyncIterator { (item: T, callback: AsyncSingleResultCallback): void; }
11 | interface AsyncMemoIterator { (memo: R, item: T, callback: AsyncSingleResultCallback): void; }
12 |
13 | interface AsyncWorker { (task: T, callback: Function): void; }
14 |
15 | interface AsyncQueue {
16 | length(): number;
17 | concurrency: number;
18 | push(task: T, callback?: AsyncMultipleResultsCallback): void;
19 | push(task: T[], callback?: AsyncMultipleResultsCallback): void;
20 | saturated: AsyncMultipleResultsCallback;
21 | empty: AsyncMultipleResultsCallback;
22 | drain: AsyncMultipleResultsCallback;
23 | }
24 |
25 | interface Async {
26 |
27 | // Collections
28 | forEach(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): void;
29 | forEachSeries(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): void;
30 | forEachLimit(arr: T[], limit: number, iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): void;
31 | map(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
32 | mapSeries(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
33 | filter(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
34 | select(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
35 | filterSeries(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
36 | selectSeries(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
37 | reject(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
38 | rejectSeries(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
39 | reduce(arr: T[], memo: R, iterator: AsyncMemoIterator, callback: AsyncSingleResultCallback): any;
40 | inject(arr: T[], memo: R, iterator: AsyncMemoIterator, callback: AsyncSingleResultCallback): any;
41 | foldl(arr: T[], memo: R, iterator: AsyncMemoIterator, callback: AsyncSingleResultCallback): any;
42 | reduceRight(arr: T[], memo: R, iterator: AsyncMemoIterator, callback: AsyncSingleResultCallback): any;
43 | foldr(arr: T[], memo: R, iterator: AsyncMemoIterator, callback: AsyncSingleResultCallback): any;
44 | detect(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
45 | detectSeries(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
46 | sortBy(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
47 | some(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
48 | any(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
49 | every(arr: T[], iterator: AsyncIterator, callback: (result: boolean) => any): any;
50 | all(arr: T[], iterator: AsyncIterator, callback: (result: boolean) => any): any;
51 | concat(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
52 | concatSeries(arr: T[], iterator: AsyncIterator, callback: AsyncMultipleResultsCallback): any;
53 |
54 | // Control Flow
55 | series(tasks: T[], callback?: AsyncMultipleResultsCallback): void;
56 | series(tasks: T, callback?: AsyncMultipleResultsCallback): void;
57 | parallel(tasks: T[], callback?: AsyncMultipleResultsCallback): void;
58 | parallel(tasks: T, callback?: AsyncMultipleResultsCallback): void;
59 | parallelLimit(tasks: T[], limit: number, callback?: AsyncMultipleResultsCallback): void;
60 | parallelLimit(tasks: T, limit: number, callback?: AsyncMultipleResultsCallback): void;
61 | whilst(test: Function, fn: Function, callback: Function): void;
62 | until(test: Function, fn: Function, callback: Function): void;
63 | waterfall(tasks: T[], callback?: AsyncMultipleResultsCallback): void;
64 | waterfall(tasks: T, callback?: AsyncMultipleResultsCallback): void;
65 | queue(worker: AsyncWorker, concurrency: number): AsyncQueue;
66 | // auto(tasks: any[], callback?: AsyncMultipleResultsCallback): void;
67 | auto(tasks: any, callback?: AsyncMultipleResultsCallback): void;
68 | iterator(tasks: Function[]): Function;
69 | apply(fn: Function, ...arguments: any[]): void;
70 | nextTick(callback: Function): void;
71 |
72 | times (n: number, callback: AsyncTimesCallback): void;
73 | timesSeries (n: number, callback: AsyncTimesCallback): void;
74 |
75 | // Utils
76 | memoize(fn: Function, hasher?: Function): Function;
77 | unmemoize(fn: Function): Function;
78 | log(fn: Function, ...arguments: any[]): void;
79 | dir(fn: Function, ...arguments: any[]): void;
80 | noConflict(): Async;
81 | }
82 |
83 | declare var async: Async;
84 |
85 | declare module "async" {
86 | export = async;
87 | }
88 |
--------------------------------------------------------------------------------
/lib/node_redis.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for node_redis 0.8
2 | // Project: https://github.com/mranney/node_redis
3 | // Definitions by: Boris Yankov
4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped
5 |
6 |
7 | declare module 'redis' {
8 | export var debug_mode: boolean;
9 | export function createClient(): RedisClient;
10 | export function createClient(port: number, host: string, options?: RedisOptions): RedisClient;
11 | export function print(err: string, reply?: string);
12 |
13 | interface RedisOptions {
14 | parser?: string;
15 | return_buffers?: boolean;
16 | detect_buffers?: boolean;
17 | socket_nodelay?: boolean;
18 | no_ready_check?: boolean;
19 | enable_offline_queue?: boolean;
20 | }
21 |
22 | interface Command {
23 | (...args: any[]): any;
24 | }
25 |
26 | interface Commands {
27 |
28 | get: Command;
29 | set: Command;
30 | setnx: Command;
31 | setex: Command;
32 | append: Command;
33 | strlen: Command;
34 | del: Command;
35 | exists: Command;
36 | setbit: Command;
37 | getbit: Command;
38 | setrange: Command;
39 | getrange: Command;
40 | substr: Command;
41 | incr: Command;
42 | decr: Command;
43 | mget: Command;
44 |
45 | rpush: Command;
46 | lpush: Command;
47 | rpushx: Command;
48 | lpushx: Command;
49 | linsert: Command;
50 | rpop: Command;
51 | lpop: Command;
52 | brpop: Command;
53 | brpoplpush: Command;
54 | blpop: Command;
55 | llen: Command;
56 | lindex: Command;
57 | lset: Command;
58 | lrange: Command;
59 | ltrim: Command;
60 | lrem: Command;
61 | rpoplpush: Command;
62 |
63 | sadd: Command;
64 | srem: Command;
65 | smove: Command;
66 | sismember: Command;
67 | scard: Command;
68 | spop: Command;
69 | srandmember: Command;
70 | sinter: Command;
71 | sinterstore: Command;
72 | sunion: Command;
73 | sunionstore: Command;
74 | sdiff: Command;
75 | sdiffstore: Command;
76 | smembers: Command;
77 |
78 | zadd: Command;
79 | zincrby: Command;
80 | zrem: Command;
81 | zremrangebyscore: Command;
82 | zremrangebyrank: Command;
83 | zunionstore: Command;
84 | zinterstore: Command;
85 | zrange: Command;
86 | zrangebyscore: Command;
87 | zrevrangebyscore: Command;
88 | zcount: Command;
89 | zrevrange: Command;
90 | zcard: Command;
91 | zscore: Command;
92 | zrank: Command;
93 | zrevrank: Command;
94 |
95 | hset: Command;
96 | hsetnx: Command;
97 | hget: Command;
98 | hmset: Command;
99 | hmget: Command;
100 | hincrby: Command;
101 | hdel: Command;
102 | hlen: Command;
103 | hkeys: Command;
104 | hvals: Command;
105 | hgetall: Command;
106 | hexists: Command;
107 |
108 | incrby: Command;
109 | decrby: Command;
110 | getset: Command;
111 | mset: Command;
112 | msetnx: Command;
113 | randomkey: Command;
114 | select: Command;
115 | move: Command;
116 | rename: Command;
117 | renamenx: Command;
118 | expire: Command;
119 | expireat: Command;
120 | keys: Command;
121 | dbsize: Command;
122 | auth: Command;
123 | ping: Command;
124 | echo: Command;
125 | save: Command;
126 | bgsave: Command;
127 | bgrewriteaof: Command;
128 | shutdown: Command;
129 | lastsave: Command;
130 | type: Command;
131 | multi: Command;
132 | exec: Command;
133 | discard: Command;
134 | sync: Command;
135 | flushdb: Command;
136 | flushall: Command;
137 | sort: Command;
138 | info: Command;
139 | monitor: Command;
140 | ttl: Command;
141 | persist: Command;
142 | slaveof: Command;
143 | debug: Command;
144 | config: Command;
145 | subscribe: Command;
146 | unsubscribe: Command;
147 | psubscribe: Command;
148 | punsubscribe: Command;
149 | publish: Command;
150 | watch: Command;
151 | unwatch: Command;
152 | cluster: Command;
153 | restore: Command;
154 | migrate: Command;
155 | dump: Command;
156 | object: Command;
157 | client: Command;
158 | eval: Command;
159 | evalsha: Command;
160 |
161 | quit: Command;
162 |
163 | /////////////////
164 |
165 | GET: Command;
166 | SET: Command;
167 | SETNX: Command;
168 | SETEX: Command;
169 | APPEND: Command;
170 | STRLEN: Command;
171 | DEL: Command;
172 | EXISTS: Command;
173 | SETBIT: Command;
174 | GETBIT: Command;
175 | SETRANGE: Command;
176 | GETRANGE: Command;
177 | SUBSTR: Command;
178 | INCR: Command;
179 | DECR: Command;
180 | MGET: Command;
181 |
182 | RPUSH: Command;
183 | LPUSH: Command;
184 | RPUSHX: Command;
185 | LPUSHX: Command;
186 | LINSERT: Command;
187 | RPOP: Command;
188 | LPOP: Command;
189 | BRPOP: Command;
190 | BRPOPLPUSH: Command;
191 | BLPOP: Command;
192 | LLEN: Command;
193 | LINDEX: Command;
194 | LSET: Command;
195 | LRANGE: Command;
196 | LTRIM: Command;
197 | LREM: Command;
198 | RPOPLPUSH: Command;
199 |
200 | SADD: Command;
201 | SREM: Command;
202 | SMOVE: Command;
203 | SISMEMBER: Command;
204 | SCARD: Command;
205 | SPOP: Command;
206 | SRANDMEMBER: Command;
207 | SINTER: Command;
208 | SINTERSTORE: Command;
209 | SUNION: Command;
210 | SUNIONSTORE: Command;
211 | SDIFF: Command;
212 | SDIFFSTORE: Command;
213 | SMEMBERS: Command;
214 |
215 | ZADD: Command;
216 | ZINCRBY: Command;
217 | ZREM: Command;
218 | ZREMRANGEBYSCORE: Command;
219 | ZREMRANGEBYRANK: Command;
220 | ZUNIONSTORE: Command;
221 | ZINTERSTORE: Command;
222 | ZRANGE: Command;
223 | ZRANGEBYSCORE: Command;
224 | ZREVRANGEBYSCORE: Command;
225 | ZCOUNT: Command;
226 | ZREVRANGE: Command;
227 | ZCARD: Command;
228 | ZSCORE: Command;
229 | ZRANK: Command;
230 | ZREVRANK: Command;
231 |
232 | HSET: Command;
233 | HSETNX: Command;
234 | HGET: Command;
235 | HMSET: Command;
236 | HMGET: Command;
237 | HINCRBY: Command;
238 | HDEL: Command;
239 | HLEN: Command;
240 | HKEYS: Command;
241 | HVALS: Command;
242 | HGETALL: Command;
243 | HEXISTS: Command;
244 |
245 | INCRBY: Command;
246 | DECRBY: Command;
247 | GETSET: Command;
248 | MSET: Command;
249 | MSETNX: Command;
250 | RANDOMKEY: Command;
251 | SELECT: Command;
252 | MOVE: Command;
253 | RENAME: Command;
254 | RENAMENX: Command;
255 | EXPIRE: Command;
256 | EXPIREAT: Command;
257 | KEYS: Command;
258 | DBSIZE: Command;
259 | AUTH: Command;
260 | PING: Command;
261 | ECHO: Command;
262 | SAVE: Command;
263 | BGSAVE: Command;
264 | BGREWRITEAOF: Command;
265 | SHUTDOWN: Command;
266 | LASTSAVE: Command;
267 | TYPE: Command;
268 | MULTI: Command;
269 | EXEC: Command;
270 | DISCARD: Command;
271 | SYNC: Command;
272 | FLUSHDB: Command;
273 | FLUSHALL: Command;
274 | SORT: Command;
275 | INFO: Command;
276 | MONITOR: Command;
277 | TTL: Command;
278 | PERSIST: Command;
279 | SLAVEOF: Command;
280 | DEBUG: Command;
281 | CONFIG: Command;
282 | SUBSCRIBE: Command;
283 | UNSUBSCRIBE: Command;
284 | PSUBSCRIBE: Command;
285 | PUNSUBSCRIBE: Command;
286 | PUBLISH: Command;
287 | WATCH: Command;
288 | UNWATCH: Command;
289 | CLUSTER: Command;
290 | RESTORE: Command;
291 | MIGRATE: Command;
292 | DUMP: Command;
293 | OBJECT: Command;
294 | CLIENT: Command;
295 | EVAL: Command;
296 | EVALSHA: Command;
297 |
298 | QUIT: Command;
299 | }
300 |
301 | interface Multi extends Commands {
302 | }
303 |
304 | interface RedisClient extends Commands {
305 |
306 | initialize_retry_vars(): void;
307 | flush_and_error(message: string): void;
308 | on_error(message: string): void;
309 | do_auth(): void;
310 | on_connect(): void;
311 | init_parser(): void;
312 | on_ready(): void;
313 | on_info_cmd(err, res): void;
314 | ready_check(): void;
315 | send_offline_queue(): void;
316 | connection_gone(why: string): void;
317 | on_data(data): void;
318 | return_error(err): void;
319 | return_reply(reply): void;
320 | send_command(command: string, args: any[], callback?: Function);
321 | send_command(command: string, ...args: any[]);
322 | pub_sub_command(command: { command: string; args: any[]; });
323 |
324 | port: number;
325 | host: string;
326 | reply_parser;
327 | stream;
328 |
329 | server_info;
330 | connected: boolean;
331 | command_queue: any[];
332 | offline_queue: any[];
333 | retry_delay : number;
334 | retry_backoff: number;
335 |
336 | auth(password?: string, callback?: Function): void;
337 | AUTH(password?: string, callback?: Function): void;
338 |
339 | end(): RedisClient;
340 |
341 | on(eventName: string, callback: Function): void;
342 | once(eventName: string, callback: Function): void;
343 | removeListener(eventName: string, callback: Function): void;
344 |
345 | multi(commands?: any[]): Multi;
346 | MULTI(): Multi;
347 | }
348 | }
--------------------------------------------------------------------------------
/lib/cqrs-typescript.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 | import Redis = require('redis');
5 | import Async = require('async');
6 |
7 | export interface IEnvelope{
8 | body : T;
9 | correlationId: string;
10 | messageId: string;
11 | TTL? : number;
12 | }
13 |
14 | export interface ICommand{
15 | id: string;
16 | name : string
17 | }
18 |
19 | export interface ICommandHandler{
20 | handleCommand(commandToHandle : IEnvelope, callback: (error)=>void): void;
21 | }
22 |
23 | export interface IEvent{
24 | sourceId : string;
25 | name : string;
26 | }
27 |
28 | export interface IEventHandler{
29 | handleEvent(eventToHandle : IEnvelope, callback: (error)=>void): void;
30 | }
31 |
32 | export class HandlerRegistry implements ICommandHandler, IEventHandler{
33 | constructor(){
34 | this.commandsRegistry = {};
35 | this.eventsRegistry = {};
36 | }
37 |
38 | commandsRegistry : any;
39 | eventsRegistry : any;
40 |
41 | registerCommandHandler(commandName: string, commandHandler : ICommandHandler){
42 | var handlers = this.commandsRegistry[commandName];
43 | if(!handlers){
44 | handlers = [];
45 | }
46 |
47 | handlers.push(commandHandler);
48 | this.commandsRegistry[commandName] = handlers;
49 | }
50 |
51 | registerEventHandler(eventName: string, eventHandler : IEventHandler){
52 | var handlers = this.eventsRegistry[eventName];
53 | if(!handlers){
54 | handlers = [];
55 | }
56 |
57 | handlers.push(eventHandler);
58 | this.eventsRegistry[eventName] = handlers;
59 | }
60 |
61 | handleCommand(commandToHandle : IEnvelope, callback: (error)=>void){
62 | var handlers = this.commandsRegistry[commandToHandle.body.name];
63 | if(!handlers) return callback(null);
64 |
65 | Async.forEach(handlers,function(handler : ICommandHandler, callback : (error:any)=>void){
66 | handler.handleCommand(commandToHandle,callback);
67 | },callback);
68 | }
69 |
70 | handleEvent(eventToHandle : IEnvelope, callback: (error)=>void){
71 | var handlers = this.eventsRegistry[eventToHandle.body.name];
72 | if(!handlers) return callback(null);
73 |
74 | Async.forEach(handlers,function(handler : IEventHandler, callback : (error:any)=>void){
75 | handler.handleEvent(eventToHandle,callback);
76 | },callback);
77 | }
78 | }
79 |
80 | export interface IVersionedEvent extends IEvent{
81 | version : number;
82 | }
83 |
84 | export interface IEventSourced{
85 | getId() : string;
86 | getVersion() : number;
87 | getEvents() : Array;
88 | }
89 |
90 | export class EventSourced implements IEventSourced {
91 | private id: string;
92 | private version : number;
93 | private events : Array;
94 |
95 | constructor(id : string){
96 | this.id = id;
97 | this.events = new Array();
98 | this.version = 0;
99 | }
100 |
101 | getId() : string{
102 | return this.id;
103 | }
104 |
105 | getVersion() : number{
106 | return this.version;
107 | }
108 |
109 | getEvents() : Array{
110 | return this.events;
111 | }
112 |
113 | loadFromEvents(events : Array) : void{
114 | var self = this;
115 | events.forEach(function(item){
116 | self["on" + item.name](item);
117 | self.version = item.version;
118 | });
119 | }
120 |
121 | update(versionedEvent : IVersionedEvent) : void{
122 | versionedEvent.sourceId = this.id;
123 | versionedEvent.version = this.version + 1;
124 | this["on" + versionedEvent.name](versionedEvent);
125 | this.version = versionedEvent.version;
126 | this.events.push(versionedEvent);
127 | }
128 | }
129 |
130 | export class RedisResource {
131 | private client : Redis.RedisClient;
132 |
133 | constructor(options : IRedisConnectionOptions){
134 | this.options = options;
135 | }
136 |
137 | options : IRedisConnectionOptions;
138 |
139 | getClient() : Redis.RedisClient{
140 | return this.client;
141 | }
142 |
143 | connect(callback : (error)=>void ):void{
144 | this.client = Redis.createClient(this.options.port, this.options.host);
145 |
146 | this.client.on('error', function(errorMessage){
147 | if (errorMessage.indexOf && errorMessage.indexOf('connect') >= 0) {
148 | callback(errorMessage);
149 | }
150 | });
151 |
152 | var self = this;
153 | this.client.on('ready', ()=>{
154 | if(self['onConnected']){
155 | self['onConnected']();
156 | }
157 |
158 | callback(null);
159 | });
160 | }
161 | }
162 |
163 | export class RedisCommandReceiver extends RedisResource{
164 | constructor(options: IRedisConnectionOptions, commandReceiver : ICommandHandler){
165 | super(options);
166 | this.commandReceiver = commandReceiver;
167 | }
168 |
169 | commandReceiver : ICommandHandler;
170 | paused : boolean;
171 |
172 | onConnected(){
173 | var self = this;
174 | var receiveLoop = function(){
175 | if(self.paused) return setTimeout(receiveLoop, 500);
176 |
177 | self.getClient().rpoplpush('messaging.queuedcommands','messaging.activecommands',function(error, result){
178 | if(result){
179 | var command = JSON.parse(result);
180 | return self.commandReceiver.handleCommand(command, (error)=>{
181 | self.getClient().lrem('messaging.activecommands', 0, result,function(error, count){
182 | if(count !== 1)throw "invalid count " + count;
183 | receiveLoop();
184 | });
185 | });
186 | }
187 |
188 | setTimeout(receiveLoop, 500);
189 | });
190 | };
191 |
192 | receiveLoop();
193 | }
194 | }
195 |
196 | export class RedisEventReceiver extends RedisResource{
197 | constructor(options: IRedisConnectionOptions, eventReceiver : IEventHandler){
198 | super(options);
199 | this.eventReceiver = eventReceiver;
200 | }
201 |
202 | eventReceiver : IEventHandler;
203 | paused : boolean;
204 |
205 | onConnected(){
206 | var self = this;
207 | var receiveLoop = function(){
208 | if(self.paused) return setTimeout(receiveLoop, 500);
209 |
210 | self.getClient().rpoplpush('messaging.queuedevents','messaging.activeevents',function(error, result){
211 | if(result){
212 | var _event = JSON.parse(result);
213 | return self.eventReceiver.handleEvent(_event, (error)=>{
214 | self.getClient().lrem('messaging.activeevents', 0, result,function(error, count){
215 | if(count !== 1) throw 'invalid "messaging.activeevents" count ' + count;
216 | receiveLoop();
217 | });
218 | });
219 | }
220 |
221 | setTimeout(receiveLoop, 500);
222 | });
223 | };
224 |
225 | receiveLoop();
226 | }
227 | }
228 |
229 | export class RedisCommandBus extends RedisResource implements ICommandHandler{
230 | constructor(options : IRedisConnectionOptions){
231 | super(options);
232 | }
233 |
234 | handleCommand(commandToHandle : IEnvelope, callback: (error)=>void): void{
235 | var commandSerialized = JSON.stringify(commandToHandle);
236 | this.getClient().rpush('messaging.queuedcommands', commandSerialized, callback);
237 | }
238 | }
239 |
240 | export class RedisEventBus extends RedisResource implements IEventHandler{
241 | constructor(options : IRedisConnectionOptions){
242 | super(options);
243 | }
244 |
245 | handleEvent(eventToHandle : IEnvelope, callback: (error)=>void): void{
246 | var eventSerialized = JSON.stringify(eventToHandle);
247 | this.getClient().rpush('messaging.queuedevents', eventSerialized, callback);
248 | }
249 | }
250 |
251 | export interface IEventSourcedRepository {
252 | getEventsByAggregateId(id : string, callback : (error : any, events : Array) => void);
253 | saveEventsByAggregateId(id : string, events : Array, callback: (error: any) => void);
254 | }
255 |
256 | export class InMemoryEventSourcedRepository implements IEventSourcedRepository{
257 | private db : any;
258 |
259 | constructor(){
260 | this.db = {};
261 | }
262 |
263 | getEventsByAggregateId(id : string, callback : (error : any, events : Array) => void){
264 | if(!this.db[id]) return callback(null,[]);
265 |
266 | var aggregateEvents = this.db[id];
267 | callback(null,aggregateEvents);
268 | }
269 |
270 | saveEventsByAggregateId(id : string, events : Array, callback: (error: any) => void){
271 | var aggregateEvents = this.db[id];
272 | if(!aggregateEvents) aggregateEvents = [];
273 | aggregateEvents = aggregateEvents.concat(events);
274 | this.db[id] = aggregateEvents;
275 | callback(null);
276 | }
277 | }
278 |
279 | export interface IRedisConnectionOptions{
280 | host:string;
281 | port:number;
282 | }
283 |
284 | export class EventSourceRepositoryWithNotifications implements IEventSourcedRepository{
285 | constructor(repository: IEventSourcedRepository, onSaveCallback: (id : string, events : Array)=>void){
286 | this.repository = repository;
287 | this.onSaveCallback = onSaveCallback;
288 | }
289 |
290 | repository : IEventSourcedRepository;
291 | onSaveCallback: (id : string, events : Array)=>void;
292 |
293 | getEventsByAggregateId(id : string, callback : (error : any, events : Array) => void){
294 | this.repository.getEventsByAggregateId(id,callback);
295 | }
296 |
297 | saveEventsByAggregateId(id : string, events : Array, callback: (error: any) => void){
298 | var self = this;
299 | this.repository.saveEventsByAggregateId(id,events,(error)=>{
300 | if(!error){
301 | self.onSaveCallback(id,events);
302 | }
303 |
304 | callback(error);
305 | });
306 | }
307 | }
308 |
309 | export class RedisEventSourcedRepository extends RedisResource implements IEventSourcedRepository{
310 | constructor(options : IRedisConnectionOptions){
311 | super(options);
312 | }
313 |
314 | getEventsByAggregateId(id : string, callback : (error : any, events : Array) => void){
315 | var self = this;
316 | this.getClient().lrange('eventsourcing.aggregate:' + id,0,-1, function(error, results){
317 | self.constructResultsResponse(error, results, callback);
318 | });
319 | }
320 |
321 | saveEventsByAggregateId(id : string, events : Array, callback: (error: any) => void){
322 | if (!events || events.length === 0) {
323 | callback(null);
324 | return;
325 | }
326 |
327 | var self = this;
328 | Async.forEachSeries(events, function(versionedEvent : IVersionedEvent, callback : (error:any)=>void){
329 | var serializedEvent = JSON.stringify(versionedEvent);
330 | self.getClient().rpush('eventsourcing.aggregate:' + versionedEvent.sourceId, serializedEvent, function(error){
331 | if(error) return callback(error);
332 | callback(null);
333 | });
334 | },callback);
335 | }
336 |
337 | private constructResultsResponse(error : any, results : Array, callback : (error: any, results: Array)=>void){
338 | if(error) return callback(error,null);
339 |
340 | if (results && results.length > 0) {
341 | var arr = [];
342 |
343 | results.forEach(function(item) {
344 | arr.push(JSON.parse(item));
345 | });
346 |
347 | return callback(null, arr);
348 | }
349 |
350 | callback(null, []);
351 | }
352 | }
353 |
--------------------------------------------------------------------------------
/lib/cqrs-typescript.js:
--------------------------------------------------------------------------------
1 | var __extends = this.__extends || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | __.prototype = b.prototype;
5 | d.prototype = new __();
6 | };
7 | ///
8 | ///
9 | ///
10 | var Redis = require('redis');
11 | var Async = require('async');
12 |
13 | var HandlerRegistry = (function () {
14 | function HandlerRegistry() {
15 | this.commandsRegistry = {};
16 | this.eventsRegistry = {};
17 | }
18 | HandlerRegistry.prototype.registerCommandHandler = function (commandName, commandHandler) {
19 | var handlers = this.commandsRegistry[commandName];
20 | if (!handlers) {
21 | handlers = [];
22 | }
23 |
24 | handlers.push(commandHandler);
25 | this.commandsRegistry[commandName] = handlers;
26 | };
27 |
28 | HandlerRegistry.prototype.registerEventHandler = function (eventName, eventHandler) {
29 | var handlers = this.eventsRegistry[eventName];
30 | if (!handlers) {
31 | handlers = [];
32 | }
33 |
34 | handlers.push(eventHandler);
35 | this.eventsRegistry[eventName] = handlers;
36 | };
37 |
38 | HandlerRegistry.prototype.handleCommand = function (commandToHandle, callback) {
39 | var handlers = this.commandsRegistry[commandToHandle.body.name];
40 | if (!handlers)
41 | return callback(null);
42 |
43 | Async.forEach(handlers, function (handler, callback) {
44 | handler.handleCommand(commandToHandle, callback);
45 | }, callback);
46 | };
47 |
48 | HandlerRegistry.prototype.handleEvent = function (eventToHandle, callback) {
49 | var handlers = this.eventsRegistry[eventToHandle.body.name];
50 | if (!handlers)
51 | return callback(null);
52 |
53 | Async.forEach(handlers, function (handler, callback) {
54 | handler.handleEvent(eventToHandle, callback);
55 | }, callback);
56 | };
57 | return HandlerRegistry;
58 | })();
59 | exports.HandlerRegistry = HandlerRegistry;
60 |
61 | var EventSourced = (function () {
62 | function EventSourced(id) {
63 | this.id = id;
64 | this.events = new Array();
65 | this.version = 0;
66 | }
67 | EventSourced.prototype.getId = function () {
68 | return this.id;
69 | };
70 |
71 | EventSourced.prototype.getVersion = function () {
72 | return this.version;
73 | };
74 |
75 | EventSourced.prototype.getEvents = function () {
76 | return this.events;
77 | };
78 |
79 | EventSourced.prototype.loadFromEvents = function (events) {
80 | var self = this;
81 | events.forEach(function (item) {
82 | self["on" + item.name](item);
83 | self.version = item.version;
84 | });
85 | };
86 |
87 | EventSourced.prototype.update = function (versionedEvent) {
88 | versionedEvent.sourceId = this.id;
89 | versionedEvent.version = this.version + 1;
90 | this["on" + versionedEvent.name](versionedEvent);
91 | this.version = versionedEvent.version;
92 | this.events.push(versionedEvent);
93 | };
94 | return EventSourced;
95 | })();
96 | exports.EventSourced = EventSourced;
97 |
98 | var RedisResource = (function () {
99 | function RedisResource(options) {
100 | this.options = options;
101 | }
102 | RedisResource.prototype.getClient = function () {
103 | return this.client;
104 | };
105 |
106 | RedisResource.prototype.connect = function (callback) {
107 | this.client = Redis.createClient(this.options.port, this.options.host);
108 |
109 | this.client.on('error', function (errorMessage) {
110 | if (errorMessage.indexOf && errorMessage.indexOf('connect') >= 0) {
111 | callback(errorMessage);
112 | }
113 | });
114 |
115 | var self = this;
116 | this.client.on('ready', function () {
117 | if (self['onConnected']) {
118 | self['onConnected']();
119 | }
120 |
121 | callback(null);
122 | });
123 | };
124 | return RedisResource;
125 | })();
126 | exports.RedisResource = RedisResource;
127 |
128 | var RedisCommandReceiver = (function (_super) {
129 | __extends(RedisCommandReceiver, _super);
130 | function RedisCommandReceiver(options, commandReceiver) {
131 | _super.call(this, options);
132 | this.commandReceiver = commandReceiver;
133 | }
134 | RedisCommandReceiver.prototype.onConnected = function () {
135 | var self = this;
136 | var receiveLoop = function () {
137 | if (self.paused)
138 | return setTimeout(receiveLoop, 500);
139 |
140 | self.getClient().rpoplpush('messaging.queuedcommands', 'messaging.activecommands', function (error, result) {
141 | if (result) {
142 | var command = JSON.parse(result);
143 | return self.commandReceiver.handleCommand(command, function (error) {
144 | self.getClient().lrem('messaging.activecommands', 0, result, function (error, count) {
145 | if (count !== 1)
146 | throw "invalid count " + count;
147 | receiveLoop();
148 | });
149 | });
150 | }
151 |
152 | setTimeout(receiveLoop, 500);
153 | });
154 | };
155 |
156 | receiveLoop();
157 | };
158 | return RedisCommandReceiver;
159 | })(RedisResource);
160 | exports.RedisCommandReceiver = RedisCommandReceiver;
161 |
162 | var RedisEventReceiver = (function (_super) {
163 | __extends(RedisEventReceiver, _super);
164 | function RedisEventReceiver(options, eventReceiver) {
165 | _super.call(this, options);
166 | this.eventReceiver = eventReceiver;
167 | }
168 | RedisEventReceiver.prototype.onConnected = function () {
169 | var self = this;
170 | var receiveLoop = function () {
171 | if (self.paused)
172 | return setTimeout(receiveLoop, 500);
173 |
174 | self.getClient().rpoplpush('messaging.queuedevents', 'messaging.activeevents', function (error, result) {
175 | if (result) {
176 | var _event = JSON.parse(result);
177 | return self.eventReceiver.handleEvent(_event, function (error) {
178 | self.getClient().lrem('messaging.activeevents', 0, result, function (error, count) {
179 | if (count !== 1)
180 | throw 'invalid "messaging.activeevents" count ' + count;
181 | receiveLoop();
182 | });
183 | });
184 | }
185 |
186 | setTimeout(receiveLoop, 500);
187 | });
188 | };
189 |
190 | receiveLoop();
191 | };
192 | return RedisEventReceiver;
193 | })(RedisResource);
194 | exports.RedisEventReceiver = RedisEventReceiver;
195 |
196 | var RedisCommandBus = (function (_super) {
197 | __extends(RedisCommandBus, _super);
198 | function RedisCommandBus(options) {
199 | _super.call(this, options);
200 | }
201 | RedisCommandBus.prototype.handleCommand = function (commandToHandle, callback) {
202 | var commandSerialized = JSON.stringify(commandToHandle);
203 | this.getClient().rpush('messaging.queuedcommands', commandSerialized, callback);
204 | };
205 | return RedisCommandBus;
206 | })(RedisResource);
207 | exports.RedisCommandBus = RedisCommandBus;
208 |
209 | var RedisEventBus = (function (_super) {
210 | __extends(RedisEventBus, _super);
211 | function RedisEventBus(options) {
212 | _super.call(this, options);
213 | }
214 | RedisEventBus.prototype.handleEvent = function (eventToHandle, callback) {
215 | var eventSerialized = JSON.stringify(eventToHandle);
216 | this.getClient().rpush('messaging.queuedevents', eventSerialized, callback);
217 | };
218 | return RedisEventBus;
219 | })(RedisResource);
220 | exports.RedisEventBus = RedisEventBus;
221 |
222 | var InMemoryEventSourcedRepository = (function () {
223 | function InMemoryEventSourcedRepository() {
224 | this.db = {};
225 | }
226 | InMemoryEventSourcedRepository.prototype.getEventsByAggregateId = function (id, callback) {
227 | if (!this.db[id])
228 | return callback(null, []);
229 |
230 | var aggregateEvents = this.db[id];
231 | callback(null, aggregateEvents);
232 | };
233 |
234 | InMemoryEventSourcedRepository.prototype.saveEventsByAggregateId = function (id, events, callback) {
235 | var aggregateEvents = this.db[id];
236 | if (!aggregateEvents)
237 | aggregateEvents = [];
238 | aggregateEvents = aggregateEvents.concat(events);
239 | this.db[id] = aggregateEvents;
240 | callback(null);
241 | };
242 | return InMemoryEventSourcedRepository;
243 | })();
244 | exports.InMemoryEventSourcedRepository = InMemoryEventSourcedRepository;
245 |
246 | var EventSourceRepositoryWithNotifications = (function () {
247 | function EventSourceRepositoryWithNotifications(repository, onSaveCallback) {
248 | this.repository = repository;
249 | this.onSaveCallback = onSaveCallback;
250 | }
251 | EventSourceRepositoryWithNotifications.prototype.getEventsByAggregateId = function (id, callback) {
252 | this.repository.getEventsByAggregateId(id, callback);
253 | };
254 |
255 | EventSourceRepositoryWithNotifications.prototype.saveEventsByAggregateId = function (id, events, callback) {
256 | var self = this;
257 | this.repository.saveEventsByAggregateId(id, events, function (error) {
258 | if (!error) {
259 | self.onSaveCallback(id, events);
260 | }
261 |
262 | callback(error);
263 | });
264 | };
265 | return EventSourceRepositoryWithNotifications;
266 | })();
267 | exports.EventSourceRepositoryWithNotifications = EventSourceRepositoryWithNotifications;
268 |
269 | var RedisEventSourcedRepository = (function (_super) {
270 | __extends(RedisEventSourcedRepository, _super);
271 | function RedisEventSourcedRepository(options) {
272 | _super.call(this, options);
273 | }
274 | RedisEventSourcedRepository.prototype.getEventsByAggregateId = function (id, callback) {
275 | var self = this;
276 | this.getClient().lrange('eventsourcing.aggregate:' + id, 0, -1, function (error, results) {
277 | self.constructResultsResponse(error, results, callback);
278 | });
279 | };
280 |
281 | RedisEventSourcedRepository.prototype.saveEventsByAggregateId = function (id, events, callback) {
282 | if (!events || events.length === 0) {
283 | callback(null);
284 | return;
285 | }
286 |
287 | var self = this;
288 | Async.forEachSeries(events, function (versionedEvent, callback) {
289 | var serializedEvent = JSON.stringify(versionedEvent);
290 | self.getClient().rpush('eventsourcing.aggregate:' + versionedEvent.sourceId, serializedEvent, function (error) {
291 | if (error)
292 | return callback(error);
293 | callback(null);
294 | });
295 | }, callback);
296 | };
297 |
298 | RedisEventSourcedRepository.prototype.constructResultsResponse = function (error, results, callback) {
299 | if (error)
300 | return callback(error, null);
301 |
302 | if (results && results.length > 0) {
303 | var arr = [];
304 |
305 | results.forEach(function (item) {
306 | arr.push(JSON.parse(item));
307 | });
308 |
309 | return callback(null, arr);
310 | }
311 |
312 | callback(null, []);
313 | };
314 | return RedisEventSourcedRepository;
315 | })(RedisResource);
316 | exports.RedisEventSourcedRepository = RedisEventSourcedRepository;
317 |
--------------------------------------------------------------------------------
/test/CQRSTest.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | /*global describe, it, import */
5 | /*jslint node: true */
6 | import CQRS = require('../lib/cqrs-typescript');
7 | import should = require('should');
8 | should.equal('actual', 'actual');
9 |
10 | interface ICreditAccountEvent extends CQRS.IVersionedEvent{
11 | amount:number
12 | }
13 |
14 | interface IDebitAccountEvent extends CQRS.IVersionedEvent{
15 | amount:number
16 | }
17 |
18 | class BankAccount extends CQRS.EventSourced{
19 | constructor(id :string){
20 | super(id);
21 | this.balance = 0;
22 | }
23 |
24 | balance : number;
25 |
26 | credit(amount:number) : void {
27 | this.update({
28 | name: 'CreditAccount',
29 | amount: amount,
30 | version: -1,
31 | sourceId: ''
32 | });
33 | }
34 |
35 | debit(amount:number) : void{
36 | this.update({
37 | name: 'DebitAccount',
38 | amount: amount,
39 | version: -1,
40 | sourceId: ''
41 | });
42 | }
43 |
44 | private onCreditAccount(e : ICreditAccountEvent):void{
45 | this.balance += e.amount;
46 | }
47 |
48 | private onDebitAccount(e : IDebitAccountEvent):void{
49 | this.balance -= e.amount;
50 | }
51 | }
52 |
53 | class TestCommand implements CQRS.ICommand{
54 | constructor(message: string){
55 | this.name = 'TestCommand';
56 | this.message = message;
57 | }
58 |
59 | id :string;
60 | name: string;
61 | message : string;
62 | }
63 |
64 | class TestCommandHandler implements CQRS.ICommandHandler{
65 | handleCommand(commandToHandle : CQRS.IEnvelope, callback: (error)=>void): void{
66 | commandToHandle.body.name.should.be.exactly('TestCommand');
67 | commandToHandle.body.message.should.be.exactly('hello world');
68 | callback(null);
69 | }
70 | };
71 |
72 | class RedisCommandReceiverTestHandler implements CQRS.ICommandHandler{
73 | constructor(done){
74 | this.done = done;
75 | this.callCount = 0;
76 | }
77 |
78 | done : ()=>void;
79 | callCount : number;
80 | handleCommand(commandToHandle : CQRS.IEnvelope, callback: (error)=>void): void{
81 | callback(null);
82 | this.done();
83 | }
84 | }
85 |
86 | class RedisEventReceiverTestHandler implements CQRS.IEventHandler{
87 | constructor(done, expectedMessage){
88 | this.done = done;
89 | this.callCount = 0;
90 | this.expectedMessage = expectedMessage;
91 | }
92 |
93 | expectedMessage : string;
94 | done : ()=>void;
95 | callCount : number;
96 | handleEvent(eventToHandle : CQRS.IEnvelope, callback: (error)=>void): void{
97 | eventToHandle.body.message.should.be.exactly(this.expectedMessage);
98 | callback(null);
99 | this.done();
100 | }
101 | }
102 |
103 | class TestEventMessageReceived implements CQRS.IEvent{
104 | constructor(message: string){
105 | this.name = 'TestEventMessageReceived';
106 | this.message = message;
107 | }
108 |
109 | sourceId :string;
110 | name: string;
111 | message : string;
112 | }
113 |
114 | class TestEventMessageReceivedHandler implements CQRS.IEventHandler{
115 | handleEvent(eventToHandle : CQRS.IEnvelope, callback: (error)=>void): void{
116 | eventToHandle.body.name.should.be.exactly('TestEventMessageReceived');
117 | eventToHandle.body.message.should.be.exactly('hello world');
118 | callback(null);
119 | }
120 | };
121 |
122 | describe('CQRS Tests', function() {
123 | describe('Core Tests', function(){
124 | var account :BankAccount;
125 |
126 | describe('extending from "EventSourced" to create a "bank account"',function(){
127 | it('should be ok to create one once supplying an id ', function() {
128 | account = new BankAccount('1');
129 | });
130 |
131 | it('should be ok to credit the account to 100 by raising an event',function(){
132 | account.credit(100);
133 | account.balance.should.be.exactly(100);
134 | account.getEvents().length.should.be.exactly(1);
135 | account.getVersion().should.be.exactly(1);
136 | });
137 |
138 | it('should be ok to credit the account to 150 by raising an event',function(){
139 | account.credit(50);
140 | account.balance.should.be.exactly(150);
141 | account.getEvents().length.should.be.exactly(2);
142 | account.getVersion().should.be.exactly(2);
143 | });
144 |
145 | it('should be ok to debit the account by 100 by raising an event',function(){
146 | account.debit(100);
147 | account.balance.should.be.exactly(50);
148 | account.getEvents().length.should.be.exactly(3);
149 | account.getVersion().should.be.exactly(3);
150 | });
151 |
152 | it('should be ok to load a bank account from an event stream',function(){
153 | var accountFromEvents = new BankAccount('1');
154 | var events = account.getEvents();
155 | accountFromEvents.loadFromEvents(events);
156 | accountFromEvents.balance.should.be.exactly(account.balance);
157 | accountFromEvents.getVersion().should.be.exactly(account.getVersion());
158 | });
159 | });
160 |
161 | describe('using an in memory "event sourced" repository',function(){
162 | var provider = new CQRS.InMemoryEventSourcedRepository();
163 |
164 | it('should be able to save events in memory',function(done){
165 | provider.saveEventsByAggregateId(account.getId(), account.getEvents(), (error)=>{
166 | should.equal(error,null);
167 | done();
168 | });
169 | });
170 |
171 | it('should be able to load events previously saved',function(done){
172 | provider.getEventsByAggregateId(account.getId(), (error, events)=>{
173 | events.should.be.an.Array;
174 | events.length.should.be.exactly(account.getEvents().length);
175 | done();
176 | });
177 | });
178 |
179 | it('should be possible to load a bank account from events loaded from the repository',function(done){
180 | provider.getEventsByAggregateId(account.getId(), (error, events)=>{
181 | should.equal(error, null);
182 | var accountFromEvents = new BankAccount(account.getId());
183 | accountFromEvents.loadFromEvents(events);
184 | accountFromEvents.balance.should.be.exactly(account.balance);
185 | done();
186 | });
187 | });
188 | });
189 |
190 | describe('Handler registry', function(){
191 | var registry = new CQRS.HandlerRegistry();
192 |
193 | describe('command registration',function(){
194 | var testCommandHandler = new TestCommandHandler();
195 | var commandName = 'TestCommand';
196 |
197 | it('should be possible to register a command handler', function(){
198 | registry.registerCommandHandler(commandName, testCommandHandler);
199 | var handlers = registry.commandsRegistry[commandName];
200 | handlers.length.should.be.exactly(1);
201 | });
202 |
203 | it('should be possible to execute a command handler having sending a command through the "HandlerRegistry"',function(done){
204 | var testCommand = new TestCommand('hello world');
205 | testCommand.id = "1";
206 | registry.handleCommand({
207 | messageId : "1",
208 | correlationId : "1",
209 | body: testCommand
210 | },(error)=>{
211 | should.equal(error, null);
212 | done();
213 | });
214 | });
215 | });
216 |
217 | describe('event registration',function(){
218 | var testEventHandler = new TestEventMessageReceivedHandler();
219 | var eventName = 'TestEventMessageReceived';
220 |
221 | it('should be possible to register an event handler', function(){
222 | registry.registerEventHandler(eventName, testEventHandler);
223 | var handlers = registry.eventsRegistry[eventName];
224 | handlers.length.should.be.exactly(1);
225 | });
226 |
227 | it('should be possible to execute an event handler having sending an event through the "HandlerRegistry"',function(done){
228 | var testEvent = new TestEventMessageReceived('hello world');
229 | testEvent.sourceId = "1";
230 | registry.handleEvent({
231 | messageId : "1",
232 | correlationId : "1",
233 | body: testEvent
234 | },(error)=>{
235 | should.equal(error, null);
236 | done();
237 | });
238 | });
239 | });
240 | });
241 | });
242 |
243 | describe('Infrastructure tests',function(){
244 | describe('Redis event sourced repository',function(){
245 | var account = new BankAccount('2');
246 | account.credit(100);
247 | account.credit(100);
248 | account.debit(50);
249 | account.credit(100);
250 | account.debit(200);
251 | account.balance.should.be.exactly(50);
252 |
253 | var provider = new CQRS.RedisEventSourcedRepository({ host: "127.0.0.1", port:6379});
254 | it('should connect to a specified Redis server',function(done){
255 | provider.connect((error)=>{
256 | should.equal(error, null);
257 | done();
258 | });
259 | });
260 |
261 | it('should be able to persist an event stream for an given aggregate id',function(done){
262 | var events = account.getEvents();
263 | events.length.should.be.exactly(5);
264 | provider.saveEventsByAggregateId(account.getId(),events, (error)=>{
265 | should.equal(error, null);
266 | done();
267 | });
268 | });
269 |
270 | it('should be able to retrieve an event stream by aggregate id and recreate an aggregate instance',function(done){
271 | provider.getEventsByAggregateId(account.getId(),(error, events)=>{
272 | should.equal(error, null);
273 | events.length.should.be.exactly(5);
274 |
275 | var accountFromEvents = new BankAccount(account.getId());
276 | accountFromEvents.loadFromEvents(events);
277 | accountFromEvents.balance.should.be.exactly(account.balance);
278 | accountFromEvents.getEvents().length.should.be.exactly(0);
279 | done();
280 | });
281 | });
282 |
283 | describe('using an "EventSourceRepositoryWithNotifications"',function(){
284 | it('should be able to persist an event can get notified via a callback',function(done){
285 | var eventSourceRepositoryWithNotifications = new CQRS.EventSourceRepositoryWithNotifications(
286 | provider, (id:string, events : Array)=>{
287 | id.should.be.exactly('2');
288 | events.length.should.be.exactly(2);
289 | events[1].amount.should.be.exactly(70);
290 | done();
291 | }
292 | );
293 |
294 | var accountFromEvents = new BankAccount(account.getId());
295 | accountFromEvents.loadFromEvents(account.getEvents());
296 | accountFromEvents.balance.should.be.exactly(account.balance);
297 | accountFromEvents.getEvents().length.should.be.exactly(0);
298 |
299 | accountFromEvents.credit(230);
300 | accountFromEvents.credit(70);
301 | accountFromEvents.getEvents().length.should.be.exactly(2);
302 |
303 | eventSourceRepositoryWithNotifications.saveEventsByAggregateId(accountFromEvents.getId(),accountFromEvents.getEvents(), (error)=>{
304 | should.equal(error, null);
305 | });
306 | });
307 | });
308 |
309 | after(function(done){
310 | provider.getClient().del('eventsourcing.aggregate:' + account.getId(),(error)=>{
311 | should.equal(error, null);
312 | done();
313 | });
314 | });
315 | });
316 |
317 | describe('Redis command bus',function(){
318 | var redisCommandBus = new CQRS.RedisCommandBus({ host: "127.0.0.1", port:6379});
319 | it('should connect to a specified Redis server',function(done){
320 | redisCommandBus.connect((error)=>{
321 | should.equal(error, null);
322 | done();
323 | });
324 | });
325 |
326 | it('should be possible to persist a command into Redis in the pending commands list',function(done){
327 | var testCommand = new TestCommand('hello world');
328 | testCommand.id = "1";
329 | redisCommandBus.handleCommand({
330 | messageId : "1",
331 | correlationId : "1",
332 | body: testCommand
333 | },(error)=>{
334 | should.equal(error, null);
335 |
336 | redisCommandBus.getClient().lrange('messaging.queuedcommands', 0, -1, function(error, results){
337 | should.equal(error, null);
338 | results.length.should.be.exactly(1);
339 | var commandSerialized = results[0];
340 | var command = JSON.parse(commandSerialized);
341 | command.body.message.should.be.exactly(testCommand.message);
342 | done();
343 | });
344 | });
345 | });
346 |
347 | it('should be possible to persist another command into Redis in the pending commands list',function(done){
348 | var testCommand = new TestCommand('hello world2');
349 | testCommand.id = "1";
350 | redisCommandBus.handleCommand({
351 | messageId : "1",
352 | correlationId : "1",
353 | body: testCommand
354 | },(error)=>{
355 | should.equal(error, null);
356 |
357 | redisCommandBus.getClient().lrange('messaging.queuedcommands', 0, -1, function(error, results){
358 | should.equal(error, null);
359 | results.length.should.be.exactly(2);
360 | var commandSerialized = results[1];
361 | var command = JSON.parse(commandSerialized);
362 | command.body.message.should.be.exactly(testCommand.message);
363 | done();
364 | });
365 | });
366 | });
367 |
368 | describe('using the "RedisCommandReceiver"',function(){
369 | it('should be possible to receive pending commands using the "RedisCommandReceiver"',function(done){
370 | var redisCommandReceiverTestHandler = new RedisCommandReceiverTestHandler(()=>{
371 | redisCommandReceiverTestHandler.callCount +=1;
372 | if(redisCommandReceiverTestHandler.callCount == 2) return done();
373 | });
374 |
375 | var redisCommandReceiver = new CQRS.RedisCommandReceiver(
376 | { host: "127.0.0.1", port:6379},
377 | redisCommandReceiverTestHandler);
378 |
379 | redisCommandReceiver.connect((error)=>{
380 | should.equal(error, null);
381 | });
382 | });
383 | });
384 |
385 | after(function(done){
386 | redisCommandBus.getClient().del('messaging.queuedcommands',(error)=>{
387 | should.equal(error, null);
388 | done();
389 | });
390 | });
391 | });
392 |
393 |
394 | describe('Redis event bus',function(){
395 | var redisEventBus = new CQRS.RedisEventBus({ host: "127.0.0.1", port:6379});
396 | it('should connect to a specified Redis server',function(done){
397 | redisEventBus.connect((error)=>{
398 | should.equal(error, null);
399 | done();
400 | });
401 | });
402 |
403 | it('should be possible to persist an event into Redis in the pending commands list',function(done){
404 | var testEvent = new TestEventMessageReceived('hello world');
405 | testEvent.sourceId = "1";
406 | redisEventBus.handleEvent({
407 | messageId : "1",
408 | correlationId : "1",
409 | body: testEvent
410 | },(error)=>{
411 | should.equal(error, null);
412 |
413 | redisEventBus.getClient().lrange('messaging.queuedevents', 0, -1, function(error, results){
414 | should.equal(error, null);
415 | results.length.should.be.exactly(1);
416 | var eventSerialized = results[0];
417 | var _event = JSON.parse(eventSerialized);
418 | _event.body.message.should.be.exactly(testEvent.message);
419 | done();
420 | });
421 | });
422 | });
423 |
424 | it('should be possible to persist another event into Redis in the pending commands list',function(done){
425 | var testEvent = new TestEventMessageReceived('hello world');
426 | testEvent.sourceId = "1";
427 | redisEventBus.handleEvent({
428 | messageId : "1",
429 | correlationId : "1",
430 | body: testEvent
431 | },(error)=>{
432 | should.equal(error, null);
433 |
434 | redisEventBus.getClient().lrange('messaging.queuedevents', 0, -1, function(error, results){
435 | should.equal(error, null);
436 | results.length.should.be.exactly(2);
437 | var eventSerialized = results[0];
438 | var _event = JSON.parse(eventSerialized);
439 | _event.body.message.should.be.exactly(testEvent.message);
440 | done();
441 | });
442 | });
443 | });
444 |
445 | describe('using the "RedisEventReceiver"',function(){
446 | it('should be possible to receive pending events using the "RedisEventReceiver"',function(done){
447 | var redisEventReceiverTestHandler = new RedisEventReceiverTestHandler(()=>{
448 | redisEventReceiverTestHandler.callCount +=1;
449 | if(redisEventReceiverTestHandler.callCount == 2) return done();
450 | },'hello world');
451 |
452 | var redisEventReceiver = new CQRS.RedisEventReceiver(
453 | { host: "127.0.0.1", port:6379},
454 | redisEventReceiverTestHandler);
455 |
456 | redisEventReceiver.connect((error)=>{
457 | should.equal(error, null);
458 | });
459 | });
460 | });
461 |
462 | after(function(done){
463 | redisEventBus.getClient().del('messaging.queuedevents',(error)=>{
464 | should.equal(error, null);
465 | done();
466 | });
467 | });
468 | });
469 | });
470 | });
471 |
--------------------------------------------------------------------------------
/test/CQRSTest.js:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | var __extends = this.__extends || function (d, b) {
4 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
5 | function __() { this.constructor = d; }
6 | __.prototype = b.prototype;
7 | d.prototype = new __();
8 | };
9 | /*global describe, it, import */
10 | /*jslint node: true */
11 | var CQRS = require('../lib/cqrs-typescript');
12 | var should = require('should');
13 | should.equal('actual', 'actual');
14 |
15 | var BankAccount = (function (_super) {
16 | __extends(BankAccount, _super);
17 | function BankAccount(id) {
18 | _super.call(this, id);
19 | this.balance = 0;
20 | }
21 | BankAccount.prototype.credit = function (amount) {
22 | this.update({
23 | name: 'CreditAccount',
24 | amount: amount,
25 | version: -1,
26 | sourceId: ''
27 | });
28 | };
29 |
30 | BankAccount.prototype.debit = function (amount) {
31 | this.update({
32 | name: 'DebitAccount',
33 | amount: amount,
34 | version: -1,
35 | sourceId: ''
36 | });
37 | };
38 |
39 | BankAccount.prototype.onCreditAccount = function (e) {
40 | this.balance += e.amount;
41 | };
42 |
43 | BankAccount.prototype.onDebitAccount = function (e) {
44 | this.balance -= e.amount;
45 | };
46 | return BankAccount;
47 | })(CQRS.EventSourced);
48 |
49 | var TestCommand = (function () {
50 | function TestCommand(message) {
51 | this.name = 'TestCommand';
52 | this.message = message;
53 | }
54 | return TestCommand;
55 | })();
56 |
57 | var TestCommandHandler = (function () {
58 | function TestCommandHandler() {
59 | }
60 | TestCommandHandler.prototype.handleCommand = function (commandToHandle, callback) {
61 | commandToHandle.body.name.should.be.exactly('TestCommand');
62 | commandToHandle.body.message.should.be.exactly('hello world');
63 | callback(null);
64 | };
65 | return TestCommandHandler;
66 | })();
67 | ;
68 |
69 | var RedisCommandReceiverTestHandler = (function () {
70 | function RedisCommandReceiverTestHandler(done) {
71 | this.done = done;
72 | this.callCount = 0;
73 | }
74 | RedisCommandReceiverTestHandler.prototype.handleCommand = function (commandToHandle, callback) {
75 | callback(null);
76 | this.done();
77 | };
78 | return RedisCommandReceiverTestHandler;
79 | })();
80 |
81 | var RedisEventReceiverTestHandler = (function () {
82 | function RedisEventReceiverTestHandler(done, expectedMessage) {
83 | this.done = done;
84 | this.callCount = 0;
85 | this.expectedMessage = expectedMessage;
86 | }
87 | RedisEventReceiverTestHandler.prototype.handleEvent = function (eventToHandle, callback) {
88 | eventToHandle.body.message.should.be.exactly(this.expectedMessage);
89 | callback(null);
90 | this.done();
91 | };
92 | return RedisEventReceiverTestHandler;
93 | })();
94 |
95 | var TestEventMessageReceived = (function () {
96 | function TestEventMessageReceived(message) {
97 | this.name = 'TestEventMessageReceived';
98 | this.message = message;
99 | }
100 | return TestEventMessageReceived;
101 | })();
102 |
103 | var TestEventMessageReceivedHandler = (function () {
104 | function TestEventMessageReceivedHandler() {
105 | }
106 | TestEventMessageReceivedHandler.prototype.handleEvent = function (eventToHandle, callback) {
107 | eventToHandle.body.name.should.be.exactly('TestEventMessageReceived');
108 | eventToHandle.body.message.should.be.exactly('hello world');
109 | callback(null);
110 | };
111 | return TestEventMessageReceivedHandler;
112 | })();
113 | ;
114 |
115 | describe('CQRS Tests', function () {
116 | describe('Core Tests', function () {
117 | var account;
118 |
119 | describe('extending from "EventSourced" to create a "bank account"', function () {
120 | it('should be ok to create one once supplying an id ', function () {
121 | account = new BankAccount('1');
122 | });
123 |
124 | it('should be ok to credit the account to 100 by raising an event', function () {
125 | account.credit(100);
126 | account.balance.should.be.exactly(100);
127 | account.getEvents().length.should.be.exactly(1);
128 | account.getVersion().should.be.exactly(1);
129 | });
130 |
131 | it('should be ok to credit the account to 150 by raising an event', function () {
132 | account.credit(50);
133 | account.balance.should.be.exactly(150);
134 | account.getEvents().length.should.be.exactly(2);
135 | account.getVersion().should.be.exactly(2);
136 | });
137 |
138 | it('should be ok to debit the account by 100 by raising an event', function () {
139 | account.debit(100);
140 | account.balance.should.be.exactly(50);
141 | account.getEvents().length.should.be.exactly(3);
142 | account.getVersion().should.be.exactly(3);
143 | });
144 |
145 | it('should be ok to load a bank account from an event stream', function () {
146 | var accountFromEvents = new BankAccount('1');
147 | var events = account.getEvents();
148 | accountFromEvents.loadFromEvents(events);
149 | accountFromEvents.balance.should.be.exactly(account.balance);
150 | accountFromEvents.getVersion().should.be.exactly(account.getVersion());
151 | });
152 | });
153 |
154 | describe('using an in memory "event sourced" repository', function () {
155 | var provider = new CQRS.InMemoryEventSourcedRepository();
156 |
157 | it('should be able to save events in memory', function (done) {
158 | provider.saveEventsByAggregateId(account.getId(), account.getEvents(), function (error) {
159 | should.equal(error, null);
160 | done();
161 | });
162 | });
163 |
164 | it('should be able to load events previously saved', function (done) {
165 | provider.getEventsByAggregateId(account.getId(), function (error, events) {
166 | events.should.be.an.Array;
167 | events.length.should.be.exactly(account.getEvents().length);
168 | done();
169 | });
170 | });
171 |
172 | it('should be possible to load a bank account from events loaded from the repository', function (done) {
173 | provider.getEventsByAggregateId(account.getId(), function (error, events) {
174 | should.equal(error, null);
175 | var accountFromEvents = new BankAccount(account.getId());
176 | accountFromEvents.loadFromEvents(events);
177 | accountFromEvents.balance.should.be.exactly(account.balance);
178 | done();
179 | });
180 | });
181 | });
182 |
183 | describe('Handler registry', function () {
184 | var registry = new CQRS.HandlerRegistry();
185 |
186 | describe('command registration', function () {
187 | var testCommandHandler = new TestCommandHandler();
188 | var commandName = 'TestCommand';
189 |
190 | it('should be possible to register a command handler', function () {
191 | registry.registerCommandHandler(commandName, testCommandHandler);
192 | var handlers = registry.commandsRegistry[commandName];
193 | handlers.length.should.be.exactly(1);
194 | });
195 |
196 | it('should be possible to execute a command handler having sending a command through the "HandlerRegistry"', function (done) {
197 | var testCommand = new TestCommand('hello world');
198 | testCommand.id = "1";
199 | registry.handleCommand({
200 | messageId: "1",
201 | correlationId: "1",
202 | body: testCommand
203 | }, function (error) {
204 | should.equal(error, null);
205 | done();
206 | });
207 | });
208 | });
209 |
210 | describe('event registration', function () {
211 | var testEventHandler = new TestEventMessageReceivedHandler();
212 | var eventName = 'TestEventMessageReceived';
213 |
214 | it('should be possible to register an event handler', function () {
215 | registry.registerEventHandler(eventName, testEventHandler);
216 | var handlers = registry.eventsRegistry[eventName];
217 | handlers.length.should.be.exactly(1);
218 | });
219 |
220 | it('should be possible to execute an event handler having sending an event through the "HandlerRegistry"', function (done) {
221 | var testEvent = new TestEventMessageReceived('hello world');
222 | testEvent.sourceId = "1";
223 | registry.handleEvent({
224 | messageId: "1",
225 | correlationId: "1",
226 | body: testEvent
227 | }, function (error) {
228 | should.equal(error, null);
229 | done();
230 | });
231 | });
232 | });
233 | });
234 | });
235 |
236 | describe('Infrastructure tests', function () {
237 | describe('Redis event sourced repository', function () {
238 | var account = new BankAccount('2');
239 | account.credit(100);
240 | account.credit(100);
241 | account.debit(50);
242 | account.credit(100);
243 | account.debit(200);
244 | account.balance.should.be.exactly(50);
245 |
246 | var provider = new CQRS.RedisEventSourcedRepository({ host: "127.0.0.1", port: 6379 });
247 | it('should connect to a specified Redis server', function (done) {
248 | provider.connect(function (error) {
249 | should.equal(error, null);
250 | done();
251 | });
252 | });
253 |
254 | it('should be able to persist an event stream for an given aggregate id', function (done) {
255 | var events = account.getEvents();
256 | events.length.should.be.exactly(5);
257 | provider.saveEventsByAggregateId(account.getId(), events, function (error) {
258 | should.equal(error, null);
259 | done();
260 | });
261 | });
262 |
263 | it('should be able to retrieve an event stream by aggregate id and recreate an aggregate instance', function (done) {
264 | provider.getEventsByAggregateId(account.getId(), function (error, events) {
265 | should.equal(error, null);
266 | events.length.should.be.exactly(5);
267 |
268 | var accountFromEvents = new BankAccount(account.getId());
269 | accountFromEvents.loadFromEvents(events);
270 | accountFromEvents.balance.should.be.exactly(account.balance);
271 | accountFromEvents.getEvents().length.should.be.exactly(0);
272 | done();
273 | });
274 | });
275 |
276 | describe('using an "EventSourceRepositoryWithNotifications"', function () {
277 | it('should be able to persist an event can get notified via a callback', function (done) {
278 | var eventSourceRepositoryWithNotifications = new CQRS.EventSourceRepositoryWithNotifications(provider, function (id, events) {
279 | id.should.be.exactly('2');
280 | events.length.should.be.exactly(2);
281 | events[1].amount.should.be.exactly(70);
282 | done();
283 | });
284 |
285 | var accountFromEvents = new BankAccount(account.getId());
286 | accountFromEvents.loadFromEvents(account.getEvents());
287 | accountFromEvents.balance.should.be.exactly(account.balance);
288 | accountFromEvents.getEvents().length.should.be.exactly(0);
289 |
290 | accountFromEvents.credit(230);
291 | accountFromEvents.credit(70);
292 | accountFromEvents.getEvents().length.should.be.exactly(2);
293 |
294 | eventSourceRepositoryWithNotifications.saveEventsByAggregateId(accountFromEvents.getId(), accountFromEvents.getEvents(), function (error) {
295 | should.equal(error, null);
296 | });
297 | });
298 | });
299 |
300 | after(function (done) {
301 | provider.getClient().del('eventsourcing.aggregate:' + account.getId(), function (error) {
302 | should.equal(error, null);
303 | done();
304 | });
305 | });
306 | });
307 |
308 | describe('Redis command bus', function () {
309 | var redisCommandBus = new CQRS.RedisCommandBus({ host: "127.0.0.1", port: 6379 });
310 | it('should connect to a specified Redis server', function (done) {
311 | redisCommandBus.connect(function (error) {
312 | should.equal(error, null);
313 | done();
314 | });
315 | });
316 |
317 | it('should be possible to persist a command into Redis in the pending commands list', function (done) {
318 | var testCommand = new TestCommand('hello world');
319 | testCommand.id = "1";
320 | redisCommandBus.handleCommand({
321 | messageId: "1",
322 | correlationId: "1",
323 | body: testCommand
324 | }, function (error) {
325 | should.equal(error, null);
326 |
327 | redisCommandBus.getClient().lrange('messaging.queuedcommands', 0, -1, function (error, results) {
328 | should.equal(error, null);
329 | results.length.should.be.exactly(1);
330 | var commandSerialized = results[0];
331 | var command = JSON.parse(commandSerialized);
332 | command.body.message.should.be.exactly(testCommand.message);
333 | done();
334 | });
335 | });
336 | });
337 |
338 | it('should be possible to persist another command into Redis in the pending commands list', function (done) {
339 | var testCommand = new TestCommand('hello world2');
340 | testCommand.id = "1";
341 | redisCommandBus.handleCommand({
342 | messageId: "1",
343 | correlationId: "1",
344 | body: testCommand
345 | }, function (error) {
346 | should.equal(error, null);
347 |
348 | redisCommandBus.getClient().lrange('messaging.queuedcommands', 0, -1, function (error, results) {
349 | should.equal(error, null);
350 | results.length.should.be.exactly(2);
351 | var commandSerialized = results[1];
352 | var command = JSON.parse(commandSerialized);
353 | command.body.message.should.be.exactly(testCommand.message);
354 | done();
355 | });
356 | });
357 | });
358 |
359 | describe('using the "RedisCommandReceiver"', function () {
360 | it('should be possible to receive pending commands using the "RedisCommandReceiver"', function (done) {
361 | var redisCommandReceiverTestHandler = new RedisCommandReceiverTestHandler(function () {
362 | redisCommandReceiverTestHandler.callCount += 1;
363 | if (redisCommandReceiverTestHandler.callCount == 2)
364 | return done();
365 | });
366 |
367 | var redisCommandReceiver = new CQRS.RedisCommandReceiver({ host: "127.0.0.1", port: 6379 }, redisCommandReceiverTestHandler);
368 |
369 | redisCommandReceiver.connect(function (error) {
370 | should.equal(error, null);
371 | });
372 | });
373 | });
374 |
375 | after(function (done) {
376 | redisCommandBus.getClient().del('messaging.queuedcommands', function (error) {
377 | should.equal(error, null);
378 | done();
379 | });
380 | });
381 | });
382 |
383 | describe('Redis event bus', function () {
384 | var redisEventBus = new CQRS.RedisEventBus({ host: "127.0.0.1", port: 6379 });
385 | it('should connect to a specified Redis server', function (done) {
386 | redisEventBus.connect(function (error) {
387 | should.equal(error, null);
388 | done();
389 | });
390 | });
391 |
392 | it('should be possible to persist an event into Redis in the pending commands list', function (done) {
393 | var testEvent = new TestEventMessageReceived('hello world');
394 | testEvent.sourceId = "1";
395 | redisEventBus.handleEvent({
396 | messageId: "1",
397 | correlationId: "1",
398 | body: testEvent
399 | }, function (error) {
400 | should.equal(error, null);
401 |
402 | redisEventBus.getClient().lrange('messaging.queuedevents', 0, -1, function (error, results) {
403 | should.equal(error, null);
404 | results.length.should.be.exactly(1);
405 | var eventSerialized = results[0];
406 | var _event = JSON.parse(eventSerialized);
407 | _event.body.message.should.be.exactly(testEvent.message);
408 | done();
409 | });
410 | });
411 | });
412 |
413 | it('should be possible to persist another event into Redis in the pending commands list', function (done) {
414 | var testEvent = new TestEventMessageReceived('hello world');
415 | testEvent.sourceId = "1";
416 | redisEventBus.handleEvent({
417 | messageId: "1",
418 | correlationId: "1",
419 | body: testEvent
420 | }, function (error) {
421 | should.equal(error, null);
422 |
423 | redisEventBus.getClient().lrange('messaging.queuedevents', 0, -1, function (error, results) {
424 | should.equal(error, null);
425 | results.length.should.be.exactly(2);
426 | var eventSerialized = results[0];
427 | var _event = JSON.parse(eventSerialized);
428 | _event.body.message.should.be.exactly(testEvent.message);
429 | done();
430 | });
431 | });
432 | });
433 |
434 | describe('using the "RedisEventReceiver"', function () {
435 | it('should be possible to receive pending events using the "RedisEventReceiver"', function (done) {
436 | var redisEventReceiverTestHandler = new RedisEventReceiverTestHandler(function () {
437 | redisEventReceiverTestHandler.callCount += 1;
438 | if (redisEventReceiverTestHandler.callCount == 2)
439 | return done();
440 | }, 'hello world');
441 |
442 | var redisEventReceiver = new CQRS.RedisEventReceiver({ host: "127.0.0.1", port: 6379 }, redisEventReceiverTestHandler);
443 |
444 | redisEventReceiver.connect(function (error) {
445 | should.equal(error, null);
446 | });
447 | });
448 | });
449 |
450 | after(function (done) {
451 | redisEventBus.getClient().del('messaging.queuedevents', function (error) {
452 | should.equal(error, null);
453 | done();
454 | });
455 | });
456 | });
457 | });
458 | });
459 |
--------------------------------------------------------------------------------
/lib/node.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for Node.js v0.10.1
2 | // Project: http://nodejs.org/
3 | // Definitions by: Microsoft TypeScript , DefinitelyTyped
4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped
5 |
6 | /************************************************
7 | * *
8 | * Node.js v0.10.1 API *
9 | * *
10 | ************************************************/
11 |
12 | /************************************************
13 | * *
14 | * GLOBAL *
15 | * *
16 | ************************************************/
17 | declare var process: NodeJS.Process;
18 | declare var global: any;
19 |
20 | declare var __filename: string;
21 | declare var __dirname: string;
22 |
23 | declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
24 | declare function clearTimeout(timeoutId: NodeJS.Timer): void;
25 | declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
26 | declare function clearInterval(intervalId: NodeJS.Timer): void;
27 | declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any;
28 | declare function clearImmediate(immediateId: any): void;
29 |
30 | declare var require: {
31 | (id: string): any;
32 | resolve(id:string): string;
33 | cache: any;
34 | extensions: any;
35 | main: any;
36 | };
37 |
38 | declare var module: {
39 | exports: any;
40 | require(id: string): any;
41 | id: string;
42 | filename: string;
43 | loaded: boolean;
44 | parent: any;
45 | children: any[];
46 | };
47 |
48 | // Same as module.exports
49 | declare var exports: any;
50 | declare var SlowBuffer: {
51 | new (str: string, encoding?: string): Buffer;
52 | new (size: number): Buffer;
53 | new (array: any[]): Buffer;
54 | prototype: Buffer;
55 | isBuffer(obj: any): boolean;
56 | byteLength(string: string, encoding?: string): number;
57 | concat(list: Buffer[], totalLength?: number): Buffer;
58 | };
59 |
60 |
61 | // Buffer class
62 | interface Buffer extends NodeBuffer {}
63 | declare var Buffer: {
64 | new (str: string, encoding?: string): Buffer;
65 | new (size: number): Buffer;
66 | new (array: any[]): Buffer;
67 | prototype: Buffer;
68 | isBuffer(obj: any): boolean;
69 | byteLength(string: string, encoding?: string): number;
70 | concat(list: Buffer[], totalLength?: number): Buffer;
71 | };
72 |
73 | /************************************************
74 | * *
75 | * GLOBAL INTERFACES *
76 | * *
77 | ************************************************/
78 | declare module NodeJS {
79 | export interface ErrnoException extends Error {
80 | errno?: any;
81 | code?: string;
82 | path?: string;
83 | syscall?: string;
84 | }
85 |
86 | export interface EventEmitter {
87 | addListener(event: string, listener: Function): EventEmitter;
88 | on(event: string, listener: Function): EventEmitter;
89 | once(event: string, listener: Function): EventEmitter;
90 | removeListener(event: string, listener: Function): EventEmitter;
91 | removeAllListeners(event?: string): EventEmitter;
92 | setMaxListeners(n: number): void;
93 | listeners(event: string): Function[];
94 | emit(event: string, ...args: any[]): boolean;
95 | }
96 |
97 | export interface ReadableStream extends EventEmitter {
98 | readable: boolean;
99 | read(size?: number): any;
100 | setEncoding(encoding: string): void;
101 | pause(): void;
102 | resume(): void;
103 | pipe(destination: T, options?: { end?: boolean; }): T;
104 | unpipe(destination?: T): void;
105 | unshift(chunk: string): void;
106 | unshift(chunk: Buffer): void;
107 | wrap(oldStream: ReadableStream): ReadableStream;
108 | }
109 |
110 | export interface WritableStream extends EventEmitter {
111 | writable: boolean;
112 | write(buffer: Buffer, cb?: Function): boolean;
113 | write(str: string, cb?: Function): boolean;
114 | write(str: string, encoding?: string, cb?: Function): boolean;
115 | end(): void;
116 | end(buffer: Buffer, cb?: Function): void;
117 | end(str: string, cb?: Function): void;
118 | end(str: string, encoding?: string, cb?: Function): void;
119 | }
120 |
121 | export interface ReadWriteStream extends ReadableStream, WritableStream {}
122 |
123 | export interface Process extends EventEmitter {
124 | stdout: WritableStream;
125 | stderr: WritableStream;
126 | stdin: ReadableStream;
127 | argv: string[];
128 | execPath: string;
129 | abort(): void;
130 | chdir(directory: string): void;
131 | cwd(): string;
132 | env: any;
133 | exit(code?: number): void;
134 | getgid(): number;
135 | setgid(id: number): void;
136 | setgid(id: string): void;
137 | getuid(): number;
138 | setuid(id: number): void;
139 | setuid(id: string): void;
140 | version: string;
141 | versions: {
142 | http_parser: string;
143 | node: string;
144 | v8: string;
145 | ares: string;
146 | uv: string;
147 | zlib: string;
148 | openssl: string;
149 | };
150 | config: {
151 | target_defaults: {
152 | cflags: any[];
153 | default_configuration: string;
154 | defines: string[];
155 | include_dirs: string[];
156 | libraries: string[];
157 | };
158 | variables: {
159 | clang: number;
160 | host_arch: string;
161 | node_install_npm: boolean;
162 | node_install_waf: boolean;
163 | node_prefix: string;
164 | node_shared_openssl: boolean;
165 | node_shared_v8: boolean;
166 | node_shared_zlib: boolean;
167 | node_use_dtrace: boolean;
168 | node_use_etw: boolean;
169 | node_use_openssl: boolean;
170 | target_arch: string;
171 | v8_no_strict_aliasing: number;
172 | v8_use_snapshot: boolean;
173 | visibility: string;
174 | };
175 | };
176 | kill(pid: number, signal?: string): void;
177 | pid: number;
178 | title: string;
179 | arch: string;
180 | platform: string;
181 | memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; };
182 | nextTick(callback: Function): void;
183 | umask(mask?: number): number;
184 | uptime(): number;
185 | hrtime(time?:number[]): number[];
186 |
187 | // Worker
188 | send?(message: any, sendHandle?: any): void;
189 | }
190 |
191 | export interface Timer {
192 | ref() : void;
193 | unref() : void;
194 | }
195 | }
196 |
197 | /**
198 | * @deprecated
199 | */
200 | interface NodeBuffer {
201 | [index: number]: number;
202 | write(string: string, offset?: number, length?: number, encoding?: string): number;
203 | toString(encoding?: string, start?: number, end?: number): string;
204 | toJSON(): any;
205 | length: number;
206 | copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
207 | slice(start?: number, end?: number): Buffer;
208 | readUInt8(offset: number, noAsset?: boolean): number;
209 | readUInt16LE(offset: number, noAssert?: boolean): number;
210 | readUInt16BE(offset: number, noAssert?: boolean): number;
211 | readUInt32LE(offset: number, noAssert?: boolean): number;
212 | readUInt32BE(offset: number, noAssert?: boolean): number;
213 | readInt8(offset: number, noAssert?: boolean): number;
214 | readInt16LE(offset: number, noAssert?: boolean): number;
215 | readInt16BE(offset: number, noAssert?: boolean): number;
216 | readInt32LE(offset: number, noAssert?: boolean): number;
217 | readInt32BE(offset: number, noAssert?: boolean): number;
218 | readFloatLE(offset: number, noAssert?: boolean): number;
219 | readFloatBE(offset: number, noAssert?: boolean): number;
220 | readDoubleLE(offset: number, noAssert?: boolean): number;
221 | readDoubleBE(offset: number, noAssert?: boolean): number;
222 | writeUInt8(value: number, offset: number, noAssert?: boolean): void;
223 | writeUInt16LE(value: number, offset: number, noAssert?: boolean): void;
224 | writeUInt16BE(value: number, offset: number, noAssert?: boolean): void;
225 | writeUInt32LE(value: number, offset: number, noAssert?: boolean): void;
226 | writeUInt32BE(value: number, offset: number, noAssert?: boolean): void;
227 | writeInt8(value: number, offset: number, noAssert?: boolean): void;
228 | writeInt16LE(value: number, offset: number, noAssert?: boolean): void;
229 | writeInt16BE(value: number, offset: number, noAssert?: boolean): void;
230 | writeInt32LE(value: number, offset: number, noAssert?: boolean): void;
231 | writeInt32BE(value: number, offset: number, noAssert?: boolean): void;
232 | writeFloatLE(value: number, offset: number, noAssert?: boolean): void;
233 | writeFloatBE(value: number, offset: number, noAssert?: boolean): void;
234 | writeDoubleLE(value: number, offset: number, noAssert?: boolean): void;
235 | writeDoubleBE(value: number, offset: number, noAssert?: boolean): void;
236 | fill(value: any, offset?: number, end?: number): void;
237 | }
238 |
239 | /************************************************
240 | * *
241 | * MODULES *
242 | * *
243 | ************************************************/
244 | declare module "buffer" {
245 | export var INSPECT_MAX_BYTES: number;
246 | }
247 |
248 | declare module "querystring" {
249 | export function stringify(obj: any, sep?: string, eq?: string): string;
250 | export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any;
251 | export function escape(): any;
252 | export function unescape(): any;
253 | }
254 |
255 | declare module "events" {
256 | export class EventEmitter implements NodeJS.EventEmitter {
257 | static listenerCount(emitter: EventEmitter, event: string): number;
258 |
259 | addListener(event: string, listener: Function): EventEmitter;
260 | on(event: string, listener: Function): EventEmitter;
261 | once(event: string, listener: Function): EventEmitter;
262 | removeListener(event: string, listener: Function): EventEmitter;
263 | removeAllListeners(event?: string): EventEmitter;
264 | setMaxListeners(n: number): void;
265 | listeners(event: string): Function[];
266 | emit(event: string, ...args: any[]): boolean;
267 | }
268 | }
269 |
270 | declare module "http" {
271 | import events = require("events");
272 | import net = require("net");
273 | import stream = require("stream");
274 |
275 | export interface Server extends events.EventEmitter {
276 | listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server;
277 | listen(path: string, callback?: Function): Server;
278 | listen(handle: any, listeningListener?: Function): Server;
279 | close(cb?: any): Server;
280 | address(): { port: number; family: string; address: string; };
281 | maxHeadersCount: number;
282 | }
283 | export interface ServerRequest extends events.EventEmitter, stream.Readable {
284 | method: string;
285 | url: string;
286 | headers: any;
287 | trailers: string;
288 | httpVersion: string;
289 | setEncoding(encoding?: string): void;
290 | pause(): void;
291 | resume(): void;
292 | connection: net.Socket;
293 | }
294 | export interface ServerResponse extends events.EventEmitter, stream.Writable {
295 | // Extended base methods
296 | write(buffer: Buffer): boolean;
297 | write(buffer: Buffer, cb?: Function): boolean;
298 | write(str: string, cb?: Function): boolean;
299 | write(str: string, encoding?: string, cb?: Function): boolean;
300 | write(str: string, encoding?: string, fd?: string): boolean;
301 |
302 | writeContinue(): void;
303 | writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void;
304 | writeHead(statusCode: number, headers?: any): void;
305 | statusCode: number;
306 | setHeader(name: string, value: string): void;
307 | sendDate: boolean;
308 | getHeader(name: string): string;
309 | removeHeader(name: string): void;
310 | write(chunk: any, encoding?: string): any;
311 | addTrailers(headers: any): void;
312 |
313 | // Extended base methods
314 | end(): void;
315 | end(buffer: Buffer, cb?: Function): void;
316 | end(str: string, cb?: Function): void;
317 | end(str: string, encoding?: string, cb?: Function): void;
318 | end(data?: any, encoding?: string): void;
319 | }
320 | export interface ClientRequest extends events.EventEmitter, stream.Writable {
321 | // Extended base methods
322 | write(buffer: Buffer): boolean;
323 | write(buffer: Buffer, cb?: Function): boolean;
324 | write(str: string, cb?: Function): boolean;
325 | write(str: string, encoding?: string, cb?: Function): boolean;
326 | write(str: string, encoding?: string, fd?: string): boolean;
327 |
328 | write(chunk: any, encoding?: string): void;
329 | abort(): void;
330 | setTimeout(timeout: number, callback?: Function): void;
331 | setNoDelay(noDelay?: boolean): void;
332 | setSocketKeepAlive(enable?: boolean, initialDelay?: number): void;
333 |
334 | // Extended base methods
335 | end(): void;
336 | end(buffer: Buffer, cb?: Function): void;
337 | end(str: string, cb?: Function): void;
338 | end(str: string, encoding?: string, cb?: Function): void;
339 | end(data?: any, encoding?: string): void;
340 | }
341 | export interface ClientResponse extends events.EventEmitter, stream.Readable {
342 | statusCode: number;
343 | httpVersion: string;
344 | headers: any;
345 | trailers: any;
346 | setEncoding(encoding?: string): void;
347 | pause(): void;
348 | resume(): void;
349 | }
350 | export interface Agent { maxSockets: number; sockets: any; requests: any; }
351 |
352 | export var STATUS_CODES: {
353 | [errorCode: number]: string;
354 | [errorCode: string]: string;
355 | };
356 | export function createServer(requestListener?: (request: ServerRequest, response: ServerResponse) =>void ): Server;
357 | export function createClient(port?: number, host?: string): any;
358 | export function request(options: any, callback?: Function): ClientRequest;
359 | export function get(options: any, callback?: Function): ClientRequest;
360 | export var globalAgent: Agent;
361 | }
362 |
363 | declare module "cluster" {
364 | import child = require("child_process");
365 | import events = require("events");
366 |
367 | export interface ClusterSettings {
368 | exec?: string;
369 | args?: string[];
370 | silent?: boolean;
371 | }
372 |
373 | export class Worker extends events.EventEmitter {
374 | id: string;
375 | process: child.ChildProcess;
376 | suicide: boolean;
377 | send(message: any, sendHandle?: any): void;
378 | kill(signal?: string): void;
379 | destroy(signal?: string): void;
380 | disconnect(): void;
381 | }
382 |
383 | export var settings: ClusterSettings;
384 | export var isMaster: boolean;
385 | export var isWorker: boolean;
386 | export function setupMaster(settings?: ClusterSettings): void;
387 | export function fork(env?: any): Worker;
388 | export function disconnect(callback?: Function): void;
389 | export var worker: Worker;
390 | export var workers: Worker[];
391 |
392 | // Event emitter
393 | export function addListener(event: string, listener: Function): void;
394 | export function on(event: string, listener: Function): any;
395 | export function once(event: string, listener: Function): void;
396 | export function removeListener(event: string, listener: Function): void;
397 | export function removeAllListeners(event?: string): void;
398 | export function setMaxListeners(n: number): void;
399 | export function listeners(event: string): Function[];
400 | export function emit(event: string, ...args: any[]): boolean;
401 | }
402 |
403 | declare module "zlib" {
404 | import stream = require("stream");
405 | export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; }
406 |
407 | export interface Gzip extends stream.Transform { }
408 | export interface Gunzip extends stream.Transform { }
409 | export interface Deflate extends stream.Transform { }
410 | export interface Inflate extends stream.Transform { }
411 | export interface DeflateRaw extends stream.Transform { }
412 | export interface InflateRaw extends stream.Transform { }
413 | export interface Unzip extends stream.Transform { }
414 |
415 | export function createGzip(options?: ZlibOptions): Gzip;
416 | export function createGunzip(options?: ZlibOptions): Gunzip;
417 | export function createDeflate(options?: ZlibOptions): Deflate;
418 | export function createInflate(options?: ZlibOptions): Inflate;
419 | export function createDeflateRaw(options?: ZlibOptions): DeflateRaw;
420 | export function createInflateRaw(options?: ZlibOptions): InflateRaw;
421 | export function createUnzip(options?: ZlibOptions): Unzip;
422 |
423 | export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void;
424 | export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void;
425 | export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void;
426 | export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void;
427 | export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void;
428 | export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void;
429 | export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void;
430 |
431 | // Constants
432 | export var Z_NO_FLUSH: number;
433 | export var Z_PARTIAL_FLUSH: number;
434 | export var Z_SYNC_FLUSH: number;
435 | export var Z_FULL_FLUSH: number;
436 | export var Z_FINISH: number;
437 | export var Z_BLOCK: number;
438 | export var Z_TREES: number;
439 | export var Z_OK: number;
440 | export var Z_STREAM_END: number;
441 | export var Z_NEED_DICT: number;
442 | export var Z_ERRNO: number;
443 | export var Z_STREAM_ERROR: number;
444 | export var Z_DATA_ERROR: number;
445 | export var Z_MEM_ERROR: number;
446 | export var Z_BUF_ERROR: number;
447 | export var Z_VERSION_ERROR: number;
448 | export var Z_NO_COMPRESSION: number;
449 | export var Z_BEST_SPEED: number;
450 | export var Z_BEST_COMPRESSION: number;
451 | export var Z_DEFAULT_COMPRESSION: number;
452 | export var Z_FILTERED: number;
453 | export var Z_HUFFMAN_ONLY: number;
454 | export var Z_RLE: number;
455 | export var Z_FIXED: number;
456 | export var Z_DEFAULT_STRATEGY: number;
457 | export var Z_BINARY: number;
458 | export var Z_TEXT: number;
459 | export var Z_ASCII: number;
460 | export var Z_UNKNOWN: number;
461 | export var Z_DEFLATED: number;
462 | export var Z_NULL: number;
463 | }
464 |
465 | declare module "os" {
466 | export function tmpDir(): string;
467 | export function hostname(): string;
468 | export function type(): string;
469 | export function platform(): string;
470 | export function arch(): string;
471 | export function release(): string;
472 | export function uptime(): number;
473 | export function loadavg(): number[];
474 | export function totalmem(): number;
475 | export function freemem(): number;
476 | export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[];
477 | export function networkInterfaces(): any;
478 | export var EOL: string;
479 | }
480 |
481 | declare module "https" {
482 | import tls = require("tls");
483 | import events = require("events");
484 | import http = require("http");
485 |
486 | export interface ServerOptions {
487 | pfx?: any;
488 | key?: any;
489 | passphrase?: string;
490 | cert?: any;
491 | ca?: any;
492 | crl?: any;
493 | ciphers?: string;
494 | honorCipherOrder?: boolean;
495 | requestCert?: boolean;
496 | rejectUnauthorized?: boolean;
497 | NPNProtocols?: any;
498 | SNICallback?: (servername: string) => any;
499 | }
500 |
501 | export interface RequestOptions {
502 | host?: string;
503 | hostname?: string;
504 | port?: number;
505 | path?: string;
506 | method?: string;
507 | headers?: any;
508 | auth?: string;
509 | agent?: any;
510 | pfx?: any;
511 | key?: any;
512 | passphrase?: string;
513 | cert?: any;
514 | ca?: any;
515 | ciphers?: string;
516 | rejectUnauthorized?: boolean;
517 | }
518 |
519 | export interface Agent {
520 | maxSockets: number;
521 | sockets: any;
522 | requests: any;
523 | }
524 | export var Agent: {
525 | new (options?: RequestOptions): Agent;
526 | };
527 | export interface Server extends tls.Server { }
528 | export function createServer(options: ServerOptions, requestListener?: Function): Server;
529 | export function request(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest;
530 | export function get(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest;
531 | export var globalAgent: Agent;
532 | }
533 |
534 | declare module "punycode" {
535 | export function decode(string: string): string;
536 | export function encode(string: string): string;
537 | export function toUnicode(domain: string): string;
538 | export function toASCII(domain: string): string;
539 | export var ucs2: ucs2;
540 | interface ucs2 {
541 | decode(string: string): string;
542 | encode(codePoints: number[]): string;
543 | }
544 | export var version: any;
545 | }
546 |
547 | declare module "repl" {
548 | import stream = require("stream");
549 | import events = require("events");
550 |
551 | export interface ReplOptions {
552 | prompt?: string;
553 | input?: NodeJS.ReadableStream;
554 | output?: NodeJS.WritableStream;
555 | terminal?: boolean;
556 | eval?: Function;
557 | useColors?: boolean;
558 | useGlobal?: boolean;
559 | ignoreUndefined?: boolean;
560 | writer?: Function;
561 | }
562 | export function start(options: ReplOptions): events.EventEmitter;
563 | }
564 |
565 | declare module "readline" {
566 | import events = require("events");
567 | import stream = require("stream");
568 |
569 | export interface ReadLine extends events.EventEmitter {
570 | setPrompt(prompt: string, length: number): void;
571 | prompt(preserveCursor?: boolean): void;
572 | question(query: string, callback: Function): void;
573 | pause(): void;
574 | resume(): void;
575 | close(): void;
576 | write(data: any, key?: any): void;
577 | }
578 | export interface ReadLineOptions {
579 | input: NodeJS.ReadableStream;
580 | output: NodeJS.WritableStream;
581 | completer?: Function;
582 | terminal?: boolean;
583 | }
584 | export function createInterface(options: ReadLineOptions): ReadLine;
585 | }
586 |
587 | declare module "vm" {
588 | export interface Context { }
589 | export interface Script {
590 | runInThisContext(): void;
591 | runInNewContext(sandbox?: Context): void;
592 | }
593 | export function runInThisContext(code: string, filename?: string): void;
594 | export function runInNewContext(code: string, sandbox?: Context, filename?: string): void;
595 | export function runInContext(code: string, context: Context, filename?: string): void;
596 | export function createContext(initSandbox?: Context): Context;
597 | export function createScript(code: string, filename?: string): Script;
598 | }
599 |
600 | declare module "child_process" {
601 | import events = require("events");
602 | import stream = require("stream");
603 |
604 | export interface ChildProcess extends events.EventEmitter {
605 | stdin: stream.Writable;
606 | stdout: stream.Readable;
607 | stderr: stream.Readable;
608 | pid: number;
609 | kill(signal?: string): void;
610 | send(message: any, sendHandle: any): void;
611 | disconnect(): void;
612 | }
613 |
614 | export function spawn(command: string, args?: string[], options?: {
615 | cwd?: string;
616 | stdio?: any;
617 | custom?: any;
618 | env?: any;
619 | detached?: boolean;
620 | }): ChildProcess;
621 | export function exec(command: string, options: {
622 | cwd?: string;
623 | stdio?: any;
624 | customFds?: any;
625 | env?: any;
626 | encoding?: string;
627 | timeout?: number;
628 | maxBuffer?: number;
629 | killSignal?: string;
630 | }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
631 | export function exec(command: string, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
632 | export function execFile(file: string, args: string[], options: {
633 | cwd?: string;
634 | stdio?: any;
635 | customFds?: any;
636 | env?: any;
637 | encoding?: string;
638 | timeout?: number;
639 | maxBuffer?: string;
640 | killSignal?: string;
641 | }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
642 | export function fork(modulePath: string, args?: string[], options?: {
643 | cwd?: string;
644 | env?: any;
645 | encoding?: string;
646 | }): ChildProcess;
647 | }
648 |
649 | declare module "url" {
650 | export interface Url {
651 | href: string;
652 | protocol: string;
653 | auth: string;
654 | hostname: string;
655 | port: string;
656 | host: string;
657 | pathname: string;
658 | search: string;
659 | query: string;
660 | slashes: boolean;
661 | hash?: string;
662 | path?: string;
663 | }
664 |
665 | export interface UrlOptions {
666 | protocol?: string;
667 | auth?: string;
668 | hostname?: string;
669 | port?: string;
670 | host?: string;
671 | pathname?: string;
672 | search?: string;
673 | query?: any;
674 | hash?: string;
675 | path?: string;
676 | }
677 |
678 | export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url;
679 | export function format(url: UrlOptions): string;
680 | export function resolve(from: string, to: string): string;
681 | }
682 |
683 | declare module "dns" {
684 | export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string;
685 | export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string;
686 | export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[];
687 | export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
688 | export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
689 | export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
690 | export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
691 | export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
692 | export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
693 | export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
694 | export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[];
695 | export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[];
696 | }
697 |
698 | declare module "net" {
699 | import stream = require("stream");
700 |
701 | export interface Socket extends stream.Duplex {
702 | // Extended base methods
703 | write(buffer: Buffer): boolean;
704 | write(buffer: Buffer, cb?: Function): boolean;
705 | write(str: string, cb?: Function): boolean;
706 | write(str: string, encoding?: string, cb?: Function): boolean;
707 | write(str: string, encoding?: string, fd?: string): boolean;
708 |
709 | connect(port: number, host?: string, connectionListener?: Function): void;
710 | connect(path: string, connectionListener?: Function): void;
711 | bufferSize: number;
712 | setEncoding(encoding?: string): void;
713 | write(data: any, encoding?: string, callback?: Function): void;
714 | destroy(): void;
715 | pause(): void;
716 | resume(): void;
717 | setTimeout(timeout: number, callback?: Function): void;
718 | setNoDelay(noDelay?: boolean): void;
719 | setKeepAlive(enable?: boolean, initialDelay?: number): void;
720 | address(): { port: number; family: string; address: string; };
721 | remoteAddress: string;
722 | remotePort: number;
723 | bytesRead: number;
724 | bytesWritten: number;
725 |
726 | // Extended base methods
727 | end(): void;
728 | end(buffer: Buffer, cb?: Function): void;
729 | end(str: string, cb?: Function): void;
730 | end(str: string, encoding?: string, cb?: Function): void;
731 | end(data?: any, encoding?: string): void;
732 | }
733 |
734 | export var Socket: {
735 | new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket;
736 | };
737 |
738 | export interface Server extends Socket {
739 | listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server;
740 | listen(path: string, listeningListener?: Function): Server;
741 | listen(handle: any, listeningListener?: Function): Server;
742 | close(callback?: Function): Server;
743 | address(): { port: number; family: string; address: string; };
744 | maxConnections: number;
745 | connections: number;
746 | }
747 | export function createServer(connectionListener?: (socket: Socket) =>void ): Server;
748 | export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server;
749 | export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket;
750 | export function connect(port: number, host?: string, connectionListener?: Function): Socket;
751 | export function connect(path: string, connectionListener?: Function): Socket;
752 | export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket;
753 | export function createConnection(port: number, host?: string, connectionListener?: Function): Socket;
754 | export function createConnection(path: string, connectionListener?: Function): Socket;
755 | export function isIP(input: string): number;
756 | export function isIPv4(input: string): boolean;
757 | export function isIPv6(input: string): boolean;
758 | }
759 |
760 | declare module "dgram" {
761 | import events = require("events");
762 |
763 | export function createSocket(type: string, callback?: Function): Socket;
764 |
765 | interface Socket extends events.EventEmitter {
766 | send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void;
767 | bind(port: number, address?: string, callback?: () => void): void;
768 | close(): void;
769 | address: { address: string; family: string; port: number; };
770 | setBroadcast(flag: boolean): void;
771 | setMulticastTTL(ttl: number): void;
772 | setMulticastLoopback(flag: boolean): void;
773 | addMembership(multicastAddress: string, multicastInterface?: string): void;
774 | dropMembership(multicastAddress: string, multicastInterface?: string): void;
775 | }
776 | }
777 |
778 | declare module "fs" {
779 | import stream = require("stream");
780 | import events = require("events");
781 |
782 | interface Stats {
783 | isFile(): boolean;
784 | isDirectory(): boolean;
785 | isBlockDevice(): boolean;
786 | isCharacterDevice(): boolean;
787 | isSymbolicLink(): boolean;
788 | isFIFO(): boolean;
789 | isSocket(): boolean;
790 | dev: number;
791 | ino: number;
792 | mode: number;
793 | nlink: number;
794 | uid: number;
795 | gid: number;
796 | rdev: number;
797 | size: number;
798 | blksize: number;
799 | blocks: number;
800 | atime: Date;
801 | mtime: Date;
802 | ctime: Date;
803 | }
804 |
805 | interface FSWatcher extends events.EventEmitter {
806 | close(): void;
807 | }
808 |
809 | export interface ReadStream extends stream.Readable {}
810 | export interface WriteStream extends stream.Writable {}
811 |
812 | export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
813 | export function renameSync(oldPath: string, newPath: string): void;
814 | export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
815 | export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
816 | export function truncateSync(path: string, len?: number): void;
817 | export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
818 | export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
819 | export function ftruncateSync(fd: number, len?: number): void;
820 | export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
821 | export function chownSync(path: string, uid: number, gid: number): void;
822 | export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
823 | export function fchownSync(fd: number, uid: number, gid: number): void;
824 | export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
825 | export function lchownSync(path: string, uid: number, gid: number): void;
826 | export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
827 | export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
828 | export function chmodSync(path: string, mode: number): void;
829 | export function chmodSync(path: string, mode: string): void;
830 | export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
831 | export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
832 | export function fchmodSync(fd: number, mode: number): void;
833 | export function fchmodSync(fd: number, mode: string): void;
834 | export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
835 | export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
836 | export function lchmodSync(path: string, mode: number): void;
837 | export function lchmodSync(path: string, mode: string): void;
838 | export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void;
839 | export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void;
840 | export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void;
841 | export function statSync(path: string): Stats;
842 | export function lstatSync(path: string): Stats;
843 | export function fstatSync(fd: number): Stats;
844 | export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
845 | export function linkSync(srcpath: string, dstpath: string): void;
846 | export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
847 | export function symlinkSync(srcpath: string, dstpath: string, type?: string): void;
848 | export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void;
849 | export function readlinkSync(path: string): string;
850 | export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void;
851 | export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void;
852 | export function realpathSync(path: string, cache?: {[path: string]: string}): string;
853 | export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
854 | export function unlinkSync(path: string): void;
855 | export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
856 | export function rmdirSync(path: string): void;
857 | export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
858 | export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
859 | export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void;
860 | export function mkdirSync(path: string, mode?: number): void;
861 | export function mkdirSync(path: string, mode?: string): void;
862 | export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void;
863 | export function readdirSync(path: string): string[];
864 | export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
865 | export function closeSync(fd: number): void;
866 | export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void;
867 | export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void;
868 | export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void;
869 | export function openSync(path: string, flags: string, mode?: number): number;
870 | export function openSync(path: string, flags: string, mode?: string): number;
871 | export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
872 | export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void;
873 | export function utimesSync(path: string, atime: number, mtime: number): void;
874 | export function utimesSync(path: string, atime: Date, mtime: Date): void;
875 | export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
876 | export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void;
877 | export function futimesSync(fd: number, atime: number, mtime: number): void;
878 | export function futimesSync(fd: number, atime: Date, mtime: Date): void;
879 | export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void;
880 | export function fsyncSync(fd: number): void;
881 | export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void;
882 | export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number;
883 | export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void;
884 | export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number;
885 | export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void;
886 | export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void;
887 | export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void;
888 | export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void ): void;
889 | export function readFileSync(filename: string, encoding: string): string;
890 | export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string;
891 | export function readFileSync(filename: string, options?: { flag?: string; }): Buffer;
892 | export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void;
893 | export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void;
894 | export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void;
895 | export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void;
896 | export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void;
897 | export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void;
898 | export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void;
899 | export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void;
900 | export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void;
901 | export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void;
902 | export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void;
903 | export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void;
904 | export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void;
905 | export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher;
906 | export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher;
907 | export function exists(path: string, callback?: (exists: boolean) => void): void;
908 | export function existsSync(path: string): boolean;
909 | export function createReadStream(path: string, options?: {
910 | flags?: string;
911 | encoding?: string;
912 | fd?: string;
913 | mode?: number;
914 | bufferSize?: number;
915 | }): ReadStream;
916 | export function createReadStream(path: string, options?: {
917 | flags?: string;
918 | encoding?: string;
919 | fd?: string;
920 | mode?: string;
921 | bufferSize?: number;
922 | }): ReadStream;
923 | export function createWriteStream(path: string, options?: {
924 | flags?: string;
925 | encoding?: string;
926 | string?: string;
927 | }): WriteStream;
928 | }
929 |
930 | declare module "path" {
931 | export function normalize(p: string): string;
932 | export function join(...paths: any[]): string;
933 | export function resolve(...pathSegments: any[]): string;
934 | export function relative(from: string, to: string): string;
935 | export function dirname(p: string): string;
936 | export function basename(p: string, ext?: string): string;
937 | export function extname(p: string): string;
938 | export var sep: string;
939 | }
940 |
941 | declare module "string_decoder" {
942 | export interface NodeStringDecoder {
943 | write(buffer: Buffer): string;
944 | detectIncompleteChar(buffer: Buffer): number;
945 | }
946 | export var StringDecoder: {
947 | new (encoding: string): NodeStringDecoder;
948 | };
949 | }
950 |
951 | declare module "tls" {
952 | import crypto = require("crypto");
953 | import net = require("net");
954 | import stream = require("stream");
955 |
956 | var CLIENT_RENEG_LIMIT: number;
957 | var CLIENT_RENEG_WINDOW: number;
958 |
959 | export interface TlsOptions {
960 | pfx?: any; //string or buffer
961 | key?: any; //string or buffer
962 | passphrase?: string;
963 | cert?: any;
964 | ca?: any; //string or buffer
965 | crl?: any; //string or string array
966 | ciphers?: string;
967 | honorCipherOrder?: any;
968 | requestCert?: boolean;
969 | rejectUnauthorized?: boolean;
970 | NPNProtocols?: any; //array or Buffer;
971 | SNICallback?: (servername: string) => any;
972 | }
973 |
974 | export interface ConnectionOptions {
975 | host?: string;
976 | port?: number;
977 | socket?: net.Socket;
978 | pfx?: any; //string | Buffer
979 | key?: any; //string | Buffer
980 | passphrase?: string;
981 | cert?: any; //string | Buffer
982 | ca?: any; //Array of string | Buffer
983 | rejectUnauthorized?: boolean;
984 | NPNProtocols?: any; //Array of string | Buffer
985 | servername?: string;
986 | }
987 |
988 | export interface Server extends net.Server {
989 | // Extended base methods
990 | listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server;
991 | listen(path: string, listeningListener?: Function): Server;
992 | listen(handle: any, listeningListener?: Function): Server;
993 |
994 | listen(port: number, host?: string, callback?: Function): Server;
995 | close(): Server;
996 | address(): { port: number; family: string; address: string; };
997 | addContext(hostName: string, credentials: {
998 | key: string;
999 | cert: string;
1000 | ca: string;
1001 | }): void;
1002 | maxConnections: number;
1003 | connections: number;
1004 | }
1005 |
1006 | export interface ClearTextStream extends stream.Duplex {
1007 | authorized: boolean;
1008 | authorizationError: Error;
1009 | getPeerCertificate(): any;
1010 | getCipher: {
1011 | name: string;
1012 | version: string;
1013 | };
1014 | address: {
1015 | port: number;
1016 | family: string;
1017 | address: string;
1018 | };
1019 | remoteAddress: string;
1020 | remotePort: number;
1021 | }
1022 |
1023 | export interface SecurePair {
1024 | encrypted: any;
1025 | cleartext: any;
1026 | }
1027 |
1028 | export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server;
1029 | export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream;
1030 | export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream;
1031 | export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream;
1032 | export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair;
1033 | }
1034 |
1035 | declare module "crypto" {
1036 | export interface CredentialDetails {
1037 | pfx: string;
1038 | key: string;
1039 | passphrase: string;
1040 | cert: string;
1041 | ca: any; //string | string array
1042 | crl: any; //string | string array
1043 | ciphers: string;
1044 | }
1045 | export interface Credentials { context?: any; }
1046 | export function createCredentials(details: CredentialDetails): Credentials;
1047 | export function createHash(algorithm: string): Hash;
1048 | export function createHmac(algorithm: string, key: string): Hmac;
1049 | interface Hash {
1050 | update(data: any, input_encoding?: string): Hash;
1051 | digest(encoding?: string): string;
1052 | }
1053 | interface Hmac {
1054 | update(data: any, input_encoding?: string): Hmac;
1055 | digest(encoding?: string): string;
1056 | }
1057 | export function createCipher(algorithm: string, password: any): Cipher;
1058 | export function createCipheriv(algorithm: string, key: any, iv: any): Cipher;
1059 | interface Cipher {
1060 | update(data: any, input_encoding?: string, output_encoding?: string): string;
1061 | final(output_encoding?: string): string;
1062 | setAutoPadding(auto_padding: boolean): void;
1063 | createDecipher(algorithm: string, password: any): Decipher;
1064 | createDecipheriv(algorithm: string, key: any, iv: any): Decipher;
1065 | }
1066 | interface Decipher {
1067 | update(data: any, input_encoding?: string, output_encoding?: string): void;
1068 | final(output_encoding?: string): string;
1069 | setAutoPadding(auto_padding: boolean): void;
1070 | }
1071 | export function createSign(algorithm: string): Signer;
1072 | interface Signer {
1073 | update(data: any): void;
1074 | sign(private_key: string, output_format: string): string;
1075 | }
1076 | export function createVerify(algorith: string): Verify;
1077 | interface Verify {
1078 | update(data: any): void;
1079 | verify(object: string, signature: string, signature_format?: string): boolean;
1080 | }
1081 | export function createDiffieHellman(prime_length: number): DiffieHellman;
1082 | export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman;
1083 | interface DiffieHellman {
1084 | generateKeys(encoding?: string): string;
1085 | computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string;
1086 | getPrime(encoding?: string): string;
1087 | getGenerator(encoding: string): string;
1088 | getPublicKey(encoding?: string): string;
1089 | getPrivateKey(encoding?: string): string;
1090 | setPublicKey(public_key: string, encoding?: string): void;
1091 | setPrivateKey(public_key: string, encoding?: string): void;
1092 | }
1093 | export function getDiffieHellman(group_name: string): DiffieHellman;
1094 | export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: string) => any): void;
1095 | export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer;
1096 | export function randomBytes(size: number): Buffer;
1097 | export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void;
1098 | export function pseudoRandomBytes(size: number): Buffer;
1099 | export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void;
1100 | }
1101 |
1102 | declare module "stream" {
1103 | import events = require("events");
1104 |
1105 | export interface ReadableOptions {
1106 | highWaterMark?: number;
1107 | encoding?: string;
1108 | objectMode?: boolean;
1109 | }
1110 |
1111 | export class Readable extends events.EventEmitter implements NodeJS.ReadableStream {
1112 | readable: boolean;
1113 | constructor(opts?: ReadableOptions);
1114 | _read(size: number): void;
1115 | read(size?: number): any;
1116 | setEncoding(encoding: string): void;
1117 | pause(): void;
1118 | resume(): void;
1119 | pipe(destination: T, options?: { end?: boolean; }): T;
1120 | unpipe(destination?: T): void;
1121 | unshift(chunk: string): void;
1122 | unshift(chunk: Buffer): void;
1123 | wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream;
1124 | push(chunk: any, encoding?: string): boolean;
1125 | }
1126 |
1127 | export interface WritableOptions {
1128 | highWaterMark?: number;
1129 | decodeStrings?: boolean;
1130 | }
1131 |
1132 | export class Writable extends events.EventEmitter implements NodeJS.WritableStream {
1133 | writable: boolean;
1134 | constructor(opts?: WritableOptions);
1135 | _write(data: Buffer, encoding: string, callback: Function): void;
1136 | _write(data: string, encoding: string, callback: Function): void;
1137 | write(buffer: Buffer, cb?: Function): boolean;
1138 | write(str: string, cb?: Function): boolean;
1139 | write(str: string, encoding?: string, cb?: Function): boolean;
1140 | end(): void;
1141 | end(buffer: Buffer, cb?: Function): void;
1142 | end(str: string, cb?: Function): void;
1143 | end(str: string, encoding?: string, cb?: Function): void;
1144 | }
1145 |
1146 | export interface DuplexOptions extends ReadableOptions, WritableOptions {
1147 | allowHalfOpen?: boolean;
1148 | }
1149 |
1150 | // Note: Duplex extends both Readable and Writable.
1151 | export class Duplex extends Readable implements NodeJS.ReadWriteStream {
1152 | writable: boolean;
1153 | constructor(opts?: DuplexOptions);
1154 | _write(data: Buffer, encoding: string, callback: Function): void;
1155 | _write(data: string, encoding: string, callback: Function): void;
1156 | write(buffer: Buffer, cb?: Function): boolean;
1157 | write(str: string, cb?: Function): boolean;
1158 | write(str: string, encoding?: string, cb?: Function): boolean;
1159 | end(): void;
1160 | end(buffer: Buffer, cb?: Function): void;
1161 | end(str: string, cb?: Function): void;
1162 | end(str: string, encoding?: string, cb?: Function): void;
1163 | }
1164 |
1165 | export interface TransformOptions extends ReadableOptions, WritableOptions {}
1166 |
1167 | // Note: Transform lacks the _read and _write methods of Readable/Writable.
1168 | export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream {
1169 | readable: boolean;
1170 | writable: boolean;
1171 | constructor(opts?: TransformOptions);
1172 | _transform(chunk: Buffer, encoding: string, callback: Function): void;
1173 | _transform(chunk: string, encoding: string, callback: Function): void;
1174 | _flush(callback: Function): void;
1175 | read(size?: number): any;
1176 | setEncoding(encoding: string): void;
1177 | pause(): void;
1178 | resume(): void;
1179 | pipe(destination: T, options?: { end?: boolean; }): T;
1180 | unpipe(destination?: T): void;
1181 | unshift(chunk: string): void;
1182 | unshift(chunk: Buffer): void;
1183 | wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream;
1184 | push(chunk: any, encoding?: string): boolean;
1185 | write(buffer: Buffer, cb?: Function): boolean;
1186 | write(str: string, cb?: Function): boolean;
1187 | write(str: string, encoding?: string, cb?: Function): boolean;
1188 | end(): void;
1189 | end(buffer: Buffer, cb?: Function): void;
1190 | end(str: string, cb?: Function): void;
1191 | end(str: string, encoding?: string, cb?: Function): void;
1192 | }
1193 |
1194 | export class PassThrough extends Transform {}
1195 | }
1196 |
1197 | declare module "util" {
1198 | export interface InspectOptions {
1199 | showHidden?: boolean;
1200 | depth?: number;
1201 | colors?: boolean;
1202 | customInspect?: boolean;
1203 | }
1204 |
1205 | export function format(format: any, ...param: any[]): string;
1206 | export function debug(string: string): void;
1207 | export function error(...param: any[]): void;
1208 | export function puts(...param: any[]): void;
1209 | export function print(...param: any[]): void;
1210 | export function log(string: string): void;
1211 | export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string;
1212 | export function inspect(object: any, options: InspectOptions): string;
1213 | export function isArray(object: any): boolean;
1214 | export function isRegExp(object: any): boolean;
1215 | export function isDate(object: any): boolean;
1216 | export function isError(object: any): boolean;
1217 | export function inherits(constructor: any, superConstructor: any): void;
1218 | }
1219 |
1220 | declare module "assert" {
1221 | function internal (value: any, message?: string): void;
1222 | module internal {
1223 | export class AssertionError implements Error {
1224 | name: string;
1225 | message: string;
1226 | actual: any;
1227 | expected: any;
1228 | operator: string;
1229 | generatedMessage: boolean;
1230 |
1231 | constructor(options?: {message?: string; actual?: any; expected?: any;
1232 | operator?: string; stackStartFunction?: Function});
1233 | }
1234 |
1235 | export function fail(actual?: any, expected?: any, message?: string, operator?: string): void;
1236 | export function ok(value: any, message?: string): void;
1237 | export function equal(actual: any, expected: any, message?: string): void;
1238 | export function notEqual(actual: any, expected: any, message?: string): void;
1239 | export function deepEqual(actual: any, expected: any, message?: string): void;
1240 | export function notDeepEqual(acutal: any, expected: any, message?: string): void;
1241 | export function strictEqual(actual: any, expected: any, message?: string): void;
1242 | export function notStrictEqual(actual: any, expected: any, message?: string): void;
1243 | export var throws: {
1244 | (block: Function, message?: string): void;
1245 | (block: Function, error: Function, message?: string): void;
1246 | (block: Function, error: RegExp, message?: string): void;
1247 | (block: Function, error: (err: any) => boolean, message?: string): void;
1248 | };
1249 |
1250 | export var doesNotThrow: {
1251 | (block: Function, message?: string): void;
1252 | (block: Function, error: Function, message?: string): void;
1253 | (block: Function, error: RegExp, message?: string): void;
1254 | (block: Function, error: (err: any) => boolean, message?: string): void;
1255 | };
1256 |
1257 | export function ifError(value: any): void;
1258 | }
1259 |
1260 | export = internal;
1261 | }
1262 |
1263 | declare module "tty" {
1264 | import net = require("net");
1265 |
1266 | export function isatty(fd: number): boolean;
1267 | export interface ReadStream extends net.Socket {
1268 | isRaw: boolean;
1269 | setRawMode(mode: boolean): void;
1270 | }
1271 | export interface WriteStream extends net.Socket {
1272 | columns: number;
1273 | rows: number;
1274 | }
1275 | }
1276 |
1277 | declare module "domain" {
1278 | import events = require("events");
1279 |
1280 | export class Domain extends events.EventEmitter {
1281 | run(fn: Function): void;
1282 | add(emitter: events.EventEmitter): void;
1283 | remove(emitter: events.EventEmitter): void;
1284 | bind(cb: (err: Error, data: any) => any): any;
1285 | intercept(cb: (data: any) => any): any;
1286 | dispose(): void;
1287 |
1288 | addListener(event: string, listener: Function): Domain;
1289 | on(event: string, listener: Function): Domain;
1290 | once(event: string, listener: Function): Domain;
1291 | removeListener(event: string, listener: Function): Domain;
1292 | removeAllListeners(event?: string): Domain;
1293 | }
1294 |
1295 | export function create(): Domain;
1296 | }
1297 |
--------------------------------------------------------------------------------