airfoil 0.2.0 → 0.4.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 (37) hide show
  1. package/dist/index.js +1181 -104238
  2. package/package.json +19 -24
  3. package/src/commands/cluster/data-lake/create-iceberg.ts +8 -10
  4. package/src/commands/cluster/data-lake/create-parquet.ts +8 -10
  5. package/src/commands/cluster/data-lake/create.ts +4 -10
  6. package/src/commands/cluster/data-lake/delete.ts +6 -10
  7. package/src/commands/cluster/data-lake/get.ts +7 -13
  8. package/src/commands/cluster/data-lake/list.ts +8 -18
  9. package/src/commands/cluster/index.ts +3 -6
  10. package/src/commands/cluster/namespace/create.ts +18 -28
  11. package/src/commands/cluster/namespace/delete.ts +6 -10
  12. package/src/commands/cluster/namespace/get.ts +6 -10
  13. package/src/commands/cluster/namespace/list.ts +7 -16
  14. package/src/commands/cluster/object-store/create-aws.ts +20 -24
  15. package/src/commands/cluster/object-store/create-azure.ts +17 -21
  16. package/src/commands/cluster/object-store/create-google.ts +19 -34
  17. package/src/commands/cluster/object-store/create-s3.ts +22 -34
  18. package/src/commands/cluster/object-store/create.ts +2 -1
  19. package/src/commands/cluster/object-store/delete.ts +6 -8
  20. package/src/commands/cluster/object-store/get.ts +6 -8
  21. package/src/commands/cluster/object-store/list.ts +8 -18
  22. package/src/commands/cluster/tenant/create.ts +6 -10
  23. package/src/commands/cluster/tenant/delete.ts +10 -16
  24. package/src/commands/cluster/tenant/get.ts +6 -10
  25. package/src/commands/cluster/tenant/list.ts +5 -12
  26. package/src/commands/cluster/topic/create.ts +43 -66
  27. package/src/commands/cluster/topic/delete.ts +9 -11
  28. package/src/commands/cluster/topic/get.ts +5 -5
  29. package/src/commands/cluster/topic/list.ts +7 -16
  30. package/src/commands/dev.ts +89 -192
  31. package/src/commands/sql.ts +38 -59
  32. package/src/index.ts +18 -9
  33. package/src/utils/docker.ts +43 -0
  34. package/src/utils/options.ts +16 -17
  35. package/src/utils/wings.ts +68 -64
  36. package/src/scripts/compile-all.ts +0 -21
  37. package/src/utils/effect.ts +0 -11
package/package.json CHANGED
@@ -1,41 +1,36 @@
1
1
  {
2
2
  "name": "airfoil",
3
- "version": "0.2.0",
4
- "module": "index.ts",
5
- "type": "module",
3
+ "version": "0.4.0",
4
+ "repository": "useairfoil/typescript-sdk",
5
+ "bin": {
6
+ "airfoil": "./dist/index.js"
7
+ },
6
8
  "files": [
7
9
  "dist",
8
10
  "src",
9
11
  "README.md"
10
12
  ],
11
- "bin": {
12
- "airfoil": "./dist/index.js"
13
- },
13
+ "type": "module",
14
+ "module": "index.ts",
14
15
  "scripts": {
16
+ "build": "tsdown",
15
17
  "typecheck": "tsc --noEmit",
16
- "lint": "biome check .",
17
- "lint:fix": "pnpm lint --write",
18
- "format": "biome format --write .",
19
- "airfoil:dev": "bun run src/index.ts",
20
- "build": "bun build src/index.ts --outdir dist --target node",
21
- "compile": "bun build src/index.ts --compile --outfile airfoil",
22
- "compile:all": "bun run src/scripts/compile-all.ts"
23
- },
24
- "devDependencies": {
25
- "@types/bun": "^1.3.5"
26
- },
27
- "peerDependencies": {
28
- "typescript": "^5"
18
+ "dev": "tsx src/index.ts"
29
19
  },
30
20
  "dependencies": {
31
- "@useairfoil/flight": "0.2.0",
32
- "@useairfoil/wings": "0.2.0",
33
21
  "@clack/prompts": "^0.11.0",
34
- "@effect/cli": "^0.73.1",
35
- "@effect/platform-node": "^0.104.1",
22
+ "@effect/platform-node": "4.0.0-beta.54",
23
+ "@useairfoil/flight": "0.4.0",
24
+ "@useairfoil/wings": "0.4.0",
36
25
  "console-table-printer": "^2.15.0",
37
- "effect": "^3.19.15",
26
+ "effect": "4.0.0-beta.54",
38
27
  "nice-grpc": "^2.1.13",
39
28
  "nice-grpc-common": "^2.0.2"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^24.2.0",
32
+ "tsdown": "^0.15.6",
33
+ "tsx": "^4.21.0",
34
+ "typescript": "^5.9.3"
40
35
  }
41
36
  }
