enhancement(templates): use latest faas-js-runtime + cloudevents (#1422)

* enhancement(templates): use latest faas-js-runtime + cloudevents

Better typing of handle functions and return values for typescript based functions.

/kind enhancement

Signed-off-by: Lance Ball <lball@redhat.com>

* fixup: improvements

Signed-off-by: Lance Ball <lball@redhat.com>

* fixup: missing FUNC_LOG_LEVEL

Signed-off-by: Lance Ball <lball@redhat.com>

Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
Lance Ball 2022-11-10 07:59:15 -05:00 committed by GitHub
parent 5b032bed66
commit 06693859be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 17112 additions and 15623 deletions

View File

@ -76,6 +76,8 @@ clean_templates:
@rm -rf templates/python/http/__pycache__
@rm -rf templates/typescript/cloudevents/node_modules
@rm -rf templates/typescript/http/node_modules
@rm -rf templates/typescript/cloudevents/build
@rm -rf templates/typescript/http/build
@rm -rf templates/rust/cloudevents/target
@rm -rf templates/rust/http/target
@rm -rf templates/quarkus/cloudevents/target

View File

@ -1,4 +1,4 @@
const { CloudEvent, HTTP } = require('cloudevents');
const { CloudEvent } = require('cloudevents');
/**
* Your CloudEvent handling function, invoked with each request.
@ -20,17 +20,14 @@ const { CloudEvent, HTTP } = require('cloudevents');
*/
const handle = async (context, event) => {
// YOUR CODE HERE
context.log.info("context");
context.log.info(JSON.stringify(context, null, 2));
context.log.info("context", context);
context.log.info("event", event);
context.log.info("event");
context.log.info(JSON.stringify(event, null, 2));
return HTTP.binary(new CloudEvent({
return new CloudEvent({
source: 'event.handler',
type: 'echo',
data: event
}));
data: event.data
});
};
module.exports = { handle };

File diff suppressed because it is too large Load Diff

View File

@ -9,16 +9,16 @@
},
"scripts": {
"test": "node test/unit.js && node test/integration.js",
"start": "faas-js-runtime ./index.js",
"start": "FUNC_LOG_LEVEL=info faas-js-runtime ./index.js",
"debug": "nodemon --inspect ./node_modules/faas-js-runtime/bin/cli.js ./index.js"
},
"devDependencies": {
"nodemon": "^2.0.4",
"supertest": "^4.0.2",
"supertest": "^6.3.1",
"tape": "^4.13.0"
},
"dependencies": {
"cloudevents": "^6.0.2",
"faas-js-runtime": "^0.9.1"
"cloudevents": "^6.0.3",
"faas-js-runtime": "^0.9.5"
}
}

View File

