@highstate/library 0.18.0 → 0.20.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 (65) hide show
  1. package/dist/highstate.library.msgpack +0 -0
  2. package/dist/index.js +2314 -1141
  3. package/dist/index.js.map +1 -1
  4. package/package.json +3 -3
  5. package/src/abbreviations.ts +3 -0
  6. package/src/common/access-point.ts +23 -4
  7. package/src/common/files.ts +27 -17
  8. package/src/common/server.ts +28 -7
  9. package/src/databases/etcd.ts +142 -37
  10. package/src/databases/index.ts +8 -7
  11. package/src/databases/influxdb3.ts +103 -0
  12. package/src/databases/minio.ts +157 -0
  13. package/src/databases/mongodb.ts +122 -40
  14. package/src/databases/mysql.ts +172 -0
  15. package/src/databases/postgresql.ts +133 -39
  16. package/src/databases/redis.ts +118 -43
  17. package/src/databases/s3.ts +49 -126
  18. package/src/dns.ts +12 -7
  19. package/src/index.ts +1 -1
  20. package/src/k3s.ts +7 -0
  21. package/src/k8s/apps/etcd.ts +3 -3
  22. package/src/k8s/apps/gitea.ts +1 -1
  23. package/src/k8s/apps/grafana.ts +48 -0
  24. package/src/k8s/apps/index.ts +4 -2
  25. package/src/k8s/apps/mariadb.ts +7 -38
  26. package/src/k8s/apps/matrix-stack.ts +62 -0
  27. package/src/k8s/apps/minio.ts +38 -45
  28. package/src/k8s/apps/mongodb.ts +6 -38
  29. package/src/k8s/apps/portal.ts +27 -0
  30. package/src/k8s/apps/postgresql.ts +7 -41
  31. package/src/k8s/apps/refluxdb.ts +49 -0
  32. package/src/k8s/apps/remnawave.ts +17 -1
  33. package/src/k8s/apps/shared.ts +16 -15
  34. package/src/k8s/apps/traefik.ts +5 -0
  35. package/src/k8s/apps/valkey.ts +5 -5
  36. package/src/k8s/apps/vaultwarden.ts +2 -6
  37. package/src/k8s/apps/workload.ts +14 -11
  38. package/src/k8s/cert-manager.ts +22 -0
  39. package/src/k8s/cilium.ts +17 -2
  40. package/src/k8s/resources.ts +50 -9
  41. package/src/k8s/service.ts +7 -2
  42. package/src/k8s/shared.ts +50 -18
  43. package/src/k8s/workload.ts +65 -42
  44. package/src/network/address-space.ts +17 -7
  45. package/src/network/address.ts +14 -2
  46. package/src/network/endpoint-container.ts +235 -0
  47. package/src/network/endpoint-schema.ts +8 -0
  48. package/src/network/endpoint.ts +23 -39
  49. package/src/network/index.ts +1 -1
  50. package/src/network/subnet.ts +5 -2
  51. package/src/proxmox.ts +27 -7
  52. package/src/restic.ts +9 -2
  53. package/src/ssh.ts +63 -31
  54. package/src/talos.ts +10 -1
  55. package/src/third-party/cloudflare.ts +4 -4
  56. package/src/third-party/timeweb.ts +18 -3
  57. package/src/third-party/yandex.ts +203 -86
  58. package/src/tls.ts +22 -0
  59. package/src/utils.ts +16 -1
  60. package/src/wireguard.ts +352 -120
  61. package/src/databases/mariadb.ts +0 -90
  62. package/src/databases/shared.ts +0 -67
  63. package/src/k8s/apps/kubernetes-dashboard.ts +0 -28
  64. package/src/k8s/apps/maybe.ts +0 -39
  65. package/src/network/dynamic-endpoint.ts +0 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highstate/library",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "highstate": {
6
6
  "type": "library"
@@ -25,13 +25,13 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "remeda": "^2.21.0",
28
- "@highstate/contract": "0.18.0"
28
+ "@highstate/contract": "0.20.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@biomejs/biome": "2.2.0",
32
32
  "@typescript/native-preview": "^7.0.0-dev.20250920.1",
