airfoil 0.4.5 → 0.4.7
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/LICENSE.txt +201 -0
- package/README.md +24 -0
- package/dist/index.mjs +283 -0
- package/package.json +24 -21
- 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
package/src/utils/docker.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { Effect, String } from "effect";
|
|
2
|
-
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
3
|
-
|
|
4
|
-
export const checkDockerVersion = () =>
|
|
5
|
-
Effect.gen(function* () {
|
|
6
|
-
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
7
|
-
const docker = ChildProcess.make("docker", ["--version"]);
|
|
8
|
-
|
|
9
|
-
return yield* spawner.string(docker).pipe(Effect.map(String.trim));
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
export const createDockerVolume = (volumeName: string) =>
|
|
13
|
-
Effect.gen(function* () {
|
|
14
|
-
const docker = yield* ChildProcess.make("docker", ["volume", "create", volumeName]);
|
|
15
|
-
const exitCode = yield* docker.exitCode;
|
|
16
|
-
if (exitCode !== 0) {
|
|
17
|
-
return yield* Effect.fail(new Error(`Docker volume create failed with code ${exitCode}`));
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
export const createDockerNetwork = (networkName: string) =>
|
|
22
|
-
Effect.gen(function* () {
|
|
23
|
-
const docker = yield* ChildProcess.make("docker", ["network", "create", networkName]);
|
|
24
|
-
const exitCode = yield* docker.exitCode;
|
|
25
|
-
if (exitCode !== 0) {
|
|
26
|
-
return yield* Effect.fail(new Error(`Docker network create failed with code ${exitCode}`));
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
export const removeDockerContainer = (containerName: string) =>
|
|
31
|
-
Effect.gen(function* () {
|
|
32
|
-
const docker = yield* ChildProcess.make("docker", ["rm", "-f", containerName], {
|
|
33
|
-
stdout: "ignore",
|
|
34
|
-
stderr: "ignore",
|
|
35
|
-
});
|
|
36
|
-
yield* docker.exitCode;
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
export const removeDockerNetwork = (networkName: string) =>
|
|
40
|
-
Effect.gen(function* () {
|
|
41
|
-
const docker = yield* ChildProcess.make("docker", ["network", "rm", networkName], {
|
|
42
|
-
stdout: "ignore",
|
|
43
|
-
stderr: "ignore",
|
|
44
|
-
});
|
|
45
|
-
yield* docker.exitCode;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
export const pullDockerImage = (image: string) =>
|
|
49
|
-
Effect.gen(function* () {
|
|
50
|
-
const docker = yield* ChildProcess.make("docker", ["pull", image], {
|
|
51
|
-
stdout: "inherit",
|
|
52
|
-
stderr: "inherit",
|
|
53
|
-
});
|
|
54
|
-
const exitCode = yield* docker.exitCode;
|
|
55
|
-
if (exitCode !== 0) {
|
|
56
|
-
return yield* Effect.fail(new Error(`Docker pull failed with code ${exitCode}`));
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
export const runDockerContainer = (image: string, volumeName: string) =>
|
|
61
|
-
Effect.gen(function* () {
|
|
62
|
-
const networkName = "airfoil-dev";
|
|
63
|
-
const seaweedContainerName = "airfoil-seaweedfs";
|
|
64
|
-
|
|
65
|
-
yield* removeDockerContainer(seaweedContainerName);
|
|
66
|
-
yield* removeDockerNetwork(networkName);
|
|
67
|
-
yield* createDockerNetwork(networkName);
|
|
68
|
-
yield* Effect.addFinalizer(() =>
|
|
69
|
-
removeDockerNetwork(networkName).pipe(Effect.catchCause(() => Effect.void)),
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
73
|
-
const seaweed = ChildProcess.make("docker", [
|
|
74
|
-
"run",
|
|
75
|
-
"-d",
|
|
76
|
-
"--rm",
|
|
77
|
-
"--name",
|
|
78
|
-
seaweedContainerName,
|
|
79
|
-
"--network",
|
|
80
|
-
networkName,
|
|
81
|
-
"--network-alias",
|
|
82
|
-
"seaweedfs",
|
|
83
|
-
"-e",
|
|
84
|
-
"AWS_ACCESS_KEY_ID=wingsdevaccesskey",
|
|
85
|
-
"-e",
|
|
86
|
-
"AWS_SECRET_ACCESS_KEY=wingsdevsecretkey",
|
|
87
|
-
"-e",
|
|
88
|
-
"S3_BUCKET=default-bucket",
|
|
89
|
-
"-v",
|
|
90
|
-
`${volumeName}:/data`,
|
|
91
|
-
"-p",
|
|
92
|
-
"8333:8333",
|
|
93
|
-
"chrislusf/seaweedfs:4.29",
|
|
94
|
-
"weed",
|
|
95
|
-
"mini",
|
|
96
|
-
"-s3",
|
|
97
|
-
"-dir=/data",
|
|
98
|
-
]);
|
|
99
|
-
|
|
100
|
-
yield* spawner.string(seaweed).pipe(Effect.map(String.trim));
|
|
101
|
-
yield* Effect.addFinalizer(() =>
|
|
102
|
-
removeDockerContainer(seaweedContainerName).pipe(Effect.catchCause(() => Effect.void)),
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
const docker = yield* ChildProcess.make("docker", [
|
|
106
|
-
"run",
|
|
107
|
-
"-it",
|
|
108
|
-
"--rm",
|
|
109
|
-
"--name",
|
|
110
|
-
"wings-dev",
|
|
111
|
-
"--network",
|
|
112
|
-
networkName,
|
|
113
|
-
"-e",
|
|
114
|
-
"AWS_ACCESS_KEY_ID=wingsdevaccesskey",
|
|
115
|
-
"-e",
|
|
116
|
-
"AWS_SECRET_ACCESS_KEY=wingsdevsecretkey",
|
|
117
|
-
"-e",
|
|
118
|
-
"AWS_ENDPOINT=http://seaweedfs:8333",
|
|
119
|
-
"-e",
|
|
120
|
-
"AWS_BUCKET_NAME=default-bucket",
|
|
121
|
-
"-e",
|
|
122
|
-
"AWS_DEFAULT_REGION=us-east-1",
|
|
123
|
-
"-e",
|
|
124
|
-
"AWS_ALLOW_HTTP=true",
|
|
125
|
-
"-p",
|
|
126
|
-
"7777:7777",
|
|
127
|
-
image,
|
|
128
|
-
"dev",
|
|
129
|
-
"--grpc.address=0.0.0.0:7777",
|
|
130
|
-
]);
|
|
131
|
-
|
|
132
|
-
const exitCode = yield* docker.exitCode;
|
|
133
|
-
|
|
134
|
-
if (exitCode !== 0) {
|
|
135
|
-
return yield* Effect.fail(new Error(`Docker process exited with code ${exitCode}`));
|
|
136
|
-
}
|
|
137
|
-
});
|
package/src/utils/wings.ts
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { Effect, FileSystem, Path } from "effect";
|
|
2
|
-
import { HttpClient, HttpClientResponse } from "effect/unstable/http";
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
4
|
-
import { homedir } from "node:os";
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
|
|
7
|
-
const WINGS_DIR = join(homedir(), ".local", "share", "wings");
|
|
8
|
-
const GITHUB_RELEASES_URL = "https://github.com/useairfoil/wings/releases";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Get the platform string for Wings binary naming
|
|
12
|
-
* Examples: "aarch64-linux", "x86_64-linux", "aarch64-macos"
|
|
13
|
-
*/
|
|
14
|
-
function getPlatformString(): string {
|
|
15
|
-
const platform = process.platform;
|
|
16
|
-
const arch = process.arch;
|
|
17
|
-
|
|
18
|
-
const archMap: Record<string, string> = {
|
|
19
|
-
arm64: "aarch64",
|
|
20
|
-
x64: "x86_64",
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const osMap: Record<string, string> = {
|
|
24
|
-
darwin: "macos",
|
|
25
|
-
linux: "linux",
|
|
26
|
-
win32: "windows",
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const mappedArch = archMap[arch] || arch;
|
|
30
|
-
const mappedOs = osMap[platform] || platform;
|
|
31
|
-
|
|
32
|
-
return `${mappedArch}-${mappedOs}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Get the binary filename based on platform and stress variant
|
|
37
|
-
* Examples:
|
|
38
|
-
* - "wings-aarch64-macos"
|
|
39
|
-
* - "wings-stress-aarch64-linux"
|
|
40
|
-
*/
|
|
41
|
-
function getBinaryFilename(isStress: boolean): string {
|
|
42
|
-
const platformString = getPlatformString();
|
|
43
|
-
return isStress ? `wings-stress-${platformString}` : `wings-${platformString}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const getWingsPath = (version: string, isStress = false) =>
|
|
47
|
-
Effect.gen(function* () {
|
|
48
|
-
const binaryFilename = getBinaryFilename(isStress);
|
|
49
|
-
const path = yield* Path.Path;
|
|
50
|
-
return path.join(WINGS_DIR, `${binaryFilename}-${version}`);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
export const downloadWings = (version: string, targetPath: string, isStress = false) =>
|
|
54
|
-
Effect.gen(function* () {
|
|
55
|
-
const fs = yield* FileSystem.FileSystem;
|
|
56
|
-
const client = yield* HttpClient.HttpClient;
|
|
57
|
-
|
|
58
|
-
const filename = getBinaryFilename(isStress);
|
|
59
|
-
const tempPath = `${targetPath}.download`;
|
|
60
|
-
|
|
61
|
-
const downloadPath = version === "latest" ? "latest/download" : `download/${version}`;
|
|
62
|
-
const url = `${GITHUB_RELEASES_URL}/${downloadPath}/${filename}`;
|
|
63
|
-
|
|
64
|
-
yield* fs.makeDirectory(WINGS_DIR, { recursive: true });
|
|
65
|
-
yield* fs.remove(tempPath).pipe(Effect.ignore);
|
|
66
|
-
|
|
67
|
-
const download = Effect.gen(function* () {
|
|
68
|
-
const response = yield* client.get(url);
|
|
69
|
-
const buffer = yield* HttpClientResponse.matchStatus({
|
|
70
|
-
200: (response) => response.arrayBuffer,
|
|
71
|
-
orElse: (response) =>
|
|
72
|
-
Effect.fail(new Error(`Failed to download Wings from ${url}: ${response.status}`)),
|
|
73
|
-
})(response);
|
|
74
|
-
|
|
75
|
-
yield* fs.writeFile(tempPath, new Uint8Array(buffer));
|
|
76
|
-
yield* verifyChecksum(version, tempPath, isStress);
|
|
77
|
-
yield* fs.chmod(tempPath, 0o755);
|
|
78
|
-
yield* fs.rename(tempPath, targetPath);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
yield* download.pipe(Effect.onError(() => fs.remove(tempPath).pipe(Effect.ignore)));
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Download and verify the checksum of a Wings binary
|
|
86
|
-
* The hash file format is: "<hash> <path>/wings"
|
|
87
|
-
*/
|
|
88
|
-
export const verifyChecksum = (version: string, filePath: string, isStress = false) =>
|
|
89
|
-
Effect.gen(function* () {
|
|
90
|
-
const fs = yield* FileSystem.FileSystem;
|
|
91
|
-
const client = yield* HttpClient.HttpClient;
|
|
92
|
-
|
|
93
|
-
const filename = getBinaryFilename(isStress);
|
|
94
|
-
const hashFilename = `${filename}-hash.txt`;
|
|
95
|
-
|
|
96
|
-
const downloadPath = version === "latest" ? "latest/download" : `download/${version}`;
|
|
97
|
-
const url = `${GITHUB_RELEASES_URL}/${downloadPath}/${hashFilename}`;
|
|
98
|
-
|
|
99
|
-
const response = yield* client.get(url);
|
|
100
|
-
const hashContent = yield* HttpClientResponse.matchStatus({
|
|
101
|
-
200: (response) => response.text,
|
|
102
|
-
orElse: (response) => {
|
|
103
|
-
return Effect.fail(
|
|
104
|
-
new Error(`Failed to download hash file from ${url}: ${response.status}`),
|
|
105
|
-
);
|
|
106
|
-
},
|
|
107
|
-
})(response);
|
|
108
|
-
|
|
109
|
-
const expectedChecksum = hashContent.trim().split(/\s+/)[0];
|
|
110
|
-
|
|
111
|
-
if (!expectedChecksum) {
|
|
112
|
-
return yield* Effect.fail(new Error("Invalid hash file format"));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const fileBuffer = yield* fs.readFile(filePath);
|
|
116
|
-
|
|
117
|
-
const hash = createHash("sha256");
|
|
118
|
-
hash.update(fileBuffer);
|
|
119
|
-
const actualChecksum = hash.digest("hex");
|
|
120
|
-
|
|
121
|
-
if (actualChecksum !== expectedChecksum) {
|
|
122
|
-
return yield* Effect.fail(new Error("Wings binary checksum mismatch"));
|
|
123
|
-
}
|
|
124
|
-
});
|