Definitions#

These TypeScript definitions document server validation. check.object rejects unknown fields. Custom functions and refinements specify additional checks.

Imported definitions#

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: