@highstate/library 0.9.15 → 0.9.18

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 (46) hide show
  1. package/dist/highstate.library.msgpack +0 -0
  2. package/dist/highstate.manifest.json +5 -0
  3. package/dist/index.js +1716 -1166
  4. package/dist/index.js.map +1 -1
  5. package/package.json +8 -6
  6. package/src/abbreviations.ts +35 -0
  7. package/src/apps/code-server.ts +5 -5
  8. package/src/apps/deployment.ts +20 -20
  9. package/src/apps/dns.ts +12 -14
  10. package/src/apps/gitea.ts +2 -2
  11. package/src/apps/grocy.ts +2 -2
  12. package/src/apps/hubble.ts +2 -2
  13. package/src/apps/kubernetes-dashboard.ts +2 -2
  14. package/src/apps/mariadb.ts +10 -10
  15. package/src/apps/maybe.ts +5 -5
  16. package/src/apps/mongodb.ts +10 -10
  17. package/src/apps/network.ts +6 -6
  18. package/src/apps/postgresql.ts +10 -10
  19. package/src/apps/shared.ts +18 -19
  20. package/src/apps/syncthing.ts +6 -6
  21. package/src/apps/traefik.ts +4 -4
  22. package/src/apps/vaultwarden.ts +4 -4
  23. package/src/apps/zitadel.ts +2 -2
  24. package/src/cloudflare.ts +4 -4
  25. package/src/common.ts +25 -78
  26. package/src/distributions/index.ts +1 -0
  27. package/src/distributions/ubuntu.ts +32 -0
  28. package/src/dns.ts +10 -18
  29. package/src/files.ts +135 -0
  30. package/src/git.ts +58 -0
  31. package/src/index.ts +5 -0
  32. package/src/k3s.ts +9 -17
  33. package/src/k8s.ts +130 -146
  34. package/src/mullvad.ts +5 -9
  35. package/src/network.ts +69 -44
  36. package/src/nixos.ts +51 -86
  37. package/src/obfuscators/phantun.ts +4 -4
  38. package/src/obfuscators/shared.ts +23 -43
  39. package/src/proxmox.ts +301 -60
  40. package/src/restic.ts +17 -19
  41. package/src/sops.ts +7 -6
  42. package/src/ssh.ts +21 -19
  43. package/src/talos.ts +15 -27
  44. package/src/timeweb.ts +13 -13
  45. package/src/utils.ts +3 -3
  46. package/src/wireguard.ts +90 -127
package/src/proxmox.ts CHANGED
@@ -1,22 +1,23 @@
1
- import { defineEntity, defineUnit, Type } from "@highstate/contract"
2
- import { serverOutputs } from "./common"
3
- import { keyPairEntity } from "./ssh"
1
+ import { defineEntity, defineUnit, z } from "@highstate/contract"
2
+ import { checksumSchema, fileEntity, serverOutputs } from "./common"
3
+ import { credentialsSchema, keyPairEntity } from "./ssh"
4
+ import { l7EndpointEntity } from "./network"
4
5
 
