Compare commits

...

84 Commits

Author SHA1 Message Date
d791eca5e8 2.0.6 2022-05-29 21:01:57 +02:00
63c6dac8fa fix(core): update 2022-05-29 21:01:56 +02:00
c2c1dee427 2.0.5 2022-05-29 20:43:30 +02:00
4ae90a5cf6 fix(core): update 2022-05-29 20:43:29 +02:00
803d4d2894 2.0.4 2022-05-29 20:38:47 +02:00
fcc75af1ff fix(core): update 2022-05-29 20:38:46 +02:00
0e3bb07a69 2.0.3 2022-03-29 14:50:40 +02:00
c90aa07ace fix(core): update 2022-03-29 14:50:39 +02:00
362f3f1bd0 2.0.2 2022-03-29 10:50:27 +02:00
12f7348fec fix(core): update 2022-03-29 10:50:26 +02:00
7d478c400e 2.0.1 2022-03-29 09:48:47 +02:00
ab75cf8720 fix(core): update 2022-03-29 09:48:47 +02:00
f7ef8a6828 2.0.0 2022-03-24 21:56:03 +01:00
ece2803d12 1.0.66 2022-03-24 20:02:59 +01:00
2384fc1b76 fix(core): update 2022-03-24 20:02:58 +01:00
309c282379 1.0.65 2021-11-10 13:14:41 +01:00
90c616ca41 fix(core): update 2021-11-10 13:14:40 +01:00
57177074d0 1.0.64 2021-11-10 01:41:55 +01:00
d3b5c802cd fix(core): update 2021-11-10 01:41:55 +01:00
8e64353026 1.0.63 2021-11-07 23:46:33 +01:00
290746c191 fix(core): update 2021-11-07 23:46:32 +01:00
abefef8d7c 1.0.62 2021-11-07 15:45:18 +01:00
81b042e670 fix(core): update 2021-11-07 15:45:17 +01:00
6e3ee011a9 1.0.61 2021-11-07 15:40:02 +01:00
9b5ff4b1b5 fix(core): update 2021-11-07 15:40:01 +01:00
556ba6cb30 1.0.60 2021-11-07 15:26:13 +01:00
7321ac680d fix(core): update 2021-11-07 15:26:12 +01:00
2fd8219849 1.0.59 2021-11-07 14:56:48 +01:00
ea56e2218f fix(types): better types for TypedRouter.routeAndAddResponse 2021-11-07 14:56:48 +01:00
9a07817914 1.0.58 2021-09-27 12:15:47 +02:00
9bc83b0d1e 1.0.57 2021-09-27 12:14:43 +02:00
98c638e1ab fix(core): update 2021-09-27 12:14:43 +02:00
575ddd36a0 1.0.56 2020-12-21 00:01:06 +00:00
52b731ce68 fix(core): update 2020-12-21 00:00:56 +00:00
3f6e81b2aa 1.0.55 2020-12-18 18:14:30 +00:00
adad99f6bf fix(core): update 2020-12-18 18:14:29 +00:00
2771c92e85 1.0.54 2020-10-09 10:25:29 +00:00
440ea9ff3a fix(core): update 2020-10-09 10:25:28 +00:00
51bb8dfa90 1.0.53 2020-10-06 21:33:47 +00:00
ce3bfa01b4 fix(core): update 2020-10-06 21:33:46 +00:00
265109fca6 1.0.52 2020-10-06 17:37:07 +00:00
8bfd4d8866 fix(core): update 2020-10-06 17:37:06 +00:00
785f247027 1.0.51 2020-10-06 17:28:00 +00:00
3f3f488dc4 fix(core): update 2020-10-06 17:27:59 +00:00
0241eda296 1.0.50 2020-10-06 16:37:25 +00:00
66722759af fix(core): update 2020-10-06 16:37:25 +00:00
e9fad241ee 1.0.49 2020-10-06 15:50:12 +00:00
34face164f fix(core): update 2020-10-06 15:50:12 +00:00
f7bf366962 1.0.48 2020-10-06 15:05:29 +00:00
046059d228 fix(core): update 2020-10-06 15:05:29 +00:00
78e8171a6a 1.0.47 2020-10-06 14:29:50 +00:00
c97a535035 fix(core): update 2020-10-06 14:29:49 +00:00
dcf198787a 1.0.46 2020-09-29 15:51:06 +00:00
a1e0ebd658 fix(core): update 2020-09-29 15:51:05 +00:00
8bf0a71266 1.0.45 2020-09-14 08:28:08 +00:00
e499612ecb fix(core): update 2020-09-14 08:28:07 +00:00
e049899599 1.0.44 2020-09-14 08:22:28 +00:00
37f4d34e7a fix(core): update 2020-09-14 08:22:27 +00:00
ca2e6895ce 1.0.43 2020-07-30 09:27:31 +00:00
ccc5c33656 fix(core): update 2020-07-30 09:27:30 +00:00
546f7f4fc7 1.0.42 2020-07-30 08:46:45 +00:00
8536060ce4 fix(core): update 2020-07-30 08:46:45 +00:00
e57c332d82 1.0.41 2020-07-26 13:48:57 +00:00
df87c6c75e fix(core): update 2020-07-26 13:48:57 +00:00
53a4375545 1.0.40 2020-07-14 16:37:45 +00:00
88022ea14b fix(core): update 2020-07-14 16:37:44 +00:00
2a681644eb 1.0.39 2020-07-14 02:20:15 +00:00
e2708c5bb3 fix(core): update 2020-07-14 02:20:15 +00:00
8c7a71ddce 1.0.38 2020-06-25 23:53:06 +00:00
5acbf420ae fix(core): update 2020-06-25 23:53:05 +00:00
5d673799cc 1.0.37 2020-06-16 22:25:20 +00:00
bb0271e021 fix(core): update 2020-06-16 22:25:20 +00:00
718feb74ae 1.0.36 2020-06-16 22:23:32 +00:00
82aa80d7d9 fix(core): update 2020-06-16 22:23:31 +00:00
67831cd37f 1.0.35 2020-06-16 22:00:39 +00:00
777817b588 fix(core): update 2020-06-16 22:00:38 +00:00
c7dd378eb3 1.0.34 2020-06-16 15:17:47 +00:00
9d9f67c91a fix(core): update 2020-06-16 15:17:46 +00:00
82cc8c29e1 1.0.33 2020-06-16 15:17:24 +00:00
625b1c6871 fix(core): update 2020-06-16 15:17:23 +00:00
e149b5a5f1 1.0.32 2020-06-16 15:03:11 +00:00
2879fb8cee fix(core): update 2020-06-16 15:03:10 +00:00
f98c2cc5e7 1.0.31 2020-06-15 16:52:56 +00:00
567845bc64 fix(core): update 2020-06-15 16:52:56 +00:00
15 changed files with 9170 additions and 3332 deletions

