@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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -0
  3. package/package.json +68 -0
  4. package/src/domain/audience.ts +549 -0
  5. package/src/domain/backup.ts +355 -0
  6. package/src/domain/credential.ts +55 -0
  7. package/src/domain/database.ts +467 -0
  8. package/src/domain/deploy.ts +231 -0
  9. package/src/domain/device.ts +172 -0
  10. package/src/domain/deviceFiles.ts +84 -0
  11. package/src/domain/deviceLogs.ts +82 -0
  12. package/src/domain/featureRegistry.ts +392 -0
  13. package/src/domain/finance.ts +477 -0
  14. package/src/domain/git.ts +419 -0
  15. package/src/domain/home.ts +314 -0
  16. package/src/domain/live.ts +272 -0
  17. package/src/domain/logs.ts +117 -0
  18. package/src/domain/mail.ts +394 -0
  19. package/src/domain/metrics.ts +127 -0
  20. package/src/domain/note.ts +202 -0
  21. package/src/domain/notifications.ts +268 -0
  22. package/src/domain/packages.ts +35 -0
  23. package/src/domain/password.ts +36 -0
  24. package/src/domain/presence.ts +21 -0
  25. package/src/domain/project.ts +168 -0
  26. package/src/domain/projectBoard.ts +130 -0
  27. package/src/domain/projectChat.ts +46 -0
  28. package/src/domain/projectHistory.ts +82 -0
  29. package/src/domain/projectLink.ts +87 -0
  30. package/src/domain/projectPlan.ts +68 -0
  31. package/src/domain/report.ts +492 -0
  32. package/src/domain/role.ts +8 -0
  33. package/src/domain/secrecy.ts +66 -0
  34. package/src/domain/sentinel.ts +623 -0
  35. package/src/domain/sharing.ts +186 -0
  36. package/src/domain/syncProtocol.ts +116 -0
  37. package/src/domain/twoFactor.ts +40 -0
  38. package/src/domain/uptime.ts +216 -0
  39. package/src/domain/user.ts +141 -0
  40. package/src/domain/workspace.ts +56 -0
  41. package/src/domain/workspaceRole.ts +251 -0
  42. package/src/features/admin.ts +112 -0
  43. package/src/features/audience.ts +275 -0
  44. package/src/features/backup.ts +230 -0
  45. package/src/features/database.ts +461 -0
  46. package/src/features/deploy.ts +245 -0
  47. package/src/features/device.ts +292 -0
  48. package/src/features/deviceFiles.ts +83 -0
  49. package/src/features/deviceLogs.ts +36 -0
  50. package/src/features/deviceTerminal.ts +57 -0
  51. package/src/features/finance.ts +360 -0
  52. package/src/features/git.ts +368 -0
  53. package/src/features/home.ts +32 -0
  54. package/src/features/live.ts +113 -0
  55. package/src/features/logs.ts +86 -0
  56. package/src/features/mail.ts +374 -0
  57. package/src/features/metrics.ts +185 -0
  58. package/src/features/note.ts +189 -0
  59. package/src/features/notify.ts +164 -0
  60. package/src/features/password.ts +67 -0
  61. package/src/features/project.ts +709 -0
  62. package/src/features/registry.ts +103 -0
  63. package/src/features/secrecy.ts +120 -0
  64. package/src/features/sentinel.ts +233 -0
  65. package/src/features/sharing.ts +79 -0
  66. package/src/features/twoFactor.ts +47 -0
  67. package/src/features/uptime.ts +186 -0
  68. package/src/features/user.ts +91 -0
  69. package/src/features/workspace.ts +200 -0
  70. package/src/http/auth.ts +94 -0
  71. package/src/http/device.ts +222 -0
  72. package/src/http/status.ts +45 -0
  73. package/src/index.ts +1700 -0
  74. package/src/protocol/agent.ts +1171 -0
  75. package/src/protocol/envelope.ts +46 -0
  76. package/src/protocol/error.ts +27 -0
  77. package/src/protocol/result.ts +17 -0
  78. package/src/protocol/version.ts +6 -0
  79. package/src/sdk/client-ambient.d.ts +238 -0
  80. package/src/sdk/client.ts +66 -0
  81. package/src/sdk/ids.ts +25 -0
  82. package/src/sdk/index.ts +11 -0
  83. package/src/sdk/manifest.ts +326 -0
  84. package/src/sdk/providers.ts +48 -0
  85. package/src/sdk/server.ts +378 -0
  86. package/src/sdk/testing.ts +179 -0
  87. 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;