@@ -1,18 +1,18 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
8
  import { hostOption, portOption } from "../../../utils/options.js";
9
9
 
10
- const parentOption = Options.text("parent").pipe(
11
- Options.withDescription("Parent tenant in format: tenants/{tenant}"),
10
+ const parentOption = Flag.string("parent").pipe(
11
+ Flag.withDescription("Parent tenant in format: tenants/{tenant}"),
12
12
  );
13
13
 
14
- const dataLakeIdOption = Options.text("data-lake-id").pipe(
15
- Options.withDescription("Unique identifier for the data lake"),
14
+ const dataLakeIdOption = Flag.string("data-lake-id").pipe(
15
+ Flag.withDescription("Unique identifier for the data lake"),
16
16
  );
17
17
 
18
18
  export const createDataLakeIcebergCommand = Command.make(
@@ -41,9 +41,7 @@ export const createDataLakeIcebergCommand = Command.make(
41
41
  },
42
42
  }).pipe(
43
43
  Effect.provide(layer),
44
- Effect.tapError(() =>
45
- Effect.sync(() => s.stop("Failed to create data lake")),
46
- ),
44
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to create data lake"))),
47
45
  );
48
46
 
49
47
  s.stop("Iceberg data lake created successfully");
@@ -57,5 +55,5 @@ export const createDataLakeIcebergCommand = Command.make(
57
55
  ]);
58
56
  p.outro("✓ Done");
59
57
  });
60
- }).pipe(Effect.catchAll(handleCliError("Failed to create data lake"))),
58
+ }),
61
59
  ).pipe(Command.withDescription("Create a new Iceberg data lake"));
@@ -1,18 +1,18 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
8
  import { hostOption, portOption } from "../../../utils/options.js";
9
9
 
10
- const parentOption = Options.text("parent").pipe(
11
- Options.withDescription("Parent tenant in format: tenants/{tenant}"),
10
+ const parentOption = Flag.string("parent").pipe(
11
+ Flag.withDescription("Parent tenant in format: tenants/{tenant}"),
12
12
  );
13
13
 
14
- const dataLakeIdOption = Options.text("data-lake-id").pipe(
15
- Options.withDescription("Unique identifier for the data lake"),
14
+ const dataLakeIdOption = Flag.string("data-lake-id").pipe(
15
+ Flag.withDescription("Unique identifier for the data lake"),
16
16
  );
17
17
 
18
18
  export const createDataLakeParquetCommand = Command.make(
@@ -41,9 +41,7 @@ export const createDataLakeParquetCommand = Command.make(
41
41
  },
42
42
  }).pipe(
43
43
  Effect.provide(layer),
44
- Effect.tapError(() =>
45
- Effect.sync(() => s.stop("Failed to create data lake")),
46
- ),
44
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to create data lake"))),
47
45
  );
48
46
 
49
47
  s.stop("Parquet data lake created successfully");
@@ -57,5 +55,5 @@ export const createDataLakeParquetCommand = Command.make(
57
55
  ]);
