Skip to content

Commit

Permalink
Add setContext, helper for injecting other dependencies (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
mildronize authored Jan 21, 2024
2 parents 3c91532 + bab800d commit 0259e0e
Show file tree
Hide file tree
Showing 31 changed files with 452 additions and 29 deletions.
32 changes: 32 additions & 0 deletions docs/infer-handler-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@


```ts
import { container } from '../container';
import { func } from '../nammatham';
import { injector } from '@di-extra/inversify';
import { DataService } from '../services/data.service';
import type { InferHandler } from '@nammatham/core';

const trigger = func
.httpGet('hello', {
route: 'hello-world',
})
.setContext({
// prettier-ignore
services: injector(container)
.inject('dataService', DataService).to<DataService>()
.resolve(),
});

export const _handler: InferHandler<typeof trigger> = ({ trigger, context, services }) => {
context.log('HTTP trigger function processed a request.');

return {
jsonBody: {
data: 'hello world' + services.dataService.getData(),
},
};
};

export default trigger.handler(_handler);
```
1 change: 1 addition & 0 deletions examples/azure-functions-with-inversify/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @examples/azure-functions
15 changes: 15 additions & 0 deletions examples/azure-functions-with-inversify/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.15.0, 4.0.0)"
}
}
9 changes: 9 additions & 0 deletions examples/azure-functions-with-inversify/local.settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
},
"ConnectionStrings": {}
}
29 changes: 29 additions & 0 deletions examples/azure-functions-with-inversify/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@examples/azure-functions-with-inversify",
"version": "1.0.0",
"description": "",
"main": "dist/src/main.js",
"scripts": {
"build": "tsc",
"lint": "tsc --noEmit",
"start": "tsc && func start",
"dev": "cross-env NAMMATHAM_ENV=development tsx watch src/main.ts"
},
"author": "Thada Wangthammang",
"license": "MIT",
"dependencies": {
"@azure/functions": "^4.1.0",
"@di-extra/inversify": "^0.2.0",
"@nammatham/azure-functions": "2.0.0-alpha.8",
"@nammatham/core": "2.0.0-alpha.8",
"@nammatham/express": "2.0.0-alpha.8",
"inversify": "^6.0.2",
"reflect-metadata": "^0.2.1"
},
"devDependencies": {
"cross-env": "^7.0.3",
"npm-run-all": "^4.1.5",
"tsx": "^4.7.0",
"typescript": "^5.0.2"
}
}
6 changes: 6 additions & 0 deletions examples/azure-functions-with-inversify/src/container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Container } from 'inversify';
import { DataService } from './services/data.service';

export const container = new Container();
container.bind<DataService>(DataService).toSelf();

26 changes: 26 additions & 0 deletions examples/azure-functions-with-inversify/src/functions/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { container } from '../container';
import { func } from '../nammatham';
import { injector } from '@di-extra/inversify';
import { DataService } from '../services/data.service';

// prettier-ignore
const services = injector(container)
.inject('dataService', DataService).to<DataService>()
.resolve();

export default func
.httpGet('hello', {
route: 'hello-world',
})
.setContext({
services,
})
.handler(async ({ trigger, context, services }) => {
context.log('HTTP trigger function processed a request.');

return {
jsonBody: {
data: 'hello world' + services.dataService.getData(),
},
};
});
9 changes: 9 additions & 0 deletions examples/azure-functions-with-inversify/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'reflect-metadata';
import { expressPlugin } from '@nammatham/express';
import hello from './functions/hello';
import { app } from './nammatham';

app.addFunctions(hello);

app.register(expressPlugin());
app.start();
8 changes: 8 additions & 0 deletions examples/azure-functions-with-inversify/src/nammatham.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { initNammatham } from '@nammatham/core';
import { AzureFunctionsAdapter } from '@nammatham/azure-functions';

const n = initNammatham.create(new AzureFunctionsAdapter());
n.func;
// ^?
export const func = n.func;
export const app = n.app;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { injectable } from 'inversify';

@injectable()
export class DataService {

public getData() {
return `Data from DataService`;
}
}
13 changes: 13 additions & 0 deletions examples/azure-functions-with-inversify/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "dist",
"rootDir": ".",
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"experimentalDecorators": true,
},
"exclude": ["node_modules", "**/*.test.ts"]
}
1 change: 1 addition & 0 deletions examples/azure-functions-with-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @examples/azure-functions
26 changes: 26 additions & 0 deletions examples/azure-functions-with-test/__test__/helloFunction.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect, test } from 'vitest';
import helloFunc from '../src/functions/hello';
import { HttpRequest, InvocationContext } from '@azure/functions';

