|
|
@@ -1,5 +1,6 @@ |
|
|
|
import {Endpoint, EndpointOperations} from './endpoint'; |
|
|
|
import {Operation} from './operation'; |
|
|
|
import {NamedSet, PredicateMap} from './common'; |
|
|
|
|
|
|
|
export interface BaseAppState { |
|
|
|
endpoints: unknown; |
|
|
@@ -20,8 +21,8 @@ export type AppOperations<T extends App> = ( |
|
|
|
|
|
|
|
export interface App<AppName extends string = string, AppState extends BaseAppState = BaseAppState> { |
|
|
|
name: AppName; |
|
|
|
operations: Set<Operation>; |
|
|
|
endpoints: Set<Endpoint>; |
|
|
|
endpoints: NamedSet<Endpoint>; |
|
|
|
operations: NamedSet<Operation>; |
|
|
|
operation<NewOperation extends Operation>(newOperation: NewOperation): App< |
|
|
|
AppName, |
|
|
|
{ |
|
|
@@ -48,39 +49,28 @@ interface AppParams<Name extends string = string> { |
|
|
|
|
|
|
|
class AppInstance<Params extends AppParams, State extends BaseAppState> implements App<Params['name'], State> { |
|
|
|
readonly name: Params['name']; |
|
|
|
readonly endpoints: Set<Endpoint>; |
|
|
|
readonly operations: Set<Operation>; |
|
|
|
readonly endpoints: NamedSet<Endpoint>; |
|
|
|
readonly operations: NamedSet<Operation>; |
|
|
|
|
|
|
|
constructor(params: Params) { |
|
|
|
this.name = params.name; |
|
|
|
this.endpoints = new Set<Endpoint>(); |
|
|
|
this.operations = new Set<Operation>(); |
|
|
|
this.endpoints = new Map<Endpoint['name'], Endpoint>(); |
|
|
|
this.operations = new PredicateMap<Operation['name'], Operation>((newOperation, s) => ( |
|
|
|
s.method === newOperation.method |
|
|
|
)); |
|
|
|
} |
|
|
|
|
|
|
|
operation<NewOperation extends Operation>(newOperation: NewOperation) { |
|
|
|
const existingOperations = Array.from(this.operations); |
|
|
|
|
|
|
|
if (!existingOperations.some((s) => ( |
|
|
|
s.name === newOperation.name |
|
|
|
&& s.method === newOperation.method |
|
|
|
))) { |
|
|
|
this.operations.add(newOperation); |
|
|
|
} |
|
|
|
|
|
|
|
this.operations.set(newOperation.name, newOperation); |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
endpoint<NewEndpoint extends Endpoint = Endpoint>(newEndpoint: NewEndpoint) { |
|
|
|
const existingEndpoints = Array.from(this.endpoints); |
|
|
|
|
|
|
|
if (existingEndpoints.some((s) => ( |
|
|
|
s.name === newEndpoint.name |
|
|
|
))) { |
|
|
|
if (this.endpoints.has(newEndpoint.name)) { |
|
|
|
throw new Error(`Cannot add duplicate endpoint with name: ${newEndpoint.name}`); |
|
|
|
} |
|
|
|
|
|
|
|
this.endpoints.add(newEndpoint); |
|
|
|
|
|
|
|
this.endpoints.set(newEndpoint.name, newEndpoint); |
|
|
|
return this; |
|
|
|
} |
|
|
|
} |
|
|
|