-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
577 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as types from '@azure/functions'; | ||
import { HookContext } from './HookContext'; | ||
|
||
export class AppStartContext extends HookContext implements types.AppStartContext {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as types from '@azure/functions'; | ||
import { HookContext } from './HookContext'; | ||
|
||
export class AppTerminateContext extends HookContext implements types.AppTerminateContext {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as types from '@azure/functions'; | ||
import { ReadOnlyError } from '../errors'; | ||
import { nonNullProp } from '../utils/nonNull'; | ||
|
||
export class HookContext implements types.HookContext { | ||
#init: types.HookContextInit; | ||
|
||
constructor(init?: types.HookContextInit) { | ||
this.#init = init ?? {}; | ||
this.#init.hookData ??= {}; | ||
} | ||
|
||
get hookData(): Record<string, unknown> { | ||
return nonNullProp(this.#init, 'hookData'); | ||
} | ||
|
||
set hookData(_value: unknown) { | ||
throw new ReadOnlyError('hookData'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as types from '@azure/functions'; | ||
import { InvocationContext } from '../InvocationContext'; | ||
import { ReadOnlyError } from '../errors'; | ||
import { nonNullProp } from '../utils/nonNull'; | ||
import { HookContext } from './HookContext'; | ||
|
||
export class InvocationHookContext extends HookContext implements types.InvocationHookContext { | ||
#init: types.InvocationHookContextInit; | ||
|
||
constructor(init?: types.InvocationHookContextInit) { | ||
super(init); | ||
this.#init = init ?? {}; | ||
this.#init.inputs ??= []; | ||
this.#init.invocationContext ??= new InvocationContext(); | ||
} | ||
|
||
get invocationContext(): types.InvocationContext { | ||
return nonNullProp(this.#init, 'invocationContext'); | ||
} | ||
|
||
set invocationContext(_value: types.InvocationContext) { | ||
throw new ReadOnlyError('invocationContext'); | ||
} | ||
|
||
get inputs(): unknown[] { | ||
return nonNullProp(this.#init, 'inputs'); | ||
} | ||
|
||
set inputs(value: unknown[]) { | ||
this.#init.inputs = value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as types from '@azure/functions'; | ||
import { InvocationHookContext } from './InvocationHookContext'; | ||
|
||
export class PostInvocationContext extends InvocationHookContext implements types.PostInvocationContext { | ||
#init: types.PostInvocationContextInit; | ||
|
||
constructor(init?: types.PostInvocationContextInit) { | ||
super(init); | ||
this.#init = init ?? {}; | ||
} | ||
|
||
get result(): unknown { | ||
return this.#init.result; | ||
} | ||
|
||
set result(value: unknown) { | ||
this.#init.result = value; | ||
} | ||
|
||
get error(): unknown { | ||
return this.#init.error; | ||
} | ||
|
||
set error(value: unknown) { | ||
this.#init.error = value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as types from '@azure/functions'; | ||
import { nonNullProp } from '../utils/nonNull'; | ||
import { InvocationHookContext } from './InvocationHookContext'; | ||
|
||
export class PreInvocationContext extends InvocationHookContext implements types.PreInvocationContext { | ||
#init: types.PreInvocationContextInit; | ||
|
||
constructor(init?: types.PreInvocationContextInit) { | ||
super(init); | ||
this.#init = init ?? {}; | ||
this.#init.functionCallback ??= () => {}; | ||
} | ||
|
||
get functionHandler(): types.FunctionHandler { | ||
return nonNullProp(this.#init, 'functionCallback'); | ||
} | ||
|
||
set functionHandler(value: types.FunctionHandler) { | ||
this.#init.functionCallback = value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import { AppStartHandler, AppTerminateHandler, PostInvocationHandler, PreInvocationHandler } from '@azure/functions'; | ||
import * as coreTypes from '@azure/functions-core'; | ||
import { Disposable } from '../utils/Disposable'; | ||
import { tryGetCoreApiLazy } from '../utils/tryGetCoreApiLazy'; | ||
import { AppStartContext } from './AppStartContext'; | ||
import { AppTerminateContext } from './AppTerminateContext'; | ||
import { PostInvocationContext } from './PostInvocationContext'; | ||
import { PreInvocationContext } from './PreInvocationContext'; | ||
|
||
function registerHook(hookName: string, callback: coreTypes.HookCallback): coreTypes.Disposable { | ||
const coreApi = tryGetCoreApiLazy(); | ||
if (!coreApi) { | ||
console.warn( | ||
`WARNING: Skipping call to register ${hookName} hook because the "@azure/functions" package is in test mode.` | ||
); | ||
return new Disposable(() => { | ||
console.warn( | ||
`WARNING: Skipping call to dispose ${hookName} hook because the "@azure/functions" package is in test mode.` | ||
); | ||
}); | ||
} else { | ||
return coreApi.registerHook(hookName, callback); | ||
} | ||
} | ||
|
||
export function appStart(handler: AppStartHandler): Disposable { | ||
return registerHook('appStart', (coreContext) => { | ||
return handler(new AppStartContext(coreContext)); | ||
}); | ||
} | ||
|
||
export function appTerminate(handler: AppTerminateHandler): Disposable { | ||
return registerHook('appTerminate', (coreContext) => { | ||
return handler(new AppTerminateContext(coreContext)); | ||
}); | ||
} | ||
|
||
export function preInvocation(handler: PreInvocationHandler): Disposable { | ||
return registerHook('preInvocation', (coreContext) => { | ||
return handler(new PreInvocationContext(coreContext)); | ||
}); | ||
} | ||
|
||
export function postInvocation(handler: PostInvocationHandler): Disposable { | ||
return registerHook('postInvocation', (coreContext) => { | ||
return handler(new PostInvocationContext(coreContext)); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,17 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
export { InvocationContext } from './InvocationContext'; | ||
export * as app from './app'; | ||
export { AppStartContext } from './hooks/AppStartContext'; | ||
export { AppTerminateContext } from './hooks/AppTerminateContext'; | ||
export { HookContext } from './hooks/HookContext'; | ||
export { InvocationHookContext } from './hooks/InvocationHookContext'; | ||
export { PostInvocationContext } from './hooks/PostInvocationContext'; | ||
export { PreInvocationContext } from './hooks/PreInvocationContext'; | ||
export { HttpRequest } from './http/HttpRequest'; | ||
export { HttpResponse } from './http/HttpResponse'; | ||
export * as input from './input'; | ||
export { InvocationContext } from './InvocationContext'; | ||
export * as output from './output'; | ||
export * as trigger from './trigger'; | ||
export { Disposable } from './utils/Disposable'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
/** | ||
* Based off of VS Code | ||
* https://github.com/microsoft/vscode/blob/7bed4ce3e9f5059b5fc638c348f064edabcce5d2/src/vs/workbench/api/common/extHostTypes.ts#L65 | ||
*/ | ||
export class Disposable { | ||
static from(...inDisposables: { dispose(): any }[]): Disposable { | ||
let disposables: ReadonlyArray<{ dispose(): any }> | undefined = inDisposables; | ||
return new Disposable(function () { | ||
if (disposables) { | ||
for (const disposable of disposables) { | ||
if (disposable && typeof disposable.dispose === 'function') { | ||
disposable.dispose(); | ||
} | ||
} | ||
disposables = undefined; | ||
} | ||
}); | ||
} | ||
|
||
#callOnDispose?: () => any; | ||
|
||
constructor(callOnDispose: () => any) { | ||
this.#callOnDispose = callOnDispose; | ||
} | ||
|
||
dispose(): any { | ||
if (typeof this.#callOnDispose === 'function') { | ||
this.#callOnDispose(); | ||
this.#callOnDispose = undefined; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as coreTypes from '@azure/functions-core'; | ||
|
||
let coreApi: typeof coreTypes | undefined | null; | ||
export function tryGetCoreApiLazy(): typeof coreTypes | null { | ||
if (coreApi === undefined) { | ||
try { | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
coreApi = <typeof coreTypes>require('@azure/functions-core'); | ||
} catch { | ||
coreApi = null; | ||
} | ||
} | ||
return coreApi; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import { expect } from 'chai'; | ||
import 'mocha'; | ||
import { | ||
AppStartContext, | ||
AppTerminateContext, | ||
HookContext, | ||
InvocationContext, | ||
InvocationHookContext, | ||
PostInvocationContext, | ||
PreInvocationContext, | ||
app, | ||
} from '../src/index'; | ||
|
||
describe('hooks', () => { | ||
it("register doesn't throw error in unit test mode", () => { | ||
app.hook.appStart(() => {}); | ||
app.hook.appTerminate(() => {}); | ||
app.hook.postInvocation(() => {}); | ||
const registeredHook = app.hook.preInvocation(() => {}); | ||
registeredHook.dispose(); | ||
}); | ||
|
||
it('AppTerminateContext', () => { | ||
const context = new AppTerminateContext(); | ||
validateHookContext(context); | ||
}); | ||
|
||
it('AppStartContext', () => { | ||
const context = new AppStartContext(); | ||
validateHookContext(context); | ||
}); | ||
|
||
it('PreInvocationContext', () => { | ||
const context = new PreInvocationContext(); | ||
validateInvocationHookContext(context); | ||
expect(typeof context.functionHandler).to.equal('function'); | ||
|
||
const updatedFunc = () => { | ||
console.log('changed'); | ||
}; | ||
context.functionHandler = updatedFunc; | ||
expect(context.functionHandler).to.equal(updatedFunc); | ||
}); | ||
|
||
it('PostInvocationContext', () => { | ||
const context = new PostInvocationContext(); | ||
validateInvocationHookContext(context); | ||
expect(context.error).to.equal(undefined); | ||
expect(context.result).to.equal(undefined); | ||
|
||
const newError = new Error('test1'); | ||
context.error = newError; | ||
context.result = 'test2'; | ||
expect(context.error).to.equal(newError); | ||
expect(context.result).to.equal('test2'); | ||
}); | ||
|
||
function validateInvocationHookContext(context: InvocationHookContext): void { | ||
validateHookContext(context); | ||
expect(context.inputs).to.deep.equal([]); | ||
expect(context.invocationContext).to.deep.equal(new InvocationContext()); | ||
|
||
expect(() => { | ||
context.invocationContext = <any>{}; | ||
}).to.throw(); | ||
context.inputs = ['change']; | ||
expect(context.inputs).to.deep.equal(['change']); | ||
} | ||
|
||
function validateHookContext(context: HookContext) { | ||
expect(context.hookData).to.deep.equal({}); | ||
expect(() => { | ||
context.hookData = {}; | ||
}).to.throw(); | ||
} | ||
}); |
Oops, something went wrong.