View File

@ -19,23 +19,35 @@ mirror:
stage: security
script:
- npmci git mirror
only:
- tags
tags:
- lossless
- docker
- notpriv
audit:
auditProductionDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --production --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=prod --production
tags:
- docker
auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high
- npmci command npm audit --audit-level=high --only=dev
tags:
- lossless
- docker
- notpriv
allow_failure: true
# ====================
# test stage
@ -50,9 +62,7 @@ testStable:
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- lossless
- docker
- priv
testBuild:
stage: test
@ -63,9 +73,7 @@ testBuild:
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- lossless
- docker
- notpriv
release:
stage: release
@ -85,6 +93,8 @@ release:
codequality:
stage: metadata
allow_failure: true
only:
- tags
script:
- npmci command npm install -g tslint typescript
- npmci npm prepare

View File

@ -15,7 +15,7 @@
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm"]
"enum": ["website", "element", "service", "npm", "wcc"]
}
}
}

11993
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,36 @@
{
"name": "@apiglobal/typedrequest",
"version": "1.0.30",
"version": "2.0.6",
"private": false,
"description": "make typed requests towards apis",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"type": "module",
"author": "Lossless GmbH",
"license": "MIT",
"scripts": {
"test": "(tstest test/)",
"build": "(tsbuild --web)",
"build": "(tsbuild --web --allowimplicitany && tsbundle npm)",
"format": "(gitzone format)"
},
"devDependencies": {
"@gitzone/tsbuild": "^2.1.24",
"@gitzone/tstest": "^1.0.33",
"@pushrocks/smartexpress": "^3.0.69",
"@pushrocks/tapbundle": "^3.2.1",
"@types/node": "^14.0.13",
"tslint": "^6.1.2",
"@gitzone/tsbuild": "^2.1.63",
"@gitzone/tsbundle": "^2.0.4",
"@gitzone/tstest": "^1.0.71",
"@pushrocks/smartenv": "^5.0.2",
"@pushrocks/smartexpress": "^4.0.5",
"@pushrocks/tapbundle": "^5.0.3",
"@types/node": "^17.0.36",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0"
},
"dependencies": {
"@apiglobal/typedrequest-interfaces": "^1.0.13",
"@pushrocks/lik": "^4.0.13",
"@pushrocks/smartdelay": "^2.0.9",
"@pushrocks/smartjson": "^3.0.10",
"@pushrocks/smartrequest": "^1.1.47"
"@apiglobal/typedrequest-interfaces": "^1.0.15",
"@pushrocks/isounique": "^1.0.5",
"@pushrocks/lik": "^6.0.0",
"@pushrocks/smartdelay": "^2.0.13",
"@pushrocks/smartpromise": "^3.1.7",
"@pushrocks/webrequest": "^3.0.6"
},
"files": [
"ts/**/*",
@ -39,5 +43,8 @@
"cli.js",
"npmextra.json",
"readme.md"
],
"browserslist": [
"last 1 chrome versions"
]
}