58
56
  p.outro("✓ Done");
59
57
  });
60
- }).pipe(Effect.catchAll(handleCliError("Failed to create data lake"))),
58
+ }),
61
59
  ).pipe(Command.withDescription("Create a new Parquet data lake"));
@@ -1,16 +1,10 @@
1
- import { Command } from "@effect/cli";
2
1
  import { Effect } from "effect";
2
+ import { Command } from "effect/unstable/cli";
3
+
3
4
  import { createDataLakeIcebergCommand } from "./create-iceberg.js";
4
5
  import { createDataLakeParquetCommand } from "./create-parquet.js";
5
6
 
6
- export const createDataLakeCommand = Command.make(
7
- "create-data-lake",
8
- {},
9
- () => Effect.void,
10
- ).pipe(
7
+ export const createDataLakeCommand = Command.make("create-data-lake", {}, () => Effect.void).pipe(
11
8
  Command.withDescription("Create a new data lake"),
12
- Command.withSubcommands([
13
- createDataLakeIcebergCommand,
14
- createDataLakeParquetCommand,
15
- ]),
9
+ Command.withSubcommands([createDataLakeIcebergCommand, createDataLakeParquetCommand]),
16
10
  );
@@ -1,15 +1,13 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { Effect } from "effect";
4
+ import { Command, Flag } from "effect/unstable/cli";
5
+
5
6
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
6
- import { handleCliError } from "../../../utils/effect.js";
7
7
  import { forceOption, hostOption, portOption } from "../../../utils/options.js";
8
8
 
9
- const nameOption = Options.text("name").pipe(
10
- Options.withDescription(
11
- "Data lake name in format: tenants/{tenant}/data-lakes/{data-lake}",
12
- ),
9
+ const nameOption = Flag.string("name").pipe(
10
+ Flag.withDescription("Data lake name in format: tenants/{tenant}/data-lakes/{data-lake}"),
13
11
  );
14
12
 
15
13
  export const deleteDataLakeCommand = Command.make(
@@ -47,12 +45,10 @@ export const deleteDataLakeCommand = Command.make(
47
45
 
48
46
  yield* WingsClusterMetadata.deleteDataLake({ name }).pipe(
49
47
  Effect.provide(layer),
50
- Effect.tapError(() =>
51
- Effect.sync(() => s.stop("Failed to delete data lake")),
52
- ),
48
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to delete data lake"))),
53
49
  );
54
50
 
55
51
  s.stop("Data lake deleted successfully");
56
52
  p.outro("✓ Done");
57
- }).pipe(Effect.catchAll(handleCliError("Failed to delete data lake"))),
53
+ }),
58
54
  ).pipe(Command.withDescription("Delete a data lake from the cluster"));
@@ -1,16 +1,14 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
8
  import { hostOption, portOption } from "../../../utils/options.js";
9
9
 
10
- const nameOption = Options.text("name").pipe(
11
- Options.withDescription(
12
- "Data lake name in format: tenants/{tenant}/data-lakes/{data-lake}",
13
- ),
10
+ const nameOption = Flag.string("name").pipe(
11
+ Flag.withDescription("Data lake name in format: tenants/{tenant}/data-lakes/{data-lake}"),
14
12
  );
15
13
 
16
14
  export const getDataLakeCommand = Command.make(
@@ -29,18 +27,14 @@ export const getDataLakeCommand = Command.make(
29
27
 
30
28
  const dataLake = yield* WingsClusterMetadata.getDataLake({ name }).pipe(
31
29
  Effect.provide(layer),
32
- Effect.tapError(() =>
33
- Effect.sync(() => s.stop("Failed to get data lake")),
34
- ),
30
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to get data lake"))),
35
31
  );
36
32
 
37
33
  s.stop("Data lake retrieved");
38
34
 
39
35
  yield* Effect.sync(() => {
40
- printTable([
41
- { name: dataLake.name, type: dataLake.dataLakeConfig._tag || "-" },
42
- ]);
36
+ printTable([{ name: dataLake.name, type: dataLake.dataLakeConfig._tag || "-" }]);
43
37
  p.outro("✓ Done");
44
38
  });
45
- }).pipe(Effect.catchAll(handleCliError("Failed to get data lake"))),
39
+ }),
46
40
  ).pipe(Command.withDescription("Get details of a specific data lake"));
