Releases: thaitype/nammatham
0.4.0-alpha
What's Changed
1. Change way to inject arguments in method
Azure Functions has arguments signature start with Context
and rest any object like this:
import { AzureFunction } from '@azure/functions'; // 3.5.0
type AzureFunction = (context: Context, ...args: any[]) => Promise<any> | void
Our implementation, (Namantham@0.3.0
) will auto inject Context
from BaseController
in function bootstrap phase
and the method that @functionName
decorator attach with it, will passing arguments without Context
object.
export function funcBootstrap(option: IFuncBootstrapOption) {
//...
controllerInstance.init(azureFunctionContext);
(controllerInstance as any)[option.methodName](...azureFunctionArgs);
}
This PR will change the first arguments of method injection with ContextBindings
as shown in:
export function funcBootstrap(option: IFuncBootstrapOption) {
// ... the other code
controllerInstance.init(azureFunctionContext);
if(useHelper){
/** Use Helper Mode **/
(controllerInstance as any)[option.methodName](...azureFunctionArgs);
} else {
/** Use Manual Mode **/
(controllerInstance as any)[option.methodName](azureFunctionContext.bindings, ...azureFunctionArgs);
}
}
For the usage example:
import { AuthorizationLevel, BaseController, controller, functionName, httpTrigger } from 'nammatham';
import { HttpRequest } from '@azure/functions';
@controller()
export class MyHttpController extends BaseController {
@functionName('MyHttp', httpTrigger(AuthorizationLevel.Anonymous, ['get']))
public getName(req: HttpRequest): void {
const name = req.query.name;
this.res.send(`hello get user with ${name}`);
}
}
For the full documentation, we already updated
2. Support more correctly ContextBindings
type from FunctionBinding (function.json
)
For more type correction, the user is required to assign specific type of binding in each element of tuple:
import { HttpTriggerRequestBinding, HttpTriggerResponseBinding } from 'nammatham';
const functionConfig = [
{
name: 'req',
type: 'httpTrigger',
direction: 'in',
} as HttpTriggerRequestBinding<'req'>,
{
name: 'res',
direction: 'out',
type: 'http',
} as HttpTriggerResponseBinding<'res'>,
];
and the user requires to use the utility type GetContextBindings
for extracting the type from JSON above, this will be import the original ContextBindings
from @azure/functions@3.5.0
, which is only provide the any string as a key, and any type of the value:
// from @azure/functions@3.5.0
export interface ContextBindings {
[name: string]: any;
}
To get correct type, we can use GetContextBindings
type, for example:
const contextBinding: GetContextBindings<typeof functionConfig> = {
req: HttpRequest // from @azure/functions@3.5.0,
res: HttpResponse // from @azure/functions@3.5.0,
}
For the usage example:
import { BaseController, controller, functionName, GetContextBindings, HttpTriggerRequestBinding, HttpTriggerResponseBinding } from 'nammatham';
const functionConfig = [
{
name: 'req',
type: 'httpTrigger',
direction: 'in',
} as HttpTriggerRequestBinding<'req'>,
{
name: 'res',
direction: 'out',
type: 'http',
} as HttpTriggerResponseBinding<'res'>,
];
@controller()
export class WithTypeUtilityController extends BaseController {
@functionName('WithTypeUtility', ...functionConfig)
public getName({ req }: GetContextBindings<typeof functionConfig>): void {
const name = req.query.name;
// this context will have the correct type of Response
this.context.res = {
body: `hello WithTypeUtility with ${name}`,
};
}
}
3. Add HttpResponse
in Context.res
From the original @azure/functions@3.5.0
, the Context.res
will accept only any key with string
/**
* HTTP response object. Provided to your function when using HTTP Bindings.
*/
res?: {
[key: string]: any;
};
This change, we override type Context.res
with HttpResponse
from @azure/functions, for example,
import { AuthorizationLevel, BaseController, controller, functionName, httpTrigger } from 'nammatham';
import { HttpRequest } from '@azure/functions';
@controller()
export class MyHttpController extends BaseController {
@functionName('MyHttp', httpTrigger(AuthorizationLevel.Anonymous, ['get']))
public getName(req: HttpRequest): void {
const name = req.query.name;
// this context will have the correct type of Response
this.context.res = { // Context.res?: HttpResponse | undefined
body: `hello WithTypeUtility with ${name}`,
};
}
}
4. Add Type Utility for getting object from string type in function.json
For example
import type { Binding } from 'nammatham';
type HttpTrigger = Binding<'httpTrigger'> // this will return `HttpRequest` type
For the usage example:
import { AuthorizationLevel, BaseController, Binding, controller, functionName, httpTrigger } from 'nammatham';
@controller()
export class MyHttpController extends BaseController {
@functionName('MyHttp', httpTrigger(AuthorizationLevel.Anonymous, ['get']))
// BindingType<'httpTrigger'> will return `HttpRequest` type
public getName(req: Binding<'httpTrigger'>): void {
const name = req.query.name;
this.res.send(`hello get user with ${name}`);
}
}
Pull Requests
- Add utility
GetContextBindings
for extracting type from FunctionBinding by @mildronize in #28
Full Changelog: 0.3.1-alpha.2...0.4.0-alpha
0.3.1-alpha.2
What's Changed
- Migrate to monorepo by @mildronize in #26
Full Changelog: 0.3.0-alpha.1...0.3.1-alpha.2
0.3.0-alpha.1
What's Changed
- Add Type Support for TimerTrigger in FunctionBinding interface
- Make Type support Custom Function Binding
- Fix Bug: "Bootstrap function cannot support more than 1 controller"
Custom Function Binding
In @functionName()
decorator support any JSON Binding Object that you can self-define it.
For example, if you want to use custom-type
, you can simply do like this:
Note:
custom-type
type is not available in Azure Functions, just show the example of the custom type
import { BaseController, controller, functionName } from 'nammatham';
@controller()
export class SampleHttpController extends BaseController {
/**
* To support other trigger type,
* Using Custom Function Binding instead
*/
@functionName<string>('SampleCustomFunctionBinding', {
name: 'SampleCustomFunctionBinding',
type: 'custom-type',
direction: 'in'
})
public customFunctionBinding(): void {
this.context.log(`Running custom binding funtion`);
}
}
Pull Requests
- Add Type Support for Timer Trigger in FunctionBinding interface by @mildronize in #9
- Fix Bootstrap function cannot support more than 1 controller by @mildronize in #10
Full Changelog: 0.2.0-alpha.1...0.3.0-alpha.1
0.2.0-alpha.1
What's Changed
previously, the bootstrap script (main.ts
or any filename) which is required to setup this library, it must be at root level of the project.
In this release, we make this script to be any location in the project,
For example,
- Previously, the bootstrap script is
/main.ts
- Currently, the bootstrap script is
/src/main.ts
.
├── host.json
├── local.settings.json
- ├── main.ts
├── package-lock.json
├── package.json
├── src
│ ├── controllers
│ │ └── user.controller.ts
+ │ └── main.ts
└── tsconfig.json
Pull Requests
- Feat: Bootstrap can be changed location by @mildronize in #5
Full Changelog: 0.1.0-alpha.1...0.2.0-alpha.1
0.1.0-alpha.1
What's Changed
Background
When you define Azure Function with HttpTrigger in TypeScript, we usually define like this:
import { Context, HttpRequest } from "@azure/functions";
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
context.log('HTTP trigger function processed a request.');
};
export default httpTrigger;
the type AzureFunction
is already defined type with
type AzureFunction = (context: Context, ...args: any[]) => Promise<any> | void;
The first argument is always Context
and the rest is an array of any
object,
When you using HttpTrigger, the next argument will be HttpRequest
,
So, In this release, we've changed the way defined function which automatically inject the Context
object from Azure Function runtime into our defined class, as you can see in the before & after examples.
Before
import { AuthorizationLevel, controller, functionName, httpTrigger } from "nammatham";
import { Context, HttpRequest } from "@azure/functions";
@controller()
export class UserController {
@functionName("GetUsers", httpTrigger(AuthorizationLevel.Anonymous, ["get"]))
public getUsers(context: Context, req: HttpRequest): void {
const name = req.query.name;
context.res = {
status: 200,
body: `hello get user with ${name}`
}
}
}
After
import { AuthorizationLevel, BaseController, controller, functionName, httpTrigger } from "nammatham";
import { HttpRequest } from "@azure/functions";
@controller()
export class UserController extends BaseController {
@functionName("GetUsers", httpTrigger(AuthorizationLevel.Anonymous, ["get"]))
public getUsers(req: HttpRequest): void {
const name = req.query.name;
this.res.send(`hello get user with ${name}`);
}
}
You can see the full example in example/crud UserController
.
Compatible with @azure/functions@3.5.0
Pull Requests
- inject Az Function Context in controller class by @mildronize in #3
- Refactor HttpResponse & Re-Export http-status-codes by @mildronize in #4
Full Changelog: 0.0.1-pre-alpha.5...0.1.0-alpha.1
0.0.1-pre-alpha.5
What's Changed
- Add HttpTrigger on AzureFunction and generate script by @mildronize in #1
- fix: Az function script file to correct path by @mildronize in #2
Full Changelog: https://github.com/mildronize/nammatham/commits/0.0.1-pre-alpha.5