@aneuhold/core-ts-api-lib 2.0.4 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/services/DOFunctionService/DOFunction.d.ts +11 -11
- package/lib/services/DOFunctionService/DOFunction.d.ts.map +1 -1
- package/lib/services/DOFunctionService/DOFunction.js +15 -3
- package/lib/services/DOFunctionService/DOFunction.js.map +1 -1
- package/lib/services/DOFunctionService/DOFunction.spec.ts +66 -0
- package/lib/services/DOFunctionService/DOFunction.ts +26 -14
- package/lib/services/DOFunctionService/DOFunctionService.d.ts.map +1 -1
- package/lib/services/DOFunctionService/DOFunctionService.js +11 -4
- package/lib/services/DOFunctionService/DOFunctionService.js.map +1 -1
- package/lib/services/DOFunctionService/DOFunctionService.spec.ts +61 -0
- package/lib/services/DOFunctionService/DOFunctionService.ts +11 -4
- package/package.json +2 -2
|
@@ -19,25 +19,25 @@ export interface DOFunctionRawInput {
|
|
|
19
19
|
*/
|
|
20
20
|
body: string;
|
|
21
21
|
headers: {
|
|
22
|
-
accept
|
|
23
|
-
'accept-encoding'
|
|
22
|
+
accept?: string;
|
|
23
|
+
'accept-encoding'?: string;
|
|
24
24
|
/**
|
|
25
25
|
* This is important.
|
|
26
26
|
*/
|
|
27
|
-
'content-type'
|
|
28
|
-
host
|
|
29
|
-
'user-agent'
|
|
30
|
-
'x-forwarded-for'
|
|
31
|
-
'x-forwarded-proto'
|
|
32
|
-
'x-request-id'
|
|
27
|
+
'content-type'?: string;
|
|
28
|
+
host?: string;
|
|
29
|
+
'user-agent'?: string;
|
|
30
|
+
'x-forwarded-for'?: string;
|
|
31
|
+
'x-forwarded-proto'?: string;
|
|
32
|
+
'x-request-id'?: string;
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
35
|
* This needs to be used to determine if the body is base64 encoded.
|
|
36
36
|
*/
|
|
37
37
|
isBase64Encoded: boolean;
|
|
38
|
-
method
|
|
39
|
-
path
|
|
40
|
-
queryString
|
|
38
|
+
method?: string;
|
|
39
|
+
path?: string;
|
|
40
|
+
queryString?: string;
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DOFunction.d.ts","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunction.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAErC;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE;QACJ;;WAEG;QACH,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"DOFunction.d.ts","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunction.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAErC;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE;QACJ;;WAEG;QACH,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;YAC3B;;eAEG;YACH,cAAc,CAAC,EAAE,MAAM,CAAC;YACxB,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;YAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;YAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;SACzB,CAAC;QACF;;WAEG;QACH,eAAe,EAAE,OAAO,CAAC;QACzB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QACP;;;;WAIG;QACH,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,gBAAgB;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,UAAU,CACtC,MAAM,SAAS,eAAe,EAC9B,OAAO,SAAS,gBAAgB;IAEhC;;OAEG;IACH,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEvB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAE/B,SAAS;IAIT;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM;IAIlB;;;;;;;;OAQG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAgBjE;;;;;OAKG;YACW,cAAc;CAmB7B"}
|
|
@@ -53,9 +53,21 @@ export default class DOFunction {
|
|
|
53
53
|
* @returns The decoded output.
|
|
54
54
|
*/
|
|
55
55
|
async decodeResponse(response) {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
const isBson = response.headers.get('Content-Type') === 'application/octet-stream';
|
|
57
|
+
if (isBson) {
|
|
58
|
+
const bodyText = await response.text();
|
|
59
|
+
const buffer = Buffer.from(bodyText, 'base64');
|
|
60
|
+
return BSON.deserialize(buffer);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// This normally only happens if there is an error
|
|
64
|
+
const result = (await response.json());
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
errors: [JSON.stringify(result, null, 2)],
|
|
68
|
+
data: {}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
59
71
|
}
|
|
60
72
|
}
|
|
61
73
|
//# sourceMappingURL=DOFunction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DOFunction.js","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA8E5B;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAgB,UAAU;IAItC;;OAEG;IACO,GAAG,CAAU;IAEb,YAAY,CAAS;IAE/B;QACE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,iBAAiB,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,UAAU,EAAE,YAAY;gBACxB,cAAc,EAAE,0BAA0B;aAC3C;YACD,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,cAAc,CAC1B,QAAkB;QAElB,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"DOFunction.js","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA8E5B;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAgB,UAAU;IAItC;;OAEG;IACO,GAAG,CAAU;IAEb,YAAY,CAAS;IAE/B;QACE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,iBAAiB,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,UAAU,EAAE,YAAY;gBACxB,cAAc,EAAE,0BAA0B;aAC3C;YACD,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,cAAc,CAC1B,QAAkB;QAElB,MAAM,MAAM,GACV,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,0BAA0B,CAAC;QACtE,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAkC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,kDAAkD;YAClD,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAY,CAAC;YAClD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACzC,IAAI,EAAE,EAAa;aACpB,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { BSON } from 'bson';
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import DOFunction, {
|
|
4
|
+
DOFunctionCallOutput,
|
|
5
|
+
DOFunctionInput,
|
|
6
|
+
DOFunctionOutput
|
|
7
|
+
} from './DOFunction.js';
|
|
8
|
+
|
|
9
|
+
describe('DOFunction', () => {
|
|
10
|
+
it('should call the function and return the expected output', async () => {
|
|
11
|
+
const exampleFunction = ExampleFunction.getFunction();
|
|
12
|
+
|
|
13
|
+
const input: ExampleInput = { name: 'John' };
|
|
14
|
+
const expectedOutput: DOFunctionCallOutput<ExampleOutput> = {
|
|
15
|
+
success: true,
|
|
16
|
+
errors: [],
|
|
17
|
+
data: { greeting: 'Hello, John!' }
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
global.fetch = vi.fn().mockResolvedValue({
|
|
21
|
+
text: vi
|
|
22
|
+
.fn()
|
|
23
|
+
.mockResolvedValue(
|
|
24
|
+
Buffer.from(BSON.serialize(expectedOutput)).toString('base64')
|
|
25
|
+
)
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const output = await exampleFunction.call(input);
|
|
29
|
+
|
|
30
|
+
expect(output).toEqual(expectedOutput);
|
|
31
|
+
expect(global.fetch).toHaveBeenCalledWith(EXAMPLE_FUNCTION_URL, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
Connection: 'keep-alive',
|
|
35
|
+
'Content-Type': 'application/octet-stream'
|
|
36
|
+
},
|
|
37
|
+
body: Buffer.from(BSON.serialize(input)).toString('base64')
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const EXAMPLE_FUNCTION_URL = 'https://example.com/function';
|
|
43
|
+
|
|
44
|
+
export class ExampleFunction extends DOFunction<ExampleInput, ExampleOutput> {
|
|
45
|
+
private static instance: ExampleFunction | undefined;
|
|
46
|
+
|
|
47
|
+
private constructor() {
|
|
48
|
+
super();
|
|
49
|
+
this.url = EXAMPLE_FUNCTION_URL;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static getFunction(): ExampleFunction {
|
|
53
|
+
if (!ExampleFunction.instance) {
|
|
54
|
+
ExampleFunction.instance = new ExampleFunction();
|
|
55
|
+
}
|
|
56
|
+
return ExampleFunction.instance;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface ExampleInput extends DOFunctionInput {
|
|
61
|
+
name: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface ExampleOutput extends DOFunctionOutput {
|
|
65
|
+
greeting: string;
|
|
66
|
+
}
|
|
@@ -23,25 +23,25 @@ export interface DOFunctionRawInput {
|
|
|
23
23
|
*/
|
|
24
24
|
body: string;
|
|
25
25
|
headers: {
|
|
26
|
-
accept
|
|
27
|
-
'accept-encoding'
|
|
26
|
+
accept?: string;
|
|
27
|
+
'accept-encoding'?: string;
|
|
28
28
|
/**
|
|
29
29
|
* This is important.
|
|
30
30
|
*/
|
|
31
|
-
'content-type'
|
|
32
|
-
host
|
|
33
|
-
'user-agent'
|
|
34
|
-
'x-forwarded-for'
|
|
35
|
-
'x-forwarded-proto'
|
|
36
|
-
'x-request-id'
|
|
31
|
+
'content-type'?: string;
|
|
32
|
+
host?: string;
|
|
33
|
+
'user-agent'?: string;
|
|
34
|
+
'x-forwarded-for'?: string;
|
|
35
|
+
'x-forwarded-proto'?: string;
|
|
36
|
+
'x-request-id'?: string;
|
|
37
37
|
};
|
|
38
38
|
/**
|
|
39
39
|
* This needs to be used to determine if the body is base64 encoded.
|
|
40
40
|
*/
|
|
41
41
|
isBase64Encoded: boolean;
|
|
42
|
-
method
|
|
43
|
-
path
|
|
44
|
-
queryString
|
|
42
|
+
method?: string;
|
|
43
|
+
path?: string;
|
|
44
|
+
queryString?: string;
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -140,8 +140,20 @@ export default abstract class DOFunction<
|
|
|
140
140
|
private async decodeResponse(
|
|
141
141
|
response: Response
|
|
142
142
|
): Promise<DOFunctionCallOutput<TOutput>> {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
const isBson =
|
|
144
|
+
response.headers.get('Content-Type') === 'application/octet-stream';
|
|
145
|
+
if (isBson) {
|
|
146
|
+
const bodyText = await response.text();
|
|
147
|
+
const buffer = Buffer.from(bodyText, 'base64');
|
|
148
|
+
return BSON.deserialize(buffer) as DOFunctionCallOutput<TOutput>;
|
|
149
|
+
} else {
|
|
150
|
+
// This normally only happens if there is an error
|
|
151
|
+
const result = (await response.json()) as unknown;
|
|
152
|
+
return {
|
|
153
|
+
success: false,
|
|
154
|
+
errors: [JSON.stringify(result, null, 2)],
|
|
155
|
+
data: {} as TOutput
|
|
156
|
+
};
|
|
157
|
+
}
|
|
146
158
|
}
|
|
147
159
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DOFunctionService.d.ts","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunctionService.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AACjE,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAC/D,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAE/D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;OAEG;IACH,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAAmC;IAE9E;;OAEG;IACH,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAkC;IAE3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAkC;IAE3E;;;;;;;;;;;OAWG;WACU,gBAAgB,CAC3B,MAAM,SAAS,eAAe,EAC9B,OAAO,SAAS,gBAAgB,EAEhC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,GACjE,OAAO,CAAC,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"DOFunctionService.d.ts","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunctionService.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AACjE,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAC/D,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAE/D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;OAEG;IACH,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAAmC;IAE9E;;OAEG;IACH,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAkC;IAE3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAkC;IAE3E;;;;;;;;;;;OAWG;WACU,gBAAgB,CAC3B,MAAM,SAAS,eAAe,EAC9B,OAAO,SAAS,gBAAgB,EAEhC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,GACjE,OAAO,CAAC,mBAAmB,CAAC;IAiC/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IA2B/B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;CAM/B"}
|
|
@@ -31,7 +31,7 @@ export default class DOFunctionService {
|
|
|
31
31
|
* @returns The raw output of the function call.
|
|
32
32
|
*/
|
|
33
33
|
static async handleApiRequest(rawInput, handler) {
|
|
34
|
-
|
|
34
|
+
// Default raw output
|
|
35
35
|
const rawOutput = {
|
|
36
36
|
body: '',
|
|
37
37
|
statusCode: 200,
|
|
@@ -39,20 +39,27 @@ export default class DOFunctionService {
|
|
|
39
39
|
'Content-Type': 'application/octet-stream'
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
|
-
// Default output
|
|
42
|
+
// Default output
|
|
43
43
|
const defaultOutput = {
|
|
44
44
|
success: false,
|
|
45
45
|
errors: [],
|
|
46
46
|
data: {}
|
|
47
47
|
};
|
|
48
48
|
try {
|
|
49
|
+
// Deserialize the input
|
|
50
|
+
const input = this.deserializeInput(rawInput);
|
|
51
|
+
// Call the handler
|
|
49
52
|
const output = await handler(input);
|
|
53
|
+
// Serialize the output
|
|
50
54
|
rawOutput.body = this.serializeOutput(output);
|
|
51
55
|
}
|
|
52
56
|
catch (e) {
|
|
57
|
+
// Serialize as JSON if something fails to simplify in case the error
|
|
58
|
+
// happened in the normal serialization.
|
|
53
59
|
const error = e;
|
|
54
|
-
defaultOutput.errors.push(error
|
|
55
|
-
rawOutput.body =
|
|
60
|
+
defaultOutput.errors.push(JSON.stringify(error, null, 2));
|
|
61
|
+
rawOutput.body = JSON.stringify(defaultOutput);
|
|
62
|
+
rawOutput.headers['Content-Type'] = 'application/json';
|
|
56
63
|
}
|
|
57
64
|
return rawOutput;
|
|
58
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DOFunctionService.js","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunctionService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AACjE,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAC/D,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAE/D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;OAEG;IACH,MAAM,CAAC,iBAAiB,GAAsB,iBAAiB,CAAC,WAAW,EAAE,CAAC;IAE9E;;OAEG;IACH,MAAM,CAAC,gBAAgB,GAAqB,gBAAgB,CAAC,WAAW,EAAE,CAAC;IAE3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,GAAqB,gBAAgB,CAAC,WAAW,EAAE,CAAC;IAE3E;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAI3B,QAA4B,EAC5B,OAAkE;QAElE,
|
|
1
|
+
{"version":3,"file":"DOFunctionService.js","sourceRoot":"./src/","sources":["services/DOFunctionService/DOFunctionService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { BSON } from 'bson';
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { DOFunctionRawInput, DOFunctionRawOutput } from './DOFunction.js';
|
|
4
|
+
import { ExampleFunction } from './DOFunction.spec.js';
|
|
5
|
+
import DOFunctionService from './DOFunctionService.js';
|
|
6
|
+
|
|
7
|
+
describe('DOFunctionService', () => {
|
|
8
|
+
it('should handle API request and return the expected raw output', async () => {
|
|
9
|
+
const rawInput: DOFunctionRawInput = {
|
|
10
|
+
http: {
|
|
11
|
+
body: Buffer.from(BSON.serialize({ name: 'John' })).toString('base64'),
|
|
12
|
+
headers: {
|
|
13
|
+
accept: '',
|
|
14
|
+
'accept-encoding': '',
|
|
15
|
+
'content-type': 'application/octet-stream',
|
|
16
|
+
host: '',
|
|
17
|
+
'user-agent': '',
|
|
18
|
+
'x-forwarded-for': '',
|
|
19
|
+
'x-forwarded-proto': '',
|
|
20
|
+
'x-request-id': ''
|
|
21
|
+
},
|
|
22
|
+
isBase64Encoded: true,
|
|
23
|
+
method: 'POST',
|
|
24
|
+
path: '',
|
|
25
|
+
queryString: ''
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const expectedOutput = {
|
|
30
|
+
success: true,
|
|
31
|
+
errors: [],
|
|
32
|
+
data: { greeting: 'Hello, John!' }
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const expectedRawOutput: DOFunctionRawOutput = {
|
|
36
|
+
body: Buffer.from(BSON.serialize(expectedOutput)).toString('base64'),
|
|
37
|
+
statusCode: 200,
|
|
38
|
+
headers: {
|
|
39
|
+
'Content-Type': 'application/octet-stream'
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
global.fetch = vi.fn().mockResolvedValue({
|
|
44
|
+
text: vi
|
|
45
|
+
.fn()
|
|
46
|
+
.mockResolvedValue(
|
|
47
|
+
Buffer.from(BSON.serialize(expectedOutput)).toString('base64')
|
|
48
|
+
)
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const handler = ExampleFunction.getFunction().call.bind(
|
|
52
|
+
ExampleFunction.getFunction()
|
|
53
|
+
);
|
|
54
|
+
const rawOutput = await DOFunctionService.handleApiRequest(
|
|
55
|
+
rawInput,
|
|
56
|
+
handler
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
expect(rawOutput).toEqual(expectedRawOutput);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -48,7 +48,7 @@ export default class DOFunctionService {
|
|
|
48
48
|
rawInput: DOFunctionRawInput,
|
|
49
49
|
handler: (input: TInput) => Promise<DOFunctionCallOutput<TOutput>>
|
|
50
50
|
): Promise<DOFunctionRawOutput> {
|
|
51
|
-
|
|
51
|
+
// Default raw output
|
|
52
52
|
const rawOutput: DOFunctionRawOutput = {
|
|
53
53
|
body: '',
|
|
54
54
|
statusCode: 200,
|
|
@@ -56,19 +56,26 @@ export default class DOFunctionService {
|
|
|
56
56
|
'Content-Type': 'application/octet-stream'
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
-
// Default output
|
|
59
|
+
// Default output
|
|
60
60
|
const defaultOutput: DOFunctionCallOutput<TOutput> = {
|
|
61
61
|
success: false,
|
|
62
62
|
errors: [],
|
|
63
63
|
data: {} as TOutput
|
|
64
64
|
};
|
|
65
65
|
try {
|
|
66
|
+
// Deserialize the input
|
|
67
|
+
const input: TInput = this.deserializeInput(rawInput);
|
|
68
|
+
// Call the handler
|
|
66
69
|
const output = await handler(input);
|
|
70
|
+
// Serialize the output
|
|
67
71
|
rawOutput.body = this.serializeOutput(output);
|
|
68
72
|
} catch (e) {
|
|
73
|
+
// Serialize as JSON if something fails to simplify in case the error
|
|
74
|
+
// happened in the normal serialization.
|
|
69
75
|
const error = e as Error;
|
|
70
|
-
defaultOutput.errors.push(error
|
|
71
|
-
rawOutput.body =
|
|
76
|
+
defaultOutput.errors.push(JSON.stringify(error, null, 2));
|
|
77
|
+
rawOutput.body = JSON.stringify(defaultOutput);
|
|
78
|
+
rawOutput.headers['Content-Type'] = 'application/json';
|
|
72
79
|
}
|
|
73
80
|
return rawOutput;
|
|
74
81
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@aneuhold/core-ts-api-lib",
|
|
3
3
|
"author": "Anton G. Neuhold Jr.",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "2.0.
|
|
5
|
+
"version": "2.0.7",
|
|
6
6
|
"description": "A library for interacting with the backend and defining the backend API for personal projects.",
|
|
7
7
|
"packageManager": "yarn@4.5.1",
|
|
8
8
|
"type": "module",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"bson": "^6.2.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@aneuhold/eslint-config": "^1.0.
|
|
51
|
+
"@aneuhold/eslint-config": "^1.0.41",
|
|
52
52
|
"@aneuhold/main-scripts": "^2.0.6",
|
|
53
53
|
"@types/node": "^20.17.1",
|
|
54
54
|
"eslint": "^9.13.0",
|