@@ -1,19 +1,14 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect, Option } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
- import {
9
- hostOption,
10
- pageSizeOption,
11
- pageTokenOption,
12
- portOption,
13
- } from "../../../utils/options.js";
8
+ import { hostOption, pageSizeOption, pageTokenOption, portOption } from "../../../utils/options.js";
14
9
 
15
- const parentOption = Options.text("parent").pipe(
16
- Options.withDescription("Parent tenant in format: tenants/{tenant}"),
10
+ const parentOption = Flag.string("parent").pipe(
11
+ Flag.withDescription("Parent tenant in format: tenants/{tenant}"),
17
12
  );
18
13
 
19
14
  export const listDataLakesCommand = Command.make(
@@ -38,9 +33,7 @@ export const listDataLakesCommand = Command.make(
38
33
  pageToken: Option.getOrUndefined(pageToken),
39
34
  }).pipe(
40
35
  Effect.provide(layer),
41
- Effect.tapError(() =>
42
- Effect.sync(() => s.stop("Failed to list data lakes")),
43
- ),
36
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to list data lakes"))),
44
37
  );
45
38
 
46
39
  s.stop(`Found ${response.dataLakes.length} data lake(s)`);
@@ -51,10 +44,7 @@ export const listDataLakesCommand = Command.make(
51
44
  } else {
52
45
  printTable(
53
46
  response.dataLakes.map(
54
- (dataLake: {
55
- name: string;
56
- dataLakeConfig: { _tag?: string | null };
57
- }) => ({
47
+ (dataLake: { name: string; dataLakeConfig: { _tag?: string | null } }) => ({
58
48
  name: dataLake.name,
59
49
  type: dataLake.dataLakeConfig._tag || "-",
60
50
  }),
@@ -68,5 +58,5 @@ export const listDataLakesCommand = Command.make(
68
58
 
69
59
  p.outro("✓ Done");
70
60
  });
71
- }).pipe(Effect.catchAll(handleCliError("Failed to list data lakes"))),
61
+ }),
72
62
  ).pipe(Command.withDescription("List all data lakes belonging to a tenant"));
@@ -1,5 +1,6 @@
1
- import { Command } from "@effect/cli";
2
1
  import { Effect } from "effect";
2
+ import { Command } from "effect/unstable/cli";
3
+
3
4
  import { createDataLakeCommand } from "./data-lake/create.js";
4
5
  import { deleteDataLakeCommand } from "./data-lake/delete.js";
5
6
  import { getDataLakeCommand } from "./data-lake/get.js";
@@ -21,11 +22,7 @@ import { deleteTopicCommand } from "./topic/delete.js";
21
22
  import { getTopicCommand } from "./topic/get.js";
22
23
  import { listTopicsCommand } from "./topic/list.js";
23
24
 
