airfoil 0.2.0 → 0.3.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.
- package/dist/index.js +41008 -45596
- package/package.json +5 -6
- package/src/commands/cluster/data-lake/create-iceberg.ts +6 -6
- package/src/commands/cluster/data-lake/create-parquet.ts +6 -6
- package/src/commands/cluster/data-lake/create.ts +1 -1
- package/src/commands/cluster/data-lake/delete.ts +4 -4
- package/src/commands/cluster/data-lake/get.ts +4 -4
- package/src/commands/cluster/data-lake/list.ts +4 -4
- package/src/commands/cluster/index.ts +1 -1
- package/src/commands/cluster/namespace/create.ts +16 -16
- package/src/commands/cluster/namespace/delete.ts +4 -4
- package/src/commands/cluster/namespace/get.ts +4 -4
- package/src/commands/cluster/namespace/list.ts +4 -4
- package/src/commands/cluster/object-store/create-aws.ts +18 -20
- package/src/commands/cluster/object-store/create-azure.ts +15 -15
- package/src/commands/cluster/object-store/create-google.ts +15 -15
- package/src/commands/cluster/object-store/create-s3.ts +20 -20
- package/src/commands/cluster/object-store/create.ts +1 -1
- package/src/commands/cluster/object-store/delete.ts +4 -4
- package/src/commands/cluster/object-store/get.ts +4 -4
- package/src/commands/cluster/object-store/list.ts +4 -4
- package/src/commands/cluster/tenant/create.ts +4 -6
- package/src/commands/cluster/tenant/delete.ts +4 -4
- package/src/commands/cluster/tenant/get.ts +4 -4
- package/src/commands/cluster/tenant/list.ts +2 -2
- package/src/commands/cluster/topic/create.ts +28 -30
- package/src/commands/cluster/topic/delete.ts +7 -7
- package/src/commands/cluster/topic/get.ts +4 -4
- package/src/commands/cluster/topic/list.ts +4 -4
- package/src/commands/dev.ts +21 -21
- package/src/commands/sql.ts +16 -16
- package/src/index.ts +7 -5
- package/src/utils/options.ts +18 -17
|
@@ -1,14 +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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
7
7
|
import { handleCliError } from "../../../utils/effect.js";
|
|
8
8
|
import { hostOption, portOption } from "../../../utils/options.js";
|
|
9
9
|
|
|
10
|
-
const nameOption =
|
|
11
|
-
|
|
10
|
+
const nameOption = Flag.string("name").pipe(
|
|
11
|
+
Flag.withDescription(
|
|
12
12
|
"Object store name in format: tenants/{tenant}/object-stores/{object-store}",
|
|
13
13
|
),
|
|
14
14
|
);
|
|
@@ -47,5 +47,5 @@ export const getObjectStoreCommand = Command.make(
|
|
|
47
47
|
]);
|
|
48
48
|
p.outro("✓ Done");
|
|
49
49
|
});
|
|
50
|
-
}).pipe(Effect.
|
|
50
|
+
}).pipe(Effect.catch(handleCliError("Failed to get object store"))),
|
|
51
51
|
).pipe(Command.withDescription("Get details of a specific object store"));
|
|
@@ -1,8 +1,8 @@
|
|
|
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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
7
7
|
import { handleCliError } from "../../../utils/effect.js";
|
|
8
8
|
import {
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
portOption,
|
|
13
13
|
} from "../../../utils/options.js";
|
|
14
14
|
|
|
15
|
-
const parentOption =
|
|
16
|
-
|
|
15
|
+
const parentOption = Flag.string("parent").pipe(
|
|
16
|
+
Flag.withDescription("Parent tenant in format: tenants/{tenant}"),
|
|
17
17
|
);
|
|
18
18
|
|
|
19
19
|
export const listObjectStoresCommand = Command.make(
|
|
@@ -68,5 +68,5 @@ export const listObjectStoresCommand = Command.make(
|
|
|
68
68
|
|
|
69
69
|
p.outro("✓ Done");
|
|
70
70
|
});
|
|
71
|
-
}).pipe(Effect.
|
|
71
|
+
}).pipe(Effect.catch(handleCliError("Failed to list object stores"))),
|
|
72
72
|
).pipe(Command.withDescription("List all object stores belonging to a tenant"));
|
|
@@ -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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
7
7
|
import { handleCliError } from "../../../utils/effect.js";
|
|
8
8
|
import { hostOption, portOption } from "../../../utils/options.js";
|
|
9
9
|
|
|
10
|
-
const tenantIdOption =
|
|
11
|
-
|
|
12
|
-
"Unique identifier for the tenant (e.g., 'acme-corp')",
|
|
13
|
-
),
|
|
10
|
+
const tenantIdOption = Flag.string("tenant-id").pipe(
|
|
11
|
+
Flag.withDescription("Unique identifier for the tenant (e.g., 'acme-corp')"),
|
|
14
12
|
);
|
|
15
13
|
|
|
16
14
|
export const createTenantCommand = Command.make(
|
|
@@ -44,5 +42,5 @@ export const createTenantCommand = Command.make(
|
|
|
44
42
|
printTable([{ name: tenant.name }]);
|
|
45
43
|
p.outro("✓ Done");
|
|
46
44
|
});
|
|
47
|
-
}).pipe(Effect.
|
|
45
|
+
}).pipe(Effect.catch(handleCliError("Failed to create tenant"))),
|
|
48
46
|
).pipe(Command.withDescription("Create a new tenant in the cluster"));
|
|
@@ -1,13 +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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
6
6
|
import { handleCliError } from "../../../utils/effect.js";
|
|
7
7
|
import { forceOption, hostOption, portOption } from "../../../utils/options.js";
|
|
8
8
|
|
|
9
|
-
const nameOption =
|
|
10
|
-
|
|
9
|
+
const nameOption = Flag.string("name").pipe(
|
|
10
|
+
Flag.withDescription(
|
|
11
11
|
"Tenant name in format: tenants/{tenant} (e.g., 'tenants/acme-corp')",
|
|
12
12
|
),
|
|
13
13
|
);
|
|
@@ -54,7 +54,7 @@ export const deleteTenantCommand = Command.make(
|
|
|
54
54
|
|
|
55
55
|
s.stop("Tenant deleted successfully");
|
|
56
56
|
p.outro("✓ Done");
|
|
57
|
-
}).pipe(Effect.
|
|
57
|
+
}).pipe(Effect.catch(handleCliError("Failed to delete tenant"))),
|
|
58
58
|
).pipe(
|
|
59
59
|
Command.withDescription(
|
|
60
60
|
"Delete a tenant from the cluster (fails if tenant has any namespaces)",
|
|
@@ -1,14 +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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
7
7
|
import { handleCliError } from "../../../utils/effect.js";
|
|
8
8
|
import { hostOption, portOption } from "../../../utils/options.js";
|
|
9
9
|
|
|
10
|
-
const nameOption =
|
|
11
|
-
|
|
10
|
+
const nameOption = Flag.string("name").pipe(
|
|
11
|
+
Flag.withDescription(
|
|
12
12
|
"Tenant name in format: tenants/{tenant} (e.g., 'tenants/acme-corp')",
|
|
13
13
|
),
|
|
14
14
|
);
|
|
@@ -40,5 +40,5 @@ export const getTenantCommand = Command.make(
|
|
|
40
40
|
printTable([{ name: tenant.name }]);
|
|
41
41
|
p.outro("✓ Done");
|
|
42
42
|
});
|
|
43
|
-
}).pipe(Effect.
|
|
43
|
+
}).pipe(Effect.catch(handleCliError("Failed to get tenant"))),
|
|
44
44
|
).pipe(Command.withDescription("Get details of a specific tenant"));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
|
-
import { Command } 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 } from "effect/unstable/cli";
|
|
6
6
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
7
7
|
import { handleCliError } from "../../../utils/effect.js";
|
|
8
8
|
import {
|
|
@@ -56,5 +56,5 @@ export const listTenantsCommand = Command.make(
|
|
|
56
56
|
|
|
57
57
|
p.outro("✓ Done");
|
|
58
58
|
});
|
|
59
|
-
}).pipe(Effect.
|
|
59
|
+
}).pipe(Effect.catch(handleCliError("Failed to list tenants"))),
|
|
60
60
|
).pipe(Command.withDescription("List all tenants in the cluster"));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as p from "@clack/prompts";
|
|
3
|
-
import { Command, Options } from "@effect/cli";
|
|
4
3
|
import type { FieldConfig } from "@useairfoil/wings";
|
|
5
4
|
import { WingsClusterMetadata } from "@useairfoil/wings";
|
|
6
5
|
import { printTable } from "console-table-printer";
|
|
7
6
|
import { Effect, Option } from "effect";
|
|
7
|
+
import { Command, Flag } from "effect/unstable/cli";
|
|
8
8
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
9
9
|
import { handleCliError } from "../../../utils/effect.js";
|
|
10
10
|
import { hostOption, portOption } from "../../../utils/options.js";
|
|
@@ -40,55 +40,53 @@ const SUPPORTED_INLINE_TYPES = [
|
|
|
40
40
|
|
|
41
41
|
type SupportedInlineType = (typeof SUPPORTED_INLINE_TYPES)[number];
|
|
42
42
|
|
|
43
|
-
const parentOption =
|
|
44
|
-
|
|
43
|
+
const parentOption = Flag.string("parent").pipe(
|
|
44
|
+
Flag.withDescription(
|
|
45
45
|
"Parent namespace in format: tenants/{tenant}/namespaces/{namespace}",
|
|
46
46
|
),
|
|
47
47
|
);
|
|
48
48
|
|
|
49
|
-
const topicIdOption =
|
|
50
|
-
|
|
49
|
+
const topicIdOption = Flag.string("topic-id").pipe(
|
|
50
|
+
Flag.withDescription("Unique identifier for the topic"),
|
|
51
51
|
);
|
|
52
52
|
|
|
53
|
-
const descriptionOption =
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const descriptionOption = Flag.string("description").pipe(
|
|
54
|
+
Flag.withDescription("Topic description"),
|
|
55
|
+
Flag.optional,
|
|
56
56
|
);
|
|
57
57
|
|
|
58
|
-
const fieldsOption =
|
|
59
|
-
|
|
58
|
+
const fieldsOption = Flag.string("fields").pipe(
|
|
59
|
+
Flag.withDescription(
|
|
60
60
|
'Field definitions in format "name:Type" or "name:Type?" for nullable',
|
|
61
61
|
),
|
|
62
|
-
|
|
62
|
+
Flag.atLeast(0),
|
|
63
63
|
);
|
|
64
64
|
|
|
65
|
-
const schemaFileOption =
|
|
66
|
-
|
|
65
|
+
const schemaFileOption = Flag.string("schema-file").pipe(
|
|
66
|
+
Flag.withDescription(
|
|
67
67
|
"Path to JSON file containing FieldConfig[] (for complex types)",
|
|
68
68
|
),
|
|
69
|
-
|
|
69
|
+
Flag.optional,
|
|
70
70
|
);
|
|
71
71
|
|
|
72
|
-
const partitionKeyOption =
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
const partitionKeyOption = Flag.string("partition-key").pipe(
|
|
73
|
+
Flag.withDescription("Name of the field used for partitioning"),
|
|
74
|
+
Flag.optional,
|
|
75
75
|
);
|
|
76
76
|
|
|
77
|
-
const freshnessSecondsOption =
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
const freshnessSecondsOption = Flag.integer("freshness-seconds").pipe(
|
|
78
|
+
Flag.withDescription("How often to compact the topic (seconds)"),
|
|
79
|
+
Flag.withDefault(60),
|
|
80
80
|
);
|
|
81
81
|
|
|
82
|
-
const ttlSecondsOption =
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const ttlSecondsOption = Flag.integer("ttl-seconds").pipe(
|
|
83
|
+
Flag.withDescription("How long to keep topic data (seconds)"),
|
|
84
|
+
Flag.optional,
|
|
85
85
|
);
|
|
86
86
|
|
|
87
|
-
const targetFileSizeBytesOption =
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
Options.withDescription("Target file size for compaction (bytes)"),
|
|
91
|
-
Options.withDefault(1024 * 1024),
|
|
87
|
+
const targetFileSizeBytesOption = Flag.integer("target-file-size-bytes").pipe(
|
|
88
|
+
Flag.withDescription("Target file size for compaction (bytes)"),
|
|
89
|
+
Flag.withDefault(1024 * 1024),
|
|
92
90
|
);
|
|
93
91
|
|
|
94
92
|
/**
|
|
@@ -131,7 +129,7 @@ function parseFieldString(fieldStr: string, index: number): FieldConfig {
|
|
|
131
129
|
/**
|
|
132
130
|
* Parse multiple field strings into FieldConfig array
|
|
133
131
|
*/
|
|
134
|
-
function parseFieldsFromArgs(fields: string
|
|
132
|
+
function parseFieldsFromArgs(fields: ReadonlyArray<string>): FieldConfig[] {
|
|
135
133
|
return fields.map((field, index) => parseFieldString(field, index));
|
|
136
134
|
}
|
|
137
135
|
|
|
@@ -315,5 +313,5 @@ export const createTopicCommand = Command.make(
|
|
|
315
313
|
|
|
316
314
|
p.outro("✓ Done");
|
|
317
315
|
});
|
|
318
|
-
}).pipe(Effect.
|
|
316
|
+
}).pipe(Effect.catch(handleCliError("Failed to create topic"))),
|
|
319
317
|
).pipe(Command.withDescription("Create a new topic belonging to a namespace"));
|
|
@@ -1,20 +1,20 @@
|
|
|
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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
6
6
|
import { handleCliError } from "../../../utils/effect.js";
|
|
7
7
|
import { forceOption, hostOption, portOption } from "../../../utils/options.js";
|
|
8
8
|
|
|
9
|
-
const nameOption =
|
|
10
|
-
|
|
9
|
+
const nameOption = Flag.string("name").pipe(
|
|
10
|
+
Flag.withDescription(
|
|
11
11
|
"Topic name in format: tenants/{tenant}/namespaces/{namespace}/topics/{topic}",
|
|
12
12
|
),
|
|
13
13
|
);
|
|
14
14
|
|
|
15
|
-
const forceDeleteOption =
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const forceDeleteOption = Flag.boolean("force-delete").pipe(
|
|
16
|
+
Flag.withDescription("Also delete data associated with the topic"),
|
|
17
|
+
Flag.withDefault(false),
|
|
18
18
|
);
|
|
19
19
|
|
|
20
20
|
export const deleteTopicCommand = Command.make(
|
|
@@ -63,5 +63,5 @@ export const deleteTopicCommand = Command.make(
|
|
|
63
63
|
|
|
64
64
|
s.stop("Topic deleted successfully");
|
|
65
65
|
p.outro("✓ Done");
|
|
66
|
-
}).pipe(Effect.
|
|
66
|
+
}).pipe(Effect.catch(handleCliError("Failed to delete topic"))),
|
|
67
67
|
).pipe(Command.withDescription("Delete a topic from the cluster"));
|
|
@@ -1,14 +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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
7
7
|
import { handleCliError } from "../../../utils/effect.js";
|
|
8
8
|
import { hostOption, portOption } from "../../../utils/options.js";
|
|
9
9
|
|
|
10
|
-
const nameOption =
|
|
11
|
-
|
|
10
|
+
const nameOption = Flag.string("name").pipe(
|
|
11
|
+
Flag.withDescription(
|
|
12
12
|
"Topic name in format: tenants/{tenant}/namespaces/{namespace}/topics/{topic}",
|
|
13
13
|
),
|
|
14
14
|
);
|
|
@@ -47,5 +47,5 @@ export const getTopicCommand = Command.make(
|
|
|
47
47
|
|
|
48
48
|
p.outro("✓ Done");
|
|
49
49
|
});
|
|
50
|
-
}).pipe(Effect.
|
|
50
|
+
}).pipe(Effect.catch(handleCliError("Failed to get topic"))),
|
|
51
51
|
).pipe(Command.withDescription("Get details of a specific topic"));
|
|
@@ -1,8 +1,8 @@
|
|
|
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
|
import { makeClusterMetadataLayer } from "../../../utils/client.js";
|
|
7
7
|
import { handleCliError } from "../../../utils/effect.js";
|
|
8
8
|
import {
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
portOption,
|
|
13
13
|
} from "../../../utils/options.js";
|
|
14
14
|
|
|
15
|
-
const parentOption =
|
|
16
|
-
|
|
15
|
+
const parentOption = Flag.string("parent").pipe(
|
|
16
|
+
Flag.withDescription(
|
|
17
17
|
"Parent namespace in format: tenants/{tenant}/namespaces/{namespace}",
|
|
18
18
|
),
|
|
19
19
|
);
|
|
@@ -66,5 +66,5 @@ export const listTopicsCommand = Command.make(
|
|
|
66
66
|
|
|
67
67
|
p.outro("✓ Done");
|
|
68
68
|
});
|
|
69
|
-
}).pipe(Effect.
|
|
69
|
+
}).pipe(Effect.catch(handleCliError("Failed to list topics"))),
|
|
70
70
|
).pipe(Command.withDescription("List all topics belonging to a namespace"));
|
package/src/commands/dev.ts
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
|
-
import { Command, Options } from "@effect/cli";
|
|
3
2
|
import { Effect } from "effect";
|
|
3
|
+
import { Command, Flag } from "effect/unstable/cli";
|
|
4
4
|
import { handleCliError } from "../utils/effect.js";
|
|
5
5
|
import { downloadWings, getWingsPath, verifyChecksum } from "../utils/wings.js";
|
|
6
6
|
|
|
7
|
-
const dockerOption =
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const dockerOption = Flag.boolean("docker").pipe(
|
|
8
|
+
Flag.withDescription("Run Wings using Docker (recommended)"),
|
|
9
|
+
Flag.withDefault(false),
|
|
10
10
|
);
|
|
11
11
|
|
|
12
|
-
const versionOption =
|
|
13
|
-
|
|
12
|
+
const versionOption = Flag.string("version").pipe(
|
|
13
|
+
Flag.withDescription(
|
|
14
14
|
"Specify Wings version (e.g., v0.1.0-alpha.11 or 'latest')",
|
|
15
15
|
),
|
|
16
|
-
|
|
16
|
+
Flag.withDefault("latest"),
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
const tagOption =
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const tagOption = Flag.string("tag").pipe(
|
|
20
|
+
Flag.withDescription("Docker image tag (only with --docker)"),
|
|
21
|
+
Flag.withDefault("latest"),
|
|
22
22
|
);
|
|
23
23
|
|
|
24
|
-
const forcePullOption =
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
const forcePullOption = Flag.boolean("force-pull").pipe(
|
|
25
|
+
Flag.withDescription("Force pull Docker image even if it exists locally"),
|
|
26
|
+
Flag.withDefault(false),
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
-
const stressOption =
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const stressOption = Flag.boolean("stress").pipe(
|
|
30
|
+
Flag.withDescription("Use Wings stress binary variant"),
|
|
31
|
+
Flag.withDefault(false),
|
|
32
32
|
);
|
|
33
33
|
|
|
34
|
-
const yesOption =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
const yesOption = Flag.boolean("yes").pipe(
|
|
35
|
+
Flag.withAlias("y"),
|
|
36
|
+
Flag.withDescription("Skip confirmation prompts"),
|
|
37
|
+
Flag.withDefault(false),
|
|
38
38
|
);
|
|
39
39
|
|
|
40
40
|
export const devCommand = Command.make(
|
|
@@ -53,7 +53,7 @@ export const devCommand = Command.make(
|
|
|
53
53
|
options.docker ? runWithDocker(options) : runWithBinary(options),
|
|
54
54
|
catch: (error) =>
|
|
55
55
|
error instanceof Error ? error : new Error("Operation failed"),
|
|
56
|
-
}).pipe(Effect.
|
|
56
|
+
}).pipe(Effect.catch(handleCliError("Operation failed"))),
|
|
57
57
|
).pipe(
|
|
58
58
|
Command.withDescription(
|
|
59
59
|
"Download and run Wings dev server locally (Docker recommended for portability)",
|
package/src/commands/sql.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import * as p from "@clack/prompts";
|
|
3
|
-
import { Args, Command, Options } from "@effect/cli";
|
|
4
3
|
import { ArrowFlightSqlClient } from "@useairfoil/flight";
|
|
5
4
|
import { printTable } from "console-table-printer";
|
|
6
5
|
import { Effect, Option } from "effect";
|
|
6
|
+
import { Argument, Command, Flag } from "effect/unstable/cli";
|
|
7
7
|
import { Metadata } from "nice-grpc-common";
|
|
8
8
|
import { handleCliError } from "../utils/effect.js";
|
|
9
9
|
import { hostOption, portOption } from "../utils/options.js";
|
|
10
10
|
|
|
11
|
-
const queryArg =
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const queryArg = Argument.string("query").pipe(
|
|
12
|
+
Argument.withDescription("SQL query to execute"),
|
|
13
|
+
Argument.optional,
|
|
14
14
|
);
|
|
15
15
|
|
|
16
|
-
const fileOption =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const fileOption = Flag.string("file").pipe(
|
|
17
|
+
Flag.withAlias("f"),
|
|
18
|
+
Flag.withDescription("Execute SQL from file"),
|
|
19
|
+
Flag.optional,
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
-
const namespaceOption =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const namespaceOption = Flag.string("namespace").pipe(
|
|
23
|
+
Flag.withAlias("n"),
|
|
24
|
+
Flag.withDescription("Wings namespace"),
|
|
25
|
+
Flag.withDefault("tenants/default/namespaces/default"),
|
|
26
26
|
);
|
|
27
27
|
|
|
28
|
-
const jsonOption =
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const jsonOption = Flag.boolean("json").pipe(
|
|
29
|
+
Flag.withDescription("Output results as JSON"),
|
|
30
|
+
Flag.withDefault(false),
|
|
31
31
|
);
|
|
32
32
|
|
|
33
33
|
export const sqlCommand = Command.make(
|
|
@@ -117,5 +117,5 @@ export const sqlCommand = Command.make(
|
|
|
117
117
|
}
|
|
118
118
|
p.outro("✓ Done");
|
|
119
119
|
});
|
|
120
|
-
}).pipe(Effect.
|
|
120
|
+
}).pipe(Effect.catch(handleCliError("Command failed"))),
|
|
121
121
|
).pipe(Command.withDescription("Execute SQL queries using Arrow Flight SQL"));
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import {
|
|
3
|
-
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
|
2
|
+
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
4
3
|
import { Effect } from "effect";
|
|
4
|
+
import { Command } from "effect/unstable/cli";
|
|
5
|
+
import packageJson from "../package.json";
|
|
5
6
|
import { clusterCommand } from "./commands/cluster/index.js";
|
|
6
7
|
import { devCommand } from "./commands/dev.js";
|
|
7
8
|
import { sqlCommand } from "./commands/sql.js";
|
|
8
9
|
|
|
10
|
+
const version = packageJson.version;
|
|
11
|
+
|
|
9
12
|
const program = Command.make("airfoil", {}, () => Effect.void).pipe(
|
|
10
13
|
Command.withSubcommands([devCommand, sqlCommand, clusterCommand]),
|
|
11
14
|
);
|
|
12
15
|
|
|
13
16
|
const cli = Command.run(program, {
|
|
14
|
-
|
|
15
|
-
version: "0.1.0",
|
|
17
|
+
version,
|
|
16
18
|
});
|
|
17
19
|
|
|
18
|
-
cli
|
|
20
|
+
cli.pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);
|
package/src/utils/options.ts
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flag } from "effect/unstable/cli";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Common server connection options
|
|
5
5
|
*/
|
|
6
|
-
export const hostOption =
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export const hostOption = Flag.string("host").pipe(
|
|
7
|
+
Flag.withDescription("Server host"),
|
|
8
|
+
Flag.withDefault("localhost"),
|
|
9
9
|
);
|
|
10
10
|
|
|
11
|
-
export const portOption =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export const portOption = Flag.integer("port").pipe(
|
|
12
|
+
Flag.withDescription("Server port"),
|
|
13
|
+
Flag.withAlias("p"),
|
|
14
|
+
Flag.withDefault(7777),
|
|
15
15
|
);
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Common pagination options
|
|
19
19
|
*/
|
|
20
|
-
export const pageSizeOption =
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
export const pageSizeOption = Flag.integer("page-size").pipe(
|
|
21
|
+
Flag.withDescription("Number of items to return (max: 1000)"),
|
|
22
|
+
Flag.withDefault(100),
|
|
23
23
|
);
|
|
24
24
|
|
|
25
|
-
export const pageTokenOption =
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
export const pageTokenOption = Flag.optional(
|
|
26
|
+
Flag.string("page-token").pipe(
|
|
27
|
+
Flag.withDescription("Continuation token for pagination"),
|
|
28
|
+
),
|
|
28
29
|
);
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Force flag for destructive operations
|
|
32
33
|
*/
|
|
33
|
-
export const forceOption =
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
export const forceOption = Flag.boolean("force").pipe(
|
|
35
|
+
Flag.withDescription("Skip confirmation prompt"),
|
|
36
|
+
Flag.withDefault(false),
|
|
36
37
|
);
|