@deveye/types 0.15.2 → 0.16.1
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/package.json +6 -6
- package/src/domain/device.ts +4 -29
- package/src/domain/featureRegistry.ts +40 -108
- package/src/domain/home.ts +40 -101
- package/src/domain/live.ts +36 -87
- package/src/domain/metrics.ts +10 -14
- package/src/domain/notifications.ts +39 -110
- package/src/domain/project.ts +3 -162
- package/src/domain/report.ts +54 -95
- package/src/domain/secrecy.ts +3 -5
- package/src/domain/sharing.ts +33 -70
- package/src/domain/syncProtocol.ts +5 -12
- package/src/domain/user.ts +8 -14
- package/src/domain/workspace.ts +0 -3
- package/src/domain/workspaceRole.ts +34 -82
- package/src/features/agent.ts +306 -0
- package/src/features/live.ts +17 -37
- package/src/features/notify.ts +19 -57
- package/src/features/registry.ts +7 -44
- package/src/features/secrecy.ts +4 -9
- package/src/features/sharing.ts +12 -26
- package/src/features/user.ts +6 -11
- package/src/features/workspace.ts +6 -11
- package/src/http/auth.ts +6 -13
- package/src/http/device.ts +13 -17
- package/src/http/status.ts +6 -10
- package/src/index.ts +29 -932
- package/src/protocol/agent.ts +40 -70
- package/src/protocol/envelope.ts +3 -10
- package/src/sdk/client-ambient.d.ts +228 -21
- package/src/sdk/client.ts +277 -17
- package/src/sdk/devb.ts +120 -0
- package/src/sdk/manifest.test.ts +0 -1
- package/src/sdk/manifest.ts +94 -25
- package/src/sdk/providers.ts +310 -5
- package/src/sdk/server.ts +483 -19
- package/src/sdk/testing.test.ts +2 -2
- package/src/sdk/testing.ts +302 -26
- package/src/utils/version.ts +5 -8
- package/src/domain/audience.ts +0 -549
- package/src/domain/backup.ts +0 -355
- package/src/domain/credential.ts +0 -55
- package/src/domain/database.ts +0 -467
- package/src/domain/deploy.ts +0 -231
- package/src/domain/finance.ts +0 -477
- package/src/domain/git.ts +0 -419
- package/src/domain/mail.ts +0 -394
- package/src/domain/note.ts +0 -202
- package/src/domain/password.ts +0 -36
- package/src/domain/projectBoard.ts +0 -130
- package/src/domain/projectChat.ts +0 -46
- package/src/domain/projectHistory.ts +0 -82
- package/src/domain/projectLink.ts +0 -87
- package/src/domain/projectPlan.ts +0 -68
- package/src/domain/sentinel.ts +0 -623
- package/src/domain/uptime.ts +0 -216
- package/src/features/audience.ts +0 -275
- package/src/features/backup.ts +0 -230
- package/src/features/database.ts +0 -461
- package/src/features/deploy.ts +0 -245
- package/src/features/device.ts +0 -292
- package/src/features/deviceFiles.ts +0 -83
- package/src/features/deviceLogs.ts +0 -36
- package/src/features/deviceTerminal.ts +0 -57
- package/src/features/finance.ts +0 -360
- package/src/features/git.ts +0 -368
- package/src/features/mail.ts +0 -374
- package/src/features/metrics.ts +0 -185
- package/src/features/note.ts +0 -189
- package/src/features/password.ts +0 -67
- package/src/features/project.ts +0 -709
- package/src/features/sentinel.ts +0 -233
- package/src/features/uptime.ts +0 -186
package/src/sdk/providers.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provider contracts: the inversion for
|
|
3
|
-
*
|
|
2
|
+
* Provider contracts: the inversion for code that needs a MODULE's data,
|
|
3
|
+
* whether it is the app or another module.
|
|
4
4
|
*
|
|
5
5
|
* A module exposes named contracts on its service (`FeatureService.providers`);
|
|
6
6
|
* the app looks them up at call time (`moduleProvider(key)` in its SDK
|
|
7
|
-
* assembly) and degrades cleanly when
|
|
8
|
-
*
|
|
9
|
-
* while neither may import the
|
|
7
|
+
* assembly, `ctx.providers.get(key)` from a module) and degrades cleanly when
|
|
8
|
+
* the module is absent. The contract types live here, in the published
|
|
9
|
+
* package, because both sides must agree on them while neither may import the
|
|
10
|
+
* other. Every provider is offered by a module's service: the app offers none
|
|
11
|
+
* itself.
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
/** Key under `FeatureService.providers` for the CloudSync backup source. */
|
|
@@ -46,3 +48,306 @@ export interface CloudSyncBackupProvider {
|
|
|
46
48
|
/** Decrypted plaintext stream of one blob. */
|
|
47
49
|
openBlob(shareId: number, hash: string): Promise<AsyncIterable<Uint8Array>>;
|
|
48
50
|
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Key of the database access the Backup module consumes: a logical dump goes
|
|
54
|
+
* through the SAME access as the monitoring (SSH tunnel or SOCKS proxy
|
|
55
|
+
* included), and only the Databases feature knows how to decrypt a connection.
|
|
56
|
+
*/
|
|
57
|
+
export const DATABASE_BACKUP_PROVIDER = 'database.backup' as const;
|
|
58
|
+
|
|
59
|
+
/** A database of the workspace, as the source picker lists it. */
|
|
60
|
+
export interface DatabaseBackupCandidate {
|
|
61
|
+
id: number;
|
|
62
|
+
name: string;
|
|
63
|
+
engine: 'mysql' | 'postgres';
|
|
64
|
+
host: string;
|
|
65
|
+
database: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* An OPEN access to a database: what a dump tool needs, reachable from the
|
|
70
|
+
* server (the tunnel's local listener when there is one). `close()` releases
|
|
71
|
+
* the tunnel; call it whatever happens, a forgotten tunnel keeps an SSH
|
|
72
|
+
* session and a listener alive.
|
|
73
|
+
*/
|
|
74
|
+
export interface DatabaseBackupAccess {
|
|
75
|
+
engine: 'mysql' | 'postgres';
|
|
76
|
+
host: string;
|
|
77
|
+
port: number;
|
|
78
|
+
database: string;
|
|
79
|
+
username: string;
|
|
80
|
+
password: string | null;
|
|
81
|
+
close(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface DatabaseBackupProvider {
|
|
85
|
+
/** The databases of the workspace, its own only (a projection is not a source). */
|
|
86
|
+
listDatabases(workspaceId: number): Promise<readonly DatabaseBackupCandidate[]>;
|
|
87
|
+
findDatabase(databaseId: number, workspaceId: number): Promise<DatabaseBackupCandidate | null>;
|
|
88
|
+
/** null when the database is unknown to this workspace. */
|
|
89
|
+
openAccess(databaseId: number, workspaceId: number): Promise<DatabaseBackupAccess | null>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Key under `FeatureService.providers` for the Databases items the Projects
|
|
94
|
+
* feature links to: same shape and reason as `UPTIME_ITEMS_PROVIDER`
|
|
95
|
+
* (`project_database_links` is Projects' table).
|
|
96
|
+
*/
|
|
97
|
+
export const DATABASE_ITEMS_PROVIDER = 'database.items' as const;
|
|
98
|
+
|
|
99
|
+
export interface DatabaseItemsProvider {
|
|
100
|
+
/** Does this database live in this workspace? Its home only, never a projection. */
|
|
101
|
+
exists(databaseId: number, workspaceId: number): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* The item's display name under the OPEN cipher of `workspaceId`, its home;
|
|
104
|
+
* `null` when it is gone or unreadable. What a window onto a projected
|
|
105
|
+
* project shows for a link it cannot open: a name, never an id.
|
|
106
|
+
*/
|
|
107
|
+
labelOf(databaseId: number, workspaceId: number): Promise<string | null>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Key under `FeatureService.providers` for the workspace's outgoing mail: the
|
|
112
|
+
* transport the app's notification channels of kind `email` send through.
|
|
113
|
+
* Offered by the Mail module; absent, an email channel cannot be readied and
|
|
114
|
+
* the settings screen says so. Senders are the module's OPEN-tier, enabled
|
|
115
|
+
* accounts: a guarded mailbox needs a session unlock no background job has.
|
|
116
|
+
*/
|
|
117
|
+
export const MAIL_TRANSPORT_PROVIDER = 'mail.transport' as const;
|
|
118
|
+
|
|
119
|
+
/** A mailbox able to send without anyone unlocking anything. */
|
|
120
|
+
export interface MailSender {
|
|
121
|
+
id: number;
|
|
122
|
+
label: string;
|
|
123
|
+
address: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface MailTransportProvider {
|
|
127
|
+
/** The workspace's ready senders (open tier, enabled). */
|
|
128
|
+
listSenders(workspaceId: number): Promise<readonly MailSender[]>;
|
|
129
|
+
/** Is this account a ready sender of this workspace right now? */
|
|
130
|
+
isReady(accountId: number, workspaceId: number): Promise<boolean>;
|
|
131
|
+
/**
|
|
132
|
+
* Sends one plain-text message from this account. Resolves `true` when the
|
|
133
|
+
* provider accepted it; `false` (never a throw) when the account is not a
|
|
134
|
+
* ready sender or the send failed, the failure logged by the module.
|
|
135
|
+
*/
|
|
136
|
+
send(
|
|
137
|
+
accountId: number,
|
|
138
|
+
workspaceId: number,
|
|
139
|
+
message: { to: string; subject: string; text: string }
|
|
140
|
+
): Promise<boolean>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Key under `FeatureClient.providers` for the Mail pieces the app's settings
|
|
145
|
+
* shell composes: the ready senders an email channel picks from, and the
|
|
146
|
+
* feature's own account dialog (the "+" of the channel form). The contract
|
|
147
|
+
* types live in `@deveye/types/sdk/client`.
|
|
148
|
+
*/
|
|
149
|
+
export const MAIL_CLIENT_PROVIDER = 'mail.client' as const;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Key under `FeatureService.providers` for the Audience sites the app's
|
|
153
|
+
* Projects feature links to: same shape and same reason as
|
|
154
|
+
* `UPTIME_ITEMS_PROVIDER` (`project_audience_links` is Projects' table).
|
|
155
|
+
*/
|
|
156
|
+
export const AUDIENCE_ITEMS_PROVIDER = 'audience.items' as const;
|
|
157
|
+
|
|
158
|
+
export interface AudienceItemsProvider {
|
|
159
|
+
/** Does this site live in this workspace? Its home only, never a projection. */
|
|
160
|
+
exists(siteId: number, workspaceId: number): Promise<boolean>;
|
|
161
|
+
/**
|
|
162
|
+
* The item's display name under the OPEN cipher of `workspaceId`, its home;
|
|
163
|
+
* `null` when it is gone or unreadable. What a window onto a projected
|
|
164
|
+
* project shows for a link it cannot open: a name, never an id.
|
|
165
|
+
*/
|
|
166
|
+
labelOf(siteId: number, workspaceId: number): Promise<string | null>;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Key under `FeatureClient.providers` for the Audience pieces the app's
|
|
171
|
+
* Projects screens compose: the list of the workspace's sites, a linked site
|
|
172
|
+
* shown in full inside a project's tab, and the feature's own site dialog.
|
|
173
|
+
* The contract types live in `@deveye/types/sdk/client`.
|
|
174
|
+
*/
|
|
175
|
+
export const AUDIENCE_CLIENT_PROVIDER = 'audience.client' as const;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Key under `FeatureService.providers` for the Git repositories the app's
|
|
179
|
+
* Projects feature links to: same shape and same reason as
|
|
180
|
+
* `UPTIME_ITEMS_PROVIDER` (`project_repo_links` is Projects' table).
|
|
181
|
+
*/
|
|
182
|
+
export const GIT_ITEMS_PROVIDER = 'git.items' as const;
|
|
183
|
+
|
|
184
|
+
export interface GitItemsProvider {
|
|
185
|
+
/** Does this repository live in this workspace? Its home only, never a projection. */
|
|
186
|
+
exists(repoId: number, workspaceId: number): Promise<boolean>;
|
|
187
|
+
/**
|
|
188
|
+
* The item's display name under the OPEN cipher of `workspaceId`, its home;
|
|
189
|
+
* `null` when it is gone or unreadable. What a window onto a projected
|
|
190
|
+
* project shows for a link it cannot open: a name, never an id.
|
|
191
|
+
*/
|
|
192
|
+
labelOf(repoId: number, workspaceId: number): Promise<string | null>;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Key under `FeatureClient.providers` for the Git pieces the app's Projects
|
|
197
|
+
* screens compose: the list of the workspace's repositories, a linked
|
|
198
|
+
* repository shown in full inside a project's tab, and the feature's own
|
|
199
|
+
* repository dialog. The contract types live in `@deveye/types/sdk/client`.
|
|
200
|
+
*/
|
|
201
|
+
export const GIT_CLIENT_PROVIDER = 'git.client' as const;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Key under `FeatureService.providers` for the Deploy targets the app's
|
|
205
|
+
* Projects feature links to: same shape and same reason as
|
|
206
|
+
* `UPTIME_ITEMS_PROVIDER` (`project_deploy_links` is Projects' table).
|
|
207
|
+
*/
|
|
208
|
+
export const DEPLOY_ITEMS_PROVIDER = 'deploy.items' as const;
|
|
209
|
+
|
|
210
|
+
export interface DeployItemsProvider {
|
|
211
|
+
/** Does this target live in this workspace? Its home only, never a projection. */
|
|
212
|
+
exists(targetId: number, workspaceId: number): Promise<boolean>;
|
|
213
|
+
/**
|
|
214
|
+
* The item's display name under the OPEN cipher of `workspaceId`, its home;
|
|
215
|
+
* `null` when it is gone or unreadable. What a window onto a projected
|
|
216
|
+
* project shows for a link it cannot open: a name, never an id.
|
|
217
|
+
*/
|
|
218
|
+
labelOf(targetId: number, workspaceId: number): Promise<string | null>;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Key under `FeatureClient.providers` for the Deploy pieces the app's
|
|
223
|
+
* Projects screens compose: the list of the workspace's targets, a linked
|
|
224
|
+
* target shown in full inside a project's tab, and the feature's own target
|
|
225
|
+
* dialog. The contract types live in `@deveye/types/sdk/client`.
|
|
226
|
+
*/
|
|
227
|
+
export const DEPLOY_CLIENT_PROVIDER = 'deploy.client' as const;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Key under `FeatureClient.providers` for the Databases pieces the app's
|
|
231
|
+
* Projects screens compose: the list of the workspace's databases, a linked
|
|
232
|
+
* database shown in full inside a project's tab, and the feature's own
|
|
233
|
+
* database dialog (declaring a database from a project goes through the real
|
|
234
|
+
* form, never a reduced copy). The contract types live in
|
|
235
|
+
* `@deveye/types/sdk/client` (they are React components).
|
|
236
|
+
*/
|
|
237
|
+
export const DATABASE_CLIENT_PROVIDER = 'database.client' as const;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Key of what Projects knows about the items of OTHER features: the projects
|
|
241
|
+
* of the workspace that link them (a module's list shows how many projects use
|
|
242
|
+
* each item, its detail lists them by title), without reading Projects'
|
|
243
|
+
* tables. Keyed by the linked feature's id so every linkable feature reads the
|
|
244
|
+
* same contract.
|
|
245
|
+
*/
|
|
246
|
+
export const PROJECTS_USAGE_PROVIDER = 'projects.usage' as const;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* A project that links an item. Open tier only: a guarded project cannot link
|
|
250
|
+
* a workspace item (its link row is plain, the item lives at the open tier),
|
|
251
|
+
* so every title here is readable without a session.
|
|
252
|
+
*/
|
|
253
|
+
export interface ProjectUsage {
|
|
254
|
+
projectId: number;
|
|
255
|
+
title: string;
|
|
256
|
+
status: 'draft' | 'active' | 'paused' | 'done';
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface ProjectsUsageProvider {
|
|
260
|
+
/** The workspace's projects linking this item of this feature, in Projects' display order. */
|
|
261
|
+
usageOf(feature: string, itemId: number, workspaceId: number): Promise<readonly ProjectUsage[]>;
|
|
262
|
+
/** How many projects of the workspace link each item of this feature (absent = zero). */
|
|
263
|
+
countByItem(feature: string, workspaceId: number): Promise<ReadonlyMap<number, number>>;
|
|
264
|
+
/**
|
|
265
|
+
* Writes one line in a project's timeline (a deployment triggered from a
|
|
266
|
+
* project's tab). Open tier only: an event aimed at a guarded project is
|
|
267
|
+
* dropped silently. Rejects when the write fails; a lost timeline line
|
|
268
|
+
* never turns a deployment into an error.
|
|
269
|
+
*/
|
|
270
|
+
recordEvent(
|
|
271
|
+
projectId: number,
|
|
272
|
+
workspaceId: number,
|
|
273
|
+
event: { kind: string; label: string; actorUserId: number | null }
|
|
274
|
+
): Promise<void>;
|
|
275
|
+
/**
|
|
276
|
+
* Reports a version on the projects linking this item that asked to
|
|
277
|
+
* follow it (Projects' `versionSource`, `'github_release'` for a git
|
|
278
|
+
* repository): the field then belongs to the item, and the project's
|
|
279
|
+
* screen shows it read-only. All linked projects of the workspace, open
|
|
280
|
+
* tier only; the others are left untouched.
|
|
281
|
+
*/
|
|
282
|
+
applyVersion(
|
|
283
|
+
feature: string,
|
|
284
|
+
itemId: number,
|
|
285
|
+
workspaceId: number,
|
|
286
|
+
version: string
|
|
287
|
+
): Promise<void>;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Key under `FeatureService.providers` for the Uptime items the app's Projects
|
|
292
|
+
* feature links to. Projects stores only identifiers; before linking one it
|
|
293
|
+
* asks the module whether the service exists in the workspace, so a foreign
|
|
294
|
+
* id can neither be linked nor leak its existence.
|
|
295
|
+
*/
|
|
296
|
+
export const UPTIME_ITEMS_PROVIDER = 'uptime.items' as const;
|
|
297
|
+
|
|
298
|
+
export interface UptimeItemsProvider {
|
|
299
|
+
/** Does this service live in this workspace? Its home only, never a projection. */
|
|
300
|
+
exists(serviceId: number, workspaceId: number): Promise<boolean>;
|
|
301
|
+
/**
|
|
302
|
+
* The item's display name under the OPEN cipher of `workspaceId`, its home;
|
|
303
|
+
* `null` when it is gone or unreadable. What a window onto a projected
|
|
304
|
+
* project shows for a link it cannot open: a name, never an id.
|
|
305
|
+
*/
|
|
306
|
+
labelOf(serviceId: number, workspaceId: number): Promise<string | null>;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Key under `FeatureClient.providers` for the Uptime pieces the app's Projects
|
|
311
|
+
* screens compose: the availability strip and ratios of a linked service, and
|
|
312
|
+
* the feature's own service dialog (declaring a service from a project goes
|
|
313
|
+
* through the real form, never a reduced copy). The contract types live in
|
|
314
|
+
* `@deveye/types/sdk/client` (they are React components).
|
|
315
|
+
*/
|
|
316
|
+
export const UPTIME_CLIENT_PROVIDER = 'uptime.client' as const;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* The client twin of the Devices module (`DevicesClientProvider`,
|
|
320
|
+
* `sdk/client.ts`): the workspace's devices as a store, one device's panel
|
|
321
|
+
* and tile. The app's home and topbar compose them; without the module they
|
|
322
|
+
* render nothing device-related.
|
|
323
|
+
*/
|
|
324
|
+
export const DEVICES_CLIENT_PROVIDER = 'devices.client' as const;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Key under `FeatureService.providers` for what Sentinel contributes to the
|
|
328
|
+
* collection config the app pushes to an agent (`agent.config`): whether the
|
|
329
|
+
* security probes run, and at which cadence. Absent module: the app pushes the
|
|
330
|
+
* probes off.
|
|
331
|
+
*/
|
|
332
|
+
export const SENTINEL_AGENT_CONFIG_PROVIDER = 'sentinel.agentConfig' as const;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Cadence du manifeste de persistance quand rien n'est réglé, en minutes.
|
|
336
|
+
* Vit ici et non dans le domaine du module parce que l'app l'applique
|
|
337
|
+
* elle-même : sans module installé, ou sans ligne de config pour l'appareil,
|
|
338
|
+
* la config poussée à l'agent porte ce défaut (sondes éteintes).
|
|
339
|
+
*/
|
|
340
|
+
export const DEFAULT_SENTINEL_INTEGRITY_MINUTES = 360;
|
|
341
|
+
|
|
342
|
+
export interface SentinelAgentConfig {
|
|
343
|
+
enabled: boolean;
|
|
344
|
+
/** Cadence of the persistence manifest, in minutes. */
|
|
345
|
+
integrityMinutes: number;
|
|
346
|
+
/** Whether the agent reads the authentication journal. */
|
|
347
|
+
authEvents: boolean;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface SentinelAgentConfigProvider {
|
|
351
|
+
/** The device's contribution, or null when Sentinel knows nothing about it (probes off). */
|
|
352
|
+
configFor(deviceId: string): Promise<SentinelAgentConfig | null>;
|
|
353
|
+
}
|