@clanker-code/c2c 0.8.5 → 0.8.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/bin/c2c-deliver-inbox-js-wrapper.js +41 -0
- package/bin/c2c-js-wrapper.js +40 -8
- package/index.js +160 -44
- package/package.json +7 -6
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
const childProcess = require("node:child_process");
|
|
6
|
+
const { resolveC2cBinary } = require("..");
|
|
7
|
+
|
|
8
|
+
function executableForWrapper(argv1) {
|
|
9
|
+
const basename = path.basename(argv1 || "c2c");
|
|
10
|
+
return basename.startsWith("c2c-deliver-inbox") ? "c2c-deliver-inbox" : "c2c";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function main() {
|
|
14
|
+
const executable = executableForWrapper(process.argv[1]);
|
|
15
|
+
let binary;
|
|
16
|
+
try {
|
|
17
|
+
binary = resolveC2cBinary({ selfPath: __filename, executable });
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.error(error.message);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const result = childProcess.spawnSync(binary, process.argv.slice(2), {
|
|
24
|
+
stdio: "inherit",
|
|
25
|
+
env: process.env,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (result.error) {
|
|
29
|
+
console.error(`failed to execute ${binary}: ${result.error.message}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (result.signal) {
|
|
34
|
+
process.kill(process.pid, result.signal);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
main();
|
package/bin/c2c-js-wrapper.js
CHANGED
|
@@ -1,9 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
const childProcess = require("node:child_process");
|
|
6
|
+
const { resolveC2cBinary } = require("..");
|
|
7
|
+
|
|
8
|
+
function executableForWrapper(argv1) {
|
|
9
|
+
const basename = path.basename(argv1 || "c2c");
|
|
10
|
+
return basename.startsWith("c2c-deliver-inbox") ? "c2c-deliver-inbox" : "c2c";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function main() {
|
|
14
|
+
const executable = executableForWrapper(process.argv[1]);
|
|
15
|
+
let binary;
|
|
16
|
+
try {
|
|
17
|
+
binary = resolveC2cBinary({ selfPath: __filename, executable });
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.error(error.message);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const result = childProcess.spawnSync(binary, process.argv.slice(2), {
|
|
24
|
+
stdio: "inherit",
|
|
25
|
+
env: process.env,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (result.error) {
|
|
29
|
+
console.error(`failed to execute ${binary}: ${result.error.message}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (result.signal) {
|
|
34
|
+
process.kill(process.pid, result.signal);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
main();
|
package/index.js
CHANGED
|
@@ -1,70 +1,186 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"linux-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
|
|
6
|
+
const TARGETS = {
|
|
7
|
+
"linux-x64": {
|
|
8
|
+
packageName: "@clanker-code/c2c-linux-x64",
|
|
9
|
+
},
|
|
10
|
+
"linux-arm64": {
|
|
11
|
+
packageName: "@clanker-code/c2c-linux-arm64",
|
|
12
|
+
},
|
|
13
|
+
"darwin-x64": {
|
|
14
|
+
packageName: "@clanker-code/c2c-darwin-x64",
|
|
15
|
+
},
|
|
16
|
+
"darwin-arm64": {
|
|
17
|
+
packageName: "@clanker-code/c2c-darwin-arm64",
|
|
18
|
+
},
|
|
10
19
|
};
|
|
11
20
|
|
|
12
|
-
|
|
21
|
+
const EXECUTABLES = new Set(["c2c", "c2c-deliver-inbox"]);
|
|
22
|
+
|
|
23
|
+
function normalizeExecutable(executable = "c2c") {
|
|
24
|
+
if (!EXECUTABLES.has(executable)) {
|
|
25
|
+
throw new Error(`unsupported c2c executable: ${executable}`);
|
|
26
|
+
}
|
|
27
|
+
return executable;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function envOverrideName(executable) {
|
|
31
|
+
return executable === "c2c-deliver-inbox" ? "C2C_DELIVER_INBOX_BIN" : "C2C_BIN";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function canExecute(file) {
|
|
13
35
|
try {
|
|
14
36
|
fs.accessSync(file, fs.constants.X_OK);
|
|
15
37
|
return true;
|
|
16
|
-
} catch
|
|
38
|
+
} catch {
|
|
17
39
|
return false;
|
|
18
40
|
}
|
|
19
41
|
}
|
|
20
42
|
|
|
21
|
-
function
|
|
22
|
-
|
|
43
|
+
function sameFile(left, right) {
|
|
44
|
+
if (!left || !right) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
return fs.realpathSync(left) === fs.realpathSync(right);
|
|
50
|
+
} catch {
|
|
51
|
+
return path.resolve(left) === path.resolve(right);
|
|
52
|
+
}
|
|
23
53
|
}
|
|
24
54
|
|
|
25
|
-
function
|
|
26
|
-
|
|
55
|
+
function pathCandidates(env, platform, executable) {
|
|
56
|
+
const pathValue = env.PATH || "";
|
|
57
|
+
const dirs = pathValue.split(path.delimiter).filter(Boolean);
|
|
58
|
+
const names =
|
|
59
|
+
platform === "win32"
|
|
60
|
+
? [`${executable}.exe`, `${executable}.cmd`, `${executable}.bat`, executable]
|
|
61
|
+
: [executable];
|
|
62
|
+
|
|
63
|
+
return dirs.flatMap((dir) => names.map((name) => path.join(dir, name)));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function looksLikeSelfNpmShim(candidate, selfPath) {
|
|
67
|
+
if (!candidate.match(/\.(cmd|bat)$/i)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
27
71
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
72
|
+
const body = fs.readFileSync(candidate, "utf8");
|
|
73
|
+
const normalizedBody = body.replace(/\\/g, "/").toLowerCase();
|
|
74
|
+
const normalizedSelf = selfPath.replace(/\\/g, "/").toLowerCase();
|
|
75
|
+
return normalizedBody.includes(normalizedSelf) || normalizedBody.includes("c2c-js-wrapper.js");
|
|
76
|
+
} catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function findSystemExecutable(env, selfPath, platform, executable) {
|
|
82
|
+
for (const candidate of pathCandidates(env, platform, executable)) {
|
|
83
|
+
if (canExecute(candidate) && !sameFile(candidate, selfPath) && !looksLikeSelfNpmShim(candidate, selfPath)) {
|
|
84
|
+
return candidate;
|
|
85
|
+
}
|
|
37
86
|
}
|
|
38
87
|
return null;
|
|
39
88
|
}
|
|
40
89
|
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
90
|
+
function platformTarget(platform, arch) {
|
|
91
|
+
return TARGETS[`${platform}-${arch}`] || null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function platformPackageName(platform = process.platform, arch = process.arch) {
|
|
95
|
+
const target = platformTarget(platform, arch);
|
|
96
|
+
return target ? target.packageName : null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function resolvePlatformPackage(target, requireFrom, executable) {
|
|
45
100
|
try {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
101
|
+
const packageJson = require.resolve(`${target.packageName}/package.json`, {
|
|
102
|
+
paths: [requireFrom],
|
|
103
|
+
});
|
|
104
|
+
return path.join(path.dirname(packageJson), "bin", executable);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
const directRoot = findDirectPackageRoot(requireFrom, target, executable);
|
|
107
|
+
if (directRoot) {
|
|
108
|
+
return path.join(directRoot, "bin", executable);
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function findDirectPackageRoot(requireFrom, target, executable) {
|
|
115
|
+
let current = path.resolve(requireFrom);
|
|
116
|
+
const parts = target.packageName.split("/");
|
|
117
|
+
|
|
118
|
+
while (true) {
|
|
119
|
+
const candidate = path.join(current, "node_modules", ...parts);
|
|
120
|
+
const bin = path.join(candidate, "bin", executable);
|
|
121
|
+
if (fs.existsSync(bin)) {
|
|
122
|
+
return candidate;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const next = path.dirname(current);
|
|
126
|
+
if (next === current) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
current = next;
|
|
49
130
|
}
|
|
50
131
|
}
|
|
51
132
|
|
|
52
|
-
function resolveC2cBinary() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
133
|
+
function resolveC2cBinary(options = {}) {
|
|
134
|
+
const executable = normalizeExecutable(options.executable || "c2c");
|
|
135
|
+
const env = options.env || process.env;
|
|
136
|
+
const platform = options.platform || process.platform;
|
|
137
|
+
const arch = options.arch || process.arch;
|
|
138
|
+
const requireFrom = options.requireFrom || __dirname;
|
|
139
|
+
const selfPath = options.selfPath || path.join(__dirname, "bin", "c2c-js-wrapper.js");
|
|
140
|
+
const overrideName = envOverrideName(executable);
|
|
141
|
+
|
|
142
|
+
if (env[overrideName]) {
|
|
143
|
+
if (!canExecute(env[overrideName])) {
|
|
144
|
+
throw new Error(`${overrideName} is set but is not executable: ${env[overrideName]}`);
|
|
145
|
+
}
|
|
146
|
+
return env[overrideName];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const target = platformTarget(platform, arch);
|
|
150
|
+
let platformError = null;
|
|
151
|
+
|
|
152
|
+
if (target) {
|
|
153
|
+
try {
|
|
154
|
+
const resolved = resolvePlatformPackage(target, requireFrom, executable);
|
|
155
|
+
if (canExecute(resolved)) {
|
|
156
|
+
return resolved;
|
|
157
|
+
}
|
|
158
|
+
throw new Error(`resolved package binary is not executable: ${resolved}`);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
platformError = error;
|
|
56
161
|
}
|
|
57
|
-
return process.env.C2C_BIN;
|
|
58
162
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
163
|
+
|
|
164
|
+
const systemExecutable = findSystemExecutable(env, selfPath, platform, executable);
|
|
165
|
+
if (systemExecutable) {
|
|
166
|
+
return systemExecutable;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (!target) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`No c2c npm binary package is available for ${platform}-${arch}. ` +
|
|
172
|
+
`Install ${executable} system-wide, choose a supported platform, or set ${overrideName} to a ${executable} executable.`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
63
176
|
throw new Error(
|
|
64
|
-
`
|
|
65
|
-
|
|
66
|
-
|
|
177
|
+
`Unable to find executable ${executable} in ${target.packageName} for ${platform}-${arch}. ` +
|
|
178
|
+
`Install @clanker-code/c2c with optional dependencies enabled, install ${executable} system-wide, or set ${overrideName}. ` +
|
|
179
|
+
`Cause: ${platformError.message}`
|
|
67
180
|
);
|
|
68
181
|
}
|
|
69
182
|
|
|
70
|
-
module.exports = {
|
|
183
|
+
module.exports = {
|
|
184
|
+
resolveC2cBinary,
|
|
185
|
+
_platformPackageName: platformPackageName,
|
|
186
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clanker-code/c2c",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.6",
|
|
4
4
|
"description": "Resolver and CLI wrapper for the c2c agent messaging binary",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -9,16 +9,17 @@
|
|
|
9
9
|
},
|
|
10
10
|
"main": "index.js",
|
|
11
11
|
"bin": {
|
|
12
|
-
"c2c": "bin/c2c-js-wrapper.js"
|
|
12
|
+
"c2c": "bin/c2c-js-wrapper.js",
|
|
13
|
+
"c2c-deliver-inbox": "bin/c2c-deliver-inbox-js-wrapper.js"
|
|
13
14
|
},
|
|
14
15
|
"files": [
|
|
15
16
|
"bin/",
|
|
16
17
|
"index.js"
|
|
17
18
|
],
|
|
18
19
|
"optionalDependencies": {
|
|
19
|
-
"@clanker-code/c2c-linux-x64": "0.8.
|
|
20
|
-
"@clanker-code/c2c-linux-arm64": "0.8.
|
|
21
|
-
"@clanker-code/c2c-darwin-x64": "0.8.
|
|
22
|
-
"@clanker-code/c2c-darwin-arm64": "0.8.
|
|
20
|
+
"@clanker-code/c2c-linux-x64": "0.8.6",
|
|
21
|
+
"@clanker-code/c2c-linux-arm64": "0.8.6",
|
|
22
|
+
"@clanker-code/c2c-darwin-x64": "0.8.6",
|
|
23
|
+
"@clanker-code/c2c-darwin-arm64": "0.8.6"
|
|
23
24
|
}
|
|
24
25
|
}
|