@peerbit/shared-fs-cli 0.0.1
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 +202 -0
- package/README.md +84 -0
- package/lib/esm/bin.d.ts +2 -0
- package/lib/esm/bin.js +7 -0
- package/lib/esm/bin.js.map +1 -0
- package/lib/esm/cross-os-interop.d.ts +2 -0
- package/lib/esm/cross-os-interop.js +99 -0
- package/lib/esm/cross-os-interop.js.map +1 -0
- package/lib/esm/index.d.ts +2 -0
- package/lib/esm/index.js +576 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/install-native-adapter.d.ts +2 -0
- package/lib/esm/install-native-adapter.js +38 -0
- package/lib/esm/install-native-adapter.js.map +1 -0
- package/lib/esm/native-adapter.d.ts +55 -0
- package/lib/esm/native-adapter.js +268 -0
- package/lib/esm/native-adapter.js.map +1 -0
- package/package.json +53 -0
- package/scripts/postinstall.mjs +38 -0
- package/src/bin.ts +8 -0
- package/src/cross-os-interop.ts +133 -0
- package/src/index.ts +788 -0
- package/src/install-native-adapter.ts +48 -0
- package/src/native-adapter.ts +434 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type NativeAdapterTarget = {
|
|
2
|
+
id: string;
|
|
3
|
+
platform: NodeJS.Platform;
|
|
4
|
+
arch: NodeJS.Architecture;
|
|
5
|
+
archiveExtension: "tar.gz" | "zip";
|
|
6
|
+
binaryName: string;
|
|
7
|
+
};
|
|
8
|
+
export type ResolveNativeAdapterOptions = {
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
installDir?: string;
|
|
11
|
+
platform?: NodeJS.Platform;
|
|
12
|
+
commandExists?: (command: string) => Promise<boolean>;
|
|
13
|
+
};
|
|
14
|
+
export type InstallNativeAdapterOptions = {
|
|
15
|
+
installDir?: string;
|
|
16
|
+
platform?: NodeJS.Platform;
|
|
17
|
+
arch?: NodeJS.Architecture;
|
|
18
|
+
version?: string;
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
force?: boolean;
|
|
21
|
+
ifNeeded?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export type InstallNativeAdapterResult = {
|
|
24
|
+
binaryPath: string;
|
|
25
|
+
installed: boolean;
|
|
26
|
+
skippedReason?: "already-installed";
|
|
27
|
+
target: NativeAdapterTarget;
|
|
28
|
+
assetName: string;
|
|
29
|
+
url: string;
|
|
30
|
+
};
|
|
31
|
+
export declare class NativeAdapterInstallError extends Error {
|
|
32
|
+
constructor(message: string);
|
|
33
|
+
}
|
|
34
|
+
export declare const nativeAdapterBinaryName: (platform?: NodeJS.Platform) => "peerbit-shared-fs-native" | "peerbit-shared-fs-native.exe";
|
|
35
|
+
export declare const getNativeAdapterTarget: (platform?: NodeJS.Platform, arch?: NodeJS.Architecture) => NativeAdapterTarget;
|
|
36
|
+
export declare const nativeAdapterAssetName: (target: NativeAdapterTarget) => string;
|
|
37
|
+
export declare const nativeAdapterReleaseTag: (version: string) => string;
|
|
38
|
+
export declare const nativeAdapterDownloadBaseUrl: (tag: string) => string;
|
|
39
|
+
export declare const nativeAdapterDownloadUrl: (options: {
|
|
40
|
+
assetName: string;
|
|
41
|
+
baseUrl?: string;
|
|
42
|
+
tag: string;
|
|
43
|
+
}) => string;
|
|
44
|
+
export declare const defaultNativeAdapterInstallDir: (env?: NodeJS.ProcessEnv) => string;
|
|
45
|
+
export declare const defaultNativeAdapterPath: (options?: {
|
|
46
|
+
env?: NodeJS.ProcessEnv;
|
|
47
|
+
installDir?: string;
|
|
48
|
+
platform?: NodeJS.Platform;
|
|
49
|
+
}) => string;
|
|
50
|
+
export declare const commandExistsOnPath: (command: string, options?: {
|
|
51
|
+
env?: NodeJS.ProcessEnv;
|
|
52
|
+
platform?: NodeJS.Platform;
|
|
53
|
+
}) => Promise<boolean>;
|
|
54
|
+
export declare const resolveExternalNativeAdapter: (explicitCommand?: string, options?: ResolveNativeAdapterOptions) => Promise<string | undefined>;
|
|
55
|
+
export declare const installNativeAdapter: (options?: InstallNativeAdapterOptions) => Promise<InstallNativeAdapterResult>;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import fsp from "node:fs/promises";
|
|
4
|
+
import http from "node:http";
|
|
5
|
+
import https from "node:https";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { pipeline } from "node:stream/promises";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
const CLI_PACKAGE_NAME = "@peerbit/shared-fs-cli";
|
|
11
|
+
const DEFAULT_RELEASE_REPOSITORY = "dao-xyz/peerbit-examples";
|
|
12
|
+
const DEFAULT_PATH_COMMAND = "peerbit-shared-fs-native";
|
|
13
|
+
export class NativeAdapterInstallError extends Error {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "NativeAdapterInstallError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export const nativeAdapterBinaryName = (platform = process.platform) => platform === "win32" ? `${DEFAULT_PATH_COMMAND}.exe` : DEFAULT_PATH_COMMAND;
|
|
20
|
+
export const getNativeAdapterTarget = (platform = process.platform, arch = process.arch) => {
|
|
21
|
+
if (platform !== "linux" && platform !== "darwin" && platform !== "win32") {
|
|
22
|
+
throw new NativeAdapterInstallError(`No prebuilt native adapter target for platform ${platform}.`);
|
|
23
|
+
}
|
|
24
|
+
if (arch !== "x64" && arch !== "arm64") {
|
|
25
|
+
throw new NativeAdapterInstallError(`No prebuilt native adapter target for architecture ${arch}.`);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
id: `${platform}-${arch}`,
|
|
29
|
+
platform,
|
|
30
|
+
arch,
|
|
31
|
+
archiveExtension: platform === "win32" ? "zip" : "tar.gz",
|
|
32
|
+
binaryName: nativeAdapterBinaryName(platform),
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export const nativeAdapterAssetName = (target) => `peerbit-shared-fs-native-${target.id}.${target.archiveExtension}`;
|
|
36
|
+
export const nativeAdapterReleaseTag = (version) => version.startsWith("shared-fs-native-v")
|
|
37
|
+
? version
|
|
38
|
+
: `shared-fs-native-v${version.replace(/^v/, "")}`;
|
|
39
|
+
export const nativeAdapterDownloadBaseUrl = (tag) => `https://github.com/${DEFAULT_RELEASE_REPOSITORY}/releases/download/${tag}`;
|
|
40
|
+
export const nativeAdapterDownloadUrl = (options) => {
|
|
41
|
+
const baseUrl = options.baseUrl ?? nativeAdapterDownloadBaseUrl(options.tag);
|
|
42
|
+
return `${baseUrl.replace(/\/$/, "")}/${options.assetName}`;
|
|
43
|
+
};
|
|
44
|
+
export const defaultNativeAdapterInstallDir = (env = process.env) => env.PEERBIT_SHARED_FS_NATIVE_INSTALL_DIR ||
|
|
45
|
+
path.join(os.homedir(), ".peerbit", "shared-fs", "bin");
|
|
46
|
+
export const defaultNativeAdapterPath = (options = {}) => path.join(options.installDir ??
|
|
47
|
+
defaultNativeAdapterInstallDir(options.env ?? process.env), nativeAdapterBinaryName(options.platform ?? process.platform));
|
|
48
|
+
const pathExists = async (candidate) => {
|
|
49
|
+
try {
|
|
50
|
+
await fsp.access(candidate, fs.constants.F_OK);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const executablePathExists = async (candidate) => {
|
|
58
|
+
try {
|
|
59
|
+
await fsp.access(candidate, fs.constants.X_OK);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return process.platform === "win32" && (await pathExists(candidate));
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const isPathLikeCommand = (command) => path.isAbsolute(command) || command.includes("/") || command.includes("\\");
|
|
67
|
+
export const commandExistsOnPath = async (command, options = {}) => {
|
|
68
|
+
const env = options.env ?? process.env;
|
|
69
|
+
const platform = options.platform ?? process.platform;
|
|
70
|
+
if (isPathLikeCommand(command)) {
|
|
71
|
+
return executablePathExists(command);
|
|
72
|
+
}
|
|
73
|
+
const pathValue = env.PATH;
|
|
74
|
+
if (!pathValue) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const extensions = platform === "win32"
|
|
78
|
+
? (env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean)
|
|
79
|
+
: [""];
|
|
80
|
+
const commandNames = platform === "win32" && path.extname(command) === ""
|
|
81
|
+
? [
|
|
82
|
+
command,
|
|
83
|
+
...extensions.map((extension) => `${command}${extension}`),
|
|
84
|
+
]
|
|
85
|
+
: [command];
|
|
86
|
+
for (const directory of pathValue.split(path.delimiter)) {
|
|
87
|
+
for (const commandName of commandNames) {
|
|
88
|
+
if (await executablePathExists(path.join(directory, commandName))) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
};
|
|
95
|
+
export const resolveExternalNativeAdapter = async (explicitCommand, options = {}) => {
|
|
96
|
+
const env = options.env ?? process.env;
|
|
97
|
+
const platform = options.platform ?? process.platform;
|
|
98
|
+
const commandExists = options.commandExists ??
|
|
99
|
+
((command) => commandExistsOnPath(command, { env, platform }));
|
|
100
|
+
if (explicitCommand?.trim()) {
|
|
101
|
+
return explicitCommand;
|
|
102
|
+
}
|
|
103
|
+
if (env.PEERBIT_SHARED_FS_NATIVE_ADAPTER?.trim()) {
|
|
104
|
+
return env.PEERBIT_SHARED_FS_NATIVE_ADAPTER;
|
|
105
|
+
}
|
|
106
|
+
const managedPath = defaultNativeAdapterPath({
|
|
107
|
+
env,
|
|
108
|
+
installDir: options.installDir,
|
|
109
|
+
platform,
|
|
110
|
+
});
|
|
111
|
+
if (await pathExists(managedPath)) {
|
|
112
|
+
return managedPath;
|
|
113
|
+
}
|
|
114
|
+
if (await commandExists(DEFAULT_PATH_COMMAND)) {
|
|
115
|
+
return DEFAULT_PATH_COMMAND;
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
};
|
|
119
|
+
const readCliPackageVersion = async () => {
|
|
120
|
+
let directory = path.dirname(fileURLToPath(import.meta.url));
|
|
121
|
+
while (true) {
|
|
122
|
+
const packagePath = path.join(directory, "package.json");
|
|
123
|
+
try {
|
|
124
|
+
const parsed = JSON.parse(await fsp.readFile(packagePath, "utf8"));
|
|
125
|
+
if (parsed.name === CLI_PACKAGE_NAME && parsed.version) {
|
|
126
|
+
return parsed.version;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch { }
|
|
130
|
+
const parent = path.dirname(directory);
|
|
131
|
+
if (parent === directory) {
|
|
132
|
+
throw new NativeAdapterInstallError(`Unable to find ${CLI_PACKAGE_NAME} package version.`);
|
|
133
|
+
}
|
|
134
|
+
directory = parent;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const downloadFile = async (url, destination, redirectBudget = 5) => {
|
|
138
|
+
const parsedUrl = new URL(url);
|
|
139
|
+
const client = parsedUrl.protocol === "http:" ? http : https;
|
|
140
|
+
await new Promise((resolve, reject) => {
|
|
141
|
+
const request = client.get(parsedUrl, {
|
|
142
|
+
headers: {
|
|
143
|
+
"user-agent": `${CLI_PACKAGE_NAME} native-adapter-installer`,
|
|
144
|
+
},
|
|
145
|
+
}, (response) => {
|
|
146
|
+
const statusCode = response.statusCode ?? 0;
|
|
147
|
+
const location = response.headers.location;
|
|
148
|
+
if (statusCode >= 300 &&
|
|
149
|
+
statusCode < 400 &&
|
|
150
|
+
location &&
|
|
151
|
+
redirectBudget > 0) {
|
|
152
|
+
response.resume();
|
|
153
|
+
downloadFile(new URL(location, parsedUrl).toString(), destination, redirectBudget - 1).then(resolve, reject);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (statusCode !== 200) {
|
|
157
|
+
response.resume();
|
|
158
|
+
reject(new NativeAdapterInstallError(`Download failed with HTTP ${statusCode}: ${url}`));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
pipeline(response, fs.createWriteStream(destination)).then(resolve, reject);
|
|
162
|
+
});
|
|
163
|
+
request.on("error", reject);
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
const runProcess = async (command, args) => {
|
|
167
|
+
await new Promise((resolve, reject) => {
|
|
168
|
+
const child = spawn(command, args, {
|
|
169
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
170
|
+
});
|
|
171
|
+
let stderr = "";
|
|
172
|
+
child.stderr.on("data", (chunk) => {
|
|
173
|
+
stderr += chunk.toString("utf8");
|
|
174
|
+
});
|
|
175
|
+
child.once("error", reject);
|
|
176
|
+
child.once("exit", (code, signal) => {
|
|
177
|
+
if (code === 0) {
|
|
178
|
+
resolve();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
reject(new NativeAdapterInstallError(`${command} ${args.join(" ")} failed with code=${code} signal=${signal}: ${stderr.trim()}`));
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
const extractArchive = async (archivePath, outputDirectory, target) => {
|
|
186
|
+
if (target.archiveExtension === "zip") {
|
|
187
|
+
const quotePowerShell = (value) => `'${value.replace(/'/g, "''")}'`;
|
|
188
|
+
await runProcess("powershell.exe", [
|
|
189
|
+
"-NoProfile",
|
|
190
|
+
"-ExecutionPolicy",
|
|
191
|
+
"Bypass",
|
|
192
|
+
"-Command",
|
|
193
|
+
`Expand-Archive -LiteralPath ${quotePowerShell(archivePath)} -DestinationPath ${quotePowerShell(outputDirectory)} -Force`,
|
|
194
|
+
]);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
await runProcess("tar", ["-xzf", archivePath, "-C", outputDirectory]);
|
|
198
|
+
};
|
|
199
|
+
const findExtractedBinary = async (directory, binaryName) => {
|
|
200
|
+
const entries = await fsp.readdir(directory, { withFileTypes: true });
|
|
201
|
+
for (const entry of entries) {
|
|
202
|
+
const entryPath = path.join(directory, entry.name);
|
|
203
|
+
if (entry.isFile() &&
|
|
204
|
+
entry.name.toLowerCase() === binaryName.toLowerCase()) {
|
|
205
|
+
return entryPath;
|
|
206
|
+
}
|
|
207
|
+
if (entry.isDirectory()) {
|
|
208
|
+
const found = await findExtractedBinary(entryPath, binaryName);
|
|
209
|
+
if (found) {
|
|
210
|
+
return found;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return undefined;
|
|
215
|
+
};
|
|
216
|
+
export const installNativeAdapter = async (options = {}) => {
|
|
217
|
+
const target = getNativeAdapterTarget(options.platform, options.arch);
|
|
218
|
+
const installDir = options.installDir ?? defaultNativeAdapterInstallDir(process.env);
|
|
219
|
+
const binaryPath = path.join(installDir, target.binaryName);
|
|
220
|
+
const existing = await pathExists(binaryPath);
|
|
221
|
+
const version = options.version ??
|
|
222
|
+
process.env.PEERBIT_SHARED_FS_NATIVE_VERSION ??
|
|
223
|
+
(await readCliPackageVersion());
|
|
224
|
+
const tag = nativeAdapterReleaseTag(version);
|
|
225
|
+
const assetName = nativeAdapterAssetName(target);
|
|
226
|
+
const url = nativeAdapterDownloadUrl({
|
|
227
|
+
assetName,
|
|
228
|
+
baseUrl: options.baseUrl ??
|
|
229
|
+
process.env.PEERBIT_SHARED_FS_NATIVE_RELEASE_BASE_URL,
|
|
230
|
+
tag,
|
|
231
|
+
});
|
|
232
|
+
if (existing && (options.ifNeeded || !options.force)) {
|
|
233
|
+
return {
|
|
234
|
+
binaryPath,
|
|
235
|
+
installed: false,
|
|
236
|
+
skippedReason: "already-installed",
|
|
237
|
+
target,
|
|
238
|
+
assetName,
|
|
239
|
+
url,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const tempDirectory = await fsp.mkdtemp(path.join(os.tmpdir(), "peerbit-shared-fs-native-"));
|
|
243
|
+
try {
|
|
244
|
+
const archivePath = path.join(tempDirectory, assetName);
|
|
245
|
+
await downloadFile(url, archivePath);
|
|
246
|
+
await extractArchive(archivePath, tempDirectory, target);
|
|
247
|
+
const extractedBinary = await findExtractedBinary(tempDirectory, target.binaryName);
|
|
248
|
+
if (!extractedBinary) {
|
|
249
|
+
throw new NativeAdapterInstallError(`Archive ${assetName} did not contain ${target.binaryName}.`);
|
|
250
|
+
}
|
|
251
|
+
await fsp.mkdir(installDir, { recursive: true });
|
|
252
|
+
await fsp.copyFile(extractedBinary, binaryPath);
|
|
253
|
+
if (target.platform !== "win32") {
|
|
254
|
+
await fsp.chmod(binaryPath, 0o755);
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
binaryPath,
|
|
258
|
+
installed: true,
|
|
259
|
+
target,
|
|
260
|
+
assetName,
|
|
261
|
+
url,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
finally {
|
|
265
|
+
await fsp.rm(tempDirectory, { recursive: true, force: true });
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
//# sourceMappingURL=native-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-adapter.js","sourceRoot":"","sources":["../../src/native-adapter.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@peerbit/shared-fs-cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"author": "dao.xyz",
|
|
5
|
+
"repository": "https://github.com/dao-xyz/peerbit-examples",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"private": false,
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"module": "lib/esm/index.js",
|
|
14
|
+
"types": "lib/esm/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./lib/esm/index.d.ts",
|
|
18
|
+
"import": "./lib/esm/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"bin": {
|
|
22
|
+
"peerbit-fs": "./lib/esm/bin.js"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"lib",
|
|
26
|
+
"src",
|
|
27
|
+
"scripts",
|
|
28
|
+
"!src/**/__tests__",
|
|
29
|
+
"!lib/**/__tests__",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@multiformats/multiaddr": "^13.0.1",
|
|
37
|
+
"chalk": "^5.3.0",
|
|
38
|
+
"peerbit": "^5.2.19",
|
|
39
|
+
"yargs": "^17.7.2",
|
|
40
|
+
"@peerbit/shared-fs": "0.0.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.6.3"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"clean": "shx rm -rf lib/*",
|
|
47
|
+
"build": "pnpm run clean && tsc -p tsconfig.json",
|
|
48
|
+
"install-native-adapter": "node lib/esm/install-native-adapter.js",
|
|
49
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
|
|
8
|
+
if (process.env.PEERBIT_SHARED_FS_SKIP_NATIVE_POSTINSTALL === "1") {
|
|
9
|
+
process.exit(0);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const isGlobalInstall =
|
|
13
|
+
process.env.npm_config_global === "true" ||
|
|
14
|
+
process.env.npm_config_global === "1" ||
|
|
15
|
+
process.env.npm_config_location === "global";
|
|
16
|
+
|
|
17
|
+
if (!isGlobalInstall) {
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
22
|
+
const installer = join(packageRoot, "lib", "esm", "install-native-adapter.js");
|
|
23
|
+
|
|
24
|
+
if (!existsSync(installer)) {
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const result = spawnSync(
|
|
29
|
+
process.execPath,
|
|
30
|
+
[installer, "--if-needed", "--quiet"],
|
|
31
|
+
{ stdio: "inherit" }
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
if (result.error || result.status !== 0) {
|
|
35
|
+
console.warn(
|
|
36
|
+
"peerbit-fs native adapter auto-install skipped; run `peerbit-fs install-adapter` after install."
|
|
37
|
+
);
|
|
38
|
+
}
|
package/src/bin.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { openSharedFs } from "@peerbit/shared-fs";
|
|
6
|
+
import { Peerbit } from "peerbit";
|
|
7
|
+
|
|
8
|
+
type Options = {
|
|
9
|
+
role: "seed" | "join";
|
|
10
|
+
machine: string;
|
|
11
|
+
expected: string[];
|
|
12
|
+
addressFile: string;
|
|
13
|
+
timeoutMs: number;
|
|
14
|
+
directory?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const parseArgs = (args: string[]): Options => {
|
|
18
|
+
const value = (name: string) => {
|
|
19
|
+
const index = args.indexOf(name);
|
|
20
|
+
return index === -1 ? undefined : args[index + 1];
|
|
21
|
+
};
|
|
22
|
+
const role = value("--role");
|
|
23
|
+
if (role !== "seed" && role !== "join") {
|
|
24
|
+
throw new Error("--role must be seed or join");
|
|
25
|
+
}
|
|
26
|
+
const machine = value("--machine");
|
|
27
|
+
if (!machine) {
|
|
28
|
+
throw new Error("--machine is required");
|
|
29
|
+
}
|
|
30
|
+
const addressFile = value("--address-file");
|
|
31
|
+
if (!addressFile) {
|
|
32
|
+
throw new Error("--address-file is required");
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
role,
|
|
36
|
+
machine,
|
|
37
|
+
expected: (value("--expected") ?? "linux,macos,windows")
|
|
38
|
+
.split(",")
|
|
39
|
+
.map((entry) => entry.trim())
|
|
40
|
+
.filter(Boolean),
|
|
41
|
+
addressFile,
|
|
42
|
+
timeoutMs: Number(value("--timeout-ms") ?? 10 * 60 * 1000),
|
|
43
|
+
directory: value("--directory"),
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const decode = (value: Uint8Array | undefined) =>
|
|
48
|
+
value ? new TextDecoder().decode(value) : undefined;
|
|
49
|
+
|
|
50
|
+
const waitUntil = async (
|
|
51
|
+
assertion: () => Promise<void> | void,
|
|
52
|
+
timeoutMs: number,
|
|
53
|
+
intervalMs = 2_000
|
|
54
|
+
) => {
|
|
55
|
+
const deadline = Date.now() + timeoutMs;
|
|
56
|
+
let lastError: unknown;
|
|
57
|
+
while (Date.now() < deadline) {
|
|
58
|
+
try {
|
|
59
|
+
await assertion();
|
|
60
|
+
return;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
lastError = error;
|
|
63
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
throw lastError;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const filePathForMachine = (machine: string) => `/${machine}.txt`;
|
|
70
|
+
|
|
71
|
+
const waitForAllMachines = async (
|
|
72
|
+
fs: Awaited<ReturnType<typeof openSharedFs>>,
|
|
73
|
+
expected: string[],
|
|
74
|
+
timeoutMs: number
|
|
75
|
+
) => {
|
|
76
|
+
await waitUntil(async () => {
|
|
77
|
+
const missing: string[] = [];
|
|
78
|
+
for (const machine of expected) {
|
|
79
|
+
const contents = decode(
|
|
80
|
+
await fs.readFile(filePathForMachine(machine))
|
|
81
|
+
);
|
|
82
|
+
if (contents !== `hello from ${machine}`) {
|
|
83
|
+
missing.push(machine);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (missing.length > 0) {
|
|
87
|
+
throw new Error(`Missing files from: ${missing.join(", ")}`);
|
|
88
|
+
}
|
|
89
|
+
}, timeoutMs);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const main = async () => {
|
|
93
|
+
const options = parseArgs(process.argv.slice(2));
|
|
94
|
+
const peer = await Peerbit.create({ directory: options.directory });
|
|
95
|
+
try {
|
|
96
|
+
await peer.bootstrap();
|
|
97
|
+
const address =
|
|
98
|
+
options.role === "join"
|
|
99
|
+
? (await readFile(options.addressFile, "utf8")).trim()
|
|
100
|
+
: undefined;
|
|
101
|
+
const fs = await openSharedFs({
|
|
102
|
+
peerbit: peer,
|
|
103
|
+
address,
|
|
104
|
+
machineLabel: options.machine,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (options.role === "seed") {
|
|
108
|
+
await mkdir(path.dirname(options.addressFile), { recursive: true });
|
|
109
|
+
await writeFile(options.addressFile, fs.address ?? "", "utf8");
|
|
110
|
+
console.log(`seed address: ${fs.address}`);
|
|
111
|
+
} else {
|
|
112
|
+
console.log(`joining address: ${address}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
await fs.writeFile(
|
|
116
|
+
filePathForMachine(options.machine),
|
|
117
|
+
`hello from ${options.machine}`
|
|
118
|
+
);
|
|
119
|
+
await waitForAllMachines(fs, options.expected, options.timeoutMs);
|
|
120
|
+
console.log(
|
|
121
|
+
`read files from all machines: ${options.expected.join(", ")}`
|
|
122
|
+
);
|
|
123
|
+
} finally {
|
|
124
|
+
await peer.stop();
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
main().catch((error) => {
|
|
129
|
+
console.error(
|
|
130
|
+
error instanceof Error ? error.stack || error.message : error
|
|
131
|
+
);
|
|
132
|
+
process.exitCode = 1;
|
|
133
|
+
});
|