test('helloFunc', async () => {
const handler = helloFunc.getHandler();
const result = await handler({
context: new InvocationContext(),
trigger: new HttpRequest({
method: 'GET',
url: 'http://localhost:3000/api/hello-world',
query: {
name: 'world',
},
}),
});

expect(result).toEqual({
jsonBody: {
data: {
name: 'world',
message: 'Hello, world!',
},
},
});
});
15 changes: 15 additions & 0 deletions examples/azure-functions-with-test/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.15.0, 4.0.0)"
}
}
9 changes: 9 additions & 0 deletions examples/azure-functions-with-test/local.settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
},
"ConnectionStrings": {}
}
26 changes: 26 additions & 0 deletions examples/azure-functions-with-test/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@examples/azure-functions-with-test",
"version": "1.0.0",
"description": "",
"main": "dist/src/main.js",
"scripts": {
"build": "tsc",
"lint": "tsc --noEmit",
"start": "tsc && func start",
"dev": "cross-env NAMMATHAM_ENV=development tsx watch src/main.ts"
},
"author": "Thada Wangthammang",
"license": "MIT",
"dependencies": {
"@azure/functions": "^4.1.0",
"@nammatham/azure-functions": "2.0.0-alpha.8",
"@nammatham/core": "2.0.0-alpha.8",
"@nammatham/express": "2.0.0-alpha.8"
},
"devDependencies": {
"cross-env": "^7.0.3",
"npm-run-all": "^4.1.5",
"tsx": "^4.7.0",
"typescript": "^5.0.2"
}
}
23 changes: 23 additions & 0 deletions examples/azure-functions-with-test/src/functions/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { func } from '../nammatham';

export default func
.httpGet('hello', {
route: 'hello-world',
})
.handler(async ({ trigger, context }) => {
context.log('HTTP trigger function processed a request.');
context.debug(`Http function processed request for url "${trigger.url}"`);
const name = trigger.query.get('name') || (await trigger.text()) || 'world';
if (name === 'error') {
throw new Error('this is an error');
}
const result = {
data: {
name: name,
message: `Hello, ${name}!`
}
}
return {
jsonBody: result,
}
});
8 changes: 8 additions & 0 deletions examples/azure-functions-with-test/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { expressPlugin } from '@nammatham/express';
import hello from './functions/hello';
import { app } from './nammatham';

app.addFunctions(hello);

app.register(expressPlugin());
app.start();
7 changes: 7 additions & 0 deletions examples/azure-functions-with-test/src/nammatham.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { initNammatham } from '@nammatham/core';
import { AzureFunctionsAdapter } from '@nammatham/azure-functions';

const n = initNammatham.create(new AzureFunctionsAdapter());

export const func = n.func;
export const app = n.app;
13 changes: 13 additions & 0 deletions examples/azure-functions-with-test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "dist",
"rootDir": ".",
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"experimentalDecorators": true,
},
"exclude": ["node_modules", "**/*.test.ts"]
}
14 changes: 7 additions & 7 deletions packages/azure-functions/src/handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ test(`${AzureFunctionsHandler.name}.handler should be invoked correctly`, async

// Act
const endpoint = handler.handler(() => 'handlerResult');
const result = endpoint.invokeHandler({}, new InvocationContext());
const result = endpoint.build().invokeHandler({}, new InvocationContext());

// Assert
expect(result).toBe('handlerResult');
// NOTE: invokeHandler should test end-to-end
expect(endpoint.invokeHandler).toBeInstanceOf(Function);
expect(endpoint.build().invokeHandler).toBeInstanceOf(Function);
// NOTE: registerFunc should test end-to-end
expect(endpoint.registerFunc).toBeInstanceOf(Function);

expect(handler).toBeInstanceOf(AzureFunctionsHandler);
expect(endpoint.endpointOption?.type).toBe('http');
expect(endpoint.endpointOption?.route).toBe('test');
expect(endpoint.endpointOption?.methods).toEqual(['GET']);
expect(endpoint.type).toBe('azure-functions');
expect(endpoint.name).toBe('test');
expect(endpoint.build().endpointOption?.type).toBe('http');
expect(endpoint.build().endpointOption?.route).toBe('test');
expect(endpoint.build().endpointOption?.methods).toEqual(['GET']);
expect(endpoint.build().type).toBe('azure-functions');
expect(endpoint.build().name).toBe('test');
});
Loading

0 comments on commit 0259e0e

Please sign in to comment.