33
33
  "type-fest": "^4.41.0",
34
- "@highstate/cli": "0.18.0"
34
+ "@highstate/cli": "0.20.0"
35
35
  },
36
36
  "repository": {
37
37
  "url": "https://github.com/highstate-io/highstate"
@@ -28,9 +28,12 @@ registerKnownAbbreviations([
28
28
  "CNI",
29
29
  "CSI",
30
30
  "MariaDB",
31
+ "MySQL",
31
32
  "PostgreSQL",
32
33
  "MongoDB",
33
34
  "etcd",
35
+ "MAS", // Matrix Authentication Service
36
+ "LC", // Locale
34
37
  ])
35
38
 
36
39
  export const noop = () => {}
@@ -1,4 +1,10 @@
1
- import { defineEntity, defineUnit, z } from "@highstate/contract"
1
+ import {
2
+ defineEntity,
3
+ defineUnit,
4
+ type EntityInput,
5
+ type EntityValue,
6
+ z,
7
+ } from "@highstate/contract"
2
8
  import * as dns from "../dns"
3
9
  import { implementationReferenceSchema } from "../impl-ref"
4
10
  import { l3EndpointEntity } from "../network"
@@ -21,6 +27,9 @@ export const gatewayEntity = defineEntity({
21
27
  }),
22
28
 
23
29
  meta: {
30
+ title: "Gateway",
31
+ icon: "mdi:router-network",
32
+ iconColor: "#F57F17",
24
33
  color: "#F57F17",
25
34
  },
26
35
  })
@@ -41,6 +50,9 @@ export const tlsIssuerEntity = defineEntity({
41
50
  }),
42
51
 
43
52
  meta: {
53
+ title: "TLS Issuer",
54
+ icon: "mdi:certificate-outline",
55
+ iconColor: "#F57F17",
44
56
  color: "#F57F17",
45
57
  },
46
58
  })
@@ -71,6 +83,9 @@ export const accessPointEntity = defineEntity({
71
83
  }),
72
84
 
73
85
  meta: {
86
+ title: "Access Point",
87
+ icon: "mdi:access-point",
88
+ iconColor: "#F57F17",
74
89
  color: "#F57F17",
75
90
  },
76
91
  })
@@ -125,6 +140,10 @@ export const accessPoint = defineUnit({
125
140
  },
126
141
  })
127
142
 
128
- export type Gateway = z.infer<typeof gatewayEntity.schema>
129
- export type AccessPoint = z.infer<typeof accessPointEntity.schema>
130
- export type TlsIssuer = z.infer<typeof tlsIssuerEntity.schema>
143
+ export type Gateway = EntityValue<typeof gatewayEntity>
144
+ export type AccessPoint = EntityValue<typeof accessPointEntity>
145
+ export type TlsIssuer = EntityValue<typeof tlsIssuerEntity>
146
+
147
+ export type GatewayInput = EntityInput<typeof gatewayEntity>
148
+ export type AccessPointInput = EntityInput<typeof accessPointEntity>
149
+ export type TlsIssuerInput = EntityInput<typeof tlsIssuerEntity>
@@ -4,6 +4,8 @@ import {
4
4
  fileMetaSchema as baseFileMetaSchema,
5
5
  defineEntity,
6
6
  defineUnit,
7
+ type EntityInput,
8
+ type EntityValue,
7
9
  unitArtifactSchema,
8
10
  z,
9
11
  } from "@highstate/contract"
