@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
@@ -1,22 +1,64 @@
1
- import { defineEntity, defineUnit, z } from "@highstate/contract"
2
- import { l4EndpointEntity } from "../network"
3
- import { toPatchArgs } from "../utils"
4
- import { optionalSharedArgs, sharedArgs, sharedInputs, sharedSchema, sharedSecrets } from "./shared"
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"
11
+
12
+ export const credentialsSchema = z.discriminatedUnion("type", [
13
+ z.object({
14
+ type: z.literal("password"),
15
+
16
+ /**
17
+ * The username used to authenticate against the database.
18
+ */
19
+ username: z.string(),
20
+
21
+ /**
22
+ * The password used to authenticate against the database.
23
+ */
24
+ password: secretSchema(z.string()),
25
+ }),
26
+ ])
5
27
 
6
28
  /**
7
- * Represents the PostgreSQL database or virtual database behind it.
29
+ * Represents a connection to a PostgreSQL instance, including the endpoints and credentials.
8
30
  */
9
- export const postgresqlEntity = defineEntity({
10
- type: "databases.postgresql.v1",
31
+ export const connectionEntity = defineEntity({
32
+ type: "postgresql.connection.v1",
33
+
34
+ extends: { l4EndpointContainer },
11
35
 
12
36
  includes: {
13
- endpoints: {
14
- entity: l4EndpointEntity,
15
- multiple: true,
37
+ /**
38
+ * The TLS certificate of the server if any.
39
+ */
40
+ certificate: {
41
+ entity: certificateEntity,
42
+ required: false,
16
43
  },
17
44
  },
18
45
 
19
- schema: sharedSchema,
46
+ schema: z.object({
47
+ /**
48
+ * Whether SSL is not required to connect to the database.
49
+ */
50
+ insecure: z.boolean().default(false),
51
+
52
+ /**
53
+ * The credentials for authenticating to the PostgreSQL instance.
54
+ */
55
+ credentials: credentialsSchema,
56
+
57
+ /**
58
+ * The name of the database to operate on.
59
+ */
60
+ database: z.string().optional(),
61
+ }),
20
62
 
21
63
  meta: {
22
64
  color: "#336791",
@@ -24,26 +66,52 @@ export const postgresqlEntity = defineEntity({
24
66
  })
25
67
 
26
68
  /**
27
- * The existing PostgreSQL database or virtual database behind it.
69
+ * The existing PostgreSQL connection hosted on a server or a managed service.
28
70
  */
29
- export const existingPostgresql = defineUnit({
30
- type: "databases.postgresql.existing.v1",
71
+ export const connection = defineUnit({
72
+ type: "postgresql.connection.v1",
73
+
74
+ args: {
75
+ /**
76
+ * The username to authenticate with.
77
+ */
78
+ username: z.string(),
79
+
80
+ /**
81
+ * The endpoints to connect to the PostgreSQL instance in form of `host:port`.
82
+ */
83
+ endpoints: z.string().array().default([]),
84
+ },
85
+
86
+ inputs: {
87
+ /**
88
+ * The endpoints to connect to the PostgreSQL instance.
89
+ */
90
+ endpoints: {
91
+ entity: l4EndpointEntity,
92
+ multiple: true,
93
+ required: false,
94
+ },
95
+ },
31
96
 
32
- args: sharedArgs,
33
- secrets: sharedSecrets,
34
- inputs: sharedInputs,
97
+ secrets: {
98
+ /**
99
+ * The password to authenticate with.
100
+ */
101
+ password: z.string(),
102
+ },
35
103
 
36
104
  outputs: {
37
- postgresql: postgresqlEntity,
105
+ connection: connectionEntity,
38
106
  },
39
107
 
40
108
  source: {
41
- package: "@highstate/common",
42
- path: "units/databases/existing-postgresql",
109
+ package: "@highstate/postgresql",
110
+ path: "units/connection",
43
111
  },
44
112
 
45
113
  meta: {
46
- title: "Existing PostgreSQL Database",
114
+ title: "PostgreSQL Connection",
47
115
  icon: "simple-icons:postgresql",
48
116
  secondaryIcon: "mdi:database",
49
117
  category: "Databases",
@@ -51,43 +119,69 @@ export const existingPostgresql = defineUnit({
51
119
  })
52
120
 
53
121
  /**
54
- * Patches some properties of the PostgreSQL database and outputs the updated database.
122
+ * Creates a database in a PostgreSQL instance.
55
123
  */
56
- export const postgresqlPatch = defineUnit({
57
- type: "databases.postgresql-patch.v1",
124
+ export const database = defineUnit({
125
+ type: "postgresql.database.v1",
58
126
 
59
127
  args: {
60
- ...toPatchArgs(optionalSharedArgs),
128
+ /**
129
+ * The name of the database.
130
+ *
131
+ * If not provided, it will be set to the unit name.
132
+ */
133
+ databaseName: z.string().optional(),
61
134
 
62
135
  /**
63
- * The endpoints to connect to the database in form of `host:port`.
136
+ * The username to create.
64
137
  *
65
- * If at least one endpoint is provided (either via args or inputs), the existing endpoints
66
- * will be replaced completely.
138
+ * If not provided, it will be set to the database name.
67
139
  */
68
- endpoints: z.string().array().default([]),
140
+ username: z.string().optional(),
141
+
142
+ /**
143
+ * The LC_COLLATE setting for the database, which determines the collation order (i.e., how string comparison is performed).
144
+ */
145
+ lcCollate: z.string().optional(),
146
+
147
+ /**
148
+ * The LC_CTYPE setting for the database, which determines the character classification (i.e., how characters are categorized and compared).
149
+ */
150
+ lcCtype: z.string().optional(),
69
151
  },
70
152
 
71
153
  inputs: {
72
- postgresql: postgresqlEntity,
73
- ...sharedInputs,
154
+ /**
155
+ * The connection to the PostgreSQL instance where the database should be created.
156
+ */
157
+ connection: connectionEntity,
74
158
  },
75
159
 
76
- outputs: {
77
- postgresql: postgresqlEntity,
160
+ secrets: {
161
+ /**
162
+ * The password of the created user.
163
+ *
164
+ * If not provided, a random password will be generated.
165
+ */
166
+ password: z.string().optional(),
78
167
  },
79
168
 
80
- source: {
81
- package: "@highstate/common",
82
- path: "units/databases/postgresql-patch",
169
+ outputs: {
170
+ connection: connectionEntity,
83
171
  },
84
172
 
85
173
  meta: {
86
- title: "PostgreSQL Patch",
174
+ title: "PostgreSQL Database",
87
175
  icon: "simple-icons:postgresql",
88
- secondaryIcon: "fluent:patch-20-filled",
176
+ secondaryIcon: "mdi:database-plus",
89
177
  category: "Databases",
90
178
  },
179
+
180
+ source: {
181
+ package: "@highstate/postgresql",
182
+ path: "units/database",
183
+ },
91
184
  })
92
185
 
93
- export type PostgreSQL = z.infer<typeof postgresqlEntity.schema>
186
+ export type Connection = EntityValue<typeof connectionEntity>
187
+ export type ConnectionInput = EntityInput<typeof connectionEntity>
@@ -1,26 +1,40 @@
1
- import { defineEntity, defineUnit, z } from "@highstate/contract"
2
- import { l4EndpointEntity } from "../network"
3
- import { toPatchArgs } from "../utils"
4
- import { optionalSharedArgs, sharedArgs, sharedInputs } from "./shared"
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
+
11
+ export const credentialsSchema = z.object({
12
+ /**
13
+ * The username used to authenticate against the database.
14
+ */
15
+ username: z.string().optional(),
16
+
17
+ /**
18
+ * The password used to authenticate against the database.
19
+ */
20
+ password: secretSchema(z.string()).optional(),
21
+ })
22
+
23
+ export const databaseNumberSchema = z.number().nonnegative().max(15)
5
24
 
6
25
  /**
7
- * Represents the Redis database or virtual database behind it.
26
+ * Represents a connection to a Redis instance, including the endpoints and credentials.
8
27
  */
9
- export const redisEntity = defineEntity({
10
- type: "databases.redis.v1",
28
+ export const connectionEntity = defineEntity({
29
+ type: "redis.connection.v1",
11
30
 
12
- includes: {
13
- endpoints: {
14
- entity: l4EndpointEntity,
15
- multiple: true,
16
- },
17
- },
31
+ extends: { l4EndpointContainer },
18
32
 
19
33
  schema: z.object({
20
34
  /**
21
- * The number of the database to use.
35
+ * The credentials for authenticating to the Redis instance.
22
36
  */
23
- database: z.number().default(0),
37
+ credentials: credentialsSchema.optional(),
24
38
  }),
25
39
 
26
40
  meta: {
@@ -29,25 +43,52 @@ export const redisEntity = defineEntity({
29
43
  })
30
44
 
31
45
  /**
32
- * The existing Redis database or virtual database behind it.
46
+ * The existing Redis connection hosted on a server or a managed service.
33
47
  */
34
- export const existingRedis = defineUnit({
35
- type: "databases.redis.existing.v1",
48
+ export const connection = defineUnit({
49
+ type: "redis.connection.existing.v1",
36
50
 
37
- args: sharedArgs,
38
- inputs: sharedInputs,
51
+ args: {
52
+ /**
53
+ * The username to authenticate with.
54
+ */
55
+ username: z.string().optional(),
56
+
57
+ /**
58
+ * The endpoints to connect to the database in form of `host:port`.
59
+ */
60
+ endpoints: z.string().array().default([]),
61
+ },
62
+
63
+ inputs: {
64
+ /**
65
+ * The endpoints to connect to the database.
66
+ */
67
+ endpoints: {
68
+ entity: l4EndpointEntity,
69
+ multiple: true,
70
+ required: false,
71
+ },
72
+ },
73
+
74
+ secrets: {
75
+ /**
76
+ * The password to authenticate with.
77
+ */
78
+ password: z.string().optional(),
79
+ },
39
80
 
40
81
  outputs: {
41
- redis: redisEntity,
82
+ connection: connectionEntity,
42
83
  },
43
84
 
44
85
  source: {
45
- package: "@highstate/common",
46
- path: "units/databases/existing-redis",
86
+ package: "@highstate/redis",
87
+ path: "units/connection",
47
88
  },
48
89
 
49
90
  meta: {
50
- title: "Existing Redis Database",
91
+ title: "Redis Connection",
51
92
  icon: "simple-icons:redis",
52
93
  secondaryIcon: "mdi:database",
53
94
  category: "Databases",
@@ -55,40 +96,74 @@ export const existingRedis = defineUnit({
55
96
  })
56
97
 
57
98
  /**
58
- * Patches some properties of the Redis database and outputs the updated database.
99
+ * Represents a Redis namespace within a database.
100
+ */
101
+ export const namespaceEntity = defineEntity({
102
+ type: "redis.namespace.v1",
103
+
104
+ extends: { connectionEntity },
105
+
106
+ schema: z.object({
107
+ /**
108
+ * The number of the database to use.
109
+ */
110
+ database: databaseNumberSchema.default(0),
111
+
112
+ /**
113
+ * The prefix of the namespace in the Redis database.
114
+ */
115
+ prefix: z.string().optional(),
116
+ }),
117
+
118
+ meta: {
119
+ color: "#0064bf",
120
+ },
121
+ })
122
+
123
+ /**
124
+ * Creates a Redis namespace within an existing Redis connection.
59
125
  */
60
- export const redisPatch = defineUnit({
61
- type: "databases.redis-patch.v1",
126
+ export const namespace = defineUnit({
127
+ type: "redis.database.v1",
62
128
 
63
129
  args: {
64
- ...toPatchArgs(optionalSharedArgs),
130
+ /**
131
+ * The number of the database to use.
132
+ */
133
+ database: databaseNumberSchema.default(0),
65
134
 
66
- endpoints: {
67
- ...sharedArgs.endpoints,
68
- schema: z.string().array().default([]),
69
- },
135
+ /**
136
+ * The prefix of the namespace in the Redis database.
137
+ */
138
+ prefix: z.string().optional(),
70
139
  },
71
140
 
72
141
  inputs: {
73
- redis: redisEntity,
74
- ...sharedInputs,
142
+ /**
143
+ * The connection to the Redis instance.
144
+ */
145
+ connection: connectionEntity,
75
146
  },
76
147
 
77
148
  outputs: {
78
- redis: redisEntity,
79
- },
80
-
81
- source: {
82
- package: "@highstate/common",
83
- path: "units/databases/redis-patch",
149
+ namespace: namespaceEntity,
84
150
  },
85
151
 
86
152
  meta: {
87
- title: "Redis Patch",
153
+ title: "Redis Database",
88
154
  icon: "simple-icons:redis",
89
- secondaryIcon: "fluent:patch-20-filled",
155
+ secondaryIcon: "mdi:database",
90
156
  category: "Databases",
91
157
  },
158
+
159
+ source: {
160
+ package: "@highstate/redis",
161
+ path: "units/database",
162
+ },
92
163
  })
93
164
 
94
- export type Redis = z.infer<typeof redisEntity.schema>
165
+ export type Connection = EntityValue<typeof connectionEntity>
166
+ export type ConnectionInput = EntityInput<typeof connectionEntity>
167
+
168
+ export type Namespace = EntityValue<typeof namespaceEntity>
169
+ export type NamespaceInput = EntityInput<typeof namespaceEntity>
@@ -1,113 +1,48 @@
1
- import type { Simplify } from "type-fest"
2
1
  import {
3
- $args,
4
- $inputs,
5
- $secrets,
6
2
  defineEntity,
7
3
  defineUnit,
8
- type FullComponentArgumentOptions,
4
+ type EntityInput,
5
+ type EntityValue,
6
+ secretSchema,
9
7
  z,
10
8
  } from "@highstate/contract"
11
- import { mapValues } from "remeda"
12
- import { l4EndpointEntity } from "../network"
13
- import { toPatchArgs } from "../utils"
9
+ import { l4EndpointEntity, l7EndpointContainer } from "../network"
14
10
 
15
- export const s3BucketPolicySchema = z.enum(["none", "download", "upload", "public"])
16
-
17
- export const s3BucketSchema = z.object({
18
- /**
19
- * The name of the bucket.
20
- */
21
- name: z.string(),
22
-
23
- /**
24
- * The optional policy applied to the bucket.
25
- */
26
- policy: s3BucketPolicySchema.optional(),
27
- })
28
-
29
- const s3Args = $args({
11
+ export const credentialsSchema = z.object({
30
12
  /**
31
- * The endpoints to connect to the S3-compatible API in form of `host:port`.
13
+ * The access key used to authenticate against the API.
32
14
  */
33
- endpoints: z.string().array().min(1),
15
+ accessKey: secretSchema(z.string()),
34
16
 
35
17
  /**
36
- * The access key used to authenticate against the S3-compatible API.
18
+ * The secret key used to authenticate against the API.
37
19
  */
38
- accessKey: z.string(),
39
-
40
- /**
41
- * The region associated with the S3-compatible deployment.
42
- */
43
- region: z.string().optional(),
44
-
45
- /**
46
- * The buckets that must exist on the instance.
47
- */
48
- buckets: s3BucketSchema.array().default([]),
49
- })
50
-
51
- type ToOptionalArgs<T extends Record<string, FullComponentArgumentOptions>> = Simplify<{
52
- [K in keyof T]: Simplify<Omit<T[K], "schema"> & { schema: z.ZodOptional<T[K]["schema"]> }>
53
- }>
54
-
55
- const optionalS3Args = mapValues(s3Args, arg => ({
56
- ...arg,
57
- schema: arg.schema.optional(),
58
- })) as ToOptionalArgs<typeof s3Args>
59
-
60
- const s3Secrets = $secrets({
61
- /**
62
- * The secret key used to authenticate against the S3-compatible API.
63
- */
64
- secretKey: z.string(),
65
- })
66
-
67
- const s3Inputs = $inputs({
68
- /**
69
- * The endpoints to connect to the S3-compatible API.
70
- */
71
- endpoints: {
72
- entity: l4EndpointEntity,
73
- multiple: true,
74
- required: false,
75
- },
20
+ secretKey: secretSchema(z.string()),
76
21
  })
77
22
 
78
23
  /**
79
- * Represents an S3-compatible object storage endpoint.
24
+ * Represents an S3 bucket with credentials and endpoints to access it.
80
25
  */
81
- export const s3Entity = defineEntity({
82
- type: "databases.s3.v1",
26
+ export const bucketEntity = defineEntity({
27
+ type: "s3.bucket.v1",
83
28
 
84
- includes: {
85
- endpoints: {
86
- entity: l4EndpointEntity,
87
- multiple: true,
88
- },
89
- },
29
+ extends: { l7EndpointContainer },
90
30
 
91
31
  schema: z.object({
92
32
  /**
93
- * The region associated with the object storage instance.
94
- */
95
- region: z.string().optional(),
96
-
97
- /**
98
- * The access key used to authenticate against the API.
33
+ * The name of the S3 bucket.
99
34
  */
100
- accessKey: z.string(),
35
+ name: z.string(),
101
36
 
102
37
  /**
103
- * The secret key used to authenticate against the API.
38
+ * The region where the S3 bucket is located.
104
39
  */
105
- secretKey: z.string(),
40
+ region: z.string(),
106
41
 
107
42
  /**
108
- * The buckets that must exist on the instance.
43
+ * The credentials that can be used to access the S3 bucket.
109
44
  */
110
- buckets: s3BucketSchema.array(),
45
+ credentials: credentialsSchema,
111
46
  }),
112
47
 
113
48
  meta: {
@@ -116,67 +51,55 @@ export const s3Entity = defineEntity({
116
51
  })
117
52
 
118
53
  /**
119
- * The existing S3-compatible object storage instance.
54
+ * The existing S3 bucket hosted on AWS or another S3-compatible service.
120
55
  */
121
- export const existingS3 = defineUnit({
122
- type: "databases.s3.existing.v1",
56
+ export const existingBucket = defineUnit({
57
+ type: "s3.existing-bucket.v1",
123
58
 
124
- args: s3Args,
125
- secrets: s3Secrets,
126
- inputs: s3Inputs,
127
-
128
- outputs: {
129
- s3: s3Entity,
130
- },
59
+ args: {
60
+ /**
61
+ * The name of the existing S3 bucket.
62
+ */
63
+ bucketName: z.string(),
131
64
 
132
- source: {
133
- package: "@highstate/common",
134
- path: "units/databases/existing-s3",
135
- },
65
+ /**
66
+ * The region where the existing S3 bucket is located.
67
+ */
68
+ region: z.string(),
136
69
 
137
- meta: {
138
- title: "Existing S3-Compatible Storage",
139
- icon: "simple-icons:amazons3",
140
- secondaryIcon: "mdi:bucket",
141
- category: "Databases",
70
+ /**
71
+ * The endpoints to connect to the S3 bucket.
72
+ */
73
+ endpoints: z.string().array().default([]),
142
74
  },
143
- })
144
-
145
- /**
146
- * Patches some properties of the S3-compatible object storage and outputs the updated storage.
147
- */
148
- export const s3Patch = defineUnit({
149
- type: "databases.s3-patch.v1",
150
-
151
- args: {
152
- ...toPatchArgs(optionalS3Args),
153
75
 
76
+ inputs: {
77
+ /**
78
+ * The endpoints to connect to the S3 bucket.
79
+ */
154
80
  endpoints: {
155
- ...s3Args.endpoints,
156
- schema: z.string().array().default([]),
81
+ entity: l4EndpointEntity,
82
+ multiple: true,
83
+ required: false,
157
84
  },
158
85
  },
159
86
 
160
- inputs: {
161
- s3: s3Entity,
162
- ...s3Inputs,
163
- },
164
-
165
87
  outputs: {
166
- s3: s3Entity,
88
+ bucket: bucketEntity,
167
89
  },
168
90
 
169
91
  source: {
170
92
  package: "@highstate/common",
171
- path: "units/databases/s3-patch",
93
+ path: "units/databases/existing-s3-bucket",
172
94
  },
173
95
 
174
96
  meta: {
175
- title: "S3 Patch",
176
- icon: "simple-icons:amazons3",
177
- secondaryIcon: "fluent:patch-20-filled",
97
+ title: "Existing S3 Bucket",
98
+ icon: "simple-icons:amazonaws",
99
+ secondaryIcon: "mdi:database",
178
100
  category: "Databases",
179
101
  },
180
102
  })
181
103
 
182
- export type S3 = z.infer<typeof s3Entity.schema>
104
+ export type Bucket = EntityValue<typeof bucketEntity>
105
+ export type BucketInput = EntityInput<typeof bucketEntity>