Utilities
The runtime utilities are the part of c8y-nitro you will use most after the initial module setup.
Import them from c8y-nitro/utils.
import { useUser, useUserClient } from 'c8y-nitro/utils'Most helpers that depend on request context accept either an H3Event or ServerRequest.
How To Read This Page
- Start with
ResourcesandClientif you are writing route handlers. - Use
CredentialsandTenant Optionsfor cross-tenant or configuration-aware logic. - Use
Middlewarewhen you want route-level access control. - Use
Tasks & Schedulingwhen work should happen later instead of inline with a request.
For longer examples, see Tenant Options, Auth Middleware, and Tasks & Scheduling.
Credentials
| Function | Description | Request Context |
|---|---|---|
useSubscribedTenantCredentials() | Get credentials for all subscribed tenants | ❌ |
useDeployedTenantCredentials() | Get credentials for the deployed tenant | ❌ |
useUserTenantCredentials() | Get credentials for the current user's tenant | ✅ |
useDeployedTenantCredentials() shares its cache with useSubscribedTenantCredentials(). Both support .invalidate() and .refresh().
Tenant Credentials Lifecycle Hook
c8y-nitro emits c8y:tenantCredentialsUpdated when the subscribed credentials cache is populated for the first time or refreshed with a changed tenant set.
import type { TenantCredentials } from 'c8y-nitro/types'
import { definePlugin } from 'nitro'
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook('c8y:tenantCredentialsUpdated', (prev, next) => {
const previousTenants = prev ? Object.keys(prev) : []
const nextTenants = Object.keys(next)
console.log({ previousTenants, nextTenants })
})
})Tenant Options
| Function | Description | Request Context |
|---|---|---|
useTenantOption() | Handle for a single option (one category+key) | ❌ |
useTenantOptions() | Handle for a whole settings category | ❌ |
Both take a Cumulocity Client as the first argument — the client determines which tenant is targeted (essential for multi-tenant microservices). Get one from useDeployedTenantClient() (owner tenant), useUserTenantClient(event) (current request's tenant), or useSubscribedTenantClients().
import {
useTenantOption,
useTenantOptions,
useDeployedTenantClient,
useUserTenantClient,
} from 'c8y-nitro/utils'
const client = await useDeployedTenantClient() // or useUserTenantClient(event)
// Single option handle:
const value = await useTenantOption(client, 'myOption').read()
await useTenantOption(client, 'myOption').set('new-value')
const token = await useTenantOption(client, `dynamic.${id}`).getOrInsert('')
await useTenantOption(client, 'myOption').delete()
// Category handle:
const all = await useTenantOptions(client).list()
await useTenantOptions(client).setAll({ a: '1', b: '2' })
await useTenantOptions(client).option('myOption').read()
// Foreign category — pass the key set for autocomplete; credentials.* is a compile error:
await useTenantOptions<'someKey'>(client, 'other-service').option('someKey').read()Manifest-declared keys are suggested via autocomplete but any dynamic string is accepted.
read() returns undefined for a missing option (404) instead of throwing. delete() is idempotent. set() is an upsert (create-or-update).
Cache invalidation
Reads are cached per tenant (${tenant}::${category}::${key}). Invalidate at three levels:
// one option:
await useTenantOption(client, 'myOption').invalidate()
const fresh = await useTenantOption(client, 'myOption').refresh()
// one tenant + category:
await useTenantOptions(client).invalidateAll()
await useTenantOptions(client).refreshAll()
// everything, all tenants and categories:
await useTenantOptions.invalidateAll()
await useTenantOptions.refreshAll()invalidateAll() / refreshAll() only touch keys already read in the current process.
Tasks & Scheduling
| Function | Description |
|---|---|
c8yTasks() | Create a type-charged task registry |
registry.createTask() | Register a task (function) under a compile-time name |
registry.run() | Run a task immediately, ad-hoc |
registry.scheduleJob() | Schedule a named job (once via { in }/{ at }, or { cron }) |
registry.triggerJob() | Run an existing job now, respecting its concurrency |
registry.listJobs() / getJob() | Inspect registered jobs |
registry.cancelJob() | Cancel a job by name |
Scheduling is runtime-only and self-contained (no Nitro tasks required). See Tasks & Scheduling for the full model, concurrency, and cron details.
Resources
| Function | Description | Request Context |
|---|---|---|
useUser() | Fetch current user from Cumulocity | ✅ |
useUserRoles() | Get roles of the current user | ✅ |
These are the usual entry points when your route logic needs to know who is calling it.
Client
| Function | Description | Request Context |
|---|---|---|
useUserClient() | Create a client authenticated with the user's credentials | ✅ |
useUserTenantClient() | Create a client for the user's tenant | ✅ |
useSubscribedTenantClients() | Create clients for all subscribed tenants | ❌ |
useDeployedTenantClient() | Create a client for the deployed tenant | ❌ |
These helpers are useful when you want the raw platform client but do not want to rebuild authentication context resolution by hand.
Middleware
| Function | Description | Request Context |
|---|---|---|
hasUserRequiredRole(role|roles) | Check whether the current user has the required roles | ✅ |
isUserFromAllowedTenant(tenant|tenants) | Check whether the user belongs to an allowed tenant | ✅ |
isUserFromDeployedTenant() | Check whether the user belongs to the deployed tenant | ✅ |
Probe requests targeting the configured liveness and readiness paths bypass these auth helpers so platform health checks are not blocked.