Skip to content

Commit 3b9e6e6

Browse files
committed
Apply formatting fixes
1 parent 35ba940 commit 3b9e6e6

File tree

9 files changed

+1012
-139
lines changed

9 files changed

+1012
-139
lines changed

docs/generated/api.json

+888-75
Large diffs are not rendered by default.

docs/generated/api.md

+41-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export interface EventFunctionWithCallback {
5959
}
6060

6161
// @public
62-
export type HandlerFunction<T = unknown> = HttpFunction | EventFunction | EventFunctionWithCallback | CloudEventFunction<T> | CloudEventFunctionWithCallback<T>;
62+
export type HandlerFunction<T = unknown, U = unknown> = HttpFunction | EventFunction | EventFunctionWithCallback | CloudEventFunction<T> | CloudEventFunctionWithCallback<T> | TypedHandlerFunction<T, U>;
6363

6464
// @public
6565
export const http: (functionName: string, handler: HttpFunction) => void;
@@ -70,6 +70,35 @@ export interface HttpFunction {
7070
(req: Request_2, res: Response_2): any;
7171
}
7272

73+
// @public
74+
export interface InvocationFormat<T, U> {
75+
// (undocumented)
76+
deserializeRequest(request: InvocationRequest): T | Promise<T>;
77+
// (undocumented)
78+
serializeResponse(responseWriter: InvocationResponse, response: U): void | Promise<void>;
79+
}
80+
81+
// @public
82+
export interface InvocationRequest {
83+
body(): string | Buffer;
84+
header(header: string): string | undefined;
85+
}
86+
87+
// @public
88+
export interface InvocationResponse {
89+
end(data: string | Buffer): void;
90+
setHeader(key: string, value: string): void;
91+
write(data: string | Buffer): void;
92+
}
93+
94+
// @public
95+
export class JsonInvocationFormat<T, U> implements InvocationFormat<T, U> {
96+
// (undocumented)
97+
deserializeRequest(request: InvocationRequest): T;
98+
// (undocumented)
99+
serializeResponse(responseWriter: InvocationResponse, response: U): void;
100+
}
101+
73102
// @public
74103
export type LegacyCloudFunctionsContext = CloudFunctionsContext | Data;
75104

@@ -91,6 +120,17 @@ export { Request_2 as Request }
91120

92121
export { Response_2 as Response }
93122

123+
// @public
124+
export const typed: <T, U>(functionName: string, handler: TypedHandlerFunction<T, U> | ((req: T) => U | Promise<U>)) => void;
125+
126+
// @public
127+
export interface TypedHandlerFunction<T = unknown, U = unknown> {
128+
// (undocumented)
129+
format: InvocationFormat<T, U>;
130+
// (undocumented)
131+
handler: (req: T) => U | Promise<U>;
132+
}
133+
94134
// (No @packageDocumentation comment for this package)
95135

