Adding Rsx and decorator
This commit is contained in:
parent
d18601132e
commit
9b6788b47b
@ -114,7 +114,7 @@ export function getType(node: Node, inputType: Type, text: string) {
|
||||
let simplifiedType = '';
|
||||
let simplifiedSubType = '';
|
||||
let typeImports: { path: string, type: string }[] = [];
|
||||
|
||||
|
||||
// Test if the Type is a Base-Type.
|
||||
if ((inputType.compilerType as any).intrinsicName) {
|
||||
// Basic Type.
|
||||
@ -207,7 +207,7 @@ export function isPropOfType(prop: PropertyDeclaration, reqType: string, caseSen
|
||||
* @param prop The Property Declaration.
|
||||
*/
|
||||
export function getPropertyDescription(prop: PropertyDeclaration) {
|
||||
|
||||
|
||||
return Object.assign(
|
||||
// Use the Modifiers
|
||||
getModifiers(prop),
|
||||
@ -232,7 +232,7 @@ export function getMatchingProperties(cl: ClassDeclaration, reqType: string, cas
|
||||
return cl.getProperties()
|
||||
// Firstly Filter the Properties, that they match the requested Type.
|
||||
.filter(prop => isPropOfType(
|
||||
prop,
|
||||
prop,
|
||||
reqType,
|
||||
caseSensitive))
|
||||
// Instead of returning the Property Declaration, return the
|
||||
@ -257,7 +257,7 @@ export function getDecorators(declaration: MethodDeclaration | PropertyDeclarati
|
||||
}
|
||||
|
||||
let decoratorSettings: { [index: string]: any }[] = [];
|
||||
|
||||
|
||||
let decorators: Decorator[] = declaration.getDecorators()
|
||||
.filter(usedDecorator => {
|
||||
let name = usedDecorator.getName();
|
||||
@ -285,9 +285,9 @@ export function getDecorators(declaration: MethodDeclaration | PropertyDeclarati
|
||||
if (typeof aliasToOriginal[name] === 'string') {
|
||||
return decorator === aliasToOriginal[name]
|
||||
}
|
||||
|
||||
|
||||
return decorator === name;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
declaration,
|
||||
@ -340,7 +340,7 @@ function getMethodInfo(declaration: MethodDeclaration) {
|
||||
originalCode: parameter.getText(),
|
||||
// The Index of the Parameter
|
||||
index,
|
||||
},
|
||||
},
|
||||
getType(
|
||||
parameter.getTypeNode(),
|
||||
parameter.getType(),
|
||||
@ -389,11 +389,11 @@ export function getModifiers(declaration: MethodDeclaration | PropertyDeclaratio
|
||||
if ((declaration as MethodDeclaration).getOverloads) {
|
||||
modifiers = (declaration as MethodDeclaration).getOverloads().map(overload => dict[overload.getName()]);
|
||||
|
||||
// Handle Properties
|
||||
// Handle Properties
|
||||
} else if ((declaration as PropertyDeclaration).getCombinedModifierFlags) {
|
||||
modifiers = dict[(declaration as PropertyDeclaration).getCombinedModifierFlags()];
|
||||
}
|
||||
|
||||
|
||||
// If nothing is provided => Defaults to public
|
||||
if (modifiers.length === 0) {
|
||||
modifiers.push('public')
|
||||
@ -432,7 +432,7 @@ const sharedMethods = injectedClasses[0].getMethods()
|
||||
const parsedMethods = sharedMethods.map(methodObject => getMethodInfo(methodObject.declaration as MethodDeclaration));
|
||||
|
||||
// Get the Properties
|
||||
const sharedObservables = getMatchingProperties(injectedClasses[0], 'IObservable', false)
|
||||
const sharedObservables = getMatchingProperties(injectedClasses[0], 'NopeObersvable', false)
|
||||
.filter(property =>
|
||||
property.isPublic &&
|
||||
getDecorators(property.declaration, 'inject', importMapping.aliasToOriginal, false, false)
|
||||
|
88
lib/decorators.ts
Normal file
88
lib/decorators.ts
Normal file
@ -0,0 +1,88 @@
|
||||
// Symbols for the Property Registery:
|
||||
const _registedMethods_ = Symbol('_registedMethods_');
|
||||
const _registedParams_ = Symbol('_registedParams_');
|
||||
|
||||
// Interfaces for the Class
|
||||
export interface IExportApiParameters {
|
||||
url: string,
|
||||
}
|
||||
|
||||
export interface IExportMethodParameters {
|
||||
url?: string,
|
||||
}
|
||||
|
||||
export interface IExportPropertyParameters {
|
||||
url?: string,
|
||||
readonly?: boolean
|
||||
}
|
||||
|
||||
export const unicorn = {
|
||||
test: []
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorator used to export a Class API over openAPI
|
||||
* @param options
|
||||
*/
|
||||
export function eportApi(options: IExportApiParameters) {
|
||||
return function <T extends { new(...args: any[]): {} }>(Base: T) {
|
||||
return class extends Base {
|
||||
constructor(...args: any[]) {
|
||||
super(...args);
|
||||
|
||||
// Adding the Path Option.
|
||||
(this as any).__path = options.url;
|
||||
|
||||
// extract the Registered Methods of the Class.
|
||||
const registedMethods = Base.prototype[_registedMethods_] as Map<string, IExportMethodParameters>;
|
||||
const registedParams = Base.prototype[_registedParams_] as Map<string, IExportPropertyParameters>;
|
||||
|
||||
// Online if they are present, iterate over them
|
||||
if (registedMethods) {
|
||||
registedMethods.forEach((options, methodName) => {
|
||||
|
||||
// Provide the code that should be exectuted for every
|
||||
// Registered Function
|
||||
unicorn.test.push([methodName, options]);
|
||||
console.log(unicorn.test)
|
||||
});
|
||||
}
|
||||
|
||||
// Online if they are present, iterate over them
|
||||
if (registedParams) {
|
||||
registedParams.forEach((options, parameterName) => {
|
||||
|
||||
// Provide the code that should be exectuted for every
|
||||
// Registered Function
|
||||
unicorn.test.push([parameterName, options]);
|
||||
console.log(unicorn.test)
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorator, used to export the Method.
|
||||
* @param options
|
||||
*/
|
||||
export function exportMethod(options: IExportMethodParameters = {}) {
|
||||
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
target[_registedMethods_] = target[_registedMethods_] || new Map<string, IExportMethodParameters>();
|
||||
// Here we just add some information that class decorator will use
|
||||
target[_registedMethods_].set(propertyKey, options);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorator, will create a POST and GET api for the Parameter.
|
||||
* @param options
|
||||
*/
|
||||
export function exportProperty(options: IExportPropertyParameters = {}) {
|
||||
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
target[_registedParams_] = target[_registedParams_] || new Map<string, IExportPropertyParameters>();
|
||||
// Here we just add some information that class decorator will use
|
||||
target[_registedParams_].set(propertyKey, options);
|
||||
};
|
||||
}
|
122
lib/observables/nopeObservable.ts
Normal file
122
lib/observables/nopeObservable.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import { BehaviorSubject, CompletionObserver, ErrorObserver, NextObserver, Subscription } from 'rxjs';
|
||||
|
||||
export interface nopeObserver {
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
export declare type NopePartialObserver<T> = NextObserver<T> & nopeObserver | ErrorObserver<T> & nopeObserver | CompletionObserver<T> & nopeObserver;
|
||||
|
||||
/**
|
||||
* RsJX based Observable.
|
||||
*
|
||||
* Contains additional Functionalities like:
|
||||
* - property with the current value
|
||||
* - function to publish values. (wrapper for next)
|
||||
* - enables performing a subscription with synced call or a immediate call.
|
||||
*/
|
||||
export class nopeObservable<T> extends BehaviorSubject<T> {
|
||||
|
||||
protected _currentValue: T;
|
||||
|
||||
/**
|
||||
* Getter for the Current Value.
|
||||
*/
|
||||
public get currentValue(): T {
|
||||
return this._currentValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Current value.
|
||||
*/
|
||||
public set currentValue(value: T) {
|
||||
this.next(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a custom Observable.
|
||||
* @param initialValue
|
||||
*/
|
||||
constructor(initialValue: T) {
|
||||
super(initialValue);
|
||||
|
||||
const _this = this;
|
||||
this.subscribe((data) => {
|
||||
_this._currentValue = data;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to Publish a Value to the stream.
|
||||
* @param value The Value.
|
||||
*/
|
||||
publish(value: T) {
|
||||
this.next(value);
|
||||
}
|
||||
|
||||
subscribe(observer?: NopePartialObserver<T>, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||
/** @deprecated Use an observer instead of a complete callback */
|
||||
subscribe(next: null | undefined, error: null | undefined, complete: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||
/** @deprecated Use an observer instead of an error callback */
|
||||
subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||
/** @deprecated Use an observer instead of a complete callback */
|
||||
subscribe(next: (value: T) => void, error: null | undefined, complete: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||
|
||||
// Underlying implementation
|
||||
subscribe(observerOrNext?, errorOrcbMode?, complete?: () => void, cbMode?: 'sync' | 'immediate'): Subscription {
|
||||
// The first argument could be an Observer or Callback (Depricated) and the callbacks for complete and error
|
||||
let _cbMode = cbMode;
|
||||
let _error = errorOrcbMode;
|
||||
let _complete = complete;
|
||||
let _observerOrNext = observerOrNext;
|
||||
|
||||
// If the first argument is an Observer => the second argument must be the cbMode
|
||||
if (typeof observerOrNext === 'object') {
|
||||
// Adapt the Callback
|
||||
_cbMode = errorOrcbMode || 'sync';
|
||||
// The error function must be undefined
|
||||
_error = undefined;
|
||||
}
|
||||
|
||||
// Test the cbMode
|
||||
if (_cbMode === 'immediate') {
|
||||
switch (typeof observerOrNext) {
|
||||
case 'object':
|
||||
if ((observerOrNext as NopePartialObserver<T>).next) {
|
||||
const orgFunc = observerOrNext.next;
|
||||
observerOrNext.next = (v: T) => setImmediate(() => {
|
||||
if ((observerOrNext as NopePartialObserver<T>).active) {
|
||||
orgFunc.call(observerOrNext, v);
|
||||
}
|
||||
});
|
||||
}
|
||||
if ((observerOrNext as NopePartialObserver<T>).error) {
|
||||
const orgFunc = observerOrNext.next;
|
||||
observerOrNext.next = (v: T) => setImmediate(() => {
|
||||
if ((observerOrNext as NopePartialObserver<T>).active) {
|
||||
orgFunc.call(observerOrNext, v);
|
||||
}
|
||||
});
|
||||
} if ((observerOrNext as NopePartialObserver<T>).complete) {
|
||||
const orgFunc = observerOrNext.next;
|
||||
observerOrNext.next = (v: T) => setImmediate(() => {
|
||||
if ((observerOrNext as NopePartialObserver<T>).active) {
|
||||
orgFunc.call(observerOrNext, v);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'function':
|
||||
_observerOrNext = typeof observerOrNext === 'function' ? (_value: T) => setImmediate(observerOrNext, _value) : observerOrNext;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_error = typeof errorOrcbMode === 'function' ? (_errorValue: any) => setImmediate(errorOrcbMode, _errorValue) : undefined;
|
||||
_complete = typeof complete === 'function' ? () => setImmediate(complete) : undefined;
|
||||
}
|
||||
|
||||
return super.subscribe(_observerOrNext, _error, _complete);
|
||||
}
|
||||
}
|
0
lib/pubSub/nopePubSubSystem.ts
Normal file
0
lib/pubSub/nopePubSubSystem.ts
Normal file
8
package-lock.json
generated
8
package-lock.json
generated
@ -5781,6 +5781,14 @@
|
||||
"aproba": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz",
|
||||
"integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
|
@ -36,6 +36,7 @@
|
||||
"react": "^16.13.1",
|
||||
"react-bootstrap": "^1.3.0",
|
||||
"react-dom": "^16.13.1",
|
||||
"rxjs": "^6.6.2",
|
||||
"ts-morph": "^7.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
28
test/testDecorators.ts
Normal file
28
test/testDecorators.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { eportApi, exportMethod, exportProperty } from "../lib/decorators";
|
||||
|
||||
@eportApi({
|
||||
url: 'icemaker'
|
||||
})
|
||||
export class Icemaker {
|
||||
|
||||
toppings = [];
|
||||
sugar = 0;
|
||||
|
||||
@exportMethod()
|
||||
addTopping(topping) {
|
||||
this.toppings.push(topping);
|
||||
}
|
||||
|
||||
@exportMethod()
|
||||
addSugar() {
|
||||
this.sugar++;
|
||||
}
|
||||
|
||||
@exportProperty()
|
||||
name: string;
|
||||
|
||||
}
|
||||
|
||||
const instance = new Icemaker();
|
||||
instance.addTopping('caramel')
|
||||
console.log(instance)
|
21
test/testNopeObservable.ts
Normal file
21
test/testNopeObservable.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { nopeObservable } from "../lib/observables/nopeObservable";
|
||||
|
||||
const observable = new nopeObservable(0);
|
||||
const subscriptionSmaller = observable.pipe(
|
||||
filter((v, idx) => v < 10)
|
||||
).subscribe((v) => {
|
||||
console.log('smaller 10:', v)
|
||||
});
|
||||
|
||||
const subscriptionGreater = observable.pipe(
|
||||
filter((v, idx) => v > 10)
|
||||
).subscribe((v) => {
|
||||
console.log('greater 10: ', v)
|
||||
});
|
||||
|
||||
let i = 1;
|
||||
while (i < 20) {
|
||||
observable.currentValue = i++;
|
||||
console.log('current', observable.currentValue);
|
||||
}
|
@ -7,29 +7,30 @@
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"allowUnusedLabels": true,
|
||||
"charset": "utf-8",
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"noFallthroughCasesInSwitch": false,
|
||||
"noImplicitReturns": true,
|
||||
"outDir": "./dist",
|
||||
"pretty": false,
|
||||
"removeComments": true,
|
||||
"rootDir": "./",
|
||||
"stripInternal": true
|
||||
"allowUnusedLabels": true,
|
||||
"charset": "utf-8",
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"noFallthroughCasesInSwitch": false,
|
||||
"noImplicitReturns": true,
|
||||
"outDir": "./dist",
|
||||
"pretty": false,
|
||||
"removeComments": true,
|
||||
"rootDir": "./",
|
||||
"stripInternal": true
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"helpers",
|
||||
"api",
|
||||
"src"
|
||||
"src",
|
||||
"test"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"pages",
|
||||
".next"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user