Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade template #12

Merged
merged 11 commits into from
Oct 4, 2024
5 changes: 4 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# configure pre commit hook here
# f.ex.

npm run lint
# npm test
npm test
npm run fix:package
33 changes: 16 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ Here can be implementation details of the plugin. For example which API is used,

## Usage

To run the `<YOUR-CUSTOM-PLUGIN>`, an instance of `PluginInterface` must be created. Then, the plugin's `execute()` method can be called, passing required arguments to it.
To run the `<YOUR-CUSTOM-PLUGIN>`, an instance of `PluginFactory` must be created. Then, the plugin's `execute()` method can be called, passing required arguments to it.

This is how you could run the model in Typescript:
This is how you could run the plugin in Typescript:

```typescript
async function runPlugin() {
const newPlugin = await new MyCustomPlugin().configure(params);
const usage = await newPlugin.calculate([
const usage = await MyCustomPlugin({}).execute([
{
timestamp: '2021-01-01T00:00:00Z',
duration: '15s',
Expand All @@ -34,16 +33,16 @@ async function runPlugin() {
runPlugin();
```

## Testing model integration
## Testing plugin integration

>Note: [If Core](https://github.com/Green-Software-Foundation/if-core) plugin has a set of error classes which should be used for having necessary integration with the IF framework. More information on error classes can be found at [Errors Reference](https://if.greensoftware.foundation/reference/errors/).

### Using local links

For using locally developed model in `IF Framework` please follow these steps:
For using locally developed plugin in `IF Framework` please follow these steps:

1. On the root level of a locally developed model run `npm link`, which will create global package. It uses `package.json` file's `name` field as a package name. Additionally name can be checked by running `npm ls -g --depth=0 --link=true`.
2. Use the linked model in impl by specifying `name`, `method`, `path` in initialize models section.
1. On the root level of a locally developed plugin run `npm link`, which will create global package. It uses `package.json` file's `name` field as a package name. Additionally name can be checked by running `npm ls -g --depth=0 --link=true`.
2. Use the linked plugin in manifest by specifying `name`, `method`, `path` in initialize plugins section.

```yaml
name: plugin-demo-link
Expand All @@ -54,23 +53,23 @@ initialize:
my-custom-plugin:
method: MyCustomPlugin
path: "<name-field-from-package.json>"
global-config:
config:
...
...
```

### Using directly from Github

You can simply push your model to the public Github repository and pass the path to it in your impl.
For example, for a model saved in `github.com/my-repo/my-model` you can do the following:
You can simply push your plugin to the public Github repository and pass the path to it in your manifest.
For example, for a plugin saved in `github.com/my-repo/my-plugin` you can do the following:

npm install your model:
npm install your plugin:

```
npm install -g https://github.com/my-repo/my-model
npm install -g https://github.com/my-repo/my-plugin
```

Then, in your `impl`, provide the path in the model instantiation. You also need to specify which class the model instantiates. In this case you are using the `PluginInterface`, so you can specify `OutputModel`.
Then, in your `manifest`, provide the path in the plugin instantiation. You also need to specify which method the plugin instantiates. In this case you are using the `MyCustomPlugin`.

```yaml
name: plugin-demo-git
Expand All @@ -80,14 +79,14 @@ initialize:
plugins:
my-custom-plugin:
method: MyCustomPlugin
path: https://github.com/my-repo/my-model
path: https://github.com/my-repo/my-plugin
global-config:
narekhovhannisyan marked this conversation as resolved.
Show resolved Hide resolved
...
...
```

Now, when you run the `manifest` using the IF CLI, it will load the model automatically. Run using:
Now, when you run the `manifest` using the IF CLI, it will load the plugin automatically. Run using:

```sh
ie --manifest <path-to-your-impl> --output <path-to-save-output>
if -m <path-to-your-manifest> -o <path-to-save-output>
```
23 changes: 16 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "if-plugin-template",
"description": "Impact Framework plugins template.",
"version": "v0.1.1",
"description": "<PLUGIN-NAME> plugin for Impact Framework.",
"version": "0.1.1",
"author": {
"name": "Green Software Foundation",
"email": "[email protected]"
Expand All @@ -10,7 +10,7 @@
"url": "https://github.com/Green-Software-Foundation/if-plugin-template/issues/new?assignees=&labels=feedback&projects=&template=feedback.md&title=Feedback+-+"
},
"dependencies": {
"@grnsft/if-core": "^0.0.7",
"@grnsft/if-core": "^0.0.25",
"typescript": "^5.1.6"
},
"devDependencies": {
Expand All @@ -31,7 +31,13 @@
"npm": ">=8"
},
"homepage": "https://greensoftware.foundation",
"keywords": [],
"keywords": [
"green software foundation",
"greensoftware",
"if",
"if-framework",
"impact"
],
"license": "MIT",
"main": "build/index.js",
"repository": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import {MyCustomPlugin} from '../../../lib/my-custom-plugin';
import {MyCustomPlugin} from '../../lib/my-custom-plugin';

describe('lib/my-custom-plugin: ', () => {
describe('MyCustomPlugin(): ', () => {
it('has metadata field.', () => {
const pluginInstance = MyCustomPlugin({});
const pluginInstance = MyCustomPlugin({}, {}, {});

expect(pluginInstance).toHaveProperty('metadata');
expect(pluginInstance).toHaveProperty('execute');
expect(pluginInstance.metadata).toHaveProperty('kind');
expect(typeof pluginInstance.execute).toBe('function');
});

describe('execute(): ', () => {
it('applies logic on provided inputs array.', async () => {
const pluginInstance = MyCustomPlugin({});
const pluginInstance = MyCustomPlugin({}, {}, {});
const inputs = [{}];

const response = await pluginInstance.execute(inputs, {});
const response = await pluginInstance.execute(inputs);
expect(response).toEqual(inputs);
});
});
Expand Down
51 changes: 16 additions & 35 deletions src/lib/my-custom-plugin/index.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,25 @@
import {ERRORS} from '@grnsft/if-core/utils';
import {PluginParams, ExecutePlugin} from '@grnsft/if-core/types';
import {PluginFactory} from '@grnsft/if-core/interfaces';
import {PluginParams, ConfigParams} from '@grnsft/if-core/types';

import {YourGlobalConfig} from './types';
export const MyCustomPlugin = PluginFactory({
configValidation: (config: ConfigParams) => {
// do config validation here or just pass zod schema

const {GlobalConfigError} = ERRORS;
return config;
},
inputValidation: (input: PluginParams) => {
// do input validation here or pass zod schema

export const MyCustomPlugin = (
globalConfig: YourGlobalConfig
): ExecutePlugin => {
const metadata = {
kind: 'execute',
};

/**
* Validates global config.
*/
const validateGlobalConfig = () => {
if (!globalConfig) {
throw new GlobalConfigError('My custom message here.');
}

// validator checks can be applied if needed
};

/**
* Execute's strategy description here.
*/
const execute = async (inputs: PluginParams[]): Promise<PluginParams[]> => {
validateGlobalConfig();
return input;
},
implementation: async (inputs: PluginParams[], config: ConfigParams) => {
const {yourValue} = config;

return inputs.map(input => {
// your logic here
globalConfig;
yourValue;

return input;
});
};

return {
metadata,
execute,
};
};
},
});
1 change: 0 additions & 1 deletion src/lib/my-custom-plugin/types.ts

This file was deleted.

Loading