Skip to content

Releases: thaitype/nammatham

0.4.0-alpha

30 Jan 11:45
Compare
Choose a tag to compare

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

29 Jan 01:09
Compare
Choose a tag to compare

What's Changed

Full Changelog: 0.3.0-alpha.1...0.3.1-alpha.2

0.3.0-alpha.1

21 Jan 16:36
Compare
Choose a tag to compare

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

21 Jan 08:19
Compare
Choose a tag to compare

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

Full Changelog: 0.1.0-alpha.1...0.2.0-alpha.1

0.1.0-alpha.1

21 Jan 04:06
Compare
Choose a tag to compare

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

21 Jan 03:57
Compare
Choose a tag to compare
0.0.1-pre-alpha.5 Pre-release
Pre-release

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