@highstate/library 0.9.16 → 0.9.19

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 (82) hide show
  1. package/dist/highstate.library.msgpack +0 -0
  2. package/dist/index.js +3548 -2985
  3. package/dist/index.js.map +1 -1
  4. package/package.json +5 -5
  5. package/src/common/access-point.ts +105 -0
  6. package/src/common/files.ts +137 -0
  7. package/src/common/index.ts +3 -0
  8. package/src/common/server.ts +231 -0
  9. package/src/databases/index.ts +4 -0
  10. package/src/databases/mariadb.ts +37 -0
  11. package/src/databases/mongodb.ts +37 -0
  12. package/src/databases/postgresql.ts +37 -0
  13. package/src/databases/shared.ts +61 -0
  14. package/src/distributions/ubuntu.ts +13 -11
  15. package/src/dns.ts +116 -18
  16. package/src/git.ts +14 -10
  17. package/src/impl-ref.ts +26 -0
  18. package/src/index.ts +14 -15
  19. package/src/k3s.ts +14 -12
  20. package/src/k8s/apps/code-server.ts +48 -0
  21. package/src/k8s/apps/gitea.ts +25 -0
  22. package/src/k8s/apps/grocy.ts +39 -0
  23. package/src/k8s/apps/hubble.ts +30 -0
  24. package/src/{apps → k8s/apps}/index.ts +16 -13
  25. package/src/k8s/apps/kubernetes-dashboard.ts +28 -0
  26. package/src/k8s/apps/mariadb.ts +83 -0
  27. package/src/k8s/apps/maybe.ts +39 -0
  28. package/src/k8s/apps/mongodb.ts +84 -0
  29. package/src/k8s/apps/postgresql.ts +86 -0
  30. package/src/k8s/apps/shared.ts +149 -0
  31. package/src/k8s/apps/syncthing.ts +72 -0
  32. package/src/k8s/apps/traefik.ts +40 -0
  33. package/src/k8s/apps/vaultwarden.ts +31 -0
  34. package/src/k8s/apps/workload.ts +214 -0
  35. package/src/k8s/apps/zitadel.ts +26 -0
  36. package/src/k8s/cert-manager.ts +80 -0
  37. package/src/k8s/cilium.ts +64 -0
  38. package/src/k8s/gateway.ts +70 -0
  39. package/src/k8s/index.ts +9 -0
  40. package/src/{obfuscators → k8s/obfuscators}/phantun.ts +14 -10
  41. package/src/{obfuscators → k8s/obfuscators}/shared.ts +17 -11
  42. package/src/k8s/resources.ts +111 -0
  43. package/src/k8s/service.ts +65 -0
  44. package/src/k8s/shared.ts +343 -0
  45. package/src/k8s/workload.ts +77 -0
  46. package/src/network.ts +249 -63
  47. package/src/nixos.ts +38 -77
  48. package/src/proxmox.ts +203 -96
  49. package/src/restic.ts +28 -19
  50. package/src/sops.ts +19 -8
  51. package/src/ssh.ts +122 -24
  52. package/src/talos.ts +21 -19
  53. package/src/third-party/cloudflare.ts +59 -0
  54. package/src/third-party/index.ts +3 -0
  55. package/src/{mullvad.ts → third-party/mullvad.ts} +11 -9
  56. package/src/third-party/timeweb.ts +99 -0
  57. package/src/utils.ts +27 -6
  58. package/src/wireguard.ts +249 -115
  59. package/src/apps/code-server.ts +0 -34
  60. package/src/apps/deployment.ts +0 -60
  61. package/src/apps/dns.ts +0 -107
  62. package/src/apps/gitea.ts +0 -18
  63. package/src/apps/grocy.ts +0 -20
  64. package/src/apps/hubble.ts +0 -20
  65. package/src/apps/kubernetes-dashboard.ts +0 -19
  66. package/src/apps/mariadb.ts +0 -81
  67. package/src/apps/maybe.ts +0 -25
  68. package/src/apps/mongodb.ts +0 -81
  69. package/src/apps/network.ts +0 -55
  70. package/src/apps/postgresql.ts +0 -81
  71. package/src/apps/shared.ts +0 -290
  72. package/src/apps/syncthing.ts +0 -54
  73. package/src/apps/test.ts +0 -19
  74. package/src/apps/traefik.ts +0 -36
  75. package/src/apps/vaultwarden.ts +0 -23
  76. package/src/apps/zitadel.ts +0 -21
  77. package/src/cloudflare.ts +0 -26
  78. package/src/common.ts +0 -200
  79. package/src/files.ts +0 -146
  80. package/src/k8s.ts +0 -638
  81. package/src/timeweb.ts +0 -75
  82. package/src/{obfuscators → k8s/obfuscators}/index.ts +1 -1