24
- export const clusterCommand = Command.make(
25
- "cluster",
26
- {},
27
- () => Effect.void,
28
- ).pipe(
25
+ export const clusterCommand = Command.make("cluster", {}, () => Effect.void).pipe(
29
26
  Command.withDescription("Interact with the cluster metadata server"),
30
27
  Command.withSubcommands([
31
28
  createTenantCommand,
@@ -1,46 +1,38 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
8
  import { hostOption, portOption } from "../../../utils/options.js";
9
9
 
10
- const parentOption = Options.text("parent").pipe(
11
- Options.withDescription(
12
- "Parent tenant in format: tenants/{tenant} (e.g., 'tenants/default')",
13
- ),
10
+ const parentOption = Flag.string("parent").pipe(
11
+ Flag.withDescription("Parent tenant in format: tenants/{tenant} (e.g., 'tenants/default')"),
14
12
  );
15
13
 
16
- const namespaceIdOption = Options.text("namespace-id").pipe(
17
- Options.withDescription(
18
- "Unique identifier for the namespace (e.g., 'production')",
19
- ),
14
+ const namespaceIdOption = Flag.string("namespace-id").pipe(
15
+ Flag.withDescription("Unique identifier for the namespace (e.g., 'production')"),
20
16
  );
21
17
 
22
- const flushSizeBytesOption = Options.integer("flush-size-bytes").pipe(
23
- Options.withDescription(
24
- "Size at which the current segment is flushed to object storage",
25
- ),
26
- Options.withDefault(0),
18
+ const flushSizeBytesOption = Flag.integer("flush-size-bytes").pipe(
19
+ Flag.withDescription("Size at which the current segment is flushed to object storage"),
20
+ Flag.withDefault(0),
27
21
  );
28
22
 
29
- const flushIntervalMillisOption = Options.integer("flush-interval-millis").pipe(
30
- Options.withDescription(
31
- "Maximum interval at which the current segment is flushed (milliseconds)",
32
- ),
33
- Options.withDefault(0),
23
+ const flushIntervalMillisOption = Flag.integer("flush-interval-millis").pipe(
24
+ Flag.withDescription("Maximum interval at which the current segment is flushed (milliseconds)"),
25
+ Flag.withDefault(0),
34
26
  );
35
27
 
36
- const objectStoreOption = Options.text("object-store").pipe(
37
- Options.withDescription(
28
+ const objectStoreOption = Flag.string("object-store").pipe(
29
+ Flag.withDescription(
38
30
  "Object store used by this namespace (format: tenants/{tenant}/object-stores/{object-store})",
39
31
  ),
40
32
  );
41
33
 
42
- const dataLakeOption = Options.text("data-lake").pipe(
43
- Options.withDescription(
34
+ const dataLakeOption = Flag.string("data-lake").pipe(
35
+ Flag.withDescription(
44
36
  "Data lake used by this namespace (format: tenants/{tenant}/data-lakes/{data-lake})",
45
37
  ),
46
38
  );
@@ -84,9 +76,7 @@ export const createNamespaceCommand = Command.make(
84
76
  dataLake,
85
77
  }).pipe(
86
78
  Effect.provide(layer),
87
- Effect.tapError(() =>
88
- Effect.sync(() => s.stop("Failed to create namespace")),
89
- ),
79
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to create namespace"))),
90
80
  );
91
81
 
92
82
  s.stop("Namespace created successfully");
@@ -103,5 +93,5 @@ export const createNamespaceCommand = Command.make(
103
93
  ]);
104
94
  p.outro("✓ Done");
105
95
  });
106
- }).pipe(Effect.catchAll(handleCliError("Failed to create namespace"))),
96
+ }),
107
97
  ).pipe(Command.withDescription("Create a new namespace belonging to a tenant"));
@@ -1,15 +1,13 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { Effect } from "effect";
4
+ import { Command, Flag } from "effect/unstable/cli";
5
+
5
6
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
6
- import { handleCliError } from "../../../utils/effect.js";
7
7
  import { forceOption, hostOption, portOption } from "../../../utils/options.js";
8
8
 
9
- const nameOption = Options.text("name").pipe(
10
- Options.withDescription(
11
- "Namespace name in format: tenants/{tenant}/namespaces/{namespace}",
12
- ),
9
+ const nameOption = Flag.string("name").pipe(
10
+ Flag.withDescription("Namespace name in format: tenants/{tenant}/namespaces/{namespace}"),
13
11
  );
14
12
 
15
13
  export const deleteNamespaceCommand = Command.make(
@@ -47,14 +45,12 @@ export const deleteNamespaceCommand = Command.make(
47
45
 
48
46
  yield* WingsClusterMetadata.deleteNamespace({ name }).pipe(
49
47
  Effect.provide(layer),
50
- Effect.tapError(() =>
51
- Effect.sync(() => s.stop("Failed to delete namespace")),
52
- ),
48
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to delete namespace"))),
53
49
  );
54
50
 
55
51
  s.stop("Namespace deleted successfully");
56
52
  p.outro("✓ Done");
57
- }).pipe(Effect.catchAll(handleCliError("Failed to delete namespace"))),
53
+ }),
58
54
  ).pipe(
59
55
  Command.withDescription(
60
56
  "Delete a namespace from the cluster (fails if namespace has any topics)",
@@ -1,16 +1,14 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
8
  import { hostOption, portOption } from "../../../utils/options.js";
9
9
 
10
- const nameOption = Options.text("name").pipe(
11
- Options.withDescription(
12
- "Namespace name in format: tenants/{tenant}/namespaces/{namespace}",
13
- ),
10
+ const nameOption = Flag.string("name").pipe(
11
+ Flag.withDescription("Namespace name in format: tenants/{tenant}/namespaces/{namespace}"),
14
12
  );
15
13
 
16
14
  export const getNamespaceCommand = Command.make(
@@ -29,9 +27,7 @@ export const getNamespaceCommand = Command.make(
29
27
 
30
28
  const namespace = yield* WingsClusterMetadata.getNamespace({ name }).pipe(
31
29
  Effect.provide(layer),
32
- Effect.tapError(() =>
33
- Effect.sync(() => s.stop("Failed to get namespace")),
34
- ),
30
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to get namespace"))),
35
31
  );
36
32
 
37
33
  s.stop("Namespace retrieved");
@@ -48,5 +44,5 @@ export const getNamespaceCommand = Command.make(
48
44
  ]);
49
45
  p.outro("✓ Done");
50
46
  });
51
- }).pipe(Effect.catchAll(handleCliError("Failed to get namespace"))),
47
+ }),
52
48
  ).pipe(Command.withDescription("Get details of a specific namespace"));
