airfoil 0.4.4 → 0.4.6
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.
- package/README.md +24 -0
- package/dist/index.mjs +283 -0
- package/package.json +18 -15
- package/src/commands/catalog.ts +48 -0
- package/src/commands/namespace.ts +75 -0
- package/src/commands/table.ts +111 -0
- package/src/index.ts +12 -6
- package/src/utils/iceberg.ts +58 -0
- package/src/utils/json.ts +48 -0
- package/src/utils/logger.ts +67 -0
- package/src/utils/options.ts +17 -31
- package/dist/index.js +0 -855
- package/src/commands/cluster/index.ts +0 -25
- package/src/commands/cluster/namespace/create.ts +0 -314
- package/src/commands/cluster/namespace/delete.ts +0 -54
- package/src/commands/cluster/namespace/get.ts +0 -46
- package/src/commands/cluster/namespace/list.ts +0 -53
- package/src/commands/cluster/table/create.ts +0 -279
- package/src/commands/cluster/table/delete.ts +0 -54
- package/src/commands/cluster/table/get.ts +0 -62
- package/src/commands/cluster/table/list.ts +0 -61
- package/src/commands/dev.ts +0 -136
- package/src/commands/sql.ts +0 -90
- package/src/utils/client.ts +0 -6
- package/src/utils/docker.ts +0 -137
- package/src/utils/wings.ts +0 -124
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { Command } from "effect/unstable/cli";
|
|
3
|
-
|
|
4
|
-
import { createNamespaceCommand } from "./namespace/create";
|
|
5
|
-
import { deleteNamespaceCommand } from "./namespace/delete";
|
|
6
|
-
import { getNamespaceCommand } from "./namespace/get";
|
|
7
|
-
import { listNamespacesCommand } from "./namespace/list";
|
|
8
|
-
import { createTableCommand } from "./table/create";
|
|
9
|
-
import { deleteTableCommand } from "./table/delete";
|
|
10
|
-
import { getTableCommand } from "./table/get";
|
|
11
|
-
import { listTablesCommand } from "./table/list";
|
|
12
|
-
|
|
13
|
-
export const clusterCommand = Command.make("cluster", {}, () => Effect.void).pipe(
|
|
14
|
-
Command.withDescription("Manage Wings namespaces and tables"),
|
|
15
|
-
Command.withSubcommands([
|
|
16
|
-
createNamespaceCommand,
|
|
17
|
-
listNamespacesCommand,
|
|
18
|
-
getNamespaceCommand,
|
|
19
|
-
deleteNamespaceCommand,
|
|
20
|
-
createTableCommand,
|
|
21
|
-
listTablesCommand,
|
|
22
|
-
getTableCommand,
|
|
23
|
-
deleteTableCommand,
|
|
24
|
-
]),
|
|
25
|
-
);
|
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
import * as p from "@clack/prompts";
|
|
2
|
-
import { Cluster, ClusterClient } from "@useairfoil/wings";
|
|
3
|
-
import { printTable } from "console-table-printer";
|
|
4
|
-
import { Config, Effect, Option, Redacted } from "effect";
|
|
5
|
-
import { Command, Flag } from "effect/unstable/cli";
|
|
6
|
-
|
|
7
|
-
import { makeClusterClientLayer } from "../../../utils/client";
|
|
8
|
-
import { hostOption, portOption } from "../../../utils/options";
|
|
9
|
-
|
|
10
|
-
type LakeTag = Cluster.Lake.LakeApp["lakeConfig"]["_tag"];
|
|
11
|
-
|
|
12
|
-
const namespaceIdOption = Flag.string("namespace-id").pipe(
|
|
13
|
-
Flag.withDescription("Unique identifier for the namespace (e.g., 'production')"),
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
const lakeOption = Flag.string("lake").pipe(
|
|
17
|
-
Flag.withDescription("Lake format: iceberg, parquet, or delta"),
|
|
18
|
-
Flag.withDefault("iceberg" as LakeTag),
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
const prefixOption = Flag.string("prefix").pipe(
|
|
22
|
-
Flag.withDescription("Storage prefix (optional)"),
|
|
23
|
-
Flag.optional,
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
function makeLakeConfig(lake: string): Cluster.Lake.LakeApp {
|
|
27
|
-
switch (lake) {
|
|
28
|
-
case "iceberg":
|
|
29
|
-
return { lakeConfig: { _tag: "iceberg" as const, iceberg: {} } };
|
|
30
|
-
case "parquet":
|
|
31
|
-
return { lakeConfig: { _tag: "parquet" as const, parquet: {} } };
|
|
32
|
-
case "delta":
|
|
33
|
-
return { lakeConfig: { _tag: "delta" as const, delta: {} } };
|
|
34
|
-
default:
|
|
35
|
-
throw new Error(`Invalid lake type: "${lake}". Must be iceberg, parquet, or delta.`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function displayNamespace(namespace: Cluster.Namespace.Namespace) {
|
|
40
|
-
printTable([
|
|
41
|
-
{
|
|
42
|
-
name: namespace.name,
|
|
43
|
-
object_store: namespace.objectStore?.objectStoreConfig._tag ?? "-",
|
|
44
|
-
lake: namespace.lake?.lakeConfig._tag ?? "-",
|
|
45
|
-
},
|
|
46
|
-
]);
|
|
47
|
-
p.outro("✓ Done");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// ─── AWS ──────────────────────────────────────────────────────────────────────
|
|
51
|
-
|
|
52
|
-
const createNamespaceAwsCommand = Command.make(
|
|
53
|
-
"aws",
|
|
54
|
-
{
|
|
55
|
-
namespaceId: namespaceIdOption,
|
|
56
|
-
lake: lakeOption,
|
|
57
|
-
bucketName: Flag.string("bucket-name").pipe(Flag.withDescription("AWS S3 bucket name")),
|
|
58
|
-
prefix: prefixOption,
|
|
59
|
-
accessKeyId: Flag.redacted("access-key-id").pipe(
|
|
60
|
-
Flag.withDescription("AWS access key ID (or set AWS_ACCESS_KEY_ID env var)"),
|
|
61
|
-
Flag.withFallbackConfig(Config.redacted("AWS_ACCESS_KEY_ID")),
|
|
62
|
-
),
|
|
63
|
-
secretAccessKey: Flag.redacted("secret-access-key").pipe(
|
|
64
|
-
Flag.withDescription("AWS secret access key (or set AWS_SECRET_ACCESS_KEY env var)"),
|
|
65
|
-
Flag.withFallbackConfig(Config.redacted("AWS_SECRET_ACCESS_KEY")),
|
|
66
|
-
),
|
|
67
|
-
region: Flag.string("region").pipe(
|
|
68
|
-
Flag.withDescription("AWS region (e.g., us-east-1)"),
|
|
69
|
-
Flag.optional,
|
|
70
|
-
),
|
|
71
|
-
host: hostOption,
|
|
72
|
-
port: portOption,
|
|
73
|
-
},
|
|
74
|
-
({ namespaceId, lake, bucketName, prefix, accessKeyId, secretAccessKey, region }) =>
|
|
75
|
-
Effect.gen(function* () {
|
|
76
|
-
p.intro("📁 Create Namespace (AWS S3)");
|
|
77
|
-
|
|
78
|
-
const lakeConfig = yield* Effect.try({
|
|
79
|
-
try: () => makeLakeConfig(lake),
|
|
80
|
-
catch: (e) => (e instanceof Error ? e : new Error(String(e))),
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const s = p.spinner();
|
|
84
|
-
s.start("Creating namespace...");
|
|
85
|
-
|
|
86
|
-
const namespace = yield* ClusterClient.createNamespace({
|
|
87
|
-
namespaceId,
|
|
88
|
-
objectStore: {
|
|
89
|
-
objectStoreConfig: {
|
|
90
|
-
_tag: "aws",
|
|
91
|
-
aws: {
|
|
92
|
-
bucketName,
|
|
93
|
-
prefix: Option.getOrUndefined(prefix),
|
|
94
|
-
accessKeyId: Redacted.value(accessKeyId),
|
|
95
|
-
secretAccessKey: Redacted.value(secretAccessKey),
|
|
96
|
-
region: Option.getOrUndefined(region),
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
lake: lakeConfig,
|
|
101
|
-
}).pipe(Effect.tapError(() => Effect.sync(() => s.stop("Failed to create namespace"))));
|
|
102
|
-
|
|
103
|
-
s.stop("Namespace created successfully");
|
|
104
|
-
yield* Effect.sync(() => displayNamespace(namespace));
|
|
105
|
-
}),
|
|
106
|
-
).pipe(
|
|
107
|
-
Command.withDescription("Create a namespace backed by AWS S3"),
|
|
108
|
-
Command.provide(({ host, port }) => makeClusterClientLayer(host, port)),
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
// ─── Azure ────────────────────────────────────────────────────────────────────
|
|
112
|
-
|
|
113
|
-
const createNamespaceAzureCommand = Command.make(
|
|
114
|
-
"azure",
|
|
115
|
-
{
|
|
116
|
-
namespaceId: namespaceIdOption,
|
|
117
|
-
lake: lakeOption,
|
|
118
|
-
containerName: Flag.string("container-name").pipe(
|
|
119
|
-
Flag.withDescription("Azure Blob container name"),
|
|
120
|
-
),
|
|
121
|
-
prefix: prefixOption,
|
|
122
|
-
storageAccountName: Flag.string("storage-account-name").pipe(
|
|
123
|
-
Flag.withDescription("Azure storage account name"),
|
|
124
|
-
),
|
|
125
|
-
storageAccountKey: Flag.redacted("storage-account-key").pipe(
|
|
126
|
-
Flag.withDescription("Azure storage account key (or set AZURE_STORAGE_ACCOUNT_KEY env var)"),
|
|
127
|
-
Flag.withFallbackConfig(Config.redacted("AZURE_STORAGE_ACCOUNT_KEY")),
|
|
128
|
-
),
|
|
129
|
-
host: hostOption,
|
|
130
|
-
port: portOption,
|
|
131
|
-
},
|
|
132
|
-
({ namespaceId, lake, containerName, prefix, storageAccountName, storageAccountKey }) =>
|
|
133
|
-
Effect.gen(function* () {
|
|
134
|
-
p.intro("📁 Create Namespace (Azure Blob)");
|
|
135
|
-
|
|
136
|
-
const lakeConfig = yield* Effect.try({
|
|
137
|
-
try: () => makeLakeConfig(lake),
|
|
138
|
-
catch: (e) => (e instanceof Error ? e : new Error(String(e))),
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
const s = p.spinner();
|
|
142
|
-
s.start("Creating namespace...");
|
|
143
|
-
|
|
144
|
-
const namespace = yield* ClusterClient.createNamespace({
|
|
145
|
-
namespaceId,
|
|
146
|
-
objectStore: {
|
|
147
|
-
objectStoreConfig: {
|
|
148
|
-
_tag: "azure",
|
|
149
|
-
azure: {
|
|
150
|
-
containerName,
|
|
151
|
-
prefix: Option.getOrUndefined(prefix),
|
|
152
|
-
storageAccountName,
|
|
153
|
-
storageAccountKey: Redacted.value(storageAccountKey),
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
lake: lakeConfig,
|
|
158
|
-
}).pipe(Effect.tapError(() => Effect.sync(() => s.stop("Failed to create namespace"))));
|
|
159
|
-
|
|
160
|
-
s.stop("Namespace created successfully");
|
|
161
|
-
yield* Effect.sync(() => displayNamespace(namespace));
|
|
162
|
-
}),
|
|
163
|
-
).pipe(
|
|
164
|
-
Command.withDescription("Create a namespace backed by Azure Blob Storage"),
|
|
165
|
-
Command.provide(({ host, port }) => makeClusterClientLayer(host, port)),
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
// ─── Google ───────────────────────────────────────────────────────────────────
|
|
169
|
-
|
|
170
|
-
const createNamespaceGoogleCommand = Command.make(
|
|
171
|
-
"google",
|
|
172
|
-
{
|
|
173
|
-
namespaceId: namespaceIdOption,
|
|
174
|
-
lake: lakeOption,
|
|
175
|
-
bucketName: Flag.string("bucket-name").pipe(Flag.withDescription("GCS bucket name")),
|
|
176
|
-
prefix: prefixOption,
|
|
177
|
-
serviceAccount: Flag.string("service-account").pipe(
|
|
178
|
-
Flag.withDescription("GCP service account email"),
|
|
179
|
-
),
|
|
180
|
-
serviceAccountKey: Flag.redacted("service-account-key").pipe(
|
|
181
|
-
Flag.withDescription(
|
|
182
|
-
"GCP service account key JSON (or set GOOGLE_SERVICE_ACCOUNT_KEY env var)",
|
|
183
|
-
),
|
|
184
|
-
Flag.withFallbackConfig(Config.redacted("GOOGLE_SERVICE_ACCOUNT_KEY")),
|
|
185
|
-
),
|
|
186
|
-
host: hostOption,
|
|
187
|
-
port: portOption,
|
|
188
|
-
},
|
|
189
|
-
({ namespaceId, lake, bucketName, prefix, serviceAccount, serviceAccountKey }) =>
|
|
190
|
-
Effect.gen(function* () {
|
|
191
|
-
p.intro("📁 Create Namespace (Google Cloud Storage)");
|
|
192
|
-
|
|
193
|
-
const lakeConfig = yield* Effect.try({
|
|
194
|
-
try: () => makeLakeConfig(lake),
|
|
195
|
-
catch: (e) => (e instanceof Error ? e : new Error(String(e))),
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
const s = p.spinner();
|
|
199
|
-
s.start("Creating namespace...");
|
|
200
|
-
|
|
201
|
-
const namespace = yield* ClusterClient.createNamespace({
|
|
202
|
-
namespaceId,
|
|
203
|
-
objectStore: {
|
|
204
|
-
objectStoreConfig: {
|
|
205
|
-
_tag: "google",
|
|
206
|
-
google: {
|
|
207
|
-
bucketName,
|
|
208
|
-
prefix: Option.getOrUndefined(prefix),
|
|
209
|
-
serviceAccount,
|
|
210
|
-
serviceAccountKey: Redacted.value(serviceAccountKey),
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
lake: lakeConfig,
|
|
215
|
-
}).pipe(Effect.tapError(() => Effect.sync(() => s.stop("Failed to create namespace"))));
|
|
216
|
-
|
|
217
|
-
s.stop("Namespace created successfully");
|
|
218
|
-
yield* Effect.sync(() => displayNamespace(namespace));
|
|
219
|
-
}),
|
|
220
|
-
).pipe(
|
|
221
|
-
Command.withDescription("Create a namespace backed by Google Cloud Storage"),
|
|
222
|
-
Command.provide(({ host, port }) => makeClusterClientLayer(host, port)),
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
// ─── S3-Compatible ────────────────────────────────────────────────────────────
|
|
226
|
-
|
|
227
|
-
const createNamespaceS3Command = Command.make(
|
|
228
|
-
"s3",
|
|
229
|
-
{
|
|
230
|
-
namespaceId: namespaceIdOption,
|
|
231
|
-
lake: lakeOption,
|
|
232
|
-
bucketName: Flag.string("bucket-name").pipe(Flag.withDescription("S3-compatible bucket name")),
|
|
233
|
-
prefix: prefixOption,
|
|
234
|
-
accessKeyId: Flag.redacted("access-key-id").pipe(
|
|
235
|
-
Flag.withDescription("Access key ID (or set S3_ACCESS_KEY_ID env var)"),
|
|
236
|
-
Flag.withFallbackConfig(Config.redacted("S3_ACCESS_KEY_ID")),
|
|
237
|
-
),
|
|
238
|
-
secretAccessKey: Flag.redacted("secret-access-key").pipe(
|
|
239
|
-
Flag.withDescription("Secret access key (or set S3_SECRET_ACCESS_KEY env var)"),
|
|
240
|
-
Flag.withFallbackConfig(Config.redacted("S3_SECRET_ACCESS_KEY")),
|
|
241
|
-
),
|
|
242
|
-
endpoint: Flag.string("endpoint").pipe(
|
|
243
|
-
Flag.withDescription("S3-compatible endpoint URL (e.g., http://minio:9000)"),
|
|
244
|
-
),
|
|
245
|
-
allowHttp: Flag.boolean("allow-http").pipe(
|
|
246
|
-
Flag.withDescription("Allow plain HTTP connections"),
|
|
247
|
-
Flag.withDefault(false),
|
|
248
|
-
),
|
|
249
|
-
region: Flag.string("region").pipe(Flag.withDescription("Region"), Flag.optional),
|
|
250
|
-
host: hostOption,
|
|
251
|
-
port: portOption,
|
|
252
|
-
},
|
|
253
|
-
({
|
|
254
|
-
namespaceId,
|
|
255
|
-
lake,
|
|
256
|
-
bucketName,
|
|
257
|
-
prefix,
|
|
258
|
-
accessKeyId,
|
|
259
|
-
secretAccessKey,
|
|
260
|
-
endpoint,
|
|
261
|
-
allowHttp,
|
|
262
|
-
region,
|
|
263
|
-
}) =>
|
|
264
|
-
Effect.gen(function* () {
|
|
265
|
-
p.intro("📁 Create Namespace (S3-Compatible)");
|
|
266
|
-
|
|
267
|
-
const lakeConfig = yield* Effect.try({
|
|
268
|
-
try: () => makeLakeConfig(lake),
|
|
269
|
-
catch: (e) => (e instanceof Error ? e : new Error(String(e))),
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
const s = p.spinner();
|
|
273
|
-
s.start("Creating namespace...");
|
|
274
|
-
|
|
275
|
-
const namespace = yield* ClusterClient.createNamespace({
|
|
276
|
-
namespaceId,
|
|
277
|
-
objectStore: {
|
|
278
|
-
objectStoreConfig: {
|
|
279
|
-
_tag: "s3Compatible",
|
|
280
|
-
s3Compatible: {
|
|
281
|
-
bucketName,
|
|
282
|
-
prefix: Option.getOrUndefined(prefix),
|
|
283
|
-
accessKeyId: Redacted.value(accessKeyId),
|
|
284
|
-
secretAccessKey: Redacted.value(secretAccessKey),
|
|
285
|
-
endpoint,
|
|
286
|
-
allowHttp,
|
|
287
|
-
region: Option.getOrUndefined(region),
|
|
288
|
-
},
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
lake: lakeConfig,
|
|
292
|
-
}).pipe(Effect.tapError(() => Effect.sync(() => s.stop("Failed to create namespace"))));
|
|
293
|
-
|
|
294
|
-
s.stop("Namespace created successfully");
|
|
295
|
-
yield* Effect.sync(() => displayNamespace(namespace));
|
|
296
|
-
}),
|
|
297
|
-
).pipe(
|
|
298
|
-
Command.withDescription("Create a namespace backed by an S3-compatible object store"),
|
|
299
|
-
Command.provide(({ host, port }) => makeClusterClientLayer(host, port)),
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
// ─── Parent command ───────────────────────────────────────────────────────────
|
|
303
|
-
|
|
304
|
-
export const createNamespaceCommand = Command.make("create-namespace", {}, () => Effect.void).pipe(
|
|
305
|
-
Command.withDescription(
|
|
306
|
-
"Create a new namespace (choose a storage provider as subcommand: aws, azure, google, s3)",
|
|
307
|
-
),
|
|
308
|
-
Command.withSubcommands([
|
|
309
|
-
createNamespaceAwsCommand,
|
|
310
|
-
createNamespaceAzureCommand,
|
|
311
|
-
createNamespaceGoogleCommand,
|
|
312
|
-
createNamespaceS3Command,
|
|
313
|
-
]),
|
|
314
|
-
);
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import * as p from "@clack/prompts";
|
|
2
|
-
import { ClusterClient } from "@useairfoil/wings";
|
|
3
|
-
import { Effect } from "effect";
|
|
4
|
-
import { Command, Flag } from "effect/unstable/cli";
|
|
5
|
-
|
|
6
|
-
import { makeClusterClientLayer } from "../../../utils/client";
|
|
7
|
-
import { forceOption, hostOption, portOption } from "../../../utils/options";
|
|
8
|
-
|
|
9
|
-
const nameOption = Flag.string("name").pipe(
|
|
10
|
-
Flag.withDescription("Namespace name in format: namespaces/{namespace}"),
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
export const deleteNamespaceCommand = Command.make(
|
|
14
|
-
"delete-namespace",
|
|
15
|
-
{
|
|
16
|
-
name: nameOption,
|
|
17
|
-
force: forceOption,
|
|
18
|
-
host: hostOption,
|
|
19
|
-
port: portOption,
|
|
20
|
-
},
|
|
21
|
-
({ name, force }) =>
|
|
22
|
-
Effect.gen(function* () {
|
|
23
|
-
p.intro("🗑️ Delete Namespace");
|
|
24
|
-
|
|
25
|
-
if (!force) {
|
|
26
|
-
const confirm = yield* Effect.tryPromise({
|
|
27
|
-
try: () =>
|
|
28
|
-
p.confirm({
|
|
29
|
-
message: `Are you sure you want to delete namespace ${name}?`,
|
|
30
|
-
initialValue: false,
|
|
31
|
-
}),
|
|
32
|
-
catch: () => new Error("Failed to confirm deletion"),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
if (p.isCancel(confirm) || !confirm) {
|
|
36
|
-
p.cancel("Deletion cancelled");
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const s = p.spinner();
|
|
42
|
-
s.start("Deleting namespace...");
|
|
43
|
-
|
|
44
|
-
yield* ClusterClient.deleteNamespace({ name }).pipe(
|
|
45
|
-
Effect.tapError(() => Effect.sync(() => s.stop("Failed to delete namespace"))),
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
s.stop("Namespace deleted successfully");
|
|
49
|
-
p.outro("✓ Done");
|
|
50
|
-
}),
|
|
51
|
-
).pipe(
|
|
52
|
-
Command.withDescription("Delete a namespace from the cluster"),
|
|
53
|
-
Command.provide(({ host, port }) => makeClusterClientLayer(host, port)),
|
|
54
|
-
);
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import * as p from "@clack/prompts";
|
|
2
|
-
import { ClusterClient } from "@useairfoil/wings";
|
|
3
|
-
import { printTable } from "console-table-printer";
|
|
4
|
-
import { Effect } from "effect";
|
|
5
|
-
import { Command, Flag } from "effect/unstable/cli";
|
|
6
|
-
|
|
7
|
-
import { makeClusterClientLayer } from "../../../utils/client";
|
|
8
|
-
import { hostOption, portOption } from "../../../utils/options";
|
|
9
|
-
|
|
10
|
-
const nameOption = Flag.string("name").pipe(
|
|
11
|
-
Flag.withDescription("Namespace name in format: namespaces/{namespace}"),
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
export const getNamespaceCommand = Command.make(
|
|
15
|
-
"get-namespace",
|
|
16
|
-
{
|
|
17
|
-
name: nameOption,
|
|
18
|
-
host: hostOption,
|
|
19
|
-
port: portOption,
|
|
20
|
-
},
|
|
21
|
-
({ name }) =>
|
|
22
|
-
Effect.gen(function* () {
|
|
23
|
-
const s = p.spinner();
|
|
24
|
-
s.start("Fetching namespace...");
|
|
25
|
-
|
|
26
|
-
const namespace = yield* ClusterClient.getNamespace({ name }).pipe(
|
|
27
|
-
Effect.tapError(() => Effect.sync(() => s.stop("Failed to get namespace"))),
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
s.stop("Namespace retrieved");
|
|
31
|
-
|
|
32
|
-
yield* Effect.sync(() => {
|
|
33
|
-
printTable([
|
|
34
|
-
{
|
|
35
|
-
name: namespace.name,
|
|
36
|
-
object_store: namespace.objectStore?.objectStoreConfig._tag ?? "-",
|
|
37
|
-
lake: namespace.lake?.lakeConfig._tag ?? "-",
|
|
38
|
-
},
|
|
39
|
-
]);
|
|
40
|
-
p.outro("✓ Done");
|
|
41
|
-
});
|
|
42
|
-
}),
|
|
43
|
-
).pipe(
|
|
44
|
-
Command.withDescription("Get details of a specific namespace"),
|
|
45
|
-
Command.provide(({ host, port }) => makeClusterClientLayer(host, port)),
|
|
46
|
-
);
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import * as p from "@clack/prompts";
|
|
2
|
-
import { ClusterClient } from "@useairfoil/wings";
|
|
3
|
-
import { printTable } from "console-table-printer";
|
|
4
|
-
import { Effect, Option } from "effect";
|
|
5
|
-
import { Command } from "effect/unstable/cli";
|
|
6
|
-
|
|
7
|
-
import { makeClusterClientLayer } from "../../../utils/client";
|
|
8
|
-
import { hostOption, pageSizeOption, pageTokenOption, portOption } from "../../../utils/options";
|
|
9
|
-
|
|
10
|
-
export const listNamespacesCommand = Command.make(
|
|
11
|
-
"list-namespaces",
|
|
12
|
-
{
|
|
13
|
-
pageSize: pageSizeOption,
|
|
14
|
-
pageToken: pageTokenOption,
|
|
15
|
-
host: hostOption,
|
|
16
|
-
port: portOption,
|
|
17
|
-
},
|
|
18
|
-
({ pageSize, pageToken }) =>
|
|
19
|
-
Effect.gen(function* () {
|
|
20
|
-
const s = p.spinner();
|
|
21
|
-
s.start("Fetching namespaces...");
|
|
22
|
-
|
|
23
|
-
const response = yield* ClusterClient.listNamespaces({
|
|
24
|
-
pageSize,
|
|
25
|
-
pageToken: Option.getOrUndefined(pageToken),
|
|
26
|
-
}).pipe(Effect.tapError(() => Effect.sync(() => s.stop("Failed to list namespaces"))));
|
|
27
|
-
|
|
28
|
-
s.stop(`Found ${response.namespaces.length} namespace(s)`);
|
|
29
|
-
|
|
30
|
-
yield* Effect.sync(() => {
|
|
31
|
-
if (response.namespaces.length === 0) {
|
|
32
|
-
p.log.warn("No namespaces found");
|
|
33
|
-
} else {
|
|
34
|
-
printTable(
|
|
35
|
-
response.namespaces.map((namespace) => ({
|
|
36
|
-
name: namespace.name,
|
|
37
|
-
object_store: namespace.objectStore?.objectStoreConfig._tag ?? "-",
|
|
38
|
-
lake: namespace.lake?.lakeConfig._tag ?? "-",
|
|
39
|
-
})),
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (response.nextPageToken) {
|
|
44
|
-
p.log.info(`Next page token: ${response.nextPageToken}`);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
p.outro("✓ Done");
|
|
48
|
-
});
|
|
49
|
-
}),
|
|
50
|
-
).pipe(
|
|
51
|
-
Command.withDescription("List all namespaces in the cluster"),
|
|
52
|
-
Command.provide(({ host, port }) => makeClusterClientLayer(host, port)),
|
|
53
|
-
);
|