@@ -1,290 +0,0 @@
1
- import type { TString } from "@sinclair/typebox"
2
- import type { mariadbEntity } from "./mariadb"
3
- import type { postgresqlEntity } from "./postgresql"
4
- import type { mongodbEntity } from "./mongodb"
5
- import { Type } from "@highstate/contract"
6
- import {
7
- accessPointEntity,
8
- clusterEntity,
9
- persistentVolumeClaimEntity,
10
- serviceEntity,
11
- } from "../k8s"
12
- import { repositoryEntity } from "../restic"
13
- import { providerEntity } from "../dns"
14
- import { l4EndpointEntity } from "../network"
15
-
16
- const extraArgsDefinitions = {
17
- fqdn: {
18
- schema: Type.String(),
19
- },
20
- endpoints: {
21
- schema: Type.Array(Type.String()),
22
- required: false,
23
- },
24
- external: {
25
- schema: Type.Boolean(),
26
- required: false,
27
- },
28
- } as const
29
-
30
- const extraSecretsDefinitions = {
31
- rootPassword: {
32
- schema: Type.String(),
33
- required: false,
34
- },
35
- backupPassword: {
36
- schema: Type.String(),
37
- required: false,
38
- },
39
- }
40
-
41
- type LazyExtraInputDefinitions = {
42
- mariadb: {
43
- entity: typeof mariadbEntity
44
- displayName: "MariaDB"
45
- }
46
- postgresql: {
47
- entity: typeof postgresqlEntity
48
- displayName: "PostgreSQL"
49
- }
50
- mongodb: {
51
- entity: typeof mongodbEntity
52
- displayName: "MongoDB"
53
- }
54
- }
55
-
56
- const eagerExtraInputDefinitions = {
57
- accessPoint: {
58
- entity: accessPointEntity,
59
- },
60
- resticRepo: {
61
- entity: repositoryEntity,
62
- required: false,
63
- },
64
- dnsProviders: {
65
- entity: providerEntity,
66
- required: false,
67
- multiple: true,
68
- },
69
- volume: {
70
- entity: persistentVolumeClaimEntity,
71
- required: false,
72
- },
73
- } as const
74
-
75
- export const extraInputDefinitions = {
76
- ...eagerExtraInputDefinitions,
77
- } as typeof eagerExtraInputDefinitions & LazyExtraInputDefinitions
78
-
79
- type ExtraArgsDefinitions = typeof extraArgsDefinitions
80
- type ExtraSecretsDefinitions = typeof extraSecretsDefinitions
81
- type ExtraArgsName = keyof ExtraArgsDefinitions
82
- type ExtraSecretsName = keyof ExtraSecretsDefinitions
83
-
84
- type CreateArgsOptions<R extends readonly ExtraArgsName[], O extends readonly ExtraArgsName[]> = {
85
- required?: R
86
- optional?: O
87
- }
88
-
89
- type CreateSecretsOptions<
90
- R extends readonly ExtraSecretsName[],
91
- O extends readonly ExtraSecretsName[],
92
- > = {
93
- required?: R
94
- optional?: O
95
- }
96
-
97
- export function createArgs<T extends readonly ExtraArgsName[] = []>(
98
- defaultAppName: string,
99
- extraArgs?: T,
100
- ): {
101
- appName: TString & { default: string }
102
- } & {
103
- [K in T[number]]: ExtraArgsDefinitions[K]
104
- }
105
-
106
- export function createArgs<
107
- R extends readonly ExtraArgsName[] = [],
108
- O extends readonly ExtraArgsName[] = [],
109
- >(
110
- defaultAppName: string,
111
- extraArgs?: CreateArgsOptions<R, O>,
112
- ): {
113
- appName: TString & { default: string }
114
- } & {
115
- [K in R[number]]: ExtraArgsDefinitions[K] & { required: true }
116
- } & {
117
- [K in O[number]]: ExtraArgsDefinitions[K] & { required: false }
118
- }
119
-
120
- export function createArgs<
121
- R extends readonly ExtraArgsName[] = [],
122
- O extends readonly ExtraArgsName[] = [],
123
- >(defaultAppName: string, extraArgs?: readonly ExtraArgsName[] | CreateArgsOptions<R, O>) {
124
- const base = {
125
- appName: Type.Default(Type.String(), defaultAppName),
126
- }
127
-
128
- const dynamicArgs: Partial<Record<ExtraArgsName, object>> = {}
129
-
130
- if (Array.isArray(extraArgs)) {
131
- for (const name of extraArgs as readonly ExtraArgsName[]) {
132
- dynamicArgs[name] = extraArgsDefinitions[name]
133
- }
134
- } else {
135
- const { required, optional } = (extraArgs as CreateArgsOptions<R, O>) ?? {}
136
-
137
- for (const name of required ?? []) {
138
- dynamicArgs[name] = {
139
- ...extraArgsDefinitions[name],
140
- required: true,
141
- }
142
- }
143
-
144
- for (const name of optional ?? []) {
145
- dynamicArgs[name] = {
146
- ...extraArgsDefinitions[name],
147
- required: false,
148
- }
149
- }
150
- }
151
-
152
- return {
153
- ...base,
154
- ...dynamicArgs,
155
- }
156
- }
157
-
158
- export function createSecrets<T extends readonly ExtraSecretsName[] = []>(
159
- extraSecrets?: T,
160
- ): {
161
- [K in T[number]]: ExtraSecretsDefinitions[K]
162
- }
163
-
164
- export function createSecrets<
165
- R extends readonly ExtraSecretsName[] = [],
166
- O extends readonly ExtraSecretsName[] = [],
167
- >(
168
- extraSecrets?: CreateSecretsOptions<R, O>,
169
- ): {
170
- [K in R[number]]: ExtraSecretsDefinitions[K] & { required: true }
171
- } & {
172
- [K in O[number]]: ExtraSecretsDefinitions[K] & { required: false }
173
- }
174
-
175
- export function createSecrets<
176
- R extends readonly ExtraSecretsName[] = [],
177
- O extends readonly ExtraSecretsName[] = [],
178
- >(extraSecrets?: readonly ExtraSecretsName[] | CreateSecretsOptions<R, O>) {
179
- const dynamicSecrets: Partial<Record<ExtraSecretsName, object>> = {}
180
-
181
- if (Array.isArray(extraSecrets)) {
182
- for (const name of extraSecrets as readonly ExtraSecretsName[]) {
183
- dynamicSecrets[name] = extraSecretsDefinitions[name]
184
- }
185
- } else {
186
- const { required, optional } = (extraSecrets as CreateSecretsOptions<R, O>) ?? {}
187
-
188
- for (const name of required ?? []) {
189
- dynamicSecrets[name] = {
190
- ...extraSecretsDefinitions[name],
191
- required: true,
192
- }
193
- }
194
-
195
- for (const name of optional ?? []) {
196
- dynamicSecrets[name] = {
197
- ...extraSecretsDefinitions[name],
198
- required: false,
199
- }
200
- }
201
- }
202
-
203
- return dynamicSecrets as {
204
- [K in R[number]]: ExtraSecretsDefinitions[K] & { required: true }
205
- } & {
206
- [K in O[number]]: ExtraSecretsDefinitions[K] & { required: false }
207
- }
208
- }
209
-
210
- type ExtraInputDefinitions = typeof extraInputDefinitions
211
- type ExtraInputName = keyof ExtraInputDefinitions
212
-
213
- type CreateInputsOptions<
214
- R extends readonly ExtraInputName[],
215
- O extends readonly ExtraInputName[],
216
- > = {
217
- required?: R
218
- optional?: O
219
- }
220
-
221
- export function createInputs<T extends readonly ExtraInputName[] = []>(
222
- inputs?: T,
223
- ): {
224
- k8sCluster: typeof clusterEntity
225
- } & {
226
- [K in T[number]]: ExtraInputDefinitions[K]
227
- }
228
-
229
- export function createInputs<
230
- R extends readonly ExtraInputName[] = [],
231
- O extends readonly ExtraInputName[] = [],
232
- >(
233
- inputs?: CreateInputsOptions<R, O>,
234
- ): {
235
- k8sCluster: typeof clusterEntity
236
- } & {
237
- [K in R[number]]: ExtraInputDefinitions[K] & { required: true }
238
- } & {
239
- [K in O[number]]: ExtraInputDefinitions[K] & { required: false }
240
- }
241
-
242
- export function createInputs<
243
- R extends readonly ExtraInputName[] = [],
244
- O extends readonly ExtraInputName[] = [],
245
- >(inputs?: readonly ExtraInputName[] | CreateInputsOptions<R, O>) {
246
- const base = {
247
- k8sCluster: clusterEntity,
248
- }
249
-
250
- const dynamicInputs: Partial<Record<ExtraInputName, object>> = {}
251
-
252
- if (Array.isArray(inputs)) {
253
- for (const name of inputs as readonly ExtraInputName[]) {
254
- dynamicInputs[name] = extraInputDefinitions[name]
255
- }
256
- } else {
257
- const { required, optional } = (inputs as CreateInputsOptions<R, O>) ?? {}
258
-
259
- for (const name of required ?? []) {
260
- dynamicInputs[name] = {
261
- ...extraInputDefinitions[name],
262
- required: true,
263
- }
264
- }
265
- for (const name of optional ?? []) {
266
- dynamicInputs[name] = {
267
- ...extraInputDefinitions[name],
268
- required: false,
269
- }
270
- }
271
- }
272
-
273
- return {
274
- ...base,
275
- ...dynamicInputs,
276
- }
277
- }
278
-
279
- export function createSource(path: string) {
280
- return {
281
- package: "@highstate/apps",
282
- path,
283
- }
284
- }
285
-
286
- export const databaseSchema = Type.Object({
287
- endpoints: Type.Array(l4EndpointEntity.schema),
288
- service: Type.Optional(serviceEntity.schema),
289
- rootPassword: Type.String(),
290
- })
@@ -1,54 +0,0 @@
1
- import { defineUnit, Type } from "@highstate/contract"
2
- import { persistentVolumeClaimEntity, serviceEntity } from "../k8s"
3
- import { l4EndpointEntity } from "../network"
4
- import { createArgs, createInputs, createSecrets, createSource } from "./shared"
5
-
6
- export const backupModeSchema = Type.StringEnum(["state", "full"])
7
-
8
- export const syncthing = defineUnit({
9
- type: "apps.syncthing",
10
-
11
- args: {
12
- ...createArgs("syncthing", ["fqdn", "external"]),
13
-
14
- /**
15
- * The FQDN of the Syncthing instance used to sync with other devices.
16
- *
17
- * The `fqdn` argument unlike this one points to the gateway and used to
18
- * access the Syncthing Web UI.
19
- */
20
- deviceFqdn: Type.Optional(Type.String()),
21
-
22
- /**
23
- * The backup mode to use for the Syncthing instance.
24
- *
25
- * - `state`: Only the state is backed up. When the instance is restored, it will
26
- * sync files from the other devices automatically.
27
- * - `full`: A full backup is created including all files.
28
- *
29
- * The default is `state`.
30
- */
31
- backupMode: Type.Default(backupModeSchema, "state"),
32
- },
33
-
34
- secrets: createSecrets(["backupPassword"]),
35
- inputs: createInputs(["accessPoint", "resticRepo", "volume"]),
36
-
37
- outputs: {
38
- volume: persistentVolumeClaimEntity,
39
- service: serviceEntity,
40
- endpoints: {
41
- entity: l4EndpointEntity,
42
- multiple: true,
43
- },
44
- },
45
-
46
- meta: {
47
- displayName: "Syncthing",
48
- description: "The Syncthing instance deployed on Kubernetes.",
49
- primaryIcon: "simple-icons:syncthing",
50
- category: "File Sync",
51
- },
52
-
53
- source: createSource("syncthing"),
54
- })
package/src/apps/test.ts DELETED
@@ -1,19 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- import * as apps from "./mariadb"
3
-
4
- import type { InstanceInput } from "@highstate/contract"
5
-
6
- declare const cluster: InstanceInput<"k8s.cluster">
7
-
8
- const { mariadb, service } = apps.mariadb({
9
- name: "test",
10
- args: {
11
- external: true,
12
- },
13
- inputs: {
14
- k8sCluster: cluster,
15
- },
16
- })
17
-
18
- void mariadb
19
- void service
@@ -1,36 +0,0 @@
1
- import { defineUnit, Type } from "@highstate/contract"
2
- import { gatewayEntity, serviceEntity } from "../k8s"
3
- import { l4EndpointEntity } from "../network"
4
- import { createArgs, createInputs } from "./shared"
5
-
6
- export const traefikGateway = defineUnit({
7
- type: "apps.traefik-gateway",
8
-
9
- args: {
10
- ...createArgs("traefik", ["external"]),
11
- className: Type.Optional(Type.String()),
12
- },
13
-
14
- inputs: createInputs(),
15
-
16
- outputs: {
17
- gateway: gatewayEntity,
18
- service: serviceEntity,
19
- endpoints: {
20
- entity: l4EndpointEntity,
21
- multiple: true,
22
- },
23
- },
24
-
25
- meta: {
26
- displayName: "Traefik Gateway",
27
- description: "A Traefik gateway for routing traffic to services.",
28
- primaryIcon: "simple-icons:traefikproxy",
29
- category: "Network",
30
- },
31
-
32
- source: {
33
- package: "@highstate/apps",
34
- path: "traefik",
35
- },
36
- })
@@ -1,23 +0,0 @@
1
- import { defineUnit, Type } from "@highstate/contract"
2
- import { createArgs, createInputs, createSource } from "./shared"
3
-
4
- export const vaultwarden = defineUnit({
5
- type: "apps.vaultwarden",
6
-
7
- args: createArgs("vaultwarden", ["fqdn"]),
8
-
9
- secrets: {
10
- mariadbPassword: Type.Optional(Type.String()),
11
- },
12
-
13
- inputs: createInputs(["accessPoint", "mariadb"]),
14
-
15
- meta: {
16
- displayName: "Vaultwarden",
17
- description: "The Vaultwarden password manager deployed on Kubernetes.",
18
- primaryIcon: "simple-icons:vaultwarden",
19
- category: "Security",
20
- },
21
-
22
- source: createSource("vaultwarden"),
23
- })
@@ -1,21 +0,0 @@
1
- import { defineUnit } from "@highstate/contract"
2
- import { createArgs, createInputs } from "./shared"
3
-
4
- export const zitadel = defineUnit({
5
- type: "apps.zitadel",
6
-
7
- args: createArgs("zitadel", ["fqdn"]),
8
-
9
- inputs: createInputs(["accessPoint", "postgresql"]),
10
-
11
- meta: {
12
- displayName: "Zitadel",
13
- description: "The Zitadel IAM deployed on Kubernetes.",
14
- primaryIcon: "hugeicons:access",
15
- },
16
-
17
- source: {
18
- package: "@highstate/apps",
19
- path: "zitadel",
20
- },
21
- })
package/src/cloudflare.ts DELETED
@@ -1,26 +0,0 @@
1
- import { defineUnit, Type } from "@highstate/contract"
2
- import { providerEntity } from "./dns"
3
-
4
- export const connection = defineUnit({
5
- type: "cloudflare.connection",
6
-
7
- secrets: {
8
- apiToken: Type.String(),
9
- },
10
-
11
- outputs: {
12
- dnsProvider: providerEntity,
13
- },
14
-
15
- meta: {
16
- displayName: "Cloudflare Connection",
17
- description: "Creates a new Cloudflare connection for one zone.",
18
- primaryIcon: "simple-icons:cloudflare",
19
- category: "Cloudflare",
20
- },
21
-
22
- source: {
23
- package: "@highstate/cloudflare",
24
- path: "connection",
25
- },
26
- })
package/src/common.ts DELETED
@@ -1,200 +0,0 @@
1
- import { defineEntity, defineUnit, Type, type Static } from "@highstate/contract"
2
- import { credentialsSchema, keyPairEntity } from "./ssh"
3
- import { l3EndpointEntity } from "./network"
4
- import * as dns from "./dns"
5
- import { arrayPatchModeSchema } from "./utils"
6
-
7
- export const serverEntity = defineEntity({
8
- type: "common.server",
9
-
10
- schema: Type.Object({
11
- hostname: Type.String(),
12
- endpoints: Type.Array(l3EndpointEntity.schema),
13
- ssh: Type.Optional(credentialsSchema),
14
- }),
15
-
16
- meta: {
17
- color: "#009688",
18
- },
19
- })
20
-
21
- export const serverOutputs = {
22
- server: serverEntity,
23
- endpoints: {
24
- entity: l3EndpointEntity,
25
- multiple: true,
26
- },
27
- } as const
28
-
29
- export const existingServer = defineUnit({
30
- type: "common.existing-server",
31
-
32
- args: {
33
- /**
34
- * The endpoint of the server.
35
- *
36
- * Takes precedence over the `endpoint` input.
37
- */
38
- endpoint: Type.Optional(Type.String()),
39
-
40
- /**
41
- * The SSH user to use for connecting to the server.
42
- */
43
- sshUser: Type.Default(Type.String(), "root"),
44
-
45
- /**
46
- * The SSH port to use for connecting to the server.
47
- */
48
- sshPort: Type.Default(Type.Number(), 22),
49
- },
50
-
51
- secrets: {
52
- sshPassword: Type.Optional(Type.String()),
53
- sshPrivateKey: Type.Optional(Type.String()),
54
- },
55
-
56
- inputs: {
57
- sshKeyPair: {
58
- entity: keyPairEntity,
59
- required: false,
60
- },
61
- endpoint: {
62
- entity: l3EndpointEntity,
63
- required: false,
64
- },
65
- },
66
-
67
- outputs: serverOutputs,
68
-
69
- meta: {
70
- displayName: "Existing Server",
71
- description: "An existing server that can be used in the configuration.",
72
- primaryIcon: "mdi:server",
73
- defaultNamePrefix: "server",
74
- category: "Infrastructure",
75
- },
76
-
77
- source: {
78
- package: "@highstate/common",
79
- path: "units/existing-server",
80
- },
81
- })
82
-
83
- export const serverPatch = defineUnit({
84
- type: "common.server-patch",
85
-
86
- args: {
87
- /**
88
- * The endpoints of the server.
89
- *
90
- * The entry may represent real node endpoint or virtual endpoint (like a load balancer).
91
- *
92
- * The same server may also be represented by multiple entries (e.g. a node with private and public IP).
93
- */
94
- endpoints: Type.Default(Type.Array(Type.String()), []),
95
-
96
- /**
97
- * The mode to use for patching the endpoints.
98
- *
99
- * - `prepend`: prepend the new endpoints to the existing ones (default);
100
- * - `replace`: replace the existing endpoints with the new ones.
101
- */
102
- endpointsPatchMode: Type.Default(arrayPatchModeSchema, "prepend"),
103
- },
104
-
105
- inputs: {
106
- server: serverEntity,
107
- endpoints: {
108
- entity: l3EndpointEntity,
109
- required: false,
110
- multiple: true,
111
- },
112
- },
113
-
114
- outputs: {
115
- server: serverEntity,
116
- endpoints: {
117
- entity: l3EndpointEntity,
118
- multiple: true,
119
- },
120
- },
121
-
122
- meta: {
123
- displayName: "Server Patch",
124
- description: "Patches some properties of the server.",
125
- primaryIcon: "mdi:server",
126
- secondaryIcon: "fluent:patch-20-filled",
127
- category: "Infrastructure",
128
- },
129
-
130
- source: {
131
- package: "@highstate/common",
132
- path: "units/server-patch",
133
- },
134
- })
135
-
136
- export const serverDns = defineUnit({
137
- type: "common.server-dns",
138
-
139
- args: dns.createArgs(),
140
-
141
- inputs: {
142
- server: serverEntity,
143
- ...dns.inputs,
144
- },
145
-
146
- outputs: {
147
- server: serverEntity,
148
- endpoints: {
149
- entity: l3EndpointEntity,
150
- multiple: true,
151
- },
152
- },
153
-
154
- meta: {
155
- displayName: "Server DNS",
156
- description: "Creates DNS records for the server and updates endpoints.",
157
- primaryIcon: "mdi:server",
158
- secondaryIcon: "mdi:dns",
159
- category: "Infrastructure",
160
- },
161
-
162
- source: {
163
- package: "@highstate/common",
164
- path: "units/server-dns",
165
- },
166
- })
167
-
168
- export const script = defineUnit({
169
- type: "common.script",
170
-
171
- args: {
172
- script: Type.String({ language: "shell" }),
173
- updateScript: Type.Optional(Type.String({ language: "shell" })),
174
- deleteScript: Type.Optional(Type.String({ language: "shell" })),
175
- },
176
-
177
- inputs: {
178
- server: serverEntity,
179
- },
180
-
181
- outputs: {
182
- server: serverEntity,
183
- },
184
-
185
- meta: {
186
- displayName: "Shell Script",
187
- description: "Run a shell script on the server.",
188
- primaryIcon: "mdi:bash",
189
- category: "Infrastructure",
190
- },
191
-
192
- source: {
193
- package: "@highstate/common",
194
- path: "units/script",
195
- },
196
- })
197
-
198
- export type Server = Static<typeof serverEntity.schema>
199
-
200
- export * from "./files"