@@ -1,21 +1,14 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect, Option } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
- import {
9
- hostOption,
10
- pageSizeOption,
11
- pageTokenOption,
12
- portOption,
13
- } from "../../../utils/options.js";
8
+ import { hostOption, pageSizeOption, pageTokenOption, portOption } from "../../../utils/options.js";
14
9
 
15
- const parentOption = Options.text("parent").pipe(
16
- Options.withDescription(
17
- "Parent tenant in format: tenants/{tenant} (e.g., 'tenants/default')",
18
- ),
10
+ const parentOption = Flag.string("parent").pipe(
11
+ Flag.withDescription("Parent tenant in format: tenants/{tenant} (e.g., 'tenants/default')"),
19
12
  );
20
13
 
21
14
  export const listNamespacesCommand = Command.make(
@@ -40,9 +33,7 @@ export const listNamespacesCommand = Command.make(
40
33
  pageToken: Option.getOrUndefined(pageToken),
41
34
  }).pipe(
42
35
  Effect.provide(layer),
43
- Effect.tapError(() =>
44
- Effect.sync(() => s.stop("Failed to list namespaces")),
45
- ),
36
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to list namespaces"))),
46
37
  );
47
38
 
48
39
  s.stop(`Found ${response.namespaces.length} namespace(s)`);
@@ -76,5 +67,5 @@ export const listNamespacesCommand = Command.make(
76
67
 
77
68
  p.outro("✓ Done");
78
69
  });
79
- }).pipe(Effect.catchAll(handleCliError("Failed to list namespaces"))),
70
+ }),
80
71
  ).pipe(Command.withDescription("List all namespaces belonging to a tenant"));
