npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

hermod-toolkit

v1.2.4

Published

Everything you need to write Hermod actions in JavaScript or TypeScript.

Downloads

12

Readme

hermod-javascript-toolkit

npm

Everything you need to write Hermod actions in JavaScript or TypeScript.

Setup

# Run this in your favourite terminal
npm i hermod-toolkit

Then use it in your package.json file scripts.

"scripts": {
    "build": "hermod-toolkit build",
    "dev": "hermod-toolkit dev",
    "test": "hermod-toolkit test",
    "launch": "hermod-toolkit run"
}

Assumes that your action is structured in the following way by default:

.
├── src               # sources folder
|   └── index.[jt]s   # the action code entry point
|
├── dist              # the action build output folder
|
├── tests             # tests folder (can't be changed)
|   └── *.spec.[tj]s  # any number of test files
|
├── package.json      # with an extra "sandbox" key, highlighted lower in the documentation
|
├── config.ini        # action configuration file
|
└── assets
    └── i18n          # internationalization folder
        └── <locale>.json # translation file for a given language

Command line

hermod-toolkit --help

Displays a help message and exits.

hermod-toolkit build

Builds your action to ./dist/index.js using webpack.

This command will warn if your action code uses node.js native modules, and they will be automatically added to your package.json file under the sandbox key.

// Example:
"sandbox": [
  "fs",
  "http",
  "https",
  "os",
  "path",
  "stream",
  "tty",
  "url",
  "util",
  "zlib"
]

hermod-toolkit dev

Automatically rebuilds and run the Hermod action on file change.

You can debug the action by connecting a debugger to the 9229 port. Check the node.js website for more details.

Use the -c/--config-path if you need to use custom hermes options. Use the -ns/--no-sandbox to disable the sandbox.

hermod-toolkit test

Runs your test suite with jest.

Use the -s/--sandbox flag to run the tests in a sandboxed environment.

hermod-toolkit run

Runs your Hermod action.

Use the -c/--config-path if you need to use custom hermes options. Use the -ns/--no-sandbox to disable the sandbox.

Utils

import { config } from 'hermod-toolkit'

Initialize once by calling .init, then use .get to retrieve the configuration.

// Reads the configuration file located at `./config.ini`.
config.init()
// Get the configuration.
const configuration = config.get()

Depends on node.js modules fs, path.

import { i18n } from 'hermod-toolkit'

Initialize once by calling .init.

Uses the i18next library under the hood.

// Reads the `./assets/i18n/en.json` translation file and initializes an i18next instance.
await i18n.init('en')
// Get a translation. (see https://www.i18next.com/overview/api#t)
const translation = i18n.translate(keys, options)
// Get the translation for an error message.
// Assumes that the translation file contains the key 'error.<error message>'.
const errorTranslation = await i18n.errorMessage(error)
// Get a random translation for a given key.
// Assumes that the translation file maps an array of possible translations to the key.
const translation = i18n.randomTranslation(keys, options)

Depends on node.js modules fs, path.

import { http } from 'hermod-toolkit'

An http client using wretch.

const pokeapi = http('https://pokeapi.co/api/v2')

const bulbasaur = await pokeapi
    .url('/pokemon/1')
    .get()
    .json()

Depends on node.js modules http, https, stream, zlib, url.

import { logger } from 'hermod-toolkit'

A logger using debug.

// Enables error printing. You can use * as a wildcard.
logger.enable('error')
// Logs to <actionName>:error
logger.debug('error')
// Logs to <actionName>:info
logger.info('info')
// Logs to <actionName>:debug
logger.error('debug')

Depends on node.js modules tty, util, os.

import { handler } from 'hermod-toolkit'

Utilities for handling hermes callbacks.

// Wrap a dialogue handler to gracefully capture and log errors.
handler.wrap((msg, flow) => {
    // ... //
})

Depends on internal modules i18n, logger.

import { message } from 'hermod-toolkit'

Utilities for parsing hermes messages.

// Get slots matching the slot name.
const mySlot = message.getSlotsByName(
    // The message instance
    msg,
    // The slot name
    'mySlotName',
    {
        // If true, returns only the slot with the highest confidence.
        onlyMostConfident: true,
        // If specified, returns only slots having a confidence higher than this threshold.
        threshold: 0.5
    }
)
// Calculates the ASR confidence.
const confidence = message.getAsrConfidence(msg)

import { camelize } from 'hermod-toolkit'

Camelcase utilities using the camelcase package.

// Camelize a string
const camelizedKey = camelize(key)
// Returns a cloned object having camelized keys.
const camelizedObject = camelizeKeys(object)

Hermes configuration

In order to pass custom hermes options, you can use the -c flag to specify the path to a configuration file.

For instance, if you are using an mqtt broker running on a different machine, you could add options in a file named hermes_config.json.

{
    "address": "ip:port"
}

And add the -c flag in the package.json file.

"scripts": {
    "dev": "hermod-toolkit dev -c ./hermes_config.json",
    "launch": "hermod-toolkit run -c ./hermes_config.json"
}

Unit tests

During unit tests, your action code is run is parallel with the tests and i18n/http utils are mocked.

Mocks

http

You can use the provided HermodToolkit.mock.http global function to override http calls automatically during tests.

// Place this code in the root of the test file to mock.
HermodToolkit.mock.http(fetchMock => {
    // Define as many mocks as you need.
    // See http://www.wheresrhys.co.uk/fetch-mock for API details
    fetchMock.mock('https://my.super.api/route', {
        hello: "world"
    })
})

i18n

The i18n.translate output is not the translation but a stringified JSON reprensentation of the key/options.

This call:

// This call:
i18n.translate('pokemon.info', {
    name: 'Pikachu',
    weight: 10,
    height: 20
})

Returns when mocked: (in stringified form)

{
  "key": "pokemon.info",
  "options": {
    "name": "Pikachu",
    "weight": 10,
    "height": 20
  }
}

globals

You can use the provided HermodToolkit.mock.globals global function to override or define global variables.

HermodToolkit.mock.globals(globals => {
    // Mocks the Date object in a crude way.
    const BackupedDate = global.Date
    const freezedTime = 1550835788763
    const mockedDate = function Date(arg: string | number | Date) {
        return new BackupedDate(arg || freezedTime)
    }
    mockedDate.now = () => freezedTime
    mockedDate.parse = BackupedDate.parse
    mockedDate.UTC = BackupedDate.UTC

    // Assign the mocked Date to the globals object
    globals.Date = mockedDate
})

Session

To simulate dialogue session rounds, you can use the Session helper that will pass hermes messages between your test and action code.

import { Test } from 'hermod-toolkit'

/* ... */

// Initialize a session instance
const session = new Test.Session()
// Publish an intent message that is expected by the action code to start a session
await session.start({
    intentName: 'pokemon_details',
    input: 'Give me the details for Pokemon 1',
    slots: [
        // Function that creates a custom slot, omitted for the sake of brevity.
        createPokemonIdSlot('1')
    ]
})
// Expect the action code to publish a continue session message
// and reply with the following intent message (here we simulate a confirmation message)
const continuation = await session.continue({
    intentName: 'pokemon_confirm',
    input: 'Yes please'
})
// Expect the action to end the session and retrieve the end session message value
const endSessionMessage = await session.end()
// Extract the key/options of the TTS spoken by the end session message
const { key, options } = JSON.parse(endSessionMessage.text || '')
// Assert that the values are correct
expect(key).toBe('pokemon.info')
expect(options.name).toBe('bulbasaur')
expect(options.weight).toBe(69)
expect(options.height).toBe(7)

Credits

Original work by @elbywan from Snips.