5
6
  export const clusterEntity = defineEntity({
6
7
  type: "proxmox.cluster",
7
8
 
8
- schema: Type.Object({
9
- endpoint: Type.String(),
10
- insecure: Type.Optional(Type.Boolean()),
11
- username: Type.Optional(Type.String()),
9
+ schema: z.object({
10
+ endpoint: l7EndpointEntity.schema,
11
+ insecure: z.boolean().optional(),
12
+ username: z.string().optional(),
12
13
 
13
- defaultNodeName: Type.String(),
14
- defaultDatastoreId: Type.String(),
14
+ defaultNodeName: z.string(),
15
+ defaultDatastoreId: z.string(),
15
16
 
16
- password: Type.Optional(Type.String()),
17
- apiToken: Type.Optional(Type.String()),
17
+ password: z.string().optional(),
18
+ apiToken: z.string().optional(),
18
19
 
19
- sshKeyPair: Type.Optional(keyPairEntity.schema),
20
+ ssh: credentialsSchema.optional(),
20
21
  }),
21
22
 
22
23
  meta: {
@@ -27,8 +28,8 @@ export const clusterEntity = defineEntity({
27
28
  export const imageEntity = defineEntity({
28
29
  type: "proxmox.image",
29
30
 
30
- schema: Type.Object({
31
- id: Type.String(),
31
+ schema: z.object({
32
+ id: z.string(),
32
33
  }),
33
34
 
34
35
  meta: {
@@ -40,20 +41,85 @@ export const connection = defineUnit({
40
41
  type: "proxmox.connection",
41
42
 
42
43
  args: {
43
- endpoint: Type.String(),
44
- insecure: Type.Optional(Type.Boolean()),
45
- username: Type.Optional(Type.String()),
46
-
47
- defaultNodeName: Type.Optional(Type.String()),
48
- defaultDatastoreId: Type.Optional(Type.String()),
44
+ /**
45
+ * The endpoint of the Proxmox API.
46
+ */
47
+ endpoint: z.string(),
48
+
49
+ /**
50
+ * Whether to allow insecure connections to the Proxmox API.
51
+ */
52
+ insecure: z.boolean().optional(),
53
+
54
+ /**
55
+ * The username to use for the Proxmox API.
56
+ *
57
+ * Only required for password token authentication.
58
+ */
59
+ username: z.string().optional(),
60
+
61
+ /**
62
+ * The name of the default Proxmox node to use for operations.
63
+ *
64
+ * If not specified, the first node in the cluster will be used.
65
+ */
66
+ defaultNodeName: z.string().optional(),
67
+
68
+ /**
69
+ * The ID of the default Proxmox datastore to use for operations.
70
+ *
71
+ * If not specified, the first datastore in the cluster will be used.
72
+ */
73
+ defaultDatastoreId: z.string().optional(),
74
+
75
+ /**
76
+ * The username to use for SSH connections to the Proxmox nodes.
77
+ *
78
+ * By default, this is set to "root".
79
+ */
80
+ sshUser: z.string().default("root"),
81
+
82
+ /**
83
+ * The port to use for SSH connections to the Proxmox nodes.
84
+ *
85
+ * By default, this is set to 22.
86
+ */
87
+ sshPort: z.number().default(22),
49
88
  },
50
89
 
51
90
  secrets: {
52
- password: Type.Optional(Type.String()),
53
- apiToken: Type.Optional(Type.String()),
91
+ /**
92
+ * The password to use for the Proxmox API.
93
+ *
94
+ * Requires `username` to be set.
95
+ */
96
+ password: {
97
+ schema: z.string().optional(),
98
+ meta: {
99
+ title: "Proxmox Password",
100
+ },
101
+ },
102
+
103
+ /**
104
+ * The Proxmox API token to use for authentication.
105
+ */
106
+ apiToken: {
107
+ schema: z.string().optional(),
108
+ meta: {
109
+ title: "Proxmox API Token",
110
+ },
111
+ },
112
+
113
+ /**
114
+ * The SSH password to use for connecting to the Proxmox nodes.
115
+ */
116
+ sshPassword: z.string().optional(),
54
117
  },
55
118
 
56
119
  inputs: {
120
+ /**
121
+ * The key pair to use for SSH connections to the Proxmox nodes.
122
+ */
57
123
  sshKeyPair: {
58
124
  entity: keyPairEntity,
59
125
  required: false,
@@ -65,11 +131,11 @@ export const connection = defineUnit({
65
131
  },
66
132
 
67
133
  meta: {
68
- displayName: "Proxmox Connection",
134
+ title: "Proxmox Connection",
69
135
  description: "The connection to an existing Proxmox cluster.",
70
136
  category: "Proxmox",
71
- primaryIcon: "simple-icons:proxmox",
72
- primaryIconColor: "#e56901",
137
+ icon: "simple-icons:proxmox",
138
+ iconColor: "#e56901",
73
139
  },
74
140
 
75
141
  source: {
@@ -82,14 +148,54 @@ export const image = defineUnit({
82
148
  type: "proxmox.image",
83
149
 
84
150
  args: {
85
- url: Type.String(),
86
- nodeName: Type.Optional(Type.String()),
87
- sha256: Type.Optional(Type.String()),
88
- datastoreId: Type.Optional(Type.String()),
151
+ /**
152
+ * The name of the image to upload.
153
+ *
154
+ * If not specified, the default name is `<unitName>-<sha256>.<extension>`
155
+ * or `<unitName>.<extension>` if `sha256` is not provided.
156
+ */
157
+ fileName: z.string().optional(),
158
+
159
+ /**
160
+ * The URL of the image to upload.
161
+ */
162
+ url: z.string().optional(),
163
+
164
+ /**
165
+ * The checksum of the image file to verify.
166
+ */
167
+ checksum: checksumSchema.optional(),
168
+
169
+ /**
170
+ * The name of the Proxmox node to upload the image to.
171
+ *
172
+ * If not specified, the default node name from the cluster will be used.
173
+ */
174
+ nodeName: z.string().optional(),
175
+
176
+ /**
177
+ * The ID of the Proxmox datastore to upload the image to.
178
+ *
179
+ * If not specified, the default datastore ID from the cluster will be used.
180
+ */
181
+ datastoreId: z.string().optional(),
89
182
  },
90
183
 
91
184
  inputs: {
185
+ /**
186
+ * The Proxmox cluster to upload the image to.
187
+ */
92
188
  proxmoxCluster: clusterEntity,
189
+
190
+ /**
191
+ * The file to upload as an image.
192
+ *
193
+ * If `url` is not specified, this file will be used.
194
+ */
195
+ file: {
196
+ entity: fileEntity,
197
+ required: false,
198
+ },
93
199
  },
94
200
 
95
201
  outputs: {
@@ -97,11 +203,11 @@ export const image = defineUnit({
97
203
  },
98
204
 
99
205
  meta: {
100
- displayName: "Proxmox Image",
206
+ title: "Proxmox Image",
101
207
  description: "The image to upload to a Proxmox cluster.",
102
208
  category: "Proxmox",
103
- primaryIcon: "simple-icons:proxmox",
104
- primaryIconColor: "#e56901",
209
+ icon: "simple-icons:proxmox",
210
+ iconColor: "#e56901",
105
211
  secondaryIcon: "mage:compact-disk-fill",
106
212
  },
107
213
 
@@ -115,7 +221,7 @@ export const existingImage = defineUnit({
115
221
  type: "proxmox.existing-image",
116
222
 
117
223
  args: {
118
- id: Type.String(),
224
+ id: z.string(),
119
225
  },
120
226
 
121
227
  inputs: {
@@ -127,11 +233,11 @@ export const existingImage = defineUnit({
127
233
  },
128
234
 
129
235
  meta: {
130
- displayName: "Proxmox Existing Image",
236
+ title: "Proxmox Existing Image",
131
237
  description: "The existing image on a Proxmox cluster.",
132
238
  category: "Proxmox",
133
- primaryIcon: "simple-icons:proxmox",
134
- primaryIconColor: "#e56901",
239
+ icon: "simple-icons:proxmox",
240
+ iconColor: "#e56901",
135
241
  secondaryIcon: "mage:compact-disk-fill",
136
242
  },
137
243
 
@@ -145,30 +251,155 @@ export const virtualMachine = defineUnit({
145
251
  type: "proxmox.virtual-machine",
146
252
 
147
253
  args: {
148
- nodeName: Type.Optional(Type.String()),
149
-
150
- cpuType: Type.Default(Type.String(), "host"),
151
- cores: Type.Default(Type.Number(), 1),
152
- sockets: Type.Default(Type.Number(), 1),
153
- memory: Type.Default(Type.Number(), 512),
154
-
155
- ipv4: Type.Optional(Type.String()),
156
- ipv4Gateway: Type.Optional(Type.String()),
157
- dns: Type.Optional(Type.Array(Type.String())),
158
-
159
- datastoreId: Type.Optional(Type.String()),
160
- diskSize: Type.Default(Type.Number(), 8),
161
- bridge: Type.Default(Type.String(), "vmbr0"),
162
-
163
- sshPort: Type.Default(Type.Number(), 22),
164
- sshUser: Type.Default(Type.String(), "root"),
165
-
166
- waitForAgent: Type.Default(Type.Boolean(), true),
167
- vendorData: Type.Optional(Type.String({ language: "yaml" })),
254
+ /**
255
+ * The name of the node to create the virtual machine on.
256
+ *
257
+ * If not specified, the default node name from the cluster will be used.
258
+ */
259
+ nodeName: z.string().optional(),
260
+
261
+ /**
262
+ * The ID of the Proxmox datastore to create the virtual machine on.
263
+ *
264
+ * If not specified, the default datastore ID from the cluster will be used.
265
+ */
266
+ datastoreId: z.string().optional(),
267
+
268
+ /**
269
+ * The type of CPU to use for the virtual machine.
270
+ *
271
+ * By default, this is set to "host" which offers the best performance.
272
+ */
273
+ cpuType: z.string().default("host"),
274
+
275
+ /**
276
+ * The resources to allocate to the virtual machine.
277
+ */
278
+ resources: z
279
+ .object({
280
+ /**
281
+ * The number of CPU cores to allocate to the virtual machine.
282
+ *
283
+ * By default, this is set to 1.
284
+ */
285
+ cores: z.number(),
286
+
287
+ /**
288
+ * The number of CPU sockets to allocate to the virtual machine.
289
+ *
290
+ * By default, this is set to 1.
291
+ */
292
+ sockets: z.number(),
293
+
294
+ /**
295
+ * The amount of dedicated memory to allocate to the virtual machine, in MB.
296
+ *
297
+ * By default, this is set to 512 MB.
298
+ */
299
+ memory: z.number(),
300
+
301
+ /**
302
+ * The size of the disk to create for the virtual machine, in GB.
303
+ *
304
+ * By default, this is set to 8 GB.
305
+ */
306
+ diskSize: z.number(),
307
+ })
308
+ .default({
309
+ cores: 1,
310
+ sockets: 1,
311
+ memory: 512,
312
+ diskSize: 8,
313
+ }),
314
+
315
+ /**
316
+ * The IPv4 address configuration for the virtual machine.
317
+ */
318
+ ipv4: z
319
+ .discriminatedUnion("type", [
320
+ z.object({
321
+ type: z.literal("dhcp"),
322
+ }),
323
+ z.object({
324
+ type: z.literal("static"),
325
+
326
+ /**
327
+ * The IPv4 address to assign to the virtual machine.
328
+ */
329
+ address: z.string(),
330
+
331
+ /**
332
+ * The CIDR prefix for the IPv4 address.
333
+ *
334
+ * By default, this is set to 24.
335
+ */
336
+ prefix: z.number().default(24),
337
+
338
+ /**
339
+ * The IPv4 gateway for the virtual machine.
340
+ *
341
+ * If not specified, will be set to the first address in the subnet.
342
+ */
343
+ gateway: z.string().optional(),
344
+ }),
345
+ ])
346
+ .default({ type: "dhcp" }),
347
+
348
+ /**
349
+ * The network configuration for the virtual machine.
350
+ */
351
+ network: z
352
+ .object({
353
+ /**
354
+ * The list of DNS servers to use for the virtual machine.
355
+ */
356
+ dns: z.string().array(),
357
+
358
+ /**
359
+ * The name of the network bridge to connect the virtual machine to.
360
+ *
361
+ * By default, this is set to "vmbr0".
362
+ */
363
+ bridge: z.string(),
364
+ })
365
+ .default({ dns: [], bridge: "vmbr0" }),
366
+
367
+ /**
368
+ * The SSH configuration for the virtual machine.
369
+ */
370
+ ssh: z
371
+ .object({
372
+ /**
373
+ * The port to use for SSH connections to the virtual machine.
374
+ *
375
+ * By default, this is set to 22.
376
+ */
377
+ port: z.number(),
378
+
379
+ /**
380
+ * The user to use for SSH connections to the virtual machine.
381
+ *
382
+ * By default, this is set to "root".
383
+ */
384
+ user: z.string(),
385
+ })
386
+ .default({ port: 22, user: "root" }),
387
+
388
+ /**
389
+ * Whether to wait for the Proxmox agent to be ready before returning.
390
+ */
391
+ waitForAgent: z.boolean().default(true),
392
+
393
+ /**
394
+ * The cloud-init vendor data to use for the virtual machine.
395
+ *
396
+ * Will take precedence over the `vendorData` input.
397
+ */
398
+ vendorData: z.string().optional().meta({ multiline: true }),
168
399
  },
169
400
 
170
401
  secrets: {
171
- sshPassword: Type.Optional(Type.String()),
402
+ sshPassword: z.string().optional(),
172
403
  },
173
404
 
174
405
  inputs: {
@@ -179,16 +410,26 @@ export const virtualMachine = defineUnit({
179
410
  entity: keyPairEntity,
180
411
  required: false,
181
412
  },
413
+
414
+ /**
415
+ * The cloud-init vendor data to use for the virtual machine.
416
+ *
417
+ * You can provide a cloud-config from the distribution component.
418
+ */
419
+ vendorData: {
420
+ entity: fileEntity,
421
+ required: false,
422
+ },
182
423
  },
183
424
 
184
425
  outputs: serverOutputs,
185
426
 
186
427
  meta: {
187
- displayName: "Proxmox Virtual Machine",
428
+ title: "Proxmox Virtual Machine",
188
429
  description: "The virtual machine on a Proxmox cluster.",
189
430
  category: "Proxmox",
190
- primaryIcon: "simple-icons:proxmox",
191
- primaryIconColor: "#e56901",
431
+ icon: "simple-icons:proxmox",
432
+ iconColor: "#e56901",
192
433
  secondaryIcon: "codicon:vm",
193
434
  },
194
435
 
package/src/restic.ts CHANGED
@@ -1,16 +1,16 @@
1
- import { defineEntity, defineUnit, Type, type Static } from "@highstate/contract"
1
+ import { defineEntity, defineUnit, z } from "@highstate/contract"
2
2
  import { l3EndpointEntity, l4EndpointEntity } from "./network"
3
3
 
4
- export const repoEntity = defineEntity({
5
- type: "restic.repo",
4
+ export const repositoryEntity = defineEntity({
5
+ type: "restic.repository",
6
6
 
7
- schema: Type.Object({
8
- remoteEndpoints: Type.Array(Type.Union([l3EndpointEntity.schema, l4EndpointEntity.schema])),
7
+ schema: z.object({
8
+ remoteEndpoints: z.union([l3EndpointEntity.schema, l4EndpointEntity.schema]).array(),
9
9
 
10
- type: Type.Literal("rclone"),
11
- rcloneConfig: Type.String(),
12
- remoteName: Type.String(),
13
- pathPattern: Type.String(),
10
+ type: z.literal("rclone"),
11
+ rcloneConfig: z.string(),
12
+ remoteName: z.string(),
13
+ pathPattern: z.string(),
14
14
  }),
15
15
 
16
16
  meta: {
@@ -22,7 +22,7 @@ export const repo = defineUnit({
22
22
  type: "restic.repo",
23
23
 
24
24
  args: {
25
- remoteEndpoints: Type.Default(Type.Array(Type.String()), []),
25
+ remoteEndpoints: z.string().array().default([]),
26
26
 
27
27
  /**
28
28
  * The pattern for the path where backups will be stored for the specific application.
@@ -34,14 +34,12 @@ export const repo = defineUnit({
34
34
  * - `$unitName`: The name of the unit, which deploys the application, provided by the user.
35
35
  *
36
36
  * By default, the path pattern is `backups/$clusterName/$appName`.
37
- *
38
- * @schema
39
37
  */
40
- pathPattern: Type.Default(Type.String(), "backups/$clusterName/$appName"),
38
+ pathPattern: z.string().default("backups/$clusterName/$appName"),
41
39
  },
42
40
 
43
41
  secrets: {
44
- rcloneConfig: Type.String({ language: "ini" }),
42
+ rcloneConfig: z.string(),
45
43
  },
46
44
 
47
45
  inputs: {
@@ -58,14 +56,14 @@ export const repo = defineUnit({
58
56
  },
59
57
 
60
58
  outputs: {
61
- repo: repoEntity,
59
+ repo: repositoryEntity,
62
60
  },
63
61
 
64
62
  meta: {
65
- displayName: "Restic Repo",
63
+ title: "Restic Repo",
66
64
  description: "Holds the configuration for a Restic repository and its remote storage.",
67
- primaryIconColor: "#e56901",
68
- primaryIcon: "material-symbols:backup",
65
+ iconColor: "#e56901",
66
+ icon: "material-symbols:backup",
69
67
  category: "Infrastructure",
70
68
  },
71
69
 
@@ -75,4 +73,4 @@ export const repo = defineUnit({
75
73
  },
76
74
  })
77
75
 
78
- export type Repo = Static<typeof repoEntity.schema>
76
+ export type Repository = z.infer<typeof repositoryEntity.schema>
package/src/sops.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { defineUnit, Type } from "@highstate/contract"
2
- import { fileEntity, serverEntity } from "./common"
1
+ import { defineUnit, z } from "@highstate/contract"
2
+ import { fileEntity } from "./files"
3
+ import { serverEntity } from "./common"
3
4
 
4
5
  export const secrets = defineUnit({
5
6
  type: "sops.secrets",
6
7
 
7
- args: {
8
- secrets: Type.Record(Type.String(), Type.Any()),
8
+ secrets: {
9
+ data: z.record(z.string(), z.any()),
9
10
  },
10
11
 
11
12
  inputs: {
@@ -21,9 +22,9 @@ export const secrets = defineUnit({
21
22
  },
22
23
 
23
24
  meta: {
24
- displayName: "SOPS Secrets",
25
+ title: "SOPS Secrets",
25
26
  description: "Encrypts secrets using SOPS for the specified servers.",
26
- primaryIcon: "mdi:file-lock",
27
+ icon: "mdi:file-lock",
27
28
  category: "Secrets",
28
29
  },
29
30
 
package/src/ssh.ts CHANGED
@@ -1,16 +1,17 @@
1
- import { defineEntity, defineUnit, Type, type Static } from "@highstate/contract"
1
+ import { defineEntity, defineUnit, z } from "@highstate/contract"
2
2
  import { l4EndpointEntity } from "./network"
3
+ import { fileEntity } from "./files"
3
4
 
4
- export const keyTypeSchema = Type.StringEnum(["ed25519"])
5
+ export const keyTypeSchema = z.enum(["ed25519"])
5
6
 
6
7
  export const keyPairEntity = defineEntity({
7
8
  type: "ssh.key-pair",
8
9
 
9
- schema: Type.Object({
10
+ schema: z.object({
10
11
  type: keyTypeSchema,
11
- fingerprint: Type.String(),
12
- publicKey: Type.String(),
13
- privateKey: Type.String(),
12
+ fingerprint: z.string(),
13
+ publicKey: z.string(),
14
+ privateKey: z.string(),
14
15
  }),
15
16
 
16
17
  meta: {
@@ -18,31 +19,32 @@ export const keyPairEntity = defineEntity({
18
19
  },
19
20
  })
20
21
 
21
- export const credentialsSchema = Type.Object({
22
- endpoints: Type.Array(l4EndpointEntity.schema),
23
- hostKey: Type.String(),
24
- user: Type.String(),
25
- password: Type.Optional(Type.String()),
26
- keyPair: Type.Optional(keyPairEntity.schema),
22
+ export const credentialsSchema = z.object({
23
+ endpoints: l4EndpointEntity.schema.array(),
24
+ hostKey: z.string(),
25
+ user: z.string(),
26
+ password: z.string().optional(),
27
+ keyPair: keyPairEntity.schema.optional(),
27
28
  })
28
29
 
29
30
  export const keyPair = defineUnit({
30
31
  type: "ssh.key-pair",
31
32
 
32
33
  secrets: {
33
- privateKey: Type.Optional(Type.String()),
34
+ privateKey: z.string().optional(),
34
35
  },
35
36
 
36
37
  outputs: {
37
38
  keyPair: keyPairEntity,
39
+ publicKeyFile: fileEntity,
38
40
  },
39
41
 
40
42
  meta: {
41
- displayName: "SSH Key Pair",
43
+ title: "SSH Key Pair",
42
44
  description: "Holds the ED25519 SSH key pair and generates the private key if not provided.",
43
45
  category: "ssh",
44
- primaryIcon: "charm:key",
45
- primaryIconColor: "#ffffff",
46
+ icon: "charm:key",
47
+ iconColor: "#ffffff",
46
48
  secondaryIcon: "mdi:lock",
47
49
  secondaryIconColor: "#ffffff",
48
50
  },
@@ -53,6 +55,6 @@ export const keyPair = defineUnit({
53
55
  },
54
56
  })
55
57
 
56
- export type KeyType = Static<typeof keyTypeSchema>
57
- export type Credentials = Static<typeof credentialsSchema>
58
- export type KeyPair = Static<typeof keyPairEntity.schema>
58
+ export type KeyType = z.infer<typeof keyTypeSchema>
59
+ export type Credentials = z.infer<typeof credentialsSchema>
60
+ export type KeyPair = z.infer<typeof keyPairEntity.schema>