Skip to content

Commit b678aea

Browse files
authored
Typescript Definitions: Remove 'I' prefix and make methods as methods (#166)
* remove I prefix on interfaces * making sure methods show up as methods * revert accidental package name change * custom namespacing * remove merge info * remove package-lock changes * clean up * add preview tag for first release * addressing Chris's CR comments * don't do type assertion without guards * more documentation around what happens to your Promise<any> result * interface change * 1.0.1.1-preview * beta 1 instead of preview to be able to version preview bits * resolve type error * update to interface.d.ts too * removing unnecessary inputs * fixing AzureFunction type * revert changes trying to type args:any[] * let => const
1 parent a79d4c8 commit b678aea

File tree

10 files changed

+149
-131
lines changed

10 files changed

+149
-131
lines changed

src/Context.ts

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import { FunctionInfo } from './FunctionInfo';
22
import { fromRpcHttp, fromTypedData, getNormalizedBindingData, getBindingDefinitions } from './Converters';
33
import { AzureFunctionsRpcMessages as rpc } from '../azure-functions-language-worker-protobuf/src/rpc';
4-
import { Request, HttpRequest } from './http/Request';
4+
import { Request, RequestProperties } from './http/Request';
55
import { Response } from './http/Response';
66
import LogLevel = rpc.RpcLog.Level;
7-
import { IContext, IExecutionContext, ILogger, IDoneCallback, IBindingDefinition } from './public/Interfaces'
7+
import { Context, ExecutionContext, Logger, BindingDefinition, HttpRequest } from './public/Interfaces'
88

9-
export function CreateContextAndInputs(info: FunctionInfo, request: rpc.IInvocationRequest, logCallback: ILogCallback, callback: IResultCallback) {
10-
let context = new Context(info, request, logCallback, callback);
9+
export function CreateContextAndInputs(info: FunctionInfo, request: rpc.IInvocationRequest, logCallback: LogCallback, callback: ResultCallback) {
10+
let context = new InvocationContext(info, request, logCallback, callback);
1111

12-
let bindings: IDict<any> = {};
13-
let inputs: any[] = [];
14-
let httpInput: HttpRequest | undefined;
12+
let bindings: Dict<any> = {};
13+
let inputs: InputTypes[] = [];
14+
let httpInput: RequestProperties | undefined;
1515
for (let binding of <rpc.IParameterBinding[]>request.inputData) {
1616
if (binding.data && binding.name) {
17-
let input: any;
17+
let input: InputTypes;
1818
if (binding.data && binding.data.http) {
1919
input = httpInput = fromRpcHttp(binding.data.http);
2020
} else {
@@ -31,23 +31,23 @@ export function CreateContextAndInputs(info: FunctionInfo, request: rpc.IInvocat
3131
context.res = new Response(context.done);
3232
}
3333
return {
34-
context: <IContext>context,
34+
context: <Context>context,
3535
inputs: inputs
3636
}
3737
}
3838

39-
class Context implements IContext {
39+
class InvocationContext implements Context {
4040
invocationId: string;
41-
executionContext: IExecutionContext;
42-
bindings: IDict<any>;
43-
bindingData: IDict<any>;
44-
bindingDefinitions: IBindingDefinition[];
45-
log: ILogger;
41+
executionContext: ExecutionContext;
42+
bindings: Dict<any>;
43+
bindingData: Dict<any>;
44+
bindingDefinitions: BindingDefinition[];
45+
log: Logger;
4646
req?: Request;
4747
res?: Response;
48-
done: IDoneCallback;
48+
done: DoneCallback;
4949

50-
constructor(info: FunctionInfo, request: rpc.IInvocationRequest, logCallback: ILogCallback, callback: IResultCallback) {
50+
constructor(info: FunctionInfo, request: rpc.IInvocationRequest, logCallback: LogCallback, callback: ResultCallback) {
5151
this.invocationId = <string>request.invocationId;
5252
this.executionContext = {
5353
invocationId: this.invocationId,
@@ -87,31 +87,32 @@ class Context implements IContext {
8787
}
8888
}
8989

90-
function getLogger(invocationId: string, functionName: string, log: ILogCallback): ILogger{
90+
function getLogger(invocationId: string, functionName: string, log: LogCallback): Logger{
9191
return Object.assign(
92-
<ILog>(...args: any[]) => log(LogLevel.Information, ...args),
92+
<Log>(...args: any[]) => log(LogLevel.Information, ...args),
9393
{
94-
error: <ILog>(...args: any[]) => log(LogLevel.Error, ...args),
95-
warn: <ILog>(...args: any[]) => log(LogLevel.Warning, ...args),
96-
info: <ILog>(...args: any[]) => log(LogLevel.Information, ...args),
97-
verbose: <ILog>(...args: any[]) => log(LogLevel.Trace, ...args)
94+
error: <Log>(...args: any[]) => log(LogLevel.Error, ...args),
95+
warn: <Log>(...args: any[]) => log(LogLevel.Warning, ...args),
96+
info: <Log>(...args: any[]) => log(LogLevel.Information, ...args),
97+
verbose: <Log>(...args: any[]) => log(LogLevel.Trace, ...args)
9898
}
9999
);
100100
}
101101

102-
export interface IInvocationResult {
102+
export interface InvocationResult {
103103
return: any;
104-
bindings: IDict<any>;
104+
bindings: Dict<any>;
105105
}
106106

107-
export interface ILogCallback {
108-
(level: LogLevel, ...args: any[]): void;
109-
}
107+
export type DoneCallback = (err?: Error | string, result?: any) => void;
110108

111-
export interface IResultCallback {
112-
(err?: any, result?: IInvocationResult): void;
113-
}
109+
export type LogCallback = (level: LogLevel, ...args: any[]) => void;
110+
111+
export type ResultCallback = (err?: any, result?: InvocationResult) => void;
114112

115-
export interface IDict<T> {
113+
export interface Dict<T> {
116114
[key: string]: T
117-
}
115+
}
116+
117+
// Allowed input types
118+
export type InputTypes = HttpRequest | string | Buffer | null | undefined;

src/Converters.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import { AzureFunctionsRpcMessages as rpc } from '../azure-functions-language-worker-protobuf/src/rpc';
22
import { FunctionInfo } from './FunctionInfo';
3-
import { HttpRequest } from './http/Request';
4-
import { IDict } from '../src/Context';
5-
import { IBindingDefinition } from './public/Interfaces';
6-
export function fromRpcHttp(rpcHttp: rpc.IRpcHttp): HttpRequest {
7-
let httpContext: HttpRequest = {
3+
import { RequestProperties } from './http/Request';
4+
import { Dict } from '../src/Context';
5+
import { BindingDefinition } from './public/Interfaces';
6+
7+
type BindingDirection = 'in' | 'out' | 'inout' | undefined;
8+
9+
export function fromRpcHttp(rpcHttp: rpc.IRpcHttp): RequestProperties {
10+
const httpContext: RequestProperties = {
811
method: <string>rpcHttp.method,
912
url: <string>rpcHttp.url,
1013
originalUrl: <string>rpcHttp.url,
11-
headers: <IDict<string>>rpcHttp.headers,
12-
query: <IDict<string>>rpcHttp.query,
13-
params: <IDict<string>>rpcHttp.params,
14+
headers: <Dict<string>>rpcHttp.headers,
15+
query: <Dict<string>>rpcHttp.query,
16+
params: <Dict<string>>rpcHttp.params,
1417
body: fromTypedData(<rpc.ITypedData>rpcHttp.body),
1518
rawBody: fromTypedData(<rpc.ITypedData>rpcHttp.rawBody, false),
1619
};
@@ -73,7 +76,7 @@ export function toTypedData(inputObject): rpc.ITypedData {
7376
}
7477
}
7578

76-
export function getBindingDefinitions(info: FunctionInfo): IBindingDefinition[] {
79+
export function getBindingDefinitions(info: FunctionInfo): BindingDefinition[] {
7780
let bindings = info.bindings;
7881
if (!bindings) {
7982
return [];
@@ -83,13 +86,13 @@ export function getBindingDefinitions(info: FunctionInfo): IBindingDefinition[]
8386
.map(name => { return {
8487
name: name,
8588
type: bindings[name].type || "",
86-
direction: getDirectionName(bindings[name].direction) || ""
89+
direction: getDirectionName(bindings[name].direction)
8790
};
8891
});
8992
}
9093

91-
export function getNormalizedBindingData(request: rpc.IInvocationRequest): IDict<any> {
92-
let bindingData: IDict<any> = {
94+
export function getNormalizedBindingData(request: rpc.IInvocationRequest): Dict<any> {
95+
let bindingData: Dict<any> = {
9396
invocationId: request.invocationId
9497
};
9598
// node binding data is camel cased due to language convention
@@ -99,8 +102,13 @@ export function getNormalizedBindingData(request: rpc.IInvocationRequest): IDict
99102
return bindingData;
100103
}
101104

102-
function getDirectionName(direction: rpc.BindingInfo.Direction|null|undefined): string | undefined {
103-
return Object.keys(rpc.BindingInfo.Direction).find(k => rpc.BindingInfo.Direction[k] === direction);
105+
function getDirectionName(direction: rpc.BindingInfo.Direction|null|undefined): BindingDirection {
106+
let directionName = Object.keys(rpc.BindingInfo.Direction).find(k => rpc.BindingInfo.Direction[k] === direction);
107+
return isBindingDirection(directionName)? directionName as BindingDirection : undefined;
108+
}
109+
110+
function isBindingDirection(input: string | undefined): boolean {
111+
return (input == 'in' || input == 'out' || input == 'inout')
104112
}
105113

106114
// Recursively convert keys of objects to camel case
@@ -117,4 +125,4 @@ function convertKeysToCamelCase(obj: any) {
117125
}
118126
}
119127
return output;
120-
}
128+
}

src/WorkerChannel.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { format, isFunction } from 'util';
33
import { AzureFunctionsRpcMessages as rpc } from '../azure-functions-language-worker-protobuf/src/rpc';
44
import Status = rpc.StatusResult.Status;
55
import { IFunctionLoader } from './FunctionLoader';
6-
import { CreateContextAndInputs, ILogCallback, IResultCallback } from './Context';
6+
import { CreateContextAndInputs, LogCallback, ResultCallback } from './Context';
77
import { IEventStream } from './GrpcService';
88
import { toTypedData } from './Converters';
99
import { systemError } from './utils/Logger';
@@ -93,7 +93,7 @@ export class WorkerChannel {
9393

9494
public invocationRequest(requestId: string, msg: rpc.InvocationRequest) {
9595
let info = this._functionLoader.getInfo(<string>msg.functionId);
96-
let logCallback: ILogCallback = (level, ...args) => {
96+
let logCallback: LogCallback = (level, ...args) => {
9797
this.log({
9898
invocationId: msg.invocationId,
9999
category: `${info.name}.Invocation`,
@@ -102,7 +102,7 @@ export class WorkerChannel {
102102
});
103103
}
104104

105-
let resultCallback: IResultCallback = (err, result) => {
105+
let resultCallback: ResultCallback = (err, result) => {
106106
let status: rpc.IStatusResult = {
107107
status: rpc.StatusResult.Status.Success
108108
};

src/http/Request.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
3-
import { IRequest } from '../public/Interfaces';
3+
import { HttpRequest } from '../public/Interfaces';
44

5-
export class HttpRequest {
5+
export class RequestProperties implements HttpRequest {
66
method: string = "";
77
url: string = "";
88
originalUrl: string = "";
@@ -14,8 +14,8 @@ export class HttpRequest {
1414
[key:string]: any;
1515
}
1616

17-
export class Request extends HttpRequest implements IRequest {
18-
constructor(httpInput: HttpRequest) {
17+
export class Request extends RequestProperties {
18+
constructor(httpInput: RequestProperties) {
1919
super();
2020
Object.assign(this, httpInput);
2121
}

src/public/Interfaces.ts

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,29 @@
22
* Interface for your Azure Function code. This function must be exported (via module.exports or exports)
33
* and will execute when triggered. It is recommended that you declare this function as async, which
44
* implicitly returns a Promise.
5-
* @param context IContext object passed to your function from the Azure Functions runtime.
5+
* @param context Context object passed to your function from the Azure Functions runtime.
66
* @param {any[]} args Optional array of input and trigger binding data. These binding data are passed to the
7-
* function in the same order that they are defined in function.json.
8-
* @returns Output bindings (optional).
7+
* function in the same order that they are defined in function.json. Valid input types are string, HttpRequest,
8+
* and Buffer.
9+
* @returns Output bindings (optional). If you are returning a result from a Promise (or an async function), this
10+
* result will be passed to JSON.stringify unless it is a string, Buffer, ArrayBufferView, or number.
911
*/
10-
export interface IFunction {
11-
(context: IContext, ...args: any[]): Promise<any> | void;
12-
}
12+
export type AzureFunction = ((context: Context, ...args: any[]) => Promise<any> | void);
1313

1414
/**
1515
* The context object can be used for writing logs, reading data from bindings, setting outputs and using
1616
* the context.done callback when your exported function is synchronous. A context object is passed
1717
* to your function from the Azure Functions runtime on function invocation.
1818
*/
19-
export interface IContext {
19+
export interface Context {
2020
/**
2121
* A unique GUID per function invocation.
2222
*/
2323
invocationId: string;
2424
/**
2525
* Function execution metadata.
2626
*/
27-
executionContext: IExecutionContext;
27+
executionContext: ExecutionContext;
2828
/**
2929
* Input and trigger binding data, as defined in function.json. Properties on this object are dynamically
3030
* generated and named based off of the "name" property in function.json.
@@ -37,24 +37,26 @@ export interface IContext {
3737
/**
3838
* Bindings your function uses, as defined in function.json.
3939
*/
40-
bindingDefinitions: IBindingDefinition[];
40+
bindingDefinitions: BindingDefinition[];
4141
/**
42-
* Calling directly allows you to write streaming function logs at the default trace level.
42+
* Allows you to write streaming function logs. Calling directly allows you to write streaming function logs
43+
* at the default trace level.
4344
*/
44-
log: ILogger;
45+
log: Logger;
4546
/**
4647
* A callback function that signals to the runtime that your code has completed. If your function is synchronous,
4748
* you must call context.done at the end of execution. If your function is asynchronous, you should not use this
4849
* callback.
4950
*
5051
* @param err A user-defined error to pass back to the runtime. If present, your function execution will fail.
51-
* @param result An object containing output binding data.
52+
* @param result An object containing output binding data. `result` will be passed to JSON.stringify unless it is
53+
* a string, Buffer, ArrayBufferView, or number.
5254
*/
53-
done: IDoneCallback;
55+
done(err?: Error | string, result?: any): void;
5456
/**
5557
* HTTP request object. Provided to your function when using HTTP Bindings.
5658
*/
57-
req?: IRequest;
59+
req?: HttpRequest;
5860
/**
5961
* HTTP response object. Provided to your function when using HTTP Bindings.
6062
*/
@@ -64,7 +66,7 @@ export interface IContext {
6466
/**
6567
* HTTP request object. Provided to your function when using HTTP Bindings.
6668
*/
67-
export interface IRequest {
69+
export interface HttpRequest {
6870
/**
6971
* HTTP request method used to invoke this function.
7072
*/
@@ -86,16 +88,16 @@ export interface IRequest {
8688
*/
8789
params: {[key:string]: string};
8890
/**
89-
* The HTTP request body
91+
* The HTTP request body.
9092
*/
9193
body?: any;
9294
/**
93-
* The HTTP request body as a UTF-8 string
95+
* The HTTP request body as a UTF-8 string.
9496
*/
9597
rawbody?: any;
9698
}
9799

98-
export interface IExecutionContext {
100+
export interface ExecutionContext {
99101
/**
100102
* A unique GUID per function invocation.
101103
*/
@@ -111,7 +113,7 @@ export interface IExecutionContext {
111113
functionDirectory: string;
112114
}
113115

114-
export interface IBindingDefinition {
116+
export interface BindingDefinition {
115117
/**
116118
* The name of your binding, as defined in function.json.
117119
*/
@@ -121,37 +123,33 @@ export interface IBindingDefinition {
121123
*/
122124
type: string,
123125
/**
124-
* The direction of your binding ('in', 'out', or 'inout'), as defined in function.json.
126+
* The direction of your binding, as defined in function.json.
125127
*/
126-
direction: string
128+
direction: 'in' | 'out' | 'inout' | undefined;
127129
}
128130

129-
export interface ILog {
130-
(...args: any[]): void;
131-
}
132-
133131
/**
134132
* Allows you to write streaming function logs.
135133
*/
136-
export interface ILogger extends ILog {
134+
export interface Logger {
135+
/**
136+
* Writes streaming function logs at the default trace level.
137+
*/
138+
(...args: any[]): void;
137139
/**
138140
* Writes to error level logging or lower.
139141
*/
140-
error: ILog;
142+
error(...args: any[]): void;
141143
/**
142144
* Writes to warning level logging or lower.
143145
*/
144-
warn: ILog;
146+
warn(...args: any[]): void;
145147
/**
146148
* Writes to info level logging or lower.
147149
*/
148-
info: ILog;
150+
info(...args: any[]): void;
149151
/**
150152
* Writes to verbose level logging.
151153
*/
152-
verbose: ILog;
154+
verbose(...args: any[]): void;
153155
}
154-
155-
export interface IDoneCallback {
156-
(err?: any, result?: any): void;
157-
}

0 commit comments

Comments
 (0)