@ -1,17 +1,11 @@
'use strict';
const { HTTP, CloudEvent } = require('cloudevents');
const { start } = require('faas-js-runtime');
const request = require('supertest');
const func = require('..').handle;
const test = require('tape');
const Spec = {
version: 'ce-specversion',
type: 'ce-type',
id: 'ce-id',
source: 'ce-source'
};
const data = {
name: 'tiger',
customerId: '01234'
@ -22,22 +16,25 @@ const errHandler = t => err => {
t.end();
};
const message = HTTP.binary(new CloudEvent({
type: 'com.example.test',
source: 'http://localhost:8080',
data
}));
test('Integration: handles a valid event', t => {
start(func).then(server => {
t.plan(5);
request(server)
.post('/')
.send(data)
.set(Spec.id, '01234')
.set(Spec.source, '/test')
.set(Spec.type, 'com.example.cloudevents.test')
.set(Spec.version, '1.0')
.send(message.body)
.set(message.headers)
.expect(200)
.expect('Content-Type', /json/)
.end((err, result) => {
t.error(err, 'No error');
t.ok(result);
t.deepEqual(result.body.data, data);
t.deepEqual(result.body, data);
t.equal(result.headers['ce-type'], 'echo');
t.equal(result.headers['ce-source'], 'event.handler');
t.end();

View File

@ -11,6 +11,7 @@ test('Unit: handles a valid event', async t => {
name: 'tiger',
customerId: '01234'
}
// A valid event includes id, type and source at a minimum.
const cloudevent = new CloudEvent({
id: '01234',
@ -19,30 +20,11 @@ test('Unit: handles a valid event', async t => {
data
});
const mockContext = new MockContext(cloudevent);
// Invoke the function with the valid event, which should complete without error.
const result = await func(mockContext, data);
const result = await func({ log: { info: (_) => _ } }, cloudevent);
t.ok(result);
t.equal(result.body, JSON.stringify(data));
t.equal(result.headers['ce-type'], 'echo');
t.equal(result.headers['ce-source'], 'event.handler');
t.equal(result.data, data);
t.equal(result.type, 'echo');
t.equal(result.source, 'event.handler');
t.end();
});
class MockContext {
cloudevent;
constructor(cloudevent) {
this.cloudevent = cloudevent;
this.log = { info: console.log, debug: console.debug }
}
cloudEventResponse(data) {
return new CloudEvent({
data,
type: 'com.example.cloudevents.test.response',
source: '/test'
})
}
}

View File

@ -15,18 +15,17 @@
* @param {string} context.httpVersion the HTTP protocol version
* See: https://github.com/knative/func/blob/main/docs/function-developers/nodejs.md#the-context-object
*/
const handle = async (context) => {
const handle = async (context, body) => {
// YOUR CODE HERE
context.log.info(JSON.stringify(context, null, 2));
context.log.info("query", context.query);
context.log.info("body", body);
// If the request is an HTTP POST, the context will contain the request body
if (context.method === 'POST') {
return {
body: context.body,
}
// If the request is an HTTP GET, the context will include a query string, if it exists
return { body };
} else if (context.method === 'GET') {
return {
// If the request is an HTTP GET, the context will include a query string, if it exists
return {
query: context.query,
}
} else {

File diff suppressed because it is too large Load Diff

View File

@ -5,18 +5,18 @@
"main": "index.js",
"scripts": {
"test": "node test/unit.js && node test/integration.js",
"start": "faas-js-runtime ./index.js",
"start": "FUNC_LOG_LEVEL=info faas-js-runtime ./index.js",
"debug": "nodemon --inspect ./node_modules/faas-js-runtime/bin/cli.js ./index.js"
},
"keywords": [],
"author": "",
"license": "Apache-2.0",
"dependencies": {
"faas-js-runtime": "^0.9.1"
"faas-js-runtime": "^0.9.5"
},
"devDependencies": {
"nodemon": "^2.0.4",
"supertest": "^4.0.2",
"supertest": "^6.3.1",
"tape": "^5.0.1"
}
}

View File

@ -15,9 +15,10 @@ test('Unit: handles an HTTP GET', async t => {
test('Unit: handles an HTTP POST', async t => {
t.plan(1);
const body = { name: 'tiger' };
// Invoke the function, which should complete without error.
const result = await func({ ...fixture, method: 'POST', body: { name: 'tiger' } });
t.deepEqual(result, { body: { name: 'tiger' } });
const result = await func({ ...fixture, method: 'POST', body }, body);
t.deepEqual(result, { body });
t.end();
});

View File

@ -2,5 +2,5 @@
"semi": true,
"trailingComma": "none",
"singleQuote": true,
"printWidth": 120
"printWidth": 125
}

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
"test:unit": "ts-node node_modules/tape/bin/tape test/unit.ts",
"test:integration": "ts-node node_modules/tape/bin/tape test/integration.ts",
"test": "npm run test:unit && npm run test:integration",
"start": "faas-js-runtime ./build/index.js",
"start": "FUNC_LOG_LEVEL=info faas-js-runtime ./build/index.js",
"lint": "eslint \"src/**/*.{js,ts,tsx}\" \"test/**/*.{js,ts,tsx}\" --quiet",
"debug": "nodemon --inspect ./node_modules/faas-js-runtime/bin/cli.js ./build/index.js"
},
@ -26,15 +26,16 @@
"eslint-plugin-prettier": "^3.4.0",
"nodemon": "^2.0.4",
"prettier": "^2.3.0",
"supertest": "^4.0.2",
"supertest": "^6.3.1",
"tape": "^4.13.0",
"ts-node": "^9.1.1",
"tsd": "^0.24.1",
"tslint-config-prettier": "^1.18.0",
"typescript": "^4.2.4"
},
"dependencies": {
"@types/node": "^16.11.12",
"cloudevents": "^6.0.2",
"faas-js-runtime": "^0.9.1"
"cloudevents": "^6.0.3",
"faas-js-runtime": "^0.9.5"
}
}

View File

@ -1,4 +1,4 @@
import { CloudEvent, HTTP, Message } from 'cloudevents';
import { CloudEvent } from 'cloudevents';
import { Context } from 'faas-js-runtime';
/**
@ -19,7 +19,8 @@ import { Context } from 'faas-js-runtime';
* See: https://github.com/knative/func/blob/main/docs/guides/nodejs.md#the-context-object
* @param {CloudEvent} cloudevent the CloudEvent
*/
const handle = async (_: Context, cloudevent?: CloudEvent<unknown>): Promise<Message> => {
// eslint-disable-next-line prettier/prettier
const handle = async (context: Context, cloudevent?: CloudEvent<Customer>): Promise<CloudEvent<Customer|string>> => {
// YOUR CODE HERE
const meta = {
source: 'function.eventViewer',
@ -31,10 +32,10 @@ const handle = async (_: Context, cloudevent?: CloudEvent<unknown>): Promise<Mes
...meta,
...{ type: 'error', data: 'No event received' }
});
console.log(response.toString());
return HTTP.binary(response);
context.log.info(response.toString());
return response;
}
console.log(`
context.log.info(`
-----------------------------------------------------------
CloudEvent:
${cloudevent}
@ -44,7 +45,12 @@ ${JSON.stringify(cloudevent.data)}
-----------------------------------------------------------
`);
// respond with a new CloudEvent
return HTTP.binary(new CloudEvent({ ...meta, data: cloudevent.data }));
return new CloudEvent<Customer>({ ...meta, data: cloudevent.data });
};
export interface Customer {
name: string;
customerId: string;
}
export { handle };

View File

@ -1,15 +1,10 @@
'use strict';
import test from 'tape';
import { expectType } from 'tsd';
import { CloudEvent } from 'cloudevents';
import { Context } from 'faas-js-runtime';
import { handle } from '../src';
// Test typed CloudEvent data
interface Customer {
name: string;
customerId: string;
}
import { CloudEventFunction, Context } from 'faas-js-runtime';
import { handle, Customer } from '../src';
// Ensure that the function completes cleanly when passed a valid event.
test('Unit: handles a valid event', async (t) => {
@ -18,6 +13,7 @@ test('Unit: handles a valid event', async (t) => {
name: 'tiger',
customerId: '01234'
};
// A valid event includes id, type and source at a minimum.
const cloudevent: CloudEvent<Customer> = new CloudEvent({
id: '01234',
@ -27,11 +23,13 @@ test('Unit: handles a valid event', async (t) => {
});
// Invoke the function with the valid event, which should complete without error.
const result = await handle({} as Context, cloudevent);
const result = await handle({ log: { info: (_) => _ } } as Context, cloudevent);
t.ok(result);
t.deepEqual(JSON.parse(result.body as string), data);
console.log(result);
t.equal(result.headers['ce-type'], 'echo');
t.equal(result.headers['ce-source'], 'function.eventViewer');
t.deepEqual(result.data, data);
t.equal(result.type, 'echo');
t.equal(result.source, 'function.eventViewer');
t.end();
});
// Ensure that the handle function is typed correctly.
expectType<CloudEventFunction>(handle);

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
"test:unit": "ts-node node_modules/tape/bin/tape test/unit.ts",
"test:integration": "ts-node node_modules/tape/bin/tape test/integration.ts",
"test": "npm run test:unit && npm run test:integration",
"start": "faas-js-runtime ./build/index.js",
"start": "FUNC_LOG_LEVEL=info faas-js-runtime ./build/index.js",
"lint": "eslint \"src/**/*.{js,ts,tsx}\" \"test/**/*.{js,ts,tsx}\" --quiet",
"debug": "nodemon --inspect ./node_modules/faas-js-runtime/bin/cli.js ./build/index.js"
},
@ -26,14 +26,15 @@
"eslint-plugin-prettier": "^3.4.0",
"nodemon": "^2.0.4",
"prettier": "^2.3.0",
"supertest": "^4.0.2",
"supertest": "^6.3.1",
"tape": "^4.13.0",
"ts-node": "^9.1.1",
"tsd": "^0.24.1",
"tslint-config-prettier": "^1.18.0",
"typescript": "^4.2.4"
},
"dependencies": {
"@types/node": "^16.11.12",
"faas-js-runtime": "^0.9.1"
"faas-js-runtime": "^0.9.5"
}
}

View File

@ -1,4 +1,4 @@
import { Context } from 'faas-js-runtime';
import { Context, StructuredReturn } from 'faas-js-runtime';
/**
* Your HTTP handling function, invoked with each request. This is an example
@ -19,10 +19,9 @@ import { Context } from 'faas-js-runtime';
* @param {string} context.httpVersion the HTTP protocol version
* See: https://github.com/knative/func/blob/main/docs/guides/nodejs.md#the-context-object
*/
export const handle = async (context: Context): Promise<string> => {
export const handle = async (context: Context, body: string): Promise<StructuredReturn> => {
// YOUR CODE HERE
// eslint-disable-next-line no-console
console.log(`
context.log.info(`
-----------------------------------------------------------
Headers:
${JSON.stringify(context.headers)}
@ -31,8 +30,13 @@ Query:
${JSON.stringify(context.query)}
Body:
${JSON.stringify(context.body)}
${JSON.stringify(body)}
-----------------------------------------------------------
`);
return JSON.stringify(context.body);
return {
body: body,
headers: {
'content-type': 'application/json'
}
};
};

View File

@ -1,8 +1,9 @@
'use strict';
import test from 'tape';
import { Context } from 'faas-js-runtime';
import * as func from '../build/index.js';
import { expectType } from 'tsd';
import { Context, HTTPFunction } from 'faas-js-runtime';
import { handle } from '../build/index.js';
// Ensure that the function completes cleanly when passed a valid event.
test('Unit: handles a valid request', async (t) => {
@ -12,12 +13,12 @@ test('Unit: handles a valid request', async (t) => {
customerId: '01234'
};
const handle = func.handle;
const mockContext = { body } as Context;
// Invoke the function which should complete without error and echo the data
const result = await handle(mockContext);
const result = await handle({ log: { info: (_) => _ } } as Context, body);
t.ok(result);
t.equal(result, JSON.stringify(body));
t.equal(result.body, body);
t.end();
});
// Ensure that the handle function is typed correctly.
expectType<HTTPFunction>(handle);

21860
zz_filesystem_generated.go generated

File diff suppressed because it is too large Load Diff