@aneuhold/core-ts-api-lib 2.0.3 → 2.0.5
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 +33 -16
- package/lib/services/DOFunctionService/DOFunction.d.ts.map +1 -1
- package/lib/services/DOFunctionService/DOFunction.js +11 -14
- package/lib/services/DOFunctionService/DOFunction.js.map +1 -1
- package/lib/services/DOFunctionService/DOFunction.spec.ts +66 -0
- package/lib/services/DOFunctionService/DOFunction.ts +43 -25
- package/lib/services/DOFunctionService/DOFunctionService.d.ts +2 -1
- package/lib/services/DOFunctionService/DOFunctionService.d.ts.map +1 -1
- package/lib/services/DOFunctionService/DOFunctionService.js +25 -9
- package/lib/services/DOFunctionService/DOFunctionService.js.map +1 -1
- package/lib/services/DOFunctionService/DOFunctionService.spec.ts +61 -0
- package/lib/services/DOFunctionService/DOFunctionService.ts +26 -9
- package/package.json +1 -1
|
@@ -9,20 +9,35 @@ export type DOFunctionInput = object;
|
|
|
9
9
|
*/
|
|
10
10
|
export type DOFunctionOutput = object;
|
|
11
11
|
/**
|
|
12
|
-
* Raw input to a Digital Ocean function
|
|
13
|
-
*
|
|
12
|
+
* Raw input to a Digital Ocean function. This is with the expectation that
|
|
13
|
+
* `web: raw` is set in the `project.yml` file.
|
|
14
14
|
*/
|
|
15
15
|
export interface DOFunctionRawInput {
|
|
16
|
-
/**
|
|
17
|
-
* There are many other properties in the `http` object, but only the body
|
|
18
|
-
* property is used.
|
|
19
|
-
*/
|
|
20
16
|
http: {
|
|
21
17
|
/**
|
|
22
|
-
* The body
|
|
23
|
-
* other processing.
|
|
18
|
+
* The body to be parsed or deserialized.
|
|
24
19
|
*/
|
|
25
20
|
body: string;
|
|
21
|
+
headers: {
|
|
22
|
+
accept?: string;
|
|
23
|
+
'accept-encoding'?: string;
|
|
24
|
+
/**
|
|
25
|
+
* This is important.
|
|
26
|
+
*/
|
|
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
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* This needs to be used to determine if the body is base64 encoded.
|
|
36
|
+
*/
|
|
37
|
+
isBase64Encoded: boolean;
|
|
38
|
+
method?: string;
|
|
39
|
+
path?: string;
|
|
40
|
+
queryString?: string;
|
|
26
41
|
};
|
|
27
42
|
}
|
|
28
43
|
/**
|
|
@@ -36,8 +51,14 @@ export interface DOFunctionRawOutput {
|
|
|
36
51
|
* The body is a base64 encoded string.
|
|
37
52
|
*/
|
|
38
53
|
body: string;
|
|
54
|
+
statusCode: number;
|
|
39
55
|
headers: {
|
|
40
|
-
|
|
56
|
+
/**
|
|
57
|
+
* This is different than what gets passed in. This is on purpose. DO
|
|
58
|
+
* functions changes the header name when being passed in, but not when
|
|
59
|
+
* being passed out.
|
|
60
|
+
*/
|
|
61
|
+
'Content-Type': string;
|
|
41
62
|
};
|
|
42
63
|
}
|
|
43
64
|
/**
|
|
@@ -48,10 +69,6 @@ export interface DOFunctionCallOutput<TOutput extends DOFunctionOutput> {
|
|
|
48
69
|
errors: string[];
|
|
49
70
|
data: TOutput;
|
|
50
71
|
}
|
|
51
|
-
/**
|
|
52
|
-
* An abstract class that can be extended to define a Digital Ocean
|
|
53
|
-
* function.
|
|
54
|
-
*/
|
|
55
72
|
/**
|
|
56
73
|
* An abstract class representing a Digital Ocean Function.
|
|
57
74
|
*
|
|
@@ -82,11 +99,11 @@ export default abstract class DOFunction<TInput extends DOFunctionInput, TOutput
|
|
|
82
99
|
*/
|
|
83
100
|
call(input: TInput): Promise<DOFunctionCallOutput<TOutput>>;
|
|
84
101
|
/**
|
|
85
|
-
* Decodes
|
|
102
|
+
* Decodes the response from the Digital Ocean function.
|
|
86
103
|
*
|
|
87
|
-
* @param
|
|
104
|
+
* @param response - The response to decode.
|
|
88
105
|
* @returns The decoded output.
|
|
89
106
|
*/
|
|
90
|
-
private
|
|
107
|
+
private decodeResponse;
|
|
91
108
|
}
|
|
92
109
|
//# sourceMappingURL=DOFunction.d.ts.map
|
|
@@ -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
|
|
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;CAO7B"}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { BSON } from 'bson';
|
|
2
|
-
/**
|
|
3
|
-
* An abstract class that can be extended to define a Digital Ocean
|
|
4
|
-
* function.
|
|
5
|
-
*/
|
|
6
2
|
/**
|
|
7
3
|
* An abstract class representing a Digital Ocean Function.
|
|
8
4
|
*
|
|
@@ -39,26 +35,27 @@ export default class DOFunction {
|
|
|
39
35
|
if (!this.url) {
|
|
40
36
|
throw new Error(`${this.functionName} URL is not set`);
|
|
41
37
|
}
|
|
42
|
-
const
|
|
38
|
+
const body = Buffer.from(BSON.serialize(input)).toString('base64');
|
|
39
|
+
const response = await fetch(this.url, {
|
|
43
40
|
method: 'POST',
|
|
44
41
|
headers: {
|
|
42
|
+
Connection: 'keep-alive',
|
|
45
43
|
'Content-Type': 'application/octet-stream'
|
|
46
44
|
},
|
|
47
|
-
|
|
48
|
-
// as a base64 string.
|
|
49
|
-
body: BSON.serialize(input)
|
|
45
|
+
body: body
|
|
50
46
|
});
|
|
51
|
-
return
|
|
47
|
+
return await this.decodeResponse(response);
|
|
52
48
|
}
|
|
53
49
|
/**
|
|
54
|
-
* Decodes
|
|
50
|
+
* Decodes the response from the Digital Ocean function.
|
|
55
51
|
*
|
|
56
|
-
* @param
|
|
52
|
+
* @param response - The response to decode.
|
|
57
53
|
* @returns The decoded output.
|
|
58
54
|
*/
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
55
|
+
async decodeResponse(response) {
|
|
56
|
+
const bodyText = await response.text();
|
|
57
|
+
const buffer = Buffer.from(bodyText, 'base64');
|
|
58
|
+
return BSON.deserialize(buffer);
|
|
62
59
|
}
|
|
63
60
|
}
|
|
64
61
|
//# 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;
|
|
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;QACvC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAkC,CAAC;IACnE,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
|
+
}
|
|
@@ -13,20 +13,35 @@ export type DOFunctionInput = object;
|
|
|
13
13
|
export type DOFunctionOutput = object;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Raw input to a Digital Ocean function
|
|
17
|
-
*
|
|
16
|
+
* Raw input to a Digital Ocean function. This is with the expectation that
|
|
17
|
+
* `web: raw` is set in the `project.yml` file.
|
|
18
18
|
*/
|
|
19
19
|
export interface DOFunctionRawInput {
|
|
20
|
-
/**
|
|
21
|
-
* There are many other properties in the `http` object, but only the body
|
|
22
|
-
* property is used.
|
|
23
|
-
*/
|
|
24
20
|
http: {
|
|
25
21
|
/**
|
|
26
|
-
* The body
|
|
27
|
-
* other processing.
|
|
22
|
+
* The body to be parsed or deserialized.
|
|
28
23
|
*/
|
|
29
24
|
body: string;
|
|
25
|
+
headers: {
|
|
26
|
+
accept?: string;
|
|
27
|
+
'accept-encoding'?: string;
|
|
28
|
+
/**
|
|
29
|
+
* This is important.
|
|
30
|
+
*/
|
|
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
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* This needs to be used to determine if the body is base64 encoded.
|
|
40
|
+
*/
|
|
41
|
+
isBase64Encoded: boolean;
|
|
42
|
+
method?: string;
|
|
43
|
+
path?: string;
|
|
44
|
+
queryString?: string;
|
|
30
45
|
};
|
|
31
46
|
}
|
|
32
47
|
|
|
@@ -41,8 +56,14 @@ export interface DOFunctionRawOutput {
|
|
|
41
56
|
* The body is a base64 encoded string.
|
|
42
57
|
*/
|
|
43
58
|
body: string;
|
|
59
|
+
statusCode: number;
|
|
44
60
|
headers: {
|
|
45
|
-
|
|
61
|
+
/**
|
|
62
|
+
* This is different than what gets passed in. This is on purpose. DO
|
|
63
|
+
* functions changes the header name when being passed in, but not when
|
|
64
|
+
* being passed out.
|
|
65
|
+
*/
|
|
66
|
+
'Content-Type': string;
|
|
46
67
|
};
|
|
47
68
|
}
|
|
48
69
|
|
|
@@ -55,10 +76,6 @@ export interface DOFunctionCallOutput<TOutput extends DOFunctionOutput> {
|
|
|
55
76
|
data: TOutput;
|
|
56
77
|
}
|
|
57
78
|
|
|
58
|
-
/**
|
|
59
|
-
* An abstract class that can be extended to define a Digital Ocean
|
|
60
|
-
* function.
|
|
61
|
-
*/
|
|
62
79
|
/**
|
|
63
80
|
* An abstract class representing a Digital Ocean Function.
|
|
64
81
|
*
|
|
@@ -102,28 +119,29 @@ export default abstract class DOFunction<
|
|
|
102
119
|
if (!this.url) {
|
|
103
120
|
throw new Error(`${this.functionName} URL is not set`);
|
|
104
121
|
}
|
|
105
|
-
const
|
|
122
|
+
const body = Buffer.from(BSON.serialize(input)).toString('base64');
|
|
123
|
+
const response = await fetch(this.url, {
|
|
106
124
|
method: 'POST',
|
|
107
125
|
headers: {
|
|
126
|
+
Connection: 'keep-alive',
|
|
108
127
|
'Content-Type': 'application/octet-stream'
|
|
109
128
|
},
|
|
110
|
-
|
|
111
|
-
// as a base64 string.
|
|
112
|
-
body: BSON.serialize(input)
|
|
129
|
+
body: body
|
|
113
130
|
});
|
|
114
|
-
return
|
|
131
|
+
return await this.decodeResponse(response);
|
|
115
132
|
}
|
|
116
133
|
|
|
117
134
|
/**
|
|
118
|
-
* Decodes
|
|
135
|
+
* Decodes the response from the Digital Ocean function.
|
|
119
136
|
*
|
|
120
|
-
* @param
|
|
137
|
+
* @param response - The response to decode.
|
|
121
138
|
* @returns The decoded output.
|
|
122
139
|
*/
|
|
123
|
-
private
|
|
124
|
-
|
|
125
|
-
): DOFunctionCallOutput<TOutput
|
|
126
|
-
const
|
|
127
|
-
|
|
140
|
+
private async decodeResponse(
|
|
141
|
+
response: Response
|
|
142
|
+
): Promise<DOFunctionCallOutput<TOutput>> {
|
|
143
|
+
const bodyText = await response.text();
|
|
144
|
+
const buffer = Buffer.from(bodyText, 'base64');
|
|
145
|
+
return BSON.deserialize(buffer) as DOFunctionCallOutput<TOutput>;
|
|
128
146
|
}
|
|
129
147
|
}
|
|
@@ -39,7 +39,8 @@ export default class DOFunctionService {
|
|
|
39
39
|
*/
|
|
40
40
|
private static deserializeInput;
|
|
41
41
|
/**
|
|
42
|
-
* Serializes the output object into a base64 string.
|
|
42
|
+
* Serializes the output object into a base64 string. This could be updated
|
|
43
|
+
* to support other serialization methods in the future.
|
|
43
44
|
*
|
|
44
45
|
* @param output - The output object to serialize.
|
|
45
46
|
* @returns The serialized output as a base64 string.
|
|
@@ -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;IA0B/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IA2B/B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;CAM/B"}
|
|
@@ -34,6 +34,7 @@ export default class DOFunctionService {
|
|
|
34
34
|
const input = this.deserializeInput(rawInput);
|
|
35
35
|
const rawOutput = {
|
|
36
36
|
body: '',
|
|
37
|
+
statusCode: 200,
|
|
37
38
|
headers: {
|
|
38
39
|
'Content-Type': 'application/octet-stream'
|
|
39
40
|
}
|
|
@@ -62,23 +63,38 @@ export default class DOFunctionService {
|
|
|
62
63
|
* @returns The deserialized input object.
|
|
63
64
|
*/
|
|
64
65
|
static deserializeInput(rawInput) {
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const { http } = rawInput;
|
|
67
|
+
const { body, isBase64Encoded, headers } = http;
|
|
68
|
+
let decodedBody;
|
|
69
|
+
if (isBase64Encoded) {
|
|
70
|
+
decodedBody = Buffer.from(body, 'base64');
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
+
else {
|
|
73
|
+
decodedBody = Buffer.from(body, 'utf8');
|
|
74
|
+
}
|
|
75
|
+
// Determine if the incoming content type is BSON
|
|
76
|
+
const isBson = headers['content-type'] === 'application/octet-stream';
|
|
77
|
+
let requestData;
|
|
78
|
+
if (isBson) {
|
|
79
|
+
// Deserialize BSON data
|
|
80
|
+
requestData = BSON.deserialize(decodedBody);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// Parse JSON data
|
|
84
|
+
requestData = JSON.parse(decodedBody.toString('utf8'));
|
|
85
|
+
}
|
|
86
|
+
return requestData;
|
|
72
87
|
}
|
|
73
88
|
/**
|
|
74
|
-
* Serializes the output object into a base64 string.
|
|
89
|
+
* Serializes the output object into a base64 string. This could be updated
|
|
90
|
+
* to support other serialization methods in the future.
|
|
75
91
|
*
|
|
76
92
|
* @param output - The output object to serialize.
|
|
77
93
|
* @returns The serialized output as a base64 string.
|
|
78
94
|
*/
|
|
79
95
|
static serializeOutput(output) {
|
|
80
|
-
const
|
|
81
|
-
return Buffer.from(
|
|
96
|
+
const bsonBuffer = BSON.serialize(output);
|
|
97
|
+
return Buffer.from(bsonBuffer).toString('base64');
|
|
82
98
|
}
|
|
83
99
|
}
|
|
84
100
|
//# sourceMappingURL=DOFunctionService.js.map
|
|
@@ -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,MAAM,KAAK,GAAW,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,SAAS,GAAwB;YACrC,IAAI,EAAE,EAAE;YACR,OAAO,EAAE;gBACP,cAAc,EAAE,0BAA0B;aAC3C;SACF,CAAC;QACF,yCAAyC;QACzC,MAAM,aAAa,GAAkC;YACnD,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,EAAE;YACV,IAAI,EAAE,EAAa;SACpB,CAAC;QACF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;YACpC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,CAAU,CAAC;YACzB,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACzC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,gBAAgB,CAC7B,QAA4B;QAE5B,MAAM,
|
|
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,MAAM,KAAK,GAAW,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,SAAS,GAAwB;YACrC,IAAI,EAAE,EAAE;YACR,UAAU,EAAE,GAAG;YACf,OAAO,EAAE;gBACP,cAAc,EAAE,0BAA0B;aAC3C;SACF,CAAC;QACF,yCAAyC;QACzC,MAAM,aAAa,GAAkC;YACnD,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,EAAE;YACV,IAAI,EAAE,EAAa;SACpB,CAAC;QACF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;YACpC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,CAAU,CAAC;YACzB,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACzC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,gBAAgB,CAC7B,QAA4B;QAE5B,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;QAC1B,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAEhD,IAAI,WAAmB,CAAC;QACxB,IAAI,eAAe,EAAE,CAAC;YACpB,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,iDAAiD;QACjD,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,KAAK,0BAA0B,CAAC;QACtE,IAAI,WAAmB,CAAC;QACxB,IAAI,MAAM,EAAE,CAAC;YACX,wBAAwB;YACxB,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAW,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,kBAAkB;YAClB,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAW,CAAC;QACnE,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACK,MAAM,CAAC,eAAe,CAC5B,MAAqC;QAErC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC"}
|
|
@@ -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
|
+
});
|
|
@@ -51,6 +51,7 @@ export default class DOFunctionService {
|
|
|
51
51
|
const input: TInput = this.deserializeInput(rawInput);
|
|
52
52
|
const rawOutput: DOFunctionRawOutput = {
|
|
53
53
|
body: '',
|
|
54
|
+
statusCode: 200,
|
|
54
55
|
headers: {
|
|
55
56
|
'Content-Type': 'application/octet-stream'
|
|
56
57
|
}
|
|
@@ -81,17 +82,33 @@ export default class DOFunctionService {
|
|
|
81
82
|
private static deserializeInput<TInput extends DOFunctionInput>(
|
|
82
83
|
rawInput: DOFunctionRawInput
|
|
83
84
|
): TInput {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
const { http } = rawInput;
|
|
86
|
+
const { body, isBase64Encoded, headers } = http;
|
|
87
|
+
|
|
88
|
+
let decodedBody: Buffer;
|
|
89
|
+
if (isBase64Encoded) {
|
|
90
|
+
decodedBody = Buffer.from(body, 'base64');
|
|
91
|
+
} else {
|
|
92
|
+
decodedBody = Buffer.from(body, 'utf8');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Determine if the incoming content type is BSON
|
|
96
|
+
const isBson = headers['content-type'] === 'application/octet-stream';
|
|
97
|
+
let requestData: TInput;
|
|
98
|
+
if (isBson) {
|
|
99
|
+
// Deserialize BSON data
|
|
100
|
+
requestData = BSON.deserialize(decodedBody) as TInput;
|
|
101
|
+
} else {
|
|
102
|
+
// Parse JSON data
|
|
103
|
+
requestData = JSON.parse(decodedBody.toString('utf8')) as TInput;
|
|
89
104
|
}
|
|
90
|
-
|
|
105
|
+
|
|
106
|
+
return requestData;
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
/**
|
|
94
|
-
* Serializes the output object into a base64 string.
|
|
110
|
+
* Serializes the output object into a base64 string. This could be updated
|
|
111
|
+
* to support other serialization methods in the future.
|
|
95
112
|
*
|
|
96
113
|
* @param output - The output object to serialize.
|
|
97
114
|
* @returns The serialized output as a base64 string.
|
|
@@ -99,7 +116,7 @@ export default class DOFunctionService {
|
|
|
99
116
|
private static serializeOutput<TOutput extends DOFunctionOutput>(
|
|
100
117
|
output: DOFunctionCallOutput<TOutput>
|
|
101
118
|
): string {
|
|
102
|
-
const
|
|
103
|
-
return Buffer.from(
|
|
119
|
+
const bsonBuffer = BSON.serialize(output);
|
|
120
|
+
return Buffer.from(bsonBuffer).toString('base64');
|
|
104
121
|
}
|
|
105
122
|
}
|
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.5",
|
|
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",
|