@deveye/types 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +23 -0
- package/package.json +68 -0
- package/src/domain/audience.ts +549 -0
- package/src/domain/backup.ts +355 -0
- package/src/domain/credential.ts +55 -0
- package/src/domain/database.ts +467 -0
- package/src/domain/deploy.ts +231 -0
- package/src/domain/device.ts +172 -0
- package/src/domain/deviceFiles.ts +84 -0
- package/src/domain/deviceLogs.ts +82 -0
- package/src/domain/featureRegistry.ts +392 -0
- package/src/domain/finance.ts +477 -0
- package/src/domain/git.ts +419 -0
- package/src/domain/home.ts +314 -0
- package/src/domain/live.ts +272 -0
- package/src/domain/logs.ts +117 -0
- package/src/domain/mail.ts +394 -0
- package/src/domain/metrics.ts +127 -0
- package/src/domain/note.ts +202 -0
- package/src/domain/notifications.ts +268 -0
- package/src/domain/packages.ts +35 -0
- package/src/domain/password.ts +36 -0
- package/src/domain/presence.ts +21 -0
- package/src/domain/project.ts +168 -0
- package/src/domain/projectBoard.ts +130 -0
- package/src/domain/projectChat.ts +46 -0
- package/src/domain/projectHistory.ts +82 -0
- package/src/domain/projectLink.ts +87 -0
- package/src/domain/projectPlan.ts +68 -0
- package/src/domain/report.ts +492 -0
- package/src/domain/role.ts +8 -0
- package/src/domain/secrecy.ts +66 -0
- package/src/domain/sentinel.ts +623 -0
- package/src/domain/sharing.ts +186 -0
- package/src/domain/syncProtocol.ts +116 -0
- package/src/domain/twoFactor.ts +40 -0
- package/src/domain/uptime.ts +216 -0
- package/src/domain/user.ts +141 -0
- package/src/domain/workspace.ts +56 -0
- package/src/domain/workspaceRole.ts +251 -0
- package/src/features/admin.ts +112 -0
- package/src/features/audience.ts +275 -0
- package/src/features/backup.ts +230 -0
- package/src/features/database.ts +461 -0
- package/src/features/deploy.ts +245 -0
- package/src/features/device.ts +292 -0
- package/src/features/deviceFiles.ts +83 -0
- package/src/features/deviceLogs.ts +36 -0
- package/src/features/deviceTerminal.ts +57 -0
- package/src/features/finance.ts +360 -0
- package/src/features/git.ts +368 -0
- package/src/features/home.ts +32 -0
- package/src/features/live.ts +113 -0
- package/src/features/logs.ts +86 -0
- package/src/features/mail.ts +374 -0
- package/src/features/metrics.ts +185 -0
- package/src/features/note.ts +189 -0
- package/src/features/notify.ts +164 -0
- package/src/features/password.ts +67 -0
- package/src/features/project.ts +709 -0
- package/src/features/registry.ts +103 -0
- package/src/features/secrecy.ts +120 -0
- package/src/features/sentinel.ts +233 -0
- package/src/features/sharing.ts +79 -0
- package/src/features/twoFactor.ts +47 -0
- package/src/features/uptime.ts +186 -0
- package/src/features/user.ts +91 -0
- package/src/features/workspace.ts +200 -0
- package/src/http/auth.ts +94 -0
- package/src/http/device.ts +222 -0
- package/src/http/status.ts +45 -0
- package/src/index.ts +1700 -0
- package/src/protocol/agent.ts +1171 -0
- package/src/protocol/envelope.ts +46 -0
- package/src/protocol/error.ts +27 -0
- package/src/protocol/result.ts +17 -0
- package/src/protocol/version.ts +6 -0
- package/src/sdk/client-ambient.d.ts +238 -0
- package/src/sdk/client.ts +66 -0
- package/src/sdk/ids.ts +25 -0
- package/src/sdk/index.ts +11 -0
- package/src/sdk/manifest.ts +326 -0
- package/src/sdk/providers.ts +48 -0
- package/src/sdk/server.ts +378 -0
- package/src/sdk/testing.ts +179 -0
- package/src/utils/version.ts +28 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { deviceReportSchema, processCaptureSchema } from './report';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Lifecycle of a monitored machine (the Rust agent):
|
|
6
|
+
* - `pending`: enrolled via a link code but not yet confirmed in the UI.
|
|
7
|
+
* - `active`: confirmed; allowed to push metrics.
|
|
8
|
+
* - `revoked`: access withdrawn; the agent is rejected (can be reactivated).
|
|
9
|
+
* - `pending_deletion`: deletion requested; on its next connection the agent is
|
|
10
|
+
* told to self-destruct, then the device is archived. Can
|
|
11
|
+
* be cancelled until the agent reconnects.
|
|
12
|
+
* - `archived`: agent destroyed/removed; the device no longer exists for
|
|
13
|
+
* management, but its monitoring history is kept frozen and
|
|
14
|
+
* remains browsable (read-only) until explicitly purged.
|
|
15
|
+
*/
|
|
16
|
+
export const deviceStatusSchema = z.enum([
|
|
17
|
+
'pending',
|
|
18
|
+
'active',
|
|
19
|
+
'revoked',
|
|
20
|
+
'pending_deletion',
|
|
21
|
+
'archived'
|
|
22
|
+
]);
|
|
23
|
+
export type DeviceStatus = z.infer<typeof deviceStatusSchema>;
|
|
24
|
+
|
|
25
|
+
export const devicePlatformSchema = z.enum(['linux', 'macos', 'windows']);
|
|
26
|
+
export type DevicePlatform = z.infer<typeof devicePlatformSchema>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Client-facing device. Secrets (token hash, public key) are never exposed.
|
|
30
|
+
* `online` is live presence, derived from an active agent connection.
|
|
31
|
+
*/
|
|
32
|
+
export const deviceSchema = z.object({
|
|
33
|
+
id: z.uuid(),
|
|
34
|
+
ownerId: z.number().int().nonnegative(),
|
|
35
|
+
name: z.string().min(1).max(128),
|
|
36
|
+
fingerprint: z.string().min(1).max(128),
|
|
37
|
+
platform: devicePlatformSchema,
|
|
38
|
+
status: deviceStatusSchema,
|
|
39
|
+
online: z.boolean(),
|
|
40
|
+
lastSeen: z.number().int().nonnegative().nullable(),
|
|
41
|
+
created: z.number().int().nonnegative(),
|
|
42
|
+
/**
|
|
43
|
+
* Version the running agent reported on its last connection (`agent.hello`);
|
|
44
|
+
* null until it has connected at least once.
|
|
45
|
+
*/
|
|
46
|
+
agentVersion: z.string().nullable().default(null),
|
|
47
|
+
/**
|
|
48
|
+
* Version the server can update this agent to (the served/synced binary set),
|
|
49
|
+
* or null when nothing is synced. Server-computed, not stored.
|
|
50
|
+
*/
|
|
51
|
+
latestAgentVersion: z.string().nullable().default(null),
|
|
52
|
+
/**
|
|
53
|
+
* True when a newer, *signed* binary exists for this device's build target and
|
|
54
|
+
* the running agent differs from it — i.e. the UI can offer "Mettre à jour".
|
|
55
|
+
* Server-computed from the synced manifest, not stored.
|
|
56
|
+
*/
|
|
57
|
+
agentUpdateAvailable: z.boolean().default(false),
|
|
58
|
+
/** Latest known health/security report; null until the agent sends one. */
|
|
59
|
+
report: deviceReportSchema.nullable().default(null),
|
|
60
|
+
/**
|
|
61
|
+
* The agent's single collection interval in seconds — one tick yields
|
|
62
|
+
* metrics *and* processes under one timestamp. Null → server default (60).
|
|
63
|
+
*/
|
|
64
|
+
metricIntervalSeconds: z.number().int().positive().nullable().default(null),
|
|
65
|
+
/** How much of the process list each tick carries; null → server default (`all`). */
|
|
66
|
+
processCapture: processCaptureSchema.nullable().default(null),
|
|
67
|
+
/**
|
|
68
|
+
* History retention in days — one duration for the whole instant: metrics,
|
|
69
|
+
* presence *and* processes expire together. Null → server default.
|
|
70
|
+
*/
|
|
71
|
+
retentionDays: z.number().int().positive().nullable().default(null),
|
|
72
|
+
/**
|
|
73
|
+
* Workspaces this device is shared with. A device is reachable from every
|
|
74
|
+
* workspace listed here; its pairing workspace is always among them.
|
|
75
|
+
*/
|
|
76
|
+
workspaceIds: z.array(z.number().int().positive()).default([]),
|
|
77
|
+
/**
|
|
78
|
+
* Last self-destruct failure message: set when an agent failed to wipe itself
|
|
79
|
+
* during deletion, so the UI can surface it and the deletion is aborted.
|
|
80
|
+
* Null when there's no pending error.
|
|
81
|
+
*/
|
|
82
|
+
deleteError: z.string().nullable().default(null)
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export type Device = z.infer<typeof deviceSchema>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Database row shape (server-only). Mirrors columns exactly.
|
|
89
|
+
*/
|
|
90
|
+
export interface DeviceRow {
|
|
91
|
+
id: string;
|
|
92
|
+
owner_id: number;
|
|
93
|
+
/**
|
|
94
|
+
* Espace d'**appairage** : celui que visait le code de liaison. Il porte
|
|
95
|
+
* l'unicité de l'empreinte (`uniq_workspace_fingerprint`) et sert le
|
|
96
|
+
* ré-enrôlement depuis la route publique, qui n'a pas de session pour dire
|
|
97
|
+
* autrement d'où elle vient.
|
|
98
|
+
*
|
|
99
|
+
* Ce n'est plus la frontière d'accès : celle-ci est la table de jonction
|
|
100
|
+
* `device_workspaces`, un appareil pouvant être partagé avec plusieurs
|
|
101
|
+
* espaces. L'espace d'appairage y figure toujours et ne s'en retire pas.
|
|
102
|
+
*
|
|
103
|
+
* `null` quand cet espace a été supprimé : l'appareil survit — il perd son
|
|
104
|
+
* origine, pas son existence — et reste joignable par les espaces avec
|
|
105
|
+
* lesquels il est partagé.
|
|
106
|
+
*/
|
|
107
|
+
workspace_id: number | null;
|
|
108
|
+
name: string;
|
|
109
|
+
fingerprint: string;
|
|
110
|
+
platform: string;
|
|
111
|
+
status: DeviceStatus;
|
|
112
|
+
/** X25519 public key (base64) used for command signature verification. */
|
|
113
|
+
public_key: string | null;
|
|
114
|
+
/** SHA-256 hash of the device token (the raw token lives only on the agent). */
|
|
115
|
+
token_hash: string;
|
|
116
|
+
last_seen: number | null;
|
|
117
|
+
created: number;
|
|
118
|
+
/** Agent version from the last `agent.hello`; null until first connection. */
|
|
119
|
+
agent_version: string | null;
|
|
120
|
+
/** Build target the agent reported (`linux-x86_64`…); null until first hello. */
|
|
121
|
+
agent_target: string | null;
|
|
122
|
+
/** JSON-encoded latest `DeviceReport`, or null if none received yet. */
|
|
123
|
+
report_json: string | null;
|
|
124
|
+
/** Collection interval in seconds (metrics + processes); null → server default. */
|
|
125
|
+
metric_interval_seconds: number | null;
|
|
126
|
+
/** Process capture mode (`off`|`top`|`all`); null → server default. */
|
|
127
|
+
process_capture: string | null;
|
|
128
|
+
/** History retention in days (metrics, presence, processes); null → server default. */
|
|
129
|
+
retention_days: number | null;
|
|
130
|
+
/** Status to restore if a pending deletion is cancelled; null otherwise. */
|
|
131
|
+
status_before_delete: string | null;
|
|
132
|
+
/** Last self-destruct failure message (deletion aborted); null otherwise. */
|
|
133
|
+
delete_error: string | null;
|
|
134
|
+
/**
|
|
135
|
+
* Sentinelle est-elle active sur cet appareil ? Éteinte par défaut : activer
|
|
136
|
+
* la feature ne doit lire les journaux d'authentification de personne, c'est
|
|
137
|
+
* un geste explicite appareil par appareil.
|
|
138
|
+
*/
|
|
139
|
+
sentinel_enabled: number;
|
|
140
|
+
/**
|
|
141
|
+
* Fin de la fenêtre d'apprentissage, unix ms. `null` tant que Sentinelle n'a
|
|
142
|
+
* jamais été activée ; une date passée signifie « apprentissage terminé ».
|
|
143
|
+
*/
|
|
144
|
+
sentinel_learning_until: number | null;
|
|
145
|
+
/** Cadence du manifeste de persistance, en minutes. */
|
|
146
|
+
sentinel_integrity_minutes: number;
|
|
147
|
+
/** Relever les issues d'authentification (interrupteur propre). */
|
|
148
|
+
sentinel_auth_events: number;
|
|
149
|
+
/** Unix ms du dernier manifeste reçu ; `null` = jamais mesuré. */
|
|
150
|
+
sentinel_last_integrity_at: number | null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Un appareil rangé dans un espace (`device_workspaces`). Le rang est porté par
|
|
155
|
+
* la jonction et non par l'appareil : le même appareil est rangé
|
|
156
|
+
* indépendamment dans chaque espace qui y a accès.
|
|
157
|
+
*/
|
|
158
|
+
export interface DeviceWorkspaceRow {
|
|
159
|
+
device_id: string;
|
|
160
|
+
workspace_id: number;
|
|
161
|
+
/** Rank in *that* workspace's list, entirely the user's (`device.reorder`). */
|
|
162
|
+
sort_order: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Réglages appliqués à un appareil qui n'a rien choisi. Source unique : le
|
|
167
|
+
* serveur les applique en construisant la config poussée à l'agent, et le
|
|
168
|
+
* dialogue de configuration les affiche comme valeurs de départ.
|
|
169
|
+
*/
|
|
170
|
+
export const DEFAULT_METRIC_INTERVAL_SECONDS = 60;
|
|
171
|
+
export const DEFAULT_PROCESS_CAPTURE = 'all' as const;
|
|
172
|
+
export const DEFAULT_RETENTION_DAYS = 30;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Device file explorer — entities shared by the agent, server and client.
|
|
5
|
+
*
|
|
6
|
+
* A graphical, ncdu-flavoured browser over the device filesystem: list a
|
|
7
|
+
* directory, analyse recursive disk usage, search (name/extension/content + date
|
|
8
|
+
* & size windows), and clean up (delete / mkdir / rename). All paths are absolute
|
|
9
|
+
* on the device; the agent operates with its own privileges.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const fileKindSchema = z.enum(['file', 'dir', 'symlink', 'other']);
|
|
13
|
+
export type FileKind = z.infer<typeof fileKindSchema>;
|
|
14
|
+
|
|
15
|
+
/** One directory entry (shallow — `size` is the entry's own size, not recursive). */
|
|
16
|
+
export const fileEntrySchema = z.object({
|
|
17
|
+
name: z.string(),
|
|
18
|
+
kind: fileKindSchema,
|
|
19
|
+
/** Own size in bytes (file content; a directory's own inode size). */
|
|
20
|
+
size: z.number().int().nonnegative(),
|
|
21
|
+
/** Last-modified, unix milliseconds (null when unavailable). */
|
|
22
|
+
mtime: z.number().int().nullable(),
|
|
23
|
+
/** Unix permission bits for display (e.g. 0o644); null on platforms without. */
|
|
24
|
+
mode: z.number().int().nullable(),
|
|
25
|
+
/** Link target for symlinks. */
|
|
26
|
+
symlinkTarget: z.string().nullable().optional()
|
|
27
|
+
});
|
|
28
|
+
export type FileEntry = z.infer<typeof fileEntrySchema>;
|
|
29
|
+
|
|
30
|
+
/** A directory listing: the resolved path, its parent, and the entries. */
|
|
31
|
+
export const fileListingSchema = z.object({
|
|
32
|
+
path: z.string(),
|
|
33
|
+
parent: z.string().nullable(),
|
|
34
|
+
entries: z.array(fileEntrySchema)
|
|
35
|
+
});
|
|
36
|
+
export type FileListing = z.infer<typeof fileListingSchema>;
|
|
37
|
+
|
|
38
|
+
/** One child's recursive size (the ncdu view). `partial` = the walk budget was hit. */
|
|
39
|
+
export const fileUsageEntrySchema = z.object({
|
|
40
|
+
name: z.string(),
|
|
41
|
+
kind: fileKindSchema,
|
|
42
|
+
totalSize: z.number().int().nonnegative(),
|
|
43
|
+
partial: z.boolean()
|
|
44
|
+
});
|
|
45
|
+
export type FileUsageEntry = z.infer<typeof fileUsageEntrySchema>;
|
|
46
|
+
|
|
47
|
+
/** One search hit. `preview` is the matching line for a content search. */
|
|
48
|
+
export const fileMatchSchema = z.object({
|
|
49
|
+
path: z.string(),
|
|
50
|
+
name: z.string(),
|
|
51
|
+
kind: fileKindSchema,
|
|
52
|
+
size: z.number().int().nonnegative(),
|
|
53
|
+
mtime: z.number().int().nullable(),
|
|
54
|
+
preview: z.string().max(500).nullable().optional()
|
|
55
|
+
});
|
|
56
|
+
export type FileMatch = z.infer<typeof fileMatchSchema>;
|
|
57
|
+
|
|
58
|
+
/** What a search query matches against. */
|
|
59
|
+
export const fileSearchFieldSchema = z.enum(['name', 'extension', 'content']);
|
|
60
|
+
export type FileSearchField = z.infer<typeof fileSearchFieldSchema>;
|
|
61
|
+
|
|
62
|
+
export const FILE_SEARCH_MAX = 2000;
|
|
63
|
+
|
|
64
|
+
/** Advanced search surface (all optional, combined as AND). */
|
|
65
|
+
export const fileSearchFilterSchema = z.object({
|
|
66
|
+
/** The text to look for (interpreted per `field`; empty = match all, e.g. for a pure date/size filter). */
|
|
67
|
+
query: z.string().max(500).optional(),
|
|
68
|
+
/** Where to look: file name (default), extension, or file content (grep). */
|
|
69
|
+
field: fileSearchFieldSchema.optional(),
|
|
70
|
+
/** Treat `query` as a regular expression (name/content only). */
|
|
71
|
+
regex: z.boolean().optional(),
|
|
72
|
+
/** Modified at/after, unix epoch seconds. */
|
|
73
|
+
since: z.number().int().nonnegative().optional(),
|
|
74
|
+
/** Modified at/before, unix epoch seconds. */
|
|
75
|
+
until: z.number().int().nonnegative().optional(),
|
|
76
|
+
/** Size floor / ceiling in bytes. */
|
|
77
|
+
minSize: z.number().int().nonnegative().optional(),
|
|
78
|
+
maxSize: z.number().int().nonnegative().optional()
|
|
79
|
+
});
|
|
80
|
+
export type FileSearchFilter = z.infer<typeof fileSearchFilterSchema>;
|
|
81
|
+
|
|
82
|
+
/** A filesystem mutation. `rename` also needs `dest`. */
|
|
83
|
+
export const fileMutateOpSchema = z.enum(['delete', 'mkdir', 'rename']);
|
|
84
|
+
export type FileMutateOp = z.infer<typeof fileMutateOpSchema>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Device log viewer — entities shared by the agent, server and client.
|
|
5
|
+
*
|
|
6
|
+
* Distinct from `domain/logs.ts` (the *audit* log of DevEye itself). These types
|
|
7
|
+
* describe **on-device** logs the agent reads live: the system journal, per-Docker
|
|
8
|
+
* container logs, plain syslog files, the macOS unified log, the Windows event log.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** What kind of reader backs a source (drives the agent's query strategy + the icon). */
|
|
12
|
+
export const deviceLogSourceKindSchema = z.enum([
|
|
13
|
+
'journald', // systemd journal (Linux)
|
|
14
|
+
'docker', // one Docker container
|
|
15
|
+
'syslog', // a plain text log file (e.g. /var/log/syslog)
|
|
16
|
+
'oslog', // macOS unified logging (`log show`)
|
|
17
|
+
'eventlog' // Windows event log channel
|
|
18
|
+
]);
|
|
19
|
+
export type DeviceLogSourceKind = z.infer<typeof deviceLogSourceKindSchema>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A queryable log source discovered on a device. `id` is an opaque token the agent
|
|
23
|
+
* resolves back to a concrete reader (e.g. `journald`, `docker:<id>`,
|
|
24
|
+
* `file:/var/log/syslog`, `eventlog:System`) — the client never parses it.
|
|
25
|
+
*/
|
|
26
|
+
export const deviceLogSourceSchema = z.object({
|
|
27
|
+
id: z.string().min(1).max(512),
|
|
28
|
+
kind: deviceLogSourceKindSchema,
|
|
29
|
+
/** Human label (service/container/file name). */
|
|
30
|
+
label: z.string().min(1).max(256),
|
|
31
|
+
/** Extra UI context (Docker image, file path, channel description). */
|
|
32
|
+
detail: z.string().max(256).nullable().optional(),
|
|
33
|
+
/** For Docker: whether the container is currently running (stopped ones still have logs). */
|
|
34
|
+
running: z.boolean().nullable().optional()
|
|
35
|
+
});
|
|
36
|
+
export type DeviceLogSource = z.infer<typeof deviceLogSourceSchema>;
|
|
37
|
+
|
|
38
|
+
/** Normalised severity, coarsest → highest. Ordered for `levelMin` comparisons. */
|
|
39
|
+
export const DEVICE_LOG_LEVELS = [
|
|
40
|
+
'debug',
|
|
41
|
+
'info',
|
|
42
|
+
'notice',
|
|
43
|
+
'warning',
|
|
44
|
+
'error',
|
|
45
|
+
'critical'
|
|
46
|
+
] as const;
|
|
47
|
+
export const deviceLogLevelSchema = z.enum(DEVICE_LOG_LEVELS);
|
|
48
|
+
export type DeviceLogLevel = z.infer<typeof deviceLogLevelSchema>;
|
|
49
|
+
|
|
50
|
+
/** One log line. `ts` is unix **milliseconds** (null when the source carries none). */
|
|
51
|
+
export const deviceLogLineSchema = z.object({
|
|
52
|
+
ts: z.number().int().nullable(),
|
|
53
|
+
level: deviceLogLevelSchema.nullable(),
|
|
54
|
+
message: z.string(),
|
|
55
|
+
/** Originating unit/service (journald) or container short id (docker), when known. */
|
|
56
|
+
unit: z.string().max(256).nullable().optional()
|
|
57
|
+
});
|
|
58
|
+
export type DeviceLogLine = z.infer<typeof deviceLogLineSchema>;
|
|
59
|
+
|
|
60
|
+
export const DEVICE_LOG_PAGE_MAX = 1000;
|
|
61
|
+
export const DEVICE_LOG_PAGE_DEFAULT = 200;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Advanced search surface for a query. Every field is optional and combines as
|
|
65
|
+
* AND, so the UI can drill down precisely (text/regex, severity floor, unit, time
|
|
66
|
+
* window). All omitted → the newest `limit` lines of the source.
|
|
67
|
+
*/
|
|
68
|
+
export const deviceLogFilterSchema = z.object({
|
|
69
|
+
/** Free-text (or regex when `regex`) match against the message, case-insensitive. */
|
|
70
|
+
search: z.string().max(500).optional(),
|
|
71
|
+
/** Treat `search` as a regular expression. */
|
|
72
|
+
regex: z.boolean().optional(),
|
|
73
|
+
/** Severity floor (inclusive): only lines with level >= this. */
|
|
74
|
+
levelMin: deviceLogLevelSchema.optional(),
|
|
75
|
+
/** journald unit / service filter (e.g. `nginx.service`). Ignored by other kinds. */
|
|
76
|
+
unit: z.string().max(256).optional(),
|
|
77
|
+
/** Window start, unix epoch **seconds**, inclusive. */
|
|
78
|
+
since: z.number().int().nonnegative().optional(),
|
|
79
|
+
/** Window end, unix epoch **seconds**, inclusive. */
|
|
80
|
+
until: z.number().int().nonnegative().optional()
|
|
81
|
+
});
|
|
82
|
+
export type DeviceLogFilter = z.infer<typeof deviceLogFilterSchema>;
|