@@ -18,10 +20,6 @@ export const checksumSchema = z.object({
18
20
 
19
21
  export const fileContentSchema = z.union([
20
22
  baseFileContentSchema,
21
- z.object({
22
- type: z.literal("local"),
23
- path: z.string(),
24
- }),
25
23
  z.object({
26
24
  type: z.literal("remote"),
27
25
  endpoint: l7EndpointEntity.schema,
@@ -38,7 +36,10 @@ export const fileEntity = defineEntity({
38
36
  }),
39
37
 
40
38
  meta: {
41
- color: "#FF5722",
39
+ title: "File",
40
+ icon: "mdi:file",
41
+ iconColor: "#2196F3",
42
+ color: "#2196F3",
42
43
  },
43
44
  })
44
45
 
@@ -50,15 +51,6 @@ export const folderMetaSchema = z.object({
50
51
  export const folderContentSchema = z.union([
51
52
  z.object({
52
53
  type: z.literal("embedded"),
53
- files: fileEntity.schema.array(),
54
- folders: z
55
- .object({
56
- meta: folderMetaSchema,
57
- get content() {
58
- return folderContentSchema
59
- },
60
- })
61
- .array(),
62
54
  }),
63
55
  z.object({
64
56
  type: z.literal("artifact"),
@@ -77,13 +69,29 @@ export const folderContentSchema = z.union([
77
69
  export const folderEntity = defineEntity({
78
70
  type: "common.folder.v1",
79
71
 
72
+ includes: {
73
+ files: {
74
+ entity: fileEntity,
75
+ multiple: true,
76
+ required: false,
77
+ },
78
+ folders: {
79
+ entity: () => folderEntity,
80
+ multiple: true,
81
+ required: false,
82
+ },
83
+ },
84
+
80
85
  schema: z.object({
81
86
  meta: folderMetaSchema,
82
87
  content: folderContentSchema,
83
88
  }),
84
89
 
85
90
  meta: {
86
- color: "#FF9800",
91
+ title: "Folder",
92
+ icon: "mdi:folder",
93
+ iconColor: "#4CAF50",
94
+ color: "#4CAF50",
87
95
  },
88
96
  })
89
97
 
@@ -136,7 +144,8 @@ export const remoteFile = defineUnit({
136
144
  },
137
145
  })
138
146
 
139
- export type File = z.infer<typeof fileEntity.schema>
147
+ export type File = EntityValue<typeof fileEntity>
148
+ export type FileInput = EntityInput<typeof fileEntity>
140
149
  export type FileMeta = z.infer<typeof baseFileMetaSchema>
141
150
  export type FileContent = z.infer<typeof fileContentSchema>
142
151
 
@@ -145,7 +154,8 @@ export type ArtifactFile = Simplify<File & { content: { type: "artifact" } }>
145
154
  export type LocalFile = Simplify<File & { content: { type: "local" } }>
146
155
  export type RemoteFile = Simplify<File & { content: { type: "remote" } }>
147
156
 
148
- export type Folder = z.infer<typeof folderEntity.schema>
157
+ export type Folder = EntityValue<typeof folderEntity>
158
+ export type FolderInput = EntityInput<typeof folderEntity>
149
159
  export type FolderMeta = z.infer<typeof folderMetaSchema>
150
160
  export type FolderContent = z.infer<typeof folderContentSchema>
151
161
 
@@ -1,5 +1,13 @@
1
- import { $outputs, $secrets, defineEntity, defineUnit, z } from "@highstate/contract"
2
- import { l3EndpointEntity } from "../network"
1
+ import {
2
+ $outputs,
3
+ $secrets,
4
+ defineEntity,
5
+ defineUnit,
6
+ type EntityInput,
7
+ type EntityValue,
8
+ z,
9
+ } from "@highstate/contract"
10
+ import { l3EndpointContainer, l3EndpointEntity } from "../network"
3
11
  import * as ssh from "../ssh"
4
12
 
5
13
  /**
@@ -12,20 +20,32 @@ import * as ssh from "../ssh"
12
20
  export const serverEntity = defineEntity({
13
21
  type: "common.server.v1",
14
22
 
23
+ extends: { l3EndpointContainer },
24
+
15
25
  includes: {
16
- endpoints: {
17
- entity: l3EndpointEntity,
18
- multiple: true,
26
+ /**
27
+ * The SSH configuration for the server.
28
+ *
29
+ * If not specified, it will be assumed that the server is not accessible via SSH.
30
+ */
31
+ ssh: {
32
+ entity: ssh.connectionEntity,
33
+ required: false,
19
34
  },
20
35
  },
21
36
 
22
37
  schema: z.object({
38
+ /**
39
+ * The hostname of the server.
40
+ */
23
41
  hostname: z.string(),
24
- ssh: ssh.connectionSchema.optional(),
25
42
  }),
26
43
 
27
44
  meta: {
28
45
  color: "#009688",
46
+ title: "Server",
47
+ icon: "mdi:server",
48
+ iconColor: "#009688",
29
49
  },
30
50
  })
31
51
 
@@ -186,4 +206,5 @@ export const script = defineUnit({
186
206
  },
187
207
  })
188
208
 
189
- export type Server = z.infer<typeof serverEntity.schema>
209
+ export type Server = EntityValue<typeof serverEntity>
210
+ export type ServerInput = EntityInput<typeof serverEntity>
@@ -1,27 +1,57 @@
1
- import { defineEntity, defineUnit, z } from "@highstate/contract"
2
- import { l4EndpointEntity } from "../network"
3
- import { toPatchArgs } from "../utils"
1
+ import {
2
+ defineEntity,
3
+ defineUnit,
4
+ type EntityInput,
5
+ type EntityValue,
6
+ secretSchema,
7
+ z,
8
+ } from "@highstate/contract"
9
+ import { l4EndpointContainer, l4EndpointEntity } from "../network"
10
+ import { certificateEntity } from "../tls"
4
11
 
5
- const etcdArgs = {
6
- endpoints: {
7
- schema: z.string().array().default([]),
8
- },
9
- }
12
+ /**
13
+ * The credentials for authenticating to the etcd cluster.
14
+ */
15
+ export const credentialsSchema = z.discriminatedUnion("type", [
16
+ z.object({
17
+ type: z.literal("password"),
18
+
19
+ /**
20
+ * The username used to authenticate against the database.
21
+ */
22
+ username: z.string(),
23
+
24
+ /**
25
+ * The password used to authenticate against the database.
26
+ */
27
+ password: secretSchema(z.string()),
28
+ }),
29
+ ])
10
30
 
11
31
  /**
12
- * Represents the etcd database instance.
32
+ * Represents a connection to the etcd cluster.
13
33
  */
14
- export const etcdEntity = defineEntity({
15
- type: "databases.etcd.v1",
34
+ export const connectionEntity = defineEntity({
35
+ type: "etcd.connection.v1",
36
+
37
+ extends: { l4EndpointContainer },
16
38
 
17
39
  includes: {
18
- endpoints: {
19
- entity: l4EndpointEntity,
20
- multiple: true,
40
+ /**
41
+ * The TLS certificate of the server if any.
42
+ */
43
+ certificate: {
44
+ entity: certificateEntity,
45
+ required: false,
21
46
  },
22
47
  },
23
48
 
24
- schema: z.unknown(),
49
+ schema: z.object({
50
+ /**
51
+ * The credentials for authenticating to the etcd cluster.
52
+ */
53
+ credentials: credentialsSchema.optional(),
54
+ }),
25
55
 
26
56
  meta: {
27
57
  color: "#0064bf",
@@ -29,14 +59,34 @@ export const etcdEntity = defineEntity({
29
59
  })
30
60
 
31
61
  /**
32
- * The existing etcd database instance.
62
+ * The connection to an existing etcd cluster hosted on a server or a managed service.
33
63
  */
34
- export const existingEtcd = defineUnit({
35
- type: "databases.etcd.existing.v1",
64
+ export const connection = defineUnit({
65
+ type: "etcd.connection.v1",
66
+
67
+ args: {
68
+ /**
69
+ * The endpoints to connect to the etcd cluster.
70
+ */
71
+ endpoints: z.string().array().default([]),
72
+
73
+ /**
74
+ * The username to authenticate with.
75
+ */
76
+ username: z.string().optional(),
77
+ },
36
78
 
37
- args: etcdArgs,
79
+ secrets: {
80
+ /**
81
+ * The password to authenticate with.
82
+ */
83
+ password: z.string().optional(),
84
+ },
38
85
 
39
86
  inputs: {
87
+ /**
88
+ * The endpoints to connect to the etcd cluster.
89
+ */
40
90
  endpoints: {
41
91
  entity: l4EndpointEntity,
42
92
  multiple: true,
@@ -45,12 +95,12 @@ export const existingEtcd = defineUnit({
45
95
  },
46
96
 
47
97
  outputs: {
48
- etcd: etcdEntity,
98
+ connection: connectionEntity,
49
99
  },
50
100
 
51
101
  source: {
52
- package: "@highstate/common",
53
- path: "units/databases/existing-etcd",
102
+ package: "@highstate/etcd",
103
+ path: "units/connection",
54
104
  },
55
105
 
56
106
  meta: {
@@ -61,37 +111,92 @@ export const existingEtcd = defineUnit({
61
111
  },
62
112
  })
63
113
 
114
+ export const namespacePermissionSchema = z.object({
115
+ /**
116
+ * The prefix of the namespace to grant access to.
117
+ */
118
+ prefix: z.string(),
119
+
120
+ /**
121
+ * The range end of the namespace to grant access to.
122
+ *
123
+ * If not specified, all keys with the given prefix will be included in the namespace.
124
+ */
125
+ rangeEnd: z.string().optional(),
126
+
127
+ /**
128
+ * The access level to grant to the namespace.
129
+ *
130
+ * If not specified, defaults to `readwrite`.
131
+ */
132
+ permission: z.enum(["read", "write", "readwrite"]).default("readwrite"),
133
+ })
134
+
64
135
  /**
65
- * Patches some properties of the etcd database and outputs the updated database.
136
+ * The namespace within an existing etcd cluster.
66
137
  */
67
- export const etcdPatch = defineUnit({
68
- type: "databases.etcd-patch.v1",
138
+ export const namespace = defineUnit({
139
+ type: "etcd.namespace.v1",
140
+
141
+ args: {
142
+ /**
143
+ * The name of the role to define for the namespace.
144
+ *
145
+ * If not provided, the name of the unit will be used.
146
+ */
147
+ roleName: z.string().optional(),
148
+
149
+ /**
150
+ * The username of the user to create for the namespace.
151
+ *
152
+ * If not provided, the name of the role will be used.
153
+ */
154
+ username: z.string().optional(),
155
+
156
+ /**
157
+ * The permissions to grant to the namespace.
158
+ */
159
+ permissions: namespacePermissionSchema.array(),
160
+ },
69
161
 
70
- args: toPatchArgs(etcdArgs),
162
+ secrets: {
163
+ /**
164
+ * The password of the user to create for the namespace.
165
+ *
166
+ * If not provided, a random password will be generated.
167
+ */
168
+ password: z.string().optional(),
169
+ },
71
170
 
72
171
  inputs: {
73
- etcd: etcdEntity,
74
-
75
- endpoints: {
76
- entity: l4EndpointEntity,
77
- multiple: true,
78
- required: false,
172
+ /**
173
+ * The connection to the etcd cluster.
174
+ */
175
+ connection: {
176
+ entity: connectionEntity,
177
+ required: true,
79
178
  },
80
179
  },
81
180
 
82
181
  outputs: {
83
- etcd: etcdEntity,
182
+ connection: connectionEntity,
84
183
  },
85
184
 
86
185
  source: {
87
- package: "@highstate/common",
88
- path: "units/databases/etcd-patch",
186
+ package: "@highstate/etcd",
187
+ path: "units/namespace",
89
188
  },
90
189
 
91
190
  meta: {
92
- title: "etcd Patch",
191
+ title: "etcd Namespace",
93
192
  icon: "simple-icons:etcd",
94
- secondaryIcon: "fluent:patch-20-filled",
193
+ iconColor: "#0069ab",
194
+ secondaryIcon: "mdi:database",
95
195
  category: "Databases",
96
196
  },
97
197
  })
198
+
199
+ export type Credentials = z.infer<typeof credentialsSchema>
200
+
201
+ export type Connection = EntityValue<typeof connectionEntity>
202
+ export type ConnectionInput = EntityInput<typeof connectionEntity>
@@ -1,7 +1,8 @@
1
- export * from "./etcd"
2
- export * from "./mariadb"
3
- export * from "./mongodb"
4
- export * from "./postgresql"
5
- export * from "./redis"
6
- export * from "./s3"
7
- export * from "./shared"
1
+ export * as etcd from "./etcd"
2
+ export * as influxdb3 from "./influxdb3"
3
+ export * as minio from "./minio"
4
+ export * as mongodb from "./mongodb"
5
+ export * as mysql from "./mysql"
6
+ export * as postgresql from "./postgresql"
7
+ export * as redis from "./redis"
8
+ export * as s3 from "./s3"
@@ -0,0 +1,103 @@
1
+ import {
2
+ defineEntity,
3
+ defineUnit,
4
+ type EntityInput,
5
+ type EntityValue,
6
+ secretSchema,
7
+ z,
8
+ } from "@highstate/contract"
9
+ import { l7EndpointContainer } from "../network"
10
+
11
+ export const credentialsSchema = z.object({
12
+ /**
13
+ * The token for authenticating to the InfluxDB 3 instance.
14
+ */
15
+ token: secretSchema(z.string()),
16
+ })
17
+
18
+ /**
19
+ * Represents a connection to a InfluxDB 3 instance, including the endpoints and credentials.
20
+ */
21
+ export const connectionEntity = defineEntity({
22
+ type: "influxdb3.connection.v1",
23
+
24
+ extends: { l7EndpointContainer },
25
+
26
+ schema: z.object({
27
+ /**
28
+ * The credentials for authenticating to the InfluxDB 3 instance.
29
+ */
30
+ credentials: credentialsSchema,
31
+ }),
32
+
33
+ meta: {
34
+ color: "#22adf6",
35
+ },
36
+ })
37
+
38
+ /**
39
+ * Represents an InfluxDB 3 database with credentials and endpoints to access it.
40
+ */
41
+ export const databaseEntity = defineEntity({
42
+ type: "influxdb3.database.v1",
43
+
44
+ extends: { connectionEntity },
45
+
46
+ schema: z.object({
47
+ /**
48
+ * The name of the database.
49
+ */
50
+ name: z.string(),
51
+ }),
52
+
53
+ meta: {
54
+ color: "#22adf6",
55
+ },
56
+ })
57
+
58
+ /**
59
+ * Creates a database in an InfluxDB 3 instance.
60
+ */
61
+ export const database = defineUnit({
62
+ type: "influxdb3.database.v1",
63
+
64
+ args: {
65
+ /**
66
+ * The name of the database.
67
+ *
68
+ * If not provided, it will be set to the unit name.
69
+ */
70
+ databaseName: z.string().optional(),
71
+
72
+ /**
73
+ * The retention period for the database.
74
+ *
75
+ * The value is passed through to InfluxDB 3 as-is.
76
+ */
77
+ retention_period: z.string().optional(),
78
+ },
79
+
80
+ inputs: {
81
+ connection: connectionEntity,
82
+ },
83
+
84
+ outputs: {
85
+ database: databaseEntity,
86
+ },
87
+
88
+ meta: {
89
+ title: "InfluxDB 3 Database",
90
+ icon: "simple-icons:influxdb",
91
+ category: "Databases",
92
+ },
93
+
94
+ source: {
95
+ package: "@highstate/influxdb3",
96
+ path: "units/database",
97
+ },
98
+ })
99
+
100
+ export type Connection = EntityValue<typeof connectionEntity>
101
+ export type ConnectionInput = EntityInput<typeof connectionEntity>
102
+ export type Database = EntityValue<typeof databaseEntity>
103
+ export type DatabaseInput = EntityInput<typeof databaseEntity>