View File

@ -25,10 +25,77 @@ Platform support | [![Supports Windows 10](https://badgen.net/badge/supports%20W
## Usage
## Contribution
Use TypeScript for best in class intellisense.
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
```typescript
import { expect, tap } from '@pushrocks/tapbundle';
import * as smartexpress from '@pushrocks/smartexpress';
import * as typedrequest from '../ts/index';
let testServer: smartexpress.Server;
let testTypedHandler: typedrequest.TypedHandler<ITestReqRes>;
// lets define an interface
interface ITestReqRes {
method: 'hi';
request: {
name: string;
};
response: {
surname: string;
};
}
tap.test('should create a typedHandler', async () => {
// lets use the interface in a TypedHandler
testTypedHandler = new typedrequest.TypedHandler<ITestReqRes>('hi', async (reqArg) => {
return {
surname: 'wow',
};
});
});
tap.test('should spawn a server to test with', async () => {
testServer = new smartexpress.Server({
cors: true,
forceSsl: false,
port: 3000,
});
});
tap.test('should define a testHandler', async () => {
const testTypedRouter = new typedrequest.TypedRouter(); // typed routers can broker typedrequests between handlers
testTypedRouter.addTypedHandler(testTypedHandler);
testServer.addRoute(
'/testroute',
new smartexpress.HandlerTypedRouter(testTypedRouter as any) // the "any" is testspecific, since smartexpress ships with its own version of typedrequest.
);
});
tap.test('should start the server', async () => {
await testServer.start();
});
tap.test('should fire a request', async () => {
const typedRequest = new typedrequest.TypedRequest<ITestReqRes>(
'http://localhost:3000/testroute',
'hi'
);
const response = await typedRequest.fire({
name: 'really',
});
console.log('this is the response:');
console.log(response);
expect(response.surname).to.equal('wow');
});
tap.test('should end the server', async () => {
await testServer.stop();
});
tap.start();
```
## Contribution

39
test/test.browser.ts Normal file
View File

@ -0,0 +1,39 @@
import { expect, tap } from '@pushrocks/tapbundle';
import * as typedrequest from '../ts/index.js';
let testTypedHandler: typedrequest.TypedHandler<ITestReqRes>;
// lets define an interface
interface ITestReqRes {
method: 'hi';
request: {
name: string;
};
response: {
surname: string;
};
}
tap.test('should create a typedHandler', async () => {
// lets use the interface in a TypedHandler
testTypedHandler = new typedrequest.TypedHandler<ITestReqRes>('hi', async (reqArg) => {
return {
surname: 'wow',
};
});
});
tap.test('should define a testHandler', async () => {
const testTypedRouter = new typedrequest.TypedRouter(); // typed routers can broker typedrequests between handlers
testTypedRouter.addTypedHandler(testTypedHandler);
});
tap.test('should fire a request', async () => {
const typedRequest = new typedrequest.TypedRequest<ITestReqRes>(
'http://localhost:3000/testroute',
'hi'
);
});
tap.start();

View File

@ -1,11 +1,12 @@
import { expect, tap } from '@pushrocks/tapbundle';
import * as smartexpress from '@pushrocks/smartexpress';
import * as typedrequest from '../ts/index';
import * as typedrequest from '../ts/index.js';
let testServer: smartexpress.Server;
let testTypedHandler: typedrequest.TypedHandler<ITestReqRes>;
// lets define an interface
interface ITestReqRes {
method: 'hi';
request: {
@ -17,9 +18,10 @@ interface ITestReqRes {
}
tap.test('should create a typedHandler', async () => {
testTypedHandler = new typedrequest.TypedHandler<ITestReqRes>('hi', async reqArg => {
// lets use the interface in a TypedHandler
testTypedHandler = new typedrequest.TypedHandler<ITestReqRes>('hi', async (reqArg) => {
return {
surname: 'wow'
surname: 'wow',
};
});
});
@ -28,17 +30,16 @@ tap.test('should spawn a server to test with', async () => {
testServer = new smartexpress.Server({
cors: true,
forceSsl: false,
port: 3000
port: 3000,
});
});
tap.test('should define a testHandler', async () => {
const testTypedRouter = new typedrequest.TypedRouter(); // typed routers can broker typedrequests between handlers
testTypedRouter.addTypedHandler(testTypedHandler);
testServer.addRoute(
'/testroute',
new smartexpress.Handler('POST', async (req, res) => {
console.log(req.body);
res.json(await testTypedHandler.addResponse(req.body));
})
new smartexpress.HandlerTypedRouter(testTypedRouter as any) // the "any" is testspecific, since smartexpress ships with its own version of typedrequest.
);
});
@ -52,10 +53,11 @@ tap.test('should fire a request', async () => {
'hi'
);
const response = await typedRequest.fire({
name: 'really'
name: 'really',
});
console.log('this is the response:');
console.log(response);
expect(response.surname).to.equal('wow');
expect(response.surname).toEqual('wow');
});
tap.test('should end the server', async () => {

8
ts/00_commitinfo_data.ts Normal file
View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@apiglobal/typedrequest',
version: '2.0.6',
description: 'make typed requests towards apis'
}

View File

@ -1,3 +1,5 @@
export * from './typedrequest.classes.typedrequest';
export * from './typedrequest.classes.typedhandler';
export * from './typedrequest.classes.typedrouter';
export * from './typedrequest.classes.typedrequest.js';
export * from './typedrequest.classes.typedhandler.js';
export * from './typedrequest.classes.typedrouter.js';
export * from './typedrequest.classes.typedresponseerror.js';
export * from './typedrequest.classes.typedtarget.js';

View File

@ -1,6 +1,7 @@
import * as plugins from './typedrequest.plugins';
import * as plugins from './typedrequest.plugins.js';
import { TypedResponseError } from './typedrequest.classes.typedresponseerror.js';
type THandlerFunction<T extends plugins.typedRequestInterfaces.ITypedRequest> = (
export type THandlerFunction<T extends plugins.typedRequestInterfaces.ITypedRequest> = (
requestArg: T['request']
) => Promise<T['response']>;
@ -26,8 +27,28 @@ export class TypedHandler<T extends plugins.typedRequestInterfaces.ITypedRequest
'this handler has been given a wrong method to answer to. Please use a TypedRouter to filter requests'
);
}
const response = await this.handlerFunction(typedRequestArg.request);
typedRequestArg.response = response;
let typedResponseError: TypedResponseError;
const response = await this.handlerFunction(typedRequestArg.request).catch((e) => {
if (e instanceof TypedResponseError) {
typedResponseError = e;
} else {
throw e;
}
});
if (typedResponseError) {
typedRequestArg.error = {
text: typedResponseError.errorText,
data: typedResponseError.errorData,
};
}
if (response) {
typedRequestArg.response = response;
}
typedRequestArg?.correlation?.phase ? (typedRequestArg.correlation.phase = 'response') : null;
return typedRequestArg;
}
}

View File

@ -1,30 +1,69 @@
import * as plugins from './typedrequest.plugins';
import * as plugins from './typedrequest.plugins.js';
import { TypedResponseError } from './typedrequest.classes.typedresponseerror.js';
import { TypedRouter } from './typedrequest.classes.typedrouter.js';
import { TypedTarget } from './typedrequest.classes.typedtarget.js';
const webrequestInstance = new plugins.webrequest.WebRequest();
export class TypedRequest<T extends plugins.typedRequestInterfaces.ITypedRequest> {
public urlEndPoint: string;
/**
* in case we post against a url endpoint
*/
public urlEndPoint?: string;
/**
* in case we post against a TypedTarget
*/
typedTarget: TypedTarget;
public method: string;
// STATIC
constructor(urlEndPointArg: string, methodArg: T['method']) {
this.urlEndPoint = urlEndPointArg;
/**
* note the overloading is thought to deal with promises
* @param postEndPointArg
* @param methodArg
*/
constructor(postTarget: string | TypedTarget, methodArg: T['method']) {
if (typeof postTarget === 'string') {
this.urlEndPoint = postTarget;
} else {
this.typedTarget = postTarget;
}
this.method = methodArg;
}
/**
* firest the request
* fires the request
*/
public async fire(fireArg: T['request']): Promise<T['response']> {
const response = await plugins.smartrequest.postJson(this.urlEndPoint, {
requestBody: {
method: this.method,
request: fireArg,
response: null
}
});
const responseBody: T = response.body;
public async fire(fireArg: T['request'], useCacheArg: boolean = false): Promise<T['response']> {
const payload: plugins.typedRequestInterfaces.ITypedRequest = {
method: this.method,
request: fireArg,
response: null,
correlation: {
id: plugins.isounique.uni(),
phase: 'request',
},
};
let responseBody: plugins.typedRequestInterfaces.ITypedRequest;
if (this.urlEndPoint) {
const response = await webrequestInstance.postJson(this.urlEndPoint, payload, useCacheArg);
responseBody = response;
} else {
responseBody = await this.typedTarget.post(payload);
}
if (responseBody.error) {
console.log(responseBody.error.text);
console.log(responseBody.error.data);
console.error(
`Got an error ${responseBody.error.text} with data ${JSON.stringify(
responseBody.error.data
)}`
);
if (!responseBody.retry) {
throw new TypedResponseError(responseBody.error.text, responseBody.error.data);
}
return null;
}
if (responseBody.retry) {

View File

@ -0,0 +1,10 @@
import * as plugins from './typedrequest.plugins.js';
export class TypedResponseError {
public errorText: string;
public errorData: any;
constructor(errorTextArg: string, errorDataArg?: any) {
this.errorText = errorTextArg;
this.errorData = errorDataArg;
}
}

View File

@ -1,6 +1,7 @@
import * as plugins from './typedrequest.plugins';
import * as plugins from './typedrequest.plugins.js';
import { TypedHandler } from './typedrequest.classes.typedhandler';
import { TypedHandler } from './typedrequest.classes.typedhandler.js';
import { TypedRequest } from './typedrequest.classes.typedrequest.js';
/**
* A typed router decides on which typed handler to call based on the method
@ -8,19 +9,21 @@ import { TypedHandler } from './typedrequest.classes.typedhandler';
* This is thought for reusing the same url endpoint for different methods
*/
export class TypedRouter {
public upstreamTypedRouter: TypedRouter;
public routerMap = new plugins.lik.ObjectMap<TypedRouter>();
public handlerMap = new plugins.lik.ObjectMap<
TypedHandler<plugins.typedRequestInterfaces.ITypedRequest>
TypedHandler<any & plugins.typedRequestInterfaces.ITypedRequest>
>();
public fireEventInterestMap = new plugins.lik.InterestMap<
string,
plugins.typedRequestInterfaces.ITypedRequest
>((correlationId: string) => correlationId);
/**
* adds the handler to the routing map
* @param typedHandlerArg
*/
public addTypedHandler<T extends plugins.typedRequestInterfaces.ITypedRequest>(
public addTypedHandler<T extends plugins.typedRequestInterfaces.ITypedRequest> (
typedHandlerArg: TypedHandler<T>
) {
// lets check for deduplication
@ -38,15 +41,15 @@ export class TypedRouter {
* adds another sub typedRouter
* @param typedRequest
*/
public addTypedRouter(typedRouterArg: TypedRouter) {
this.routerMap.add(typedRouterArg);
public addTypedRouter (typedRouterArg: TypedRouter) {
const routerExists = this.routerMap.findSync(routerArg => routerArg === typedRouterArg)
if (!routerExists) {
this.routerMap.add(typedRouterArg);
typedRouterArg.addTypedRouter(this);
}
}
public setUpstreamTypedRouter(typedRouterArg: TypedRouter) {
this.upstreamTypedRouter = typedRouterArg;
}
public checkForTypedHandler(methodArg: string): boolean {
public checkForTypedHandler (methodArg: string): boolean {
return !!this.getTypedHandlerForMethod(methodArg);
}
@ -55,54 +58,59 @@ export class TypedRouter {
* @param methodArg
* @param checkUpstreamRouter
*/
public getTypedHandlerForMethod(
public getTypedHandlerForMethod (
methodArg: string,
checkUpstreamRouter = true
checkedRouters: TypedRouter[] = []
): TypedHandler<any> {
checkedRouters.push(this);
let typedHandler: TypedHandler<any>;
if (this.upstreamTypedRouter && checkUpstreamRouter) {
typedHandler = this.upstreamTypedRouter.getTypedHandlerForMethod(methodArg);
} else {
typedHandler = this.handlerMap.find(handler => {
return handler.method === methodArg;
});
typedHandler = this.handlerMap.findSync((handler) => {
return handler.method === methodArg;
});
if (!typedHandler) {
this.routerMap.getArray().forEach(typedRouter => {
if (!typedHandler) {
typedHandler = typedRouter.getTypedHandlerForMethod(methodArg, false);
}
});
}
if (!typedHandler) {
this.routerMap.getArray().forEach((typedRouterArg) => {
if (!typedHandler && !checkedRouters.includes(typedRouterArg)) {
typedHandler = typedRouterArg.getTypedHandlerForMethod(methodArg, checkedRouters);
}
});
}
return typedHandler;
}
/**
* routes a typed request to a handler
* if typedrequest object has correlation.phase === 'request' -> routes a typed request object to a handler
* if typedrequest object has correlation.phase === 'response' -> routes a typed request object to request fire event
* @param typedRequestArg
*/
public async routeAndAddResponse(typedRequestArg: plugins.typedRequestInterfaces.ITypedRequest) {
const typedHandler = this.getTypedHandlerForMethod(typedRequestArg.method);
public async routeAndAddResponse<T extends plugins.typedRequestInterfaces.ITypedRequest = plugins.typedRequestInterfaces.ITypedRequest> (typedRequestArg: T): Promise<T> {
if (typedRequestArg?.correlation?.phase === 'request') {
const typedHandler = this.getTypedHandlerForMethod(typedRequestArg.method);
if (!typedHandler) {
const availableMethods: string[] = [];
await this.handlerMap.forEach(async handler => {
availableMethods.push(handler.method);
});
console.log(`Cannot find method for ${typedHandler}`);
console.log(`Available methods are:`);
console.log(availableMethods);
typedRequestArg.error = {
text: 'There is no available method for this call on the server side',
data: {}
};
if (!typedHandler) {
console.log(`Cannot find handler for methodname ${typedRequestArg.method}`);
typedRequestArg.error = {
text: 'There is no available method for this call on the server side',
data: {},
};
typedRequestArg.correlation.phase = 'response';
return typedRequestArg;
}
typedRequestArg = await typedHandler.addResponse(typedRequestArg);
return typedRequestArg;
} else if (typedRequestArg?.correlation?.phase === 'response') {
this.fireEventInterestMap
.findInterest(typedRequestArg.correlation.id)
?.fullfillInterest(typedRequestArg);
return null;
} else {
console.log('received weirdly shaped request');
console.log(typedRequestArg);
return null
}
typedRequestArg = await typedHandler.addResponse(typedRequestArg);
return typedRequestArg;
}
}

View File

@ -0,0 +1,79 @@
import { TypedRouter } from './typedrequest.classes.typedrouter.js';
import * as plugins from './typedrequest.plugins.js';
export type IPostMethod = (
typedRequestPostObject: plugins.typedRequestInterfaces.ITypedRequest
) => Promise<plugins.typedRequestInterfaces.ITypedRequest>;
/**
* this is an alternative to a post url supplied in `new Typedrequest(new TypedTarget(...), 'someMethodName')`
* enables the use of custom post functions
* used for things like broadcast channels
* e.g. @designestate/dees-comms
* the main difference here is, that the response comes back async and is routed by interest through typedrouter
*/
export type IPostMethodWithTypedRouter = (
typedRequestPostObject: plugins.typedRequestInterfaces.ITypedRequest
) => Promise<void> | Promise<plugins.typedRequestInterfaces.ITypedRequest>;
export interface ITypedTargetConstructorOptions {
url?: string;
postMethod?: IPostMethod;
/**
* a post method that does not return the answer
*/
postMethodWithTypedRouter?: IPostMethodWithTypedRouter;
/**
* this typedrouter allows us to have easy async request response cycles
*/
typedRouterRef?: TypedRouter;
}
/**
* a typed target defines a target for requests
*/
export class TypedTarget {
url: string;
type: 'rest' | 'socket';
options: ITypedTargetConstructorOptions;
constructor(optionsArg: ITypedTargetConstructorOptions) {
if (optionsArg.postMethodWithTypedRouter && !optionsArg.typedRouterRef) {
throw new Error('you have to specify a typedrouter when using postmethod with typedrouter');
}
this.options = optionsArg;
}
/**
* wether calls to this target are bound to the request/response cycle
* if false, always delivers response as result of a call
* if true, delivers response in a separate call
* can only be async when type is 'socket'
*/
public isAsync: boolean;
public async post<T extends plugins.typedRequestInterfaces.ITypedRequest>(payloadArg: T): Promise<T> {
let responseInterest: plugins.lik.Interest<
string,
plugins.typedRequestInterfaces.ITypedRequest
>;
// having a typedrouter allows us to work with async request response cycles.
if (this.options.typedRouterRef) {
responseInterest = await this.options.typedRouterRef.fireEventInterestMap.addInterest(
payloadArg.correlation.id,
payloadArg
);
}
const postMethod = this.options.postMethod || this.options.postMethodWithTypedRouter;
const postMethodReturnValue = await postMethod(payloadArg);
let responseBody: T;
if (responseInterest) {
responseBody = (await responseInterest.interestFullfilled) as T;
} else if (postMethodReturnValue) {
responseBody = postMethodReturnValue as T;
} else {
responseBody = payloadArg;
}
return responseBody;
}
}

View File

@ -4,9 +4,10 @@ import * as typedRequestInterfaces from '@apiglobal/typedrequest-interfaces';
export { typedRequestInterfaces };
// pushrocks scope
import * as isounique from '@pushrocks/isounique';
import * as lik from '@pushrocks/lik';
import * as smartdelay from '@pushrocks/smartdelay';
import * as smartrequest from '@pushrocks/smartrequest';
import * as smartjson from '@pushrocks/smartjson';
import * as smartpromise from '@pushrocks/smartpromise';
import * as webrequest from '@pushrocks/webrequest';
export { lik, smartdelay, smartrequest, smartjson };
export { isounique, lik, smartdelay, smartpromise, webrequest };