Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

4.4 KiB

@alga-psa/extension-runtime

Utility types and helper functions for Alga extension components compiled with componentize-js.

Installation

npm install @alga-psa/extension-runtime

Usage

import { Handler, jsonResponse } from '@alga-psa/extension-runtime';

export const handler: Handler = async (request, host) => {
  const secret = await host.secrets.get('alga_api_key');
  await host.logging.info(`Handling request for ${request.context.tenantId}`);
  return jsonResponse({ ok: true, secret, path: request.http.path });
};

The helpers mirror the WIT definitions in ee/runner/wit/extension-runner.wit.

Host Bindings

The HostBindings interface provides access to host capabilities:

Context

host.context.get(): Promise<ContextData>

Get execution context (tenant, extension, request IDs).

Secrets

host.secrets.get(key: string): Promise<string>
host.secrets.list(): Promise<string[]>

Access install-scoped secrets. Requires cap:secrets.get.

HTTP

host.http.fetch(request: HttpRequest): Promise<HttpResponse>

Make outbound HTTP requests. Requires cap:http.fetch.

Storage

host.storage.get(namespace: string, key: string): Promise<Uint8Array | null>
host.storage.put(entry: StorageEntry): Promise<void>
host.storage.delete(namespace: string, key: string): Promise<void>
host.storage.list(namespace: string): Promise<StorageEntry[]>

Key-value storage. Requires cap:storage.kv.

Logging

host.logging.info(message: string): Promise<void>
host.logging.warn(message: string): Promise<void>
host.logging.error(message: string): Promise<void>

Emit structured logs. Requires cap:log.emit.

UI Proxy

host.uiProxy.callRoute(route: string, payload?: Uint8Array): Promise<Uint8Array>

Call host-mediated proxy routes for UI flows. Requires cap:ui.proxy.

User

host.user.getUser(): Promise<UserData>

Get current user information. Requires cap:user.read (granted by default).

interface UserData {
  tenantId: string;
  clientName: string;
  userId: string;
  userEmail: string;
  userName: string;
  userType: string;  // "internal" or "client"
  clientId?: string;
  additionalFields?: Record<string, string>;
}

Scheduler

host.scheduler.list(): Promise<ScheduleInfo[]>
host.scheduler.get(scheduleId: string): Promise<ScheduleInfo | null>
host.scheduler.create(input: CreateScheduleInput): Promise<CreateScheduleResult>
host.scheduler.update(scheduleId: string, input: UpdateScheduleInput): Promise<UpdateScheduleResult>
host.scheduler.delete(scheduleId: string): Promise<DeleteScheduleResult>
host.scheduler.getEndpoints(): Promise<EndpointInfo[]>

Manage scheduled tasks. Requires cap:scheduler.manage.

Invoicing

host.invoicing.createManualInvoice(input: CreateManualInvoiceInput): Promise<CreateManualInvoiceResult>

Create draft manual invoices. Requires cap:invoice.manual.create.

Helper Functions

jsonResponse

jsonResponse(body: unknown, init?: Partial<ExecuteResponse>): ExecuteResponse

Create a JSON response with proper headers.

emptyResponse

emptyResponse(status?: number): ExecuteResponse

Create an empty response (default status 204).

createMockHostBindings

createMockHostBindings(overrides?: Partial<HostBindings>): HostBindings

Create mock host bindings for testing.

Using WIT Imports

When building with jco componentize, host capabilities are imported from WIT modules. Create a wrapper index.ts:

import { normalizeUserData } from '@alga-psa/extension-runtime';
// Import WIT functions
// @ts-ignore
import { getUser } from 'alga:extension/user-v2';
// @ts-ignore
import { logInfo } from 'alga:extension/logging';

// Build HostBindings
const host: HostBindings = {
  user: { getUser: async () => normalizeUserData(await getUser()) },
  logging: { info: async (msg) => logInfo(msg), /* ... */ },
  // ... other bindings
};

export async function handler(request: ExecuteRequest): Promise<ExecuteResponse> {
  return myHandler(request, host);
}

See User Host API Guide, Scheduler Host API Guide, and Invoicing Host API Guide for complete examples.

Building

Run npm run build before publishing.