/** * Monitor authoring and typing for the Deepline SDK. * * A **monitor** is a Deepline-native signal feed. A deployed monitor writes * events into a Customer DB table (one row per finding). Plays react to those * rows through `sqlListeners` bindings (see {@link definePlay}). This module is * the code-first authoring surface for monitors — the same product model the * `deepline monitors` CLI drives, expressed as typed SDK code. * * Use {@link defineMonitor} to author a typed monitor definition, then deploy or * validate it with the monitors namespace: * * ```typescript * import { DeeplineClient, defineMonitor } from 'deepline'; * * const monitor = defineMonitor({ * key: 'stripe-job-openings', * tool: 'deepline_native.company_radar', * name: 'Stripe job openings', * payload: { domain: 'stripe.com', radar_type: 'company_job_openings' }, * }); * * const client = new DeeplineClient(); * const plan = await client.monitors.check(monitor); // validate, no spend * await client.monitors.deploy(monitor); // deploy for real * ``` * * @module */ /** * A monitor definition: the exact object accepted by * `client.monitors.check(...)` and `client.monitors.deploy(...)` and by the * `/api/v2/monitors/{check,deploy}` endpoints the CLI uses. * * @typeParam TPayload - Provider-specific monitor payload shape (defaults to a * loose record). Pass a concrete shape to `defineMonitor(...)` for * compile-time checking of the payload fields. */ export type MonitorDefinition< TPayload extends MonitorPayload = MonitorPayload, > = { /** Stable public key for this monitor, unique within the workspace. */ key: string; /** Monitor tool id, e.g. `"deepline_native.company_radar"`. */ tool: string; /** Optional human-readable name shown in listings and detail views. */ name?: string; /** Provider-specific monitor payload (e.g. domain + radar_type). */ payload: TPayload; /** Optional Deepline lifecycle metadata (deploy/reuse controls). */ controls?: MonitorControls; }; /** Provider-specific monitor payload. Keys and value types depend on the tool. */ export type MonitorPayload = Record; /** * Deepline lifecycle metadata attached to a monitor definition. These are * Deepline-side deploy/reuse controls, not provider payload fields. The set is * intentionally open (server-owned) so newer controls do not require an SDK * bump; known controls are typed for discoverability. */ export type MonitorControls = { /** * Request Deepline Native priority execution for a bounded urgent preview or * calibration radar. Deepline sends the upstream custom-field marker and * enforces a maximum of ten active or in-flight priority radars per org. * Omit this for regular and bulk-scale monitoring. */ execution_type?: 'priority'; [key: string]: unknown; }; /** * Define a typed monitor definition. * * Mirrors {@link definePlay} as the code-first authoring entrypoint: it gives * compile-time type safety on the definition object and returns it verbatim for * passing to `client.monitors.check(...)` / `client.monitors.deploy(...)`. It * performs the same lightweight local invariants the server enforces (non-empty * `key` and `tool`, object `payload`) so authoring mistakes fail before a * network round-trip. * * @typeParam TPayload - Provider payload shape. * @param definition - The monitor definition. * @returns The validated definition object. * * @example * ```typescript * const monitor = defineMonitor({ * key: 'job-openings', * tool: 'deepline_native.company_radar', * payload: { domain: 'stripe.com', radar_type: 'company_job_openings' }, * }); * ``` */ export function defineMonitor( definition: MonitorDefinition, ): MonitorDefinition { if (!definition || typeof definition !== 'object') { throw new Error('defineMonitor(definition) requires a definition object.'); } const key = typeof definition.key === 'string' ? definition.key.trim() : ''; if (!key) { throw new Error('defineMonitor(definition) requires a non-empty "key".'); } const tool = typeof definition.tool === 'string' ? definition.tool.trim() : ''; if (!tool) { throw new Error( 'defineMonitor(definition) requires a non-empty monitor tool id in "tool" ' + '(e.g. "deepline_native.company_radar").', ); } if ( !definition.payload || typeof definition.payload !== 'object' || Array.isArray(definition.payload) ) { throw new Error( 'defineMonitor(definition) requires "payload" to be a JSON object.', ); } if (definition.name !== undefined && typeof definition.name !== 'string') { throw new Error('defineMonitor(definition) "name" must be a string.'); } if ( definition.controls !== undefined && (typeof definition.controls !== 'object' || Array.isArray(definition.controls)) ) { throw new Error( 'defineMonitor(definition) "controls" must be a JSON object.', ); } return definition; }