@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,189 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
NOTE_FOLDER_MAX_LENGTH,
|
|
4
|
+
NOTE_MAX_BLOCKS,
|
|
5
|
+
NOTE_TITLE_MAX_LENGTH,
|
|
6
|
+
noteBlockSchema,
|
|
7
|
+
noteFolderSchema,
|
|
8
|
+
noteSchema,
|
|
9
|
+
noteSummarySchema
|
|
10
|
+
} from '../domain/note';
|
|
11
|
+
|
|
12
|
+
const folderId = z.number().int().positive();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Commandes des notes et de leurs dossiers.
|
|
16
|
+
*
|
|
17
|
+
* L'espace visé n'apparaît dans aucune entrée : il voyage sur l'enveloppe WS
|
|
18
|
+
* (voir `protocol/envelope`) et le dispatcheur le résout avant le handler.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** The editable shape of a note — everything the client may set. */
|
|
22
|
+
const noteDraftSchema = z.object({
|
|
23
|
+
title: z.string().max(NOTE_TITLE_MAX_LENGTH),
|
|
24
|
+
folderId: folderId.nullable(),
|
|
25
|
+
blocks: z.array(noteBlockSchema).max(NOTE_MAX_BLOCKS),
|
|
26
|
+
/** Encrypt the body with the password-protected key rather than the open one. */
|
|
27
|
+
private: z.boolean()
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* List the notes of the active workspace. Never gated: regular notes are decrypted with the
|
|
32
|
+
* open key, and private notes come back **masked** (metadata only,
|
|
33
|
+
* `masked: true`) while the session is locked. Unlocking and re-listing reveals
|
|
34
|
+
* them — no per-command password is involved.
|
|
35
|
+
*
|
|
36
|
+
* `archived` swaps the two disjoint sets: the active notes (default) or the
|
|
37
|
+
* archive, most recently archived first.
|
|
38
|
+
*/
|
|
39
|
+
export const noteList = {
|
|
40
|
+
command: 'note.list' as const,
|
|
41
|
+
input: z.object({ archived: z.boolean().optional() }),
|
|
42
|
+
output: z.object({ notes: z.array(noteSummarySchema) })
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Count the **active** notes of the active workspace. Pure clear metadata: every
|
|
47
|
+
* row is counted the same way — private notes included, no special case —
|
|
48
|
+
* without decrypting anything, so the dashboard widget always shows a number
|
|
49
|
+
* even when the session is locked. Archived notes are excluded.
|
|
50
|
+
*/
|
|
51
|
+
export const noteCount = {
|
|
52
|
+
command: 'note.count' as const,
|
|
53
|
+
input: z.object({}),
|
|
54
|
+
output: z.object({ count: z.number().int().nonnegative() })
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Fetch one note in full. A private note requires the session to be unlocked;
|
|
59
|
+
* otherwise the server replies `locked` and the client opens the usual unlock
|
|
60
|
+
* prompt before retrying.
|
|
61
|
+
*/
|
|
62
|
+
export const noteGet = {
|
|
63
|
+
command: 'note.get' as const,
|
|
64
|
+
input: z.object({ noteId: z.number().int().positive() }),
|
|
65
|
+
output: z.object({ note: noteSchema })
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const noteAdd = {
|
|
69
|
+
command: 'note.add' as const,
|
|
70
|
+
input: z.object({ note: noteDraftSchema }),
|
|
71
|
+
output: z.object({ note: noteSchema })
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Edit a note. Touching a note that is (or becomes) private requires the session
|
|
76
|
+
* to be unlocked; the draft's `private` flag decides which key the new body is
|
|
77
|
+
* written with, so flipping it re-encrypts the note into the other tier.
|
|
78
|
+
*/
|
|
79
|
+
export const noteEdit = {
|
|
80
|
+
command: 'note.edit' as const,
|
|
81
|
+
input: z.object({
|
|
82
|
+
noteId: z.number().int().positive(),
|
|
83
|
+
note: noteDraftSchema
|
|
84
|
+
}),
|
|
85
|
+
output: z.object({ note: noteSchema })
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Archive a note: it leaves the main list but nothing is destroyed. This is what
|
|
90
|
+
* "supprimer" does in the UI — {@link noteDelete} is the deliberate second step.
|
|
91
|
+
*/
|
|
92
|
+
export const noteArchive = {
|
|
93
|
+
command: 'note.archive' as const,
|
|
94
|
+
input: z.object({ noteId: z.number().int().positive() }),
|
|
95
|
+
output: z.object({ noteId: z.number().int().positive() })
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** Bring an archived note back into the active list. */
|
|
99
|
+
export const noteRestore = {
|
|
100
|
+
command: 'note.restore' as const,
|
|
101
|
+
input: z.object({ noteId: z.number().int().positive() }),
|
|
102
|
+
output: z.object({ noteId: z.number().int().positive() })
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Destroy a note for good. Only ever accepted on an **archived** note (`conflict`
|
|
107
|
+
* otherwise), so nothing can be lost in one click. Like archiving, it requires
|
|
108
|
+
* the session to be unlocked when the note is private.
|
|
109
|
+
*/
|
|
110
|
+
export const noteDelete = {
|
|
111
|
+
command: 'note.delete' as const,
|
|
112
|
+
input: z.object({ noteId: z.number().int().positive() }),
|
|
113
|
+
output: z.object({ noteId: z.number().int().positive() })
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Lay out one folder: `noteIds` is its **complete** content in its final order
|
|
118
|
+
* (lower index first), and every listed note is filed into `folderId` on the way.
|
|
119
|
+
* One command covers both reordering inside a folder and moving a note across
|
|
120
|
+
* folders — the destination's new order is all the server needs.
|
|
121
|
+
*
|
|
122
|
+
* Notes carry no automatic ordering: this, plus appending new notes at the end,
|
|
123
|
+
* is the only thing that positions them. Never touches the encrypted body, so it
|
|
124
|
+
* works on masked private notes too.
|
|
125
|
+
*/
|
|
126
|
+
export const noteReorder = {
|
|
127
|
+
command: 'note.reorder' as const,
|
|
128
|
+
input: z.object({
|
|
129
|
+
folderId: folderId.nullable(),
|
|
130
|
+
noteIds: z.array(z.number().int().positive()).min(1)
|
|
131
|
+
}),
|
|
132
|
+
output: z.object({
|
|
133
|
+
folderId: folderId.nullable(),
|
|
134
|
+
noteIds: z.array(z.number().int().positive())
|
|
135
|
+
})
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/** List the active workspace's folders (names decrypted server-side). */
|
|
139
|
+
export const folderList = {
|
|
140
|
+
command: 'folder.list' as const,
|
|
141
|
+
input: z.object({}),
|
|
142
|
+
output: z.object({ folders: z.array(noteFolderSchema) })
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export const folderAdd = {
|
|
146
|
+
command: 'folder.add' as const,
|
|
147
|
+
input: z.object({ name: z.string().min(1).max(NOTE_FOLDER_MAX_LENGTH) }),
|
|
148
|
+
output: z.object({ folder: noteFolderSchema })
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const folderRename = {
|
|
152
|
+
command: 'folder.rename' as const,
|
|
153
|
+
input: z.object({ folderId, name: z.string().min(1).max(NOTE_FOLDER_MAX_LENGTH) }),
|
|
154
|
+
output: z.object({ folder: noteFolderSchema })
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Reorder all of the active workspace's folders; `folderIds` is the new
|
|
159
|
+
* full order (lower index = listed first). Used by the move up/down controls.
|
|
160
|
+
*/
|
|
161
|
+
export const folderReorder = {
|
|
162
|
+
command: 'folder.reorder' as const,
|
|
163
|
+
input: z.object({ folderIds: z.array(folderId).min(1) }),
|
|
164
|
+
output: z.object({ folders: z.array(noteFolderSchema) })
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/** Delete a folder; its notes are un-filed (folderId → null), not destroyed. */
|
|
168
|
+
export const folderDelete = {
|
|
169
|
+
command: 'folder.delete' as const,
|
|
170
|
+
input: z.object({ folderId }),
|
|
171
|
+
output: z.object({ folderId })
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const noteCommands = [
|
|
175
|
+
noteList,
|
|
176
|
+
noteCount,
|
|
177
|
+
noteGet,
|
|
178
|
+
noteAdd,
|
|
179
|
+
noteEdit,
|
|
180
|
+
noteArchive,
|
|
181
|
+
noteRestore,
|
|
182
|
+
noteDelete,
|
|
183
|
+
noteReorder,
|
|
184
|
+
folderList,
|
|
185
|
+
folderAdd,
|
|
186
|
+
folderRename,
|
|
187
|
+
folderReorder,
|
|
188
|
+
folderDelete
|
|
189
|
+
] as const;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
notificationChannelInputSchema,
|
|
5
|
+
notificationChannelSchema,
|
|
6
|
+
notificationChannelUsageSchema,
|
|
7
|
+
notificationFeatureSchema,
|
|
8
|
+
notificationRouteInputSchema,
|
|
9
|
+
notificationRouteSchema,
|
|
10
|
+
notificationRouteTargetSchema,
|
|
11
|
+
notificationTestSchema
|
|
12
|
+
} from '../domain/notifications';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Les canaux d'alerte de l'espace, et les routes qui pointent vers eux.
|
|
16
|
+
*
|
|
17
|
+
* ## Pourquoi un module à part, et pas trois commandes par émetteur
|
|
18
|
+
*
|
|
19
|
+
* Il y en avait quinze — `getSettings`, `setSettings`, `testNotification`, pour
|
|
20
|
+
* chacun des cinq émetteurs — strictement identiques à leur préfixe près. Le
|
|
21
|
+
* dialogue client les reconstituait déjà par concaténation
|
|
22
|
+
* (`` `${feature}.getSettings` ``), ce qui disait tout : la fonctionnalité
|
|
23
|
+
* n'était pas dans la commande, elle était dans un **argument**. Elle l'est
|
|
24
|
+
* désormais pour de bon.
|
|
25
|
+
*
|
|
26
|
+
* Conséquence directe : brancher un sixième émetteur ne coûte plus trois
|
|
27
|
+
* commandes, trois entrées de registre et trois handlers, mais une valeur de
|
|
28
|
+
* plus dans `notificationFeatureSchema`.
|
|
29
|
+
*
|
|
30
|
+
* ## Deux étages d'autorisation, et ils ne sont pas les mêmes
|
|
31
|
+
*
|
|
32
|
+
* Gérer les **canaux** d'une fonctionnalité relève du champ `channels` de son
|
|
33
|
+
* grant de rôle (migration 093) : un canal appartient à une fonctionnalité
|
|
34
|
+
* (091), et son adresse ne se livre qu'à qui gère les canaux de celle-ci. Les
|
|
35
|
+
* **routes**, elles, relèvent de la fonctionnalité visée (`{ feature, level:
|
|
36
|
+
* 'write' }`) : décider où Uptime écrit fait partie du réglage d'Uptime, et n'a
|
|
37
|
+
* pas à ouvrir la gestion des destinations. C'est la séparation qui permet de
|
|
38
|
+
* confier le routage d'une fonctionnalité sans confier l'adresse de
|
|
39
|
+
* l'astreinte.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
const channelId = z.number().int().positive();
|
|
43
|
+
|
|
44
|
+
/** Les canaux d'une fonctionnalité, ordonnés, avec leur nombre d'usages. */
|
|
45
|
+
export const notifyChannelList = {
|
|
46
|
+
command: 'notify.channelList' as const,
|
|
47
|
+
input: z.object({ feature: notificationFeatureSchema }),
|
|
48
|
+
output: z.object({ channels: z.array(notificationChannelSchema) })
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const notifyChannelAdd = {
|
|
52
|
+
command: 'notify.channelAdd' as const,
|
|
53
|
+
/** `feature` : la fonctionnalité propriétaire, immuable ensuite. */
|
|
54
|
+
input: notificationChannelInputSchema.extend({ feature: notificationFeatureSchema }),
|
|
55
|
+
output: z.object({ channel: notificationChannelSchema })
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const notifyChannelUpdate = {
|
|
59
|
+
command: 'notify.channelUpdate' as const,
|
|
60
|
+
input: notificationChannelInputSchema.extend({ id: channelId, enabled: z.boolean() }),
|
|
61
|
+
output: z.object({ channel: notificationChannelSchema })
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Ce qu'une suppression emporterait, **sans rien supprimer**.
|
|
66
|
+
*
|
|
67
|
+
* Lue par la confirmation pour nommer les routes qui vont cesser de prévenir.
|
|
68
|
+
* Séparée de la suppression elle-même parce qu'un écran qui demande « êtes-vous
|
|
69
|
+
* sûr ? » sans dire de quoi ne fait pas confirmer, il fait cliquer.
|
|
70
|
+
*/
|
|
71
|
+
export const notifyChannelUsage = {
|
|
72
|
+
command: 'notify.channelUsage' as const,
|
|
73
|
+
input: z.object({ id: channelId }),
|
|
74
|
+
output: notificationChannelUsageSchema
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const notifyChannelDelete = {
|
|
78
|
+
command: 'notify.channelDelete' as const,
|
|
79
|
+
input: z.object({ id: channelId }),
|
|
80
|
+
output: z.object({ ok: z.literal(true) })
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const notifyChannelReorder = {
|
|
84
|
+
command: 'notify.channelReorder' as const,
|
|
85
|
+
input: z.object({ ids: z.array(channelId).max(64) }),
|
|
86
|
+
output: z.object({ ok: z.literal(true) })
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Un envoi d'essai **sur un seul canal**, tel qu'il est enregistré.
|
|
91
|
+
*
|
|
92
|
+
* L'ancien dialogue devait enregistrer avant de tester, faute de quoi l'essai
|
|
93
|
+
* partait sur les réglages précédents. Un canal étant une entité à part entière,
|
|
94
|
+
* l'essai vise directement son identifiant : plus d'enregistrement forcé, et
|
|
95
|
+
* plus de doute sur ce qui vient d'être éprouvé.
|
|
96
|
+
*/
|
|
97
|
+
export const notifyChannelTest = {
|
|
98
|
+
command: 'notify.channelTest' as const,
|
|
99
|
+
input: z.object({ id: channelId }),
|
|
100
|
+
output: notificationTestSchema
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/** Où écrit une fonctionnalité, ou un de ses éléments. */
|
|
104
|
+
export const notifyRouteGet = {
|
|
105
|
+
command: 'notify.routeGet' as const,
|
|
106
|
+
input: notificationRouteTargetSchema,
|
|
107
|
+
output: z.object({
|
|
108
|
+
route: notificationRouteSchema,
|
|
109
|
+
/**
|
|
110
|
+
* Les canaux de la route qui **n'appartiennent pas à cet espace**.
|
|
111
|
+
*
|
|
112
|
+
* Le cas d'un élément projeté depuis ailleurs : ses destinations vivent
|
|
113
|
+
* dans son espace d'origine. Sans cette liste, l'écran afficherait
|
|
114
|
+
* « aucun canal » sur un élément qui prévient bel et bien — le mensonge
|
|
115
|
+
* exact que la projection devait éviter.
|
|
116
|
+
*
|
|
117
|
+
* Rendus **masqués** : leur genre (« Salon Discord d'un autre espace »),
|
|
118
|
+
* jamais leur identité ni leur adresse.
|
|
119
|
+
*/
|
|
120
|
+
foreign: z.array(notificationChannelSchema),
|
|
121
|
+
/**
|
|
122
|
+
* Cette route se règle-t-elle **d'ici** ?
|
|
123
|
+
*
|
|
124
|
+
* Faux sur un élément projeté depuis un autre espace : ses canaux
|
|
125
|
+
* appartiennent à cet espace-là, et l'ordonnanceur qui le sonde y
|
|
126
|
+
* tourne. Laisser l'écran proposer le réglage produirait un geste que
|
|
127
|
+
* le serveur refuse — un écran qui ment, pas une garde.
|
|
128
|
+
*/
|
|
129
|
+
managedHere: z.boolean(),
|
|
130
|
+
/**
|
|
131
|
+
* L'espace **où cette route se règle** : le domicile de l'élément.
|
|
132
|
+
* Égal à l'espace de l'enveloppe quand `managedHere` est vrai. C'est ce
|
|
133
|
+
* qui permet à l'écran, sur un élément projeté, de proposer d'aller
|
|
134
|
+
* régler chez lui plutôt que d'expliquer un refus.
|
|
135
|
+
*/
|
|
136
|
+
homeWorkspaceId: z.number().int().positive()
|
|
137
|
+
})
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const notifyRouteSet = {
|
|
141
|
+
command: 'notify.routeSet' as const,
|
|
142
|
+
input: notificationRouteInputSchema,
|
|
143
|
+
output: z.object({ route: notificationRouteSchema })
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/** Un essai sur la route entière, héritage compris — ce que verrait une vraie alerte. */
|
|
147
|
+
export const notifyRouteTest = {
|
|
148
|
+
command: 'notify.routeTest' as const,
|
|
149
|
+
input: notificationRouteTargetSchema,
|
|
150
|
+
output: notificationTestSchema
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export const notifyCommands = [
|
|
154
|
+
notifyChannelList,
|
|
155
|
+
notifyChannelAdd,
|
|
156
|
+
notifyChannelUpdate,
|
|
157
|
+
notifyChannelUsage,
|
|
158
|
+
notifyChannelDelete,
|
|
159
|
+
notifyChannelReorder,
|
|
160
|
+
notifyChannelTest,
|
|
161
|
+
notifyRouteGet,
|
|
162
|
+
notifyRouteSet,
|
|
163
|
+
notifyRouteTest
|
|
164
|
+
] as const;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { passwordEntryMaskedSchema, passwordEntrySchema } from '../domain/password';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Commandes du coffre de mots de passe.
|
|
6
|
+
*
|
|
7
|
+
* L'espace visé n'apparaît dans aucune entrée : il voyage sur l'enveloppe WS
|
|
8
|
+
* (voir `protocol/envelope`) et le dispatcheur le résout avant le handler.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const passwordList = {
|
|
12
|
+
command: 'password.list' as const,
|
|
13
|
+
input: z.object({}),
|
|
14
|
+
output: z.object({ entries: z.array(passwordEntryMaskedSchema) })
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Compte les entrées de l'espace. Métadonnées claires uniquement (un nombre de
|
|
19
|
+
* lignes, aucun déchiffrement) : contrairement à `password.list`, la commande
|
|
20
|
+
* n'exige jamais que le chiffrement par mot de passe soit déverrouillé, donc le
|
|
21
|
+
* widget d'accueil affiche toujours un nombre, même session verrouillée.
|
|
22
|
+
*/
|
|
23
|
+
export const passwordCount = {
|
|
24
|
+
command: 'password.count' as const,
|
|
25
|
+
input: z.object({}),
|
|
26
|
+
output: z.object({ count: z.number().int().nonnegative() })
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const passwordGet = {
|
|
30
|
+
command: 'password.get' as const,
|
|
31
|
+
input: z.object({ passwordId: z.number().int().positive() }),
|
|
32
|
+
output: z.object({ entry: passwordEntrySchema })
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const passwordAdd = {
|
|
36
|
+
command: 'password.add' as const,
|
|
37
|
+
input: z.object({ entry: passwordEntrySchema.omit({ id: true }) }),
|
|
38
|
+
output: z.object({ entry: passwordEntrySchema })
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const passwordEdit = {
|
|
42
|
+
command: 'password.edit' as const,
|
|
43
|
+
input: z.object({ entry: passwordEntrySchema }),
|
|
44
|
+
output: z.object({ entry: passwordEntrySchema })
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const passwordDelete = {
|
|
48
|
+
command: 'password.delete' as const,
|
|
49
|
+
input: z.object({ passwordId: z.number().int().positive() }),
|
|
50
|
+
output: z.object({ passwordId: z.number().int().positive() })
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const passwordUnlock = {
|
|
54
|
+
command: 'password.unlock' as const,
|
|
55
|
+
input: z.object({ password: z.string().min(1) }),
|
|
56
|
+
output: z.object({ unlocked: z.literal(true) })
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const passwordCommands = [
|
|
60
|
+
passwordList,
|
|
61
|
+
passwordCount,
|
|
62
|
+
passwordGet,
|
|
63
|
+
passwordAdd,
|
|
64
|
+
passwordEdit,
|
|
65
|
+
passwordDelete,
|
|
66
|
+
passwordUnlock
|
|
67
|
+
] as const;
|