@@ -1,40 +1,40 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command, Options } from "@effect/cli";
3
2
  import { WingsClusterMetadata } from "@useairfoil/wings";
4
3
  import { printTable } from "console-table-printer";
5
4
  import { Effect, Option } from "effect";
5
+ import { Command, Flag } from "effect/unstable/cli";
6
+
6
7
  import { makeClusterMetadataLayer } from "../../../utils/client.js";
7
- import { handleCliError } from "../../../utils/effect.js";
8
8
  import { hostOption, portOption } from "../../../utils/options.js";
9
9
 
10
- const parentOption = Options.text("parent").pipe(
11
- Options.withDescription("Parent tenant in format: tenants/{tenant}"),
10
+ const parentOption = Flag.string("parent").pipe(
11
+ Flag.withDescription("Parent tenant in format: tenants/{tenant}"),
12
12
  );
13
13
 
14
- const objectStoreIdOption = Options.text("object-store-id").pipe(
15
- Options.withDescription("Unique identifier for the object store"),
14
+ const objectStoreIdOption = Flag.string("object-store-id").pipe(
15
+ Flag.withDescription("Unique identifier for the object store"),
16
16
  );
17
17
 
18
- const bucketNameOption = Options.text("bucket-name").pipe(
19
- Options.withDescription("AWS S3 bucket name"),
18
+ const bucketNameOption = Flag.string("bucket-name").pipe(
19
+ Flag.withDescription("AWS S3 bucket name"),
20
20
  );
21
21
 
22
- const prefixOption = Options.text("prefix").pipe(
23
- Options.withDescription("Bucket prefix (optional)"),
24
- Options.optional,
22
+ const prefixOption = Flag.string("prefix").pipe(
23
+ Flag.withDescription("Bucket prefix (optional)"),
24
+ Flag.optional,
25
25
  );
26
26
 
27
- const accessKeyIdOption = Options.text("access-key-id").pipe(
28
- Options.withDescription("AWS_ACCESS_KEY_ID"),
27
+ const accessKeyIdOption = Flag.string("access-key-id").pipe(
28
+ Flag.withDescription("AWS_ACCESS_KEY_ID"),
29
29
  );
30
30
 
31
- const secretAccessKeyOption = Options.text("secret-access-key").pipe(
32
- Options.withDescription("AWS_SECRET_ACCESS_KEY"),
31
+ const secretAccessKeyOption = Flag.string("secret-access-key").pipe(
32
+ Flag.withDescription("AWS_SECRET_ACCESS_KEY"),
33
33
  );
34
34
 
35
- const regionOption = Options.text("region").pipe(
36
- Options.withDescription("AWS_DEFAULT_REGION (e.g., us-east-1)"),
37
- Options.optional,
35
+ const regionOption = Flag.string("region").pipe(
36
+ Flag.withDescription("AWS_DEFAULT_REGION (e.g., us-east-1)"),
37
+ Flag.optional,
38
38
  );
39
39
 
40
40
  export const createObjectStoreAwsCommand = Command.make(
@@ -84,9 +84,7 @@ export const createObjectStoreAwsCommand = Command.make(
84
84
  },
85
85
  }).pipe(
86
86
  Effect.provide(layer),
87
- Effect.tapError(() =>
88
- Effect.sync(() => s.stop("Failed to create AWS object store")),
89
- ),
87
+ Effect.tapError(() => Effect.sync(() => s.stop("Failed to create AWS object store"))),
90
88
  );
91
89
 
92
90
  s.stop("AWS S3 object store created successfully");
@@ -102,7 +100,5 @@ export const createObjectStoreAwsCommand = Command.make(
102
100
  ]);
103
101
  p.outro("✓ Done");
104
102
  });
105
- }).pipe(
106
- Effect.catchAll(handleCliError("Failed to create AWS object store")),
107
- ),
103
+ }),
108
104
  ).pipe(Command.withDescription("Create a new AWS S3 object store"));