Skip to content

Commit

Permalink
project files
Browse files Browse the repository at this point in the history
  • Loading branch information
Shady Khalifa committed Aug 14, 2018
1 parent 0d32d64 commit 4177c59
Show file tree
Hide file tree
Showing 8 changed files with 9,132 additions and 3 deletions.
8,859 changes: 8,859 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 23 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
{
"name": "nest-emitter",
"version": "1.0.0",
"description": "Strongly Typed Event Emitter Module For Nestjs Framework",
"description": "Strongly Typed Eventemitter Module For Nestjs Framework",
"main": "index.js",
"scripts": {
"test": "jest --notify --config=jest.json"
"test": "jest --notify --config=jest.json",
"test:watch": "jest --watch --config=jest.json",
"test:coverage": "jest --config=jest.json --coverage --coverageDirectory=coverage",
"build": "gulp build && gulp move",
"build:lib": "gulp build --dist lib && cp -rf package.json lib && cp -rf README.md lib",
"npm:publish": "cd lib && npm publish"
},
"repository": {
"type": "git",
Expand All @@ -21,5 +26,20 @@
"bugs": {
"url": "https://github.com/shekohex/nest-emitter/issues"
},
"homepage": "https://github.com/shekohex/nest-emitter#readme"
"homepage": "https://github.com/shekohex/nest-emitter#readme",
"devDependencies": {
"@nestjs/common": "^5.0.0",
"@nestjs/core": "^5.0.0",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.0.0",
"@types/jest": "^23.3.1",
"@types/node": "^10.7.0",
"coveralls": "^3.0.2",
"gulp": "^3.9.1",
"gulp-sequence": "^1.0.0",
"gulp-typescript": "^5.0.0-alpha.3",
"jest": "^23.5.0",
"ts-node": "^7.0.1",
"typescript": "^3.0.1"
}
}
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const EVENT_EMITTER_TOKEN = '__event_emitter__';
Empty file added src/index.ts
Empty file.
15 changes: 15 additions & 0 deletions src/nest-emitter.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Module, DynamicModule, Global, Provider } from '@nestjs/common';
import { EVENT_EMITTER_TOKEN } from './constants';
import { StrictEventEmitter } from './strong-emitter';
@Global()
@Module({})
export class NestEmitterModule {
public static forRoot<TEventRecord, TEmitRecord = TEventRecord>(
emitter: NodeJS.Events,
): DynamicModule {
// FIXME: fix the types errors here !
const instance: StrictEventEmitter<NodeJS.Events, TEventRecord, TEmitRecord> = emitter;
const providers: Provider[] = [{ provide: EVENT_EMITTER_TOKEN, useValue: instance }];
return { module: NestEmitterModule, components: providers, exports: providers };
}
}
181 changes: 181 additions & 0 deletions src/strong-emitter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/**
* Thanks to Brian Terlson @bterlson <[email protected]>
* @author Brian Terlson @bterlson
* @see https://github.com/bterlson/strict-event-emitter-types
*/

// Returns any keys of TRecord with the type of TMatch
export type MatchingKeys<
TRecord,
TMatch,
K extends keyof TRecord = keyof TRecord
> = K extends (TRecord[K] extends TMatch ? K : never) ? K : never;

// Returns any property keys of Record with a void type
export type VoidKeys<Record> = MatchingKeys<Record, void>;

// TODO: Stash under a symbol key once TS compiler bug is fixed
export interface TypeRecord<T, U, V> {
' _emitterType'?: T;
' _eventsType'?: U;
' _emitType'?: V;
}

export type ReturnTypeOfMethod<T> = T extends (...args: any[]) => any ? ReturnType<T> : void;

export type ReturnTypeOfMethodIfExists<T, S extends string> = S extends keyof T
? ReturnTypeOfMethod<T[S]>
: void;

export type InnerEEMethodReturnType<T, TValue, FValue> = T extends (...args: any[]) => any
? ReturnType<T> extends void | undefined ? FValue : TValue
: FValue;

export type EEMethodReturnType<T, S extends string, TValue, FValue = void> = S extends keyof T
? InnerEEMethodReturnType<T[S], TValue, FValue>
: FValue;

type ListenerType<T> = [T] extends [(...args: infer U) => any] ? U : [T, ...any[]];

