Generated from services/crossfire/node/packages/contracts/src/fleet-control.ts at
52bf0279Definitions#
These TypeScript definitions document server validation. check.object rejects unknown fields. Custom functions and refinements specify additional checks.
Imported definitions#
services/crossfire/node/packages/contracts/src/schema/validation.tsservices/crossfire/node/packages/contracts/src/schema/request.tsservices/crossfire/node/packages/kernel/src/result.tsservices/crossfire/node/packages/contracts/src/fleet-runtime.ts
fleetControl#
fleetControl = check.object({ fleetId: check.identifier, revision: check.integer(), deliveryEnabled: check.boolean,
connection: check.object({ status: check.choice('online', 'offline'), lastSeenAt: check.nullable(check.integer()) }) })Related definitions:
messageBody#
messageBody = check.refine(check.plainText(16384), body => !!body.trim() && body.length <= 4096, 'Expected a fleet message of 1–4096 characters')Related definitions:
fleetMessageCommand#
fleetMessageCommand = check.object({ messageId: check.identifier, fleetId: check.identifier, body: messageBody,
createdAt: check.integer(), expiresAt: check.integer(), sender: check.refine(check.object({ kind: check.choice('human', 'controller'),
matrixUserId: check.nullable(check.matrixUserId) }), sender => (sender.kind === 'human') === (sender.matrixUserId !== null), 'Invalid fleet message sender'),
agentIds: check.list(check.identifier, 100) })Related definitions:
fleetControlSnapshot#
fleetControlSnapshot = check.refine(check.object({ fleetId: check.identifier, revision: check.integer(), deliveryEnabled: check.boolean,
connection: check.object({ status: check.choice('online', 'offline'), lastSeenAt: check.nullable(check.integer()) }),
agentIds: check.list(check.identifier, 100), messages: check.list(fleetMessageCommand, 1), runtimeOperations: check.list(runtimeOperation, 1) }), snapshot => new Set(snapshot.agentIds).size === snapshot.agentIds.length && snapshot.messages.every(message => message.fleetId === snapshot.fleetId
&& message.expiresAt > message.createdAt && new Set(message.agentIds).size === message.agentIds.length)
&& snapshot.runtimeOperations.every(operation => operation.fleetId === snapshot.fleetId && (operation.status === 'pending' || operation.status === 'running')), 'Invalid fleet control snapshot')Related definitions:
fleetMessageSummary#
fleetMessageSummary = check.object({ messageId: check.identifier, body: messageBody, createdAt: check.integer(), expiresAt: check.integer(),
total: check.integer(0, 100), delivered: check.integer(0, 100), failed: check.integer(0, 100), skipped: check.integer(0, 100), pending: check.integer(0, 100), expired: check.integer(0, 100) })Related definitions:
deliveryChange#
deliveryChange = check.object({ expectedRevision: check.integer(), enabled: check.boolean })Related definitions:
messageCreation#
messageCreation = check.object({ messageId: check.identifier, body: messageBody })Related definitions:
connectionReport#
connectionReport = check.object({ stopped: check.boolean })Related definitions:
receiptReport#
receiptReport = check.object({ status: check.choice('delivered', 'failed', 'skipped'), errorMessage: check.nullable(check.text(1000)) })Related definitions:
controlQuery#
export function controlQuery(input: unknown) {
const values = listQuery(['connectionId', 'revision', 'waitMs'])(input);
if (!values.ok)
return values;
const connectionId = check.identifier(values.value.get('connectionId'));
const revision = queryInteger(values.value.get('revision'), 0, Number.MAX_SAFE_INTEGER);
const waitMs = queryInteger(values.value.get('waitMs'), 0, 10000);
if (!connectionId.ok)
return connectionId;
if (!values.value.has('revision') || !revision.ok || !values.value.has('waitMs') || !waitMs.ok)
return failure('invalid', 'A revision and bounded waitMs are required');
return success({ connectionId: connectionId.value, revision: revision.value, waitMs: waitMs.value });
}Related definitions:
messagePage#
export function messagePage(input: unknown) {
const values = listQuery(['page', 'pageSize'])(input);
if (!values.ok)
return values;
const page = queryInteger(values.value.get('page') ?? '1', 1, 100000);
const pageSize = queryInteger(values.value.get('pageSize') ?? '10', 1, 10);
if (!page.ok)
return page;
if (!pageSize.ok)
return pageSize;
return success({ page: page.value, pageSize: pageSize.value });
}Related definitions:
queryInteger#
function queryInteger(value: string | null, minimum: number, maximum: number) {
return value !== null && /^(0|[1-9][0-9]*)$/u.test(value) ? check.integer(minimum, maximum)(Number(value)) : failure('invalid', 'Use a canonical integer query value');
}Related definitions:
FleetControl#
export type FleetControl = Parsed<typeof fleetControl>;Related definitions:
FleetControlSnapshot#
export type FleetControlSnapshot = Parsed<typeof fleetControlSnapshot>;Related definitions:
FleetMessageCommand#
export type FleetMessageCommand = Parsed<typeof fleetMessageCommand>;Related definitions: