npm package: @k2oss/k2-broker-core
Description: Typings for K2 Brokers
Author: K2 OSS
Latest version: 1.1.0-preview-20201001-1

# K2 TypeScript Intellisense for SmartObjects

Use this package to get intellisense for K2 SmartObject services when developing your K2 Cloud broker code in JavaScript.

## Features

  - Full object model intellisense for making development easier

## Setting up a NodeJS Project
Install the package with either NPM:

```bash
npm install --save-development @k2oss/k2-broker-core
```

or Yarn:

```bash
yarn add --dev @k2oss/k2-broker-core
```

You should then set up your `tsconfig.json` so that unsupported browser typings
are not available:

```json
{
    "extends": "@k2oss/k2-broker-core/shared/tsconfig.json"
}
```

Remember that K2 brokers must be a single bundled file, you can use a bundler of
your choice to do this, but we strongly recommend [Rollup](https://rollupjs.org/guide/en/).

## Create a Broker

Every broker must have a hard-coded metadata section:

```ts
import '@k2oss/k2-broker-core';

metadata = {
    "systemName": "MyServiceBroker",
    "displayName": "My Service Broker",
    "description": "My JavaScript service broker."
};
```

Optionally, you may add configuration settings in your metadata section:

```ts
import '@k2oss/k2-broker-core';

metadata = {
    "systemName": "MyServiceBroker",
    "displayName": "My Service Broker",
    "description": "My JavaScript service broker.",
    "configuration": {
        "MyServiceKey1": {
            "displayName": "My Service Key 1",
            "type": "string"
	    },
        "MyServiceKey2": {
            "displayName": "My Service Key 2",
            "type": "number",
            "required": "true"
	    }
	}
};
```

The remainder of the functionality is governed by methods, `ondescribe` and
`onexecute` and `onmessage`. These return value of these methods is ignored, so you can freely
return whatever you need for testing purposes (we recommend using `Promise`). At
runtime, the broker will only consider a method completed once it has no
JavaScript running and no outstanding network/IO requests.

The `ondescribe` method is called when K2 needs the schema (objects, properties
and methods) of the service broker.

```ts
function ondescribe(configuration) {
    postSchema({
        data: "top level data",
        objects: {
            "MyObject": {
                displayName: "My Object",
                description: "The description for my object",
                properties: {
                    "Value1": {
                        displayName: "Value1",
                        description: "The first value",
                        type: "number",
                        data: {complexData, "Some Data"}
                    },
                    "Value2": {
                        displayName: "Value2",
                        description: "The second value",
                        type: "number"
                    },
                    "Result": {
                        displayName: "Result",
                        description: "The result value",
                        type: "number"
                    }
                },
                methods: {
                    "Add": {
                        displayName: "Add",
                        description: "Adds two numbers",
                        type: "read",
                        inputs: ["Value1", "Value2"],
                        requiredInputs: ["Value1", "Value2"],
                        parameters: {
                            "Param1": { displayName: "Param1", description: "Description Of Param 1", type: "number" },
                            "Param2": { displayName: "Param2", description: "Description Of Param 2", type: "number" }
                        },
                        requiredParameters: ["Param1"],
                        outputs: ["Result"]
                    }
                },
                events: {
                    "MyEvent": {
                        displayName: "My Event",
                        description: "The description of my event",
                        properties: ["Value1"],
                        associatedMethod: "Add"
                    }
                }
            }
        },
        inboxes:{
            "MyInbox":{
                displayName: "My Inbox",
                description: "The description of my inbox",
            }
        }
    });
}
```

Additionally, you can add private data fields to the `postSchema` call. These are accessable in the `onexecute` method via the schema parameter. This schema paramenter is identical to what you passed in in the `postSchema`. Two examples of accessing this in your `onexecute` are shown below.

```ts
var data = schema.data //This will be "top level data"
var data2 = schema.objects.MyObject.properties.Value1.data //This will be the object {complexData, "Some Data"}
```

It is also worth noting that anything in the schema can be accessed in `onexecute` and `onmessage` in the same way, not just the data fields.

--

The `onexecute` method is called when K2 needs to execute a method that was
described by your service.

```ts
function onexecute({objectName, methodName, parameters, properties, configuration, schema}) {
    switch (objectName) {
        case "MyObject":
            switch (methodName) {
                case "Add":
                    postResult({
                        Result: properties["Value1"] + properties["Value2"] + parameters["Param1"] + parameters["Param2"];
                    });
                    break;
                default: throw new Error(`${objectName}.${methodName} is not a supported method.`);
            }
            break;
        default: throw new Error(`${objectName} is not a supported object.`);
    }
}
```

--

The `onmessage` method is called when K2 needs to handle the message coming from external webhooks before posting (raising) an event to trigger an action in K2
described by your service.

```ts
async function onmessage({inboxName, message, configuration, schema}) {
    let contentType = message.headers['content-type'];
    let messageId = message.parameters['id']; 
    let content = await message.content.text();
    //Get information from the content string if required
    switch (inboxName) {
        case "MyInbox":                
                await postEvent("MyObject", "MyEvent", {
                    Result: "Id: " + messageId + "raise event";
                });
                break;
    }
}
```

When using types sometimes you need to cast properties and parameters for type specific operations. In the example below, you have a date parameter called “dateParameter” and a file property called “fileProperty”. Note that fileProperty is of type 'Attachment'. In order to access the Blob you must get the content property of the attachment.

```ts
function onSomeExecute(properties: SingleRecord, parameters: SingleRecord){
    let date = parameters["dateParameter"];
    if(!(date instanceof Date)) throw new Error();
    //date is now of type Date, and can be used as such

    let file = properties["fileProperty"];
    if(!(file instanceof Attachment)) throw new Error();
    let content: Blob = file.content;
    //content can now be used as a Blob, while file can be used as an Attachment

    // ...
}
```
List of available types:
- Date
- Attachment
- number
- boolean
- string
- null


--

If you need to access to the configuration setttings from the metadata
reference the configuration parameter of the ondescribe and onexecute methods:

```ts
var myConfigValue = configuration["MyServiceKey1"];
```