// EventEmitter method overrides
export type OverriddenMethods<
TEmitter,
TEventRecord,
TEmitRecord = TEventRecord,
EventVK extends VoidKeys<TEventRecord> = VoidKeys<TEventRecord>,
EventNVK extends Exclude<keyof TEventRecord, EventVK> = Exclude<keyof TEventRecord, EventVK>,
EmitVK extends VoidKeys<TEmitRecord> = VoidKeys<TEmitRecord>,
EmitNVK extends Exclude<keyof TEmitRecord, EmitVK> = Exclude<keyof TEmitRecord, EmitVK>
> = {
on<P extends EventNVK, T>(
this: T,
event: P,
listener: (...args: ListenerType<TEventRecord[P]>) => void,
): EEMethodReturnType<TEmitter, 'on', T>;

on<P extends EventVK, T>(
this: T,
event: P,
listener: () => void,
): EEMethodReturnType<TEmitter, 'on', T>;

addListener<P extends EventNVK, T>(
this: T,
event: P,
listener: (...args: ListenerType<TEventRecord[P]>) => void,
): EEMethodReturnType<TEmitter, 'addListener', T>;

addListener<P extends EventVK, T>(
this: T,
event: P,
listener: () => void,
): EEMethodReturnType<TEmitter, 'addListener', T>;

addEventListener<P extends EventNVK, T>(
this: T,
event: P,
listener: (...args: ListenerType<TEventRecord[P]>) => void,
): EEMethodReturnType<TEmitter, 'addEventListener', T>;

addEventListener<P extends EventVK, T>(
this: T,
event: P,
listener: () => void,
): EEMethodReturnType<TEmitter, 'addEventListener', T>;

removeListener<P extends EventNVK, T>(
this: T,
event: P,
listener: Function,
): EEMethodReturnType<TEmitter, 'removeListener', T>;

removeListener<P extends EventVK, T>(
this: T,
event: P,
listener: Function,
): EEMethodReturnType<TEmitter, 'removeListener', T>;

removeEventListener<P extends EventNVK, T>(
this: T,
event: P,
listener: Function,
): EEMethodReturnType<TEmitter, 'removeEventListener', T>;

removeEventListener<P extends EventVK, T>(
this: T,
event: P,
listener: Function,
): EEMethodReturnType<TEmitter, 'removeEventListener', T>;

once<P extends EventNVK, T>(
this: T,
event: P,
listener: (...args: ListenerType<TEventRecord[P]>) => void,
): EEMethodReturnType<TEmitter, 'once', T>;
once<P extends EventVK, T>(
this: T,
event: P,
listener: () => void,
): EEMethodReturnType<TEmitter, 'once', T>;

emit<P extends EmitNVK, T>(
this: T,
event: P,
...args: ListenerType<TEmitRecord[P]>
): EEMethodReturnType<TEmitter, 'emit', T>;

emit<P extends EmitVK, T>(this: T, event: P): EEMethodReturnType<TEmitter, 'emit', T>;
};

export type OverriddenKeys = keyof OverriddenMethods<any, any, any>;

export type StrictEventEmitter<
TEmitterType,
TEventRecord,
TEmitRecord = TEventRecord,
UnneededMethods extends Exclude<OverriddenKeys, keyof TEmitterType> = Exclude<
OverriddenKeys,
keyof TEmitterType
>,
NeededMethods extends Exclude<OverriddenKeys, UnneededMethods> = Exclude<
OverriddenKeys,
UnneededMethods
>
> =
// Store the type parameters we've instantiated with so we can refer to them later
TypeRecord<TEmitterType, TEventRecord, TEmitRecord> &
// Pick all the methods on the original type we aren't going to override
Pick<TEmitterType, Exclude<keyof TEmitterType, OverriddenKeys>> &
// Finally, pick the needed overrides (taking care not to add an override for a method
// that doesn't exist)
Pick<OverriddenMethods<TEmitterType, TEventRecord, TEmitRecord>, NeededMethods>;

export type NoUndefined<T> = T extends undefined ? never : T;

export type StrictBroadcast<
TEmitter extends TypeRecord<any, any, any>,
TEmitRecord extends NoUndefined<TEmitter[' _emitType']> = NoUndefined<TEmitter[' _emitType']>,
VK extends VoidKeys<TEmitRecord> = VoidKeys<TEmitRecord>,
NVK extends Exclude<keyof TEmitRecord, VK> = Exclude<keyof TEmitRecord, VK>
> = {
<E extends NVK>(event: E, request: TEmitRecord[E]): any;
<E extends VK>(event: E): any;
};

export type EventNames<
TEmitter extends TypeRecord<any, any, any>,
TEventRecord extends NoUndefined<TEmitter[' _eventsType']> = NoUndefined<
TEmitter[' _eventsType']
>,
TEmitRecord extends NoUndefined<TEmitter[' _emitType']> = NoUndefined<TEmitter[' _emitType']>
> = keyof TEmitRecord | keyof TEventRecord;

export type OnEventNames<
TEmitter extends TypeRecord<any, any, any>,
TEventRecord extends NoUndefined<TEmitter[' _eventsType']> = NoUndefined<TEmitter[' _eventsType']>
> = keyof TEventRecord;

export type EmitEventNames<
TEmitter extends TypeRecord<any, any, any>,
TEmitRecord extends NoUndefined<TEmitter[' _emitType']> = NoUndefined<TEmitter[' _emitType']>
> = keyof TEmitRecord;
24 changes: 24 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"declaration": true,
"noUnusedLocals": true,
"strictNullChecks": true,
"pretty": true,
"noImplicitReturns": true,
"noUnusedParameters": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "build",
"preserveConstEnums": true,
"rootDir": "./src",
"baseUrl": ".",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"sourceMap": true,
"target": "es6",
"typeRoots": ["node_modules/@types"],
"lib": ["es7"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "src/**/*.spec.ts"]
}
29 changes: 29 additions & 0 deletions tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"defaultSeverity": "error",
"extends": ["tslint:recommended"],
"jsRules": {
"no-unused-expression": true
},
"rules": {
"eofline": false,
"quotemark": [true, "single"],
"indent": false,
"ordered-imports": [false],
"max-line-length": [true, 100],
"member-ordering": [false],
"curly": false,
"interface-name": [false],
"array-type": [false],
"no-empty-interface": false,
"no-empty": false,
"arrow-parens": false,
"object-literal-sort-keys": false,
"no-unused-expression": false,
"max-classes-per-file": [false],
"ban-types": false,
"variable-name": [false],
"one-line": [false],
"one-variable-per-declaration": [false]
},
"rulesDirectory": []
}

0 comments on commit 4177c59

Please sign in to comment.