@highstate/library 0.19.1 → 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 +19 -4
  7. package/src/common/files.ts +24 -17
  8. package/src/common/server.ts +19 -6
  9. package/src/databases/etcd.ts +141 -39
  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 -41
  14. package/src/databases/mysql.ts +172 -0
  15. package/src/databases/postgresql.ts +133 -40
  16. package/src/databases/redis.ts +118 -44
  17. package/src/databases/s3.ts +48 -127
  18. package/src/dns.ts +11 -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 +15 -2
  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 +41 -9
  41. package/src/k8s/service.ts +6 -2
  42. package/src/k8s/shared.ts +49 -18
  43. package/src/k8s/workload.ts +59 -43
  44. package/src/network/address-space.ts +16 -7
  45. package/src/network/address.ts +13 -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 +20 -39
  49. package/src/network/index.ts +1 -1
  50. package/src/network/subnet.ts +4 -2
  51. package/src/proxmox.ts +24 -7
  52. package/src/restic.ts +8 -2
  53. package/src/ssh.ts +52 -30
  54. package/src/talos.ts +8 -2
  55. package/src/third-party/cloudflare.ts +4 -4
  56. package/src/third-party/timeweb.ts +17 -3
  57. package/src/third-party/yandex.ts +198 -88
  58. package/src/tls.ts +22 -0
  59. package/src/utils.ts +16 -1
  60. package/src/wireguard.ts +346 -120
  61. package/src/databases/mariadb.ts +0 -91
  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 -43
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highstate/library",
3
- "version": "0.19.1",
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.19.1"
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.19.1"
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, type EntityInput, 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,9 +140,9 @@ 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>
131
146
 
132
147
  export type GatewayInput = EntityInput<typeof gatewayEntity>
133
148
  export type AccessPointInput = EntityInput<typeof accessPointEntity>
@@ -5,6 +5,7 @@ import {
5
5
  defineEntity,
6
6
  defineUnit,
7
7
  type EntityInput,
8
+ type EntityValue,
8
9
  unitArtifactSchema,
9
10
  z,
10
11
  } from "@highstate/contract"
@@ -19,10 +20,6 @@ export const checksumSchema = z.object({
19
20
 
20
21
  export const fileContentSchema = z.union([
21
22
  baseFileContentSchema,
22
- z.object({
23
- type: z.literal("local"),
24
- path: z.string(),
25
- }),
26
23
  z.object({
27
24
  type: z.literal("remote"),
28
25
  endpoint: l7EndpointEntity.schema,
@@ -39,7 +36,10 @@ export const fileEntity = defineEntity({
39
36
  }),
40
37
 
41
38
  meta: {
42
- color: "#FF5722",
39
+ title: "File",
40
+ icon: "mdi:file",
41
+ iconColor: "#2196F3",
42
+ color: "#2196F3",
43
43
  },
44
44
  })
45
45
 
@@ -51,15 +51,6 @@ export const folderMetaSchema = z.object({
51
51
  export const folderContentSchema = z.union([
52
52
  z.object({
53
53
  type: z.literal("embedded"),
54
- files: fileEntity.schema.array(),
55
- folders: z
56
- .object({
57
- meta: folderMetaSchema,
58
- get content() {
59
- return folderContentSchema
60
- },
61
- })
62
- .array(),
63
54
  }),
64
55
  z.object({
65
56
  type: z.literal("artifact"),
@@ -78,13 +69,29 @@ export const folderContentSchema = z.union([
78
69
  export const folderEntity = defineEntity({
79
70
  type: "common.folder.v1",
80
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
+
81
85
  schema: z.object({
82
86
  meta: folderMetaSchema,
83
87
  content: folderContentSchema,
84
88
  }),
85
89
 
86
90
  meta: {
87
- color: "#FF9800",
91
+ title: "Folder",
92
+ icon: "mdi:folder",
93
+ iconColor: "#4CAF50",
94
+ color: "#4CAF50",
88
95
  },
89
96
  })
90
97
 
@@ -137,7 +144,7 @@ export const remoteFile = defineUnit({
137
144
  },
138
145
  })
139
146
 
140
- export type File = z.infer<typeof fileEntity.schema>
147
+ export type File = EntityValue<typeof fileEntity>
141
148
  export type FileInput = EntityInput<typeof fileEntity>
142
149
  export type FileMeta = z.infer<typeof baseFileMetaSchema>
143
150
  export type FileContent = z.infer<typeof fileContentSchema>
@@ -147,7 +154,7 @@ export type ArtifactFile = Simplify<File & { content: { type: "artifact" } }>
147
154
  export type LocalFile = Simplify<File & { content: { type: "local" } }>
148
155
  export type RemoteFile = Simplify<File & { content: { type: "remote" } }>
149
156
 
150
- export type Folder = z.infer<typeof folderEntity.schema>
157
+ export type Folder = EntityValue<typeof folderEntity>
151
158
  export type FolderInput = EntityInput<typeof folderEntity>
152
159
  export type FolderMeta = z.infer<typeof folderMetaSchema>
153
160
  export type FolderContent = z.infer<typeof folderContentSchema>
@@ -4,9 +4,10 @@ import {
4
4
  defineEntity,
5
5
  defineUnit,
6
6
  type EntityInput,
7
+ type EntityValue,
7
8
  z,
8
9
  } from "@highstate/contract"
9
- import { l3EndpointEntity } from "../network"
10
+ import { l3EndpointContainer, l3EndpointEntity } from "../network"
10
11
  import * as ssh from "../ssh"
11
12
 
12
13
  /**
@@ -19,20 +20,32 @@ import * as ssh from "../ssh"
19
20
  export const serverEntity = defineEntity({
20
21
  type: "common.server.v1",
21
22
 
23
+ extends: { l3EndpointContainer },
24
+
22
25
  includes: {
23
- endpoints: {
24
- entity: l3EndpointEntity,
25
- 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,
26
34
  },
27
35
  },
28
36
 
29
37
  schema: z.object({
38
+ /**
39
+ * The hostname of the server.
40
+ */
30
41
  hostname: z.string(),
31
- ssh: ssh.connectionSchema.optional(),
32
42
  }),
33
43
 
34
44
  meta: {
35
45
  color: "#009688",
46
+ title: "Server",
47
+ icon: "mdi:server",
48
+ iconColor: "#009688",
36
49
  },
37
50
  })
38
51
 
@@ -193,5 +206,5 @@ export const script = defineUnit({
193
206
  },
194
207
  })
195
208
 
196
- export type Server = z.infer<typeof serverEntity.schema>
209
+ export type Server = EntityValue<typeof serverEntity>
197
210
  export type ServerInput = EntityInput<typeof serverEntity>
@@ -1,27 +1,57 @@
1
- import { defineEntity, defineUnit, type EntityInput, 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,40 +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
  })
98
198
 
99
- export type Etcd = z.infer<typeof etcdEntity.schema>
100
- export type EtcdInput = EntityInput<typeof etcdEntity>
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>