96136
```

src/function_registry.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
CloudEventFunction,
1818
HandlerFunction,
1919
TypedHandlerFunction,
20-
InvocationFormat,
2120
JsonInvocationFormat,
2221
} from './functions';
2322
import {SignatureType} from './types';
@@ -102,10 +101,9 @@ export const cloudEvent = <T = unknown>(
102101
register(functionName, 'cloudevent', handler);
103102
};
104103

105-
106104
/**
107105
* Register a function that handles strongly typed invocations.
108-
* @param functionName - the name of the function
106+
* @param functionName - the name of the function
109107
* @param handler - the function to trigger.
110108
*/
111109
export const typed = <T, U>(
@@ -116,7 +114,7 @@ export const typed = <T, U>(
116114
handler = {
117115
handler,
118116
format: new JsonInvocationFormat<T, U>(),
119-
}
117+
};
120118
}
121119
register(functionName, 'typed', handler);
122-
};
120+
};

src/function_wrappers.ts

+24-15
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
HandlerFunction,
2929
TypedHandlerFunction,
3030
InvocationRequest,
31-
InvocationResponse
31+
InvocationResponse,
3232
} from './functions';
3333
import {CloudEvent} from './functions';
3434
import {SignatureType} from './types';
@@ -110,7 +110,7 @@ const wrapHttpFunction = (execute: HttpFunction): RequestHandler => {
110110
console.error(`Exception from a finished function: ${err}`);
111111
} else {
112112
res.locals.functionExecutionFinished = true;
113-
sendCrashResponse({ err, res });
113+
sendCrashResponse({err, res});
114114
}
115115
};
116116

@@ -211,19 +211,19 @@ const wrapTypedFunction = (
211211
): RequestHandler => {
212212
class InvocationRequestImpl implements InvocationRequest {
213213
constructor(private req: Request) {}
214-
214+
215215
body(): string | Buffer {
216216
return this.req.body;
217217
}
218-
218+
219219
header(header: string): string | undefined {
220220
return this.req.header(header);
221221
}
222222
}
223223

224224
class InvocationResponseImpl implements InvocationResponse {
225-
constructor(private res: Response) { }
226-
225+
constructor(private res: Response) {}
226+
227227
setHeader(key: string, value: string): void {
228228
this.res.set(key, value);
229229
}
@@ -235,29 +235,38 @@ const wrapTypedFunction = (
235235
}
236236
}
237237

238-
const typedHandlerWrapper: HttpFunction = async (req: Request, res: Response) => {
239-
let reqTyped: any;
238+
const typedHandlerWrapper: HttpFunction = async (
239+
req: Request,
240+
res: Response
241+
) => {
242+
let reqTyped: unknown;
240243
try {
241-
reqTyped = typedFunction.format.deserializeRequest(new InvocationRequestImpl(req));
244+
reqTyped = typedFunction.format.deserializeRequest(
245+
new InvocationRequestImpl(req)
246+
);
242247
} catch (err) {
243248
console.log(err);
244249
sendCrashResponse({
245-
err, res,
246-
statusOverride: 400 // 400 Bad Request
250+
err,
251+
res,
252+
statusOverride: 400, // 400 Bad Request
247253
});
248254
return;
249255
}
250256

251-
let resTyped: any = typedFunction.handler(reqTyped);
257+
let resTyped: unknown = typedFunction.handler(reqTyped);
252258
if (resTyped instanceof Promise) {
253259
resTyped = await resTyped;
254260
}
255261

256-
typedFunction.format.serializeResponse(new InvocationResponseImpl(res), resTyped);
257-
}
262+
typedFunction.format.serializeResponse(
263+
new InvocationResponseImpl(res),
264+
resTyped
265+
);
266+
};
258267

259268
return wrapHttpFunction(typedHandlerWrapper);
260-
}
269+
};
261270

262271
/**
263272
* Wraps a user function with the provided signature type in an express

src/functions.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export interface CloudFunctionsContext {
149149
export type Context = CloudFunctionsContext | CloudEvent<unknown>;
150150

151151
/**
152-
* Invocation request interface describes the properties of an invocation.
152+
* InvocationRequest represents the properties of an invocation over HTTP.
153153
*/
154154
export interface InvocationRequest {
155155
/** Returns the request body as either a string or a Buffer if the body is binary. */
@@ -197,14 +197,17 @@ export interface InvocationFormat<T, U> {
197197
*/
198198
export class JsonInvocationFormat<T, U> implements InvocationFormat<T, U> {
199199
deserializeRequest(request: InvocationRequest): T {
200-
let body = request.body();
200+
const body = request.body();
201201
if (typeof body !== 'string') {
202-
throw new Error("Unsupported Content-Type, expected application/json");
202+
throw new Error('Unsupported Content-Type, expected application/json');
203203
}
204204
try {
205205
return JSON.parse(body);
206206
} catch (e) {
207-
throw new Error("Failed to parse malformatted JSON in request: " + (e as SyntaxError).message)
207+
throw new Error(
208+
'Failed to parse malformatted JSON in request: ' +
209+
(e as SyntaxError).message
210+
);
208211
}
209212
}
210213

src/logger.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function sendCrashResponse({
2828
callback,
2929
silent = false,
3030
statusHeader = 'crash',
31-
statusOverride = 500
31+
statusOverride = 500,
3232
}: {
3333
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3434
err: Error | any;

src/server.ts

+12-8
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,18 @@ export function getServer(
8686

8787
// Apply middleware
8888
if (functionSignatureType === 'typed') {
89-
app.use(bodyParser.text({
90-
limit: requestLimit,
91-
type: '*/json',
92-
}))
93-
app.use(bodyParser.text({
94-
limit: requestLimit,
95-
type: 'text/*',
96-
}))
89+
app.use(
90+
bodyParser.text({
91+
limit: requestLimit,
92+
type: '*/json',
93+
})
94+
);
95+
app.use(
96+
bodyParser.text({
97+
limit: requestLimit,
98+
type: 'text/*',
99+
})
100+
);
97101
} else {
98102
app.use(bodyParser.json(cloudEventsBodySavingOptions));
99103
app.use(bodyParser.json(defaultBodySavingOptions));

test/function_wrappers.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
import * as assert from 'assert';
2-
import * as sinon from 'sinon';
32
import {Request, Response} from 'express';
43
import {
54
Context,
65
CloudEvent,
76
JsonInvocationFormat,
87
TypedHandlerFunction,
9-
InvocationRequest,
10-
InvocationResponse,
118
} from '../src/functions';
129
import {wrapUserFunction} from '../src/function_wrappers';
13-
import {send} from 'process';
1410
import EventEmitter = require('events');
1511

1612
describe('wrapUserFunction', () => {
@@ -40,7 +36,7 @@ describe('wrapUserFunction', () => {
4036

4137
class ResponseMock extends EventEmitter {
4238
public headers: {[key: string]: string} = {};
43-
public statusCode: number = 200;
39+
public statusCode = 200;
4440
public body: string | undefined;
4541
public locals = {
4642
functionExecutionFinished: false,
@@ -151,8 +147,10 @@ describe('wrapUserFunction', () => {
151147
});
152148

153149
describe('wraps a Typed JSON function', () => {
154-
155-
const synchronousJsonFunction: TypedHandlerFunction<EchoMessage, EchoMessage> = {
150+
const synchronousJsonFunction: TypedHandlerFunction<
151+
EchoMessage,
152+
EchoMessage
153+
> = {
156154
format: new JsonInvocationFormat<EchoMessage, EchoMessage>(),
157155
handler: (req: EchoMessage): EchoMessage => {
158156
return {
@@ -235,7 +233,7 @@ describe('wrapUserFunction', () => {
235233

236234
const typedFn: TypedHandlerFunction<EchoMessage, EchoMessage> = {
237235
format: new JsonInvocationFormat<EchoMessage, EchoMessage>(),
238-
handler: (req: EchoMessage): Promise<EchoMessage> => {
236+
handler: (): Promise<EchoMessage> => {
239237
return new Promise((_, reject) => {
240238
setImmediate(() => reject(new Error('an error')));
241239
});

test/integration/typed.ts

+30-22
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,31 @@ describe('Typed Function', () => {
3232
}
3333

3434
before(() => {
35-
functions.typed<NameConcatRequest, NameConcatResponse>('nameConcatFunc', req => {
36-
callCount += 1;
37-
return {
38-
combined: req.first + req.last
39-
};
40-
});
35+
functions.typed<NameConcatRequest, NameConcatResponse>(
36+
'nameConcatFunc',
37+
req => {
38+
callCount += 1;
39+
return {
40+
combined: req.first + req.last,
41+
};
42+
}
43+
);
4144

4245
// Async function is expected to test asynchronous codepaths for echo handling.
43-
functions.typed<NameConcatRequest, NameConcatResponse>('nameConcatFuncAsync', req => {
44-
callCount += 1;
45-
return new Promise(accept => setImmediate(() => accept({combined: req.first + req.last})));
46-
});
46+
functions.typed<NameConcatRequest, NameConcatResponse>(
47+
'nameConcatFuncAsync',
48+
req => {
49+
callCount += 1;
50+
return new Promise(accept =>
51+
setImmediate(() => accept({combined: req.first + req.last}))
52+
);
53+
}
54+
);
4755

4856
// Error prone function tests simply throwing an error a synchronous function
4957
functions.typed<NameConcatRequest, NameConcatResponse>(
5058
'errorProneTypedFunc',
51-
req => {
59+
() => {
5260
callCount += 1;
5361
throw new Error('synchronous error');
5462
}
@@ -57,7 +65,7 @@ describe('Typed Function', () => {
5765
// Error prone async function throws an asynchronous error
5866
functions.typed<NameConcatRequest, NameConcatResponse>(
5967
'errorProneAsyncTypedFunc',
60-
req => {
68+
() => {
6169
callCount += 1;
6270
return new Promise((_, reject) =>
6371
setImmediate(() => reject(new Error('async error')))
@@ -79,9 +87,9 @@ describe('Typed Function', () => {
7987
const testData = [
8088
{
8189
func: 'nameConcatFunc',
82-
name: 'basic POST request to \'/\'/',
83-
requestBody: { first: 'Jane', last: 'Doe' },
84-
expectedBody: { combined: 'JaneDoe' },
90+
name: "basic POST request to '/'/",
91+
requestBody: {first: 'Jane', last: 'Doe'},
92+
expectedBody: {combined: 'JaneDoe'},
8593
expectedStatus: 200,
8694
expectedCallCount: 1,
8795
},
@@ -98,16 +106,16 @@ describe('Typed Function', () => {
98106
func: 'nameConcatFunc',
99107
name: 'POST /foo PATH',
100108
path: '/foo',
101-
requestBody: { first: 'Jane', last: 'Doe' },
102-
expectedBody: { combined: 'JaneDoe' },
109+
requestBody: {first: 'Jane', last: 'Doe'},
110+
expectedBody: {combined: 'JaneDoe'},
103111
expectedStatus: 200,
104112
expectedCallCount: 1,
105113
},
106114
{
107115
func: 'nameConcatFuncAsync',
108-
name: 'async basic POST request to \'/\'',
109-
requestBody: { first: 'Jane', last: 'Doe' },
110-
expectedBody: { combined: 'JaneDoe' },
116+
name: "async basic POST request to '/'",
117+
requestBody: {first: 'Jane', last: 'Doe'},
118+
expectedBody: {combined: 'JaneDoe'},
111119
expectedStatus: 200,
112120
expectedCallCount: 1,
113121
},
@@ -125,10 +133,10 @@ describe('Typed Function', () => {
125133
},
126134
];
127135

128-
it('does not support \'GET\' HTTP verb', async () => {
136+
it("does not support 'GET' HTTP verb", async () => {
129137
const st = supertest(getTestServer('nameConcatFunc'));
130138
await st.get('/').expect(404);
131-
})
139+
});
132140

133141
testData.forEach(test => {
134142
it(test.name, async () => {

0 commit comments

Comments
 (0)