Kora/developer documentation/Utilities

Utilities

The services every module can use through this.kora.

Every module class gets the running Kora instance as this.kora. These are the services on it you will use most.

Console

this.kora.console.log(this.kora.console.levels.info, "Sync finished.");
this.kora.console.log(this.kora.console.levels.error, `Sync failed: ${error.message}`);
LevelUse it for
infoNormal progress.
successSomething finished.
warningSomething went wrong but Kora carries on.
errorA failure.
debugExtra detail.
startupLoading and registration messages.

An unknown level prints as info with a warning. Every line also goes to the dashboard's live console and to data/logs/<date>.log, where license keys are shortened.

this.kora.console.error(error) prints a large fatal error panel. Kora uses it when it cannot keep running, so prefer log with the error level in modules.

Settings

Kora's own settings, such as LANGUAGE or ACCENT_COLOUR, plus anything you store:

const accent = this.kora.settings.get("ACCENT_COLOUR");
await this.kora.settings.set("example:last_sync", Date.now());
await this.kora.settings.delete("example:last_sync");

Settings live in the database and are cached in memory. Prefix your own keys with your module ID. For admin-facing options use a config class instead.

Cache

const prices = this.kora.cache.store("example:prices", { ttl: 60000, max: 200 });

const price = await prices.remember(productId, () => this.fetchPrice(productId));
prices.delete(productId);
MethodWhat it does
get(key) / has(key)Read an entry that has not expired.
set(key, value, ttl)Store a value.
remember(key, load, ttl)Return the cached value, or run load once and cache the result. Calls made while it loads share one request.
delete(key) / clear()Remove one entry or all of them.

ttl is in milliseconds and defaults to 10 minutes. max defaults to 500 entries, after which the oldest are dropped. this.kora.cache.clear("example:") clears every store whose name starts with the prefix.

Files

this.kora.data points at Kora's data/ folder:

const folder = this.kora.data.ensure("example", "exports");
const file = path.join(folder, "licenses.csv");
this.kora.data.remove("example", "exports");
MethodWhat it does
path(...segments)The full path, inside data/.
module(id, ...segments)The same, starting in your module's folder.
ensure(...segments)Create the folder if needed and return its path.
exists(...segments)Whether it exists.
remove(...segments)Delete it and everything in it.

Segments are cleaned so a path can never leave data/.

Audit Log

await this.kora.audit.record({
    type: "example",
    actor: request.actor,
    action: "license.synced",
    target: String(license.id),
    detail: { product: license.product_id }
});
FieldWhat it is
typeUsually your module ID.
actorWho did it. Leave it out for the system.
actionWhat happened.
targetWhat it happened to.
detailAny extra JSON.
successfalse for a failed attempt. Defaults to true.
ipThe request's IP address.

Entries show on the Audit Log page and fire audit.recorded.

Signing

Kora signs validation responses with an Ed25519 key so SDKs can check they came from your server. You can sign your own data with the same key:

const envelope = this.kora.signer.envelope({ key: license.key, valid: true });
const ok = this.kora.signer.verify(envelope.data, envelope.signature);
MethodWhat it does
sign(payload)Sign an object. Keys are sorted first, so the order does not matter.
verify(payload, signature)Check a signature from sign.
envelope(payload){ data, signature, algorithm: "ed25519" }.
detached(text)Sign a plain string.
publicKey()The public key as PEM, for your clients.

Events

this.kora.events.on("license.created", ({ license }) => {});
await this.kora.emitAsync("example.synced", { count });

Use event classes for listeners that belong to your module, so they are removed when it is turned off.

Packages

List npm packages your module needs in its manifest under dependencies.node. Kora installs any that are missing when the module loads, with Bun or npm, without adding them to package.json. To install one yourself:

await this.kora.installPackages("csv-stringify");