@appthreat/caxa 1.0.12 → 2.0.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/README.md +106 -71
- package/build/index.d.mts +1 -1
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +140 -100
- package/build/index.mjs.map +1 -1
- package/package.json +16 -8
- package/source/index.mts +200 -181
- package/stubs/go.mod +5 -0
- package/stubs/go.sum +2 -0
- package/stubs/stub--darwin--arm64 +0 -0
- package/stubs/stub--darwin--x64 +0 -0
- package/stubs/stub--linux--arm +0 -0
- package/stubs/stub--linux--arm64 +0 -0
- package/stubs/stub--linux--x64 +0 -0
- package/stubs/stub--win32--arm64 +0 -0
- package/stubs/stub--win32--x64 +0 -0
- package/stubs/stub.go +216 -230
- package/stubs/stub_test.go +144 -0
- package/tsconfig.json +28 -0
- package/source/tsconfig.json +0 -19
- package/stubs/stub--linux--riscv64 +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appthreat/caxa",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Package Node.js applications into executable binaries",
|
|
5
5
|
"author": "Team AppThreat <cloud@appthreat.com>",
|
|
6
6
|
"homepage": "https://github.com/appthreat/caxa",
|
|
@@ -21,9 +21,17 @@
|
|
|
21
21
|
"caxa": "build/index.mjs"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"prepare": "
|
|
25
|
-
"prepare:stubs": "shx rm -f stubs/stub
|
|
26
|
-
"
|
|
24
|
+
"prepare": "npm run prepare:stubs && tsc",
|
|
25
|
+
"prepare:stubs": "shx rm -f stubs/stub--* && npm run build:stub:win && npm run build:stub:mac && npm run build:stub:linux",
|
|
26
|
+
"build:stub:win": "cross-env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -C stubs -ldflags \"-s -w\" -o stub--win32--x64 stub.go && npm run append:sig -- stubs/stub--win32--x64 && cross-env CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -C stubs -ldflags \"-s -w\" -o stub--win32--arm64 stub.go && npm run append:sig -- stubs/stub--win32--arm64",
|
|
27
|
+
"build:stub:mac": "cross-env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -C stubs -ldflags \"-s -w\" -o stub--darwin--x64 stub.go && npm run append:sig -- stubs/stub--darwin--x64 && cross-env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -C stubs -ldflags \"-s -w\" -o stub--darwin--arm64 stub.go && npm run append:sig -- stubs/stub--darwin--arm64",
|
|
28
|
+
"build:stub:linux": "cross-env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -C stubs -ldflags \"-s -w\" -o stub--linux--x64 stub.go && npm run append:sig -- stubs/stub--linux--x64 && cross-env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -C stubs -ldflags \"-s -w\" -o stub--linux--arm64 stub.go && npm run append:sig -- stubs/stub--linux--arm64 && cross-env CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -C stubs -ldflags \"-s -w\" -o stub--linux--arm stub.go && npm run append:sig -- stubs/stub--linux--arm",
|
|
29
|
+
"append:sig": "node -e \"const fs=require('fs'); fs.appendFileSync(process.argv[1], '\\nCAXACAXACAXA\\n')\"",
|
|
30
|
+
"pretest": "npm run prepare:stubs",
|
|
31
|
+
"test": "npm run test:lint && npm run test:go && npm run test:e2e",
|
|
32
|
+
"test:lint": "prettier --check \"source/**/*.mts\" --end-of-line auto",
|
|
33
|
+
"test:go": "cd stubs && go test -v",
|
|
34
|
+
"test:e2e": "node test/e2e.test.mjs"
|
|
27
35
|
},
|
|
28
36
|
"dependencies": {
|
|
29
37
|
"archiver": "^7.0.1",
|
|
@@ -31,16 +39,16 @@
|
|
|
31
39
|
"crypto-random-string": "^5.0.0",
|
|
32
40
|
"dedent": "^1.6.0",
|
|
33
41
|
"fs-extra": "^11.3.0",
|
|
34
|
-
"globby": "^
|
|
42
|
+
"globby": "^16.0.0"
|
|
35
43
|
},
|
|
36
44
|
"devDependencies": {
|
|
37
|
-
"@types/archiver": "^
|
|
45
|
+
"@types/archiver": "^7.0.0",
|
|
38
46
|
"@types/dedent": "^0.7.2",
|
|
39
47
|
"@types/fs-extra": "^11.0.4",
|
|
40
48
|
"@types/node": "^24.0.10",
|
|
41
|
-
"cross-env": "^
|
|
49
|
+
"cross-env": "^10.1.0",
|
|
42
50
|
"prettier": "^3.6.2",
|
|
43
51
|
"shx": "^0.4.0",
|
|
44
52
|
"typescript": "^5.8.3"
|
|
45
53
|
}
|
|
46
|
-
}
|
|
54
|
+
}
|
package/source/index.mts
CHANGED
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import url from "node:url";
|
|
5
|
-
import os from "node:os";
|
|
6
5
|
import stream from "node:stream/promises";
|
|
7
6
|
import fs from "fs-extra";
|
|
8
|
-
import {
|
|
7
|
+
import { globby } from "globby";
|
|
9
8
|
import cryptoRandomString from "crypto-random-string";
|
|
10
9
|
import bash from "dedent";
|
|
11
|
-
import dedent from "dedent";
|
|
12
10
|
import archiver from "archiver";
|
|
13
11
|
import * as commander from "commander";
|
|
14
12
|
import process from "node:process";
|
|
15
13
|
|
|
16
|
-
// Some default excludes
|
|
17
14
|
const defaultExcludes = [
|
|
18
15
|
".*",
|
|
19
16
|
"*.exe",
|
|
@@ -53,17 +50,6 @@ export default async function caxa({
|
|
|
53
50
|
command,
|
|
54
51
|
force = true,
|
|
55
52
|
exclude = defaultExcludes,
|
|
56
|
-
filter = (() => {
|
|
57
|
-
if (!exclude.length) {
|
|
58
|
-
exclude = defaultExcludes;
|
|
59
|
-
}
|
|
60
|
-
const pathsToExclude = globbySync(exclude, {
|
|
61
|
-
expandDirectories: false,
|
|
62
|
-
onlyFiles: false,
|
|
63
|
-
}).map((pathToExclude: string) => path.normalize(pathToExclude));
|
|
64
|
-
return (pathToCopy: string) =>
|
|
65
|
-
!pathsToExclude.includes(path.normalize(pathToCopy));
|
|
66
|
-
})(),
|
|
67
53
|
includeNode = true,
|
|
68
54
|
stub = url.fileURLToPath(
|
|
69
55
|
new URL(
|
|
@@ -75,7 +61,6 @@ export default async function caxa({
|
|
|
75
61
|
path.basename(path.basename(path.basename(output, ".exe"), ".app"), ".sh"),
|
|
76
62
|
cryptoRandomString({ length: 10, type: "alphanumeric" }).toLowerCase(),
|
|
77
63
|
),
|
|
78
|
-
removeBuildDirectory = true,
|
|
79
64
|
uncompressionMessage,
|
|
80
65
|
}: {
|
|
81
66
|
input: string;
|
|
@@ -97,39 +82,145 @@ export default async function caxa({
|
|
|
97
82
|
if (process.platform === "win32" && !output.endsWith(".exe"))
|
|
98
83
|
throw new Error("Windows executable must end in ‘.exe’.");
|
|
99
84
|
|
|
100
|
-
const buildDirectory = path.join(
|
|
101
|
-
os.tmpdir(),
|
|
102
|
-
"caxa",
|
|
103
|
-
"builds",
|
|
104
|
-
cryptoRandomString({ length: 10, type: "alphanumeric" }).toLowerCase(),
|
|
105
|
-
);
|
|
106
|
-
await fs.copy(input, buildDirectory, { filter });
|
|
107
|
-
if (includeNode) {
|
|
108
|
-
const node = path.join(
|
|
109
|
-
buildDirectory,
|
|
110
|
-
"node_modules",
|
|
111
|
-
".bin",
|
|
112
|
-
path.basename(process.execPath),
|
|
113
|
-
);
|
|
114
|
-
await fs.ensureDir(path.dirname(node));
|
|
115
|
-
await fs.copyFile(process.execPath, node);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
85
|
await fs.ensureDir(path.dirname(output));
|
|
119
86
|
await fs.remove(output);
|
|
120
87
|
|
|
88
|
+
if (!exclude) exclude = defaultExcludes;
|
|
89
|
+
const files = await globby(["**/*", ...exclude.map((e) => `!${e}`)], {
|
|
90
|
+
cwd: input,
|
|
91
|
+
onlyFiles: true,
|
|
92
|
+
dot: true,
|
|
93
|
+
followSymbolicLinks: false,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
interface Component {
|
|
97
|
+
group: string;
|
|
98
|
+
name: string;
|
|
99
|
+
version: string;
|
|
100
|
+
purl: string;
|
|
101
|
+
_rawDeps?: Record<string, string>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
interface DependencyGraphEntry {
|
|
105
|
+
ref: string;
|
|
106
|
+
dependsOn: string[];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const components: Component[] = [];
|
|
110
|
+
const purlLookup = new Map<string, string>();
|
|
111
|
+
|
|
112
|
+
for (const file of files) {
|
|
113
|
+
if (path.basename(file) === "package.json") {
|
|
114
|
+
try {
|
|
115
|
+
const pkg = await fs.readJson(path.join(input, file));
|
|
116
|
+
if (pkg.name && pkg.version) {
|
|
117
|
+
let name = pkg.name;
|
|
118
|
+
let namespace = "";
|
|
119
|
+
if (name.startsWith("@")) {
|
|
120
|
+
const parts = name.split("/");
|
|
121
|
+
namespace = parts[0];
|
|
122
|
+
name = parts[1];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let purl = "pkg:npm/";
|
|
126
|
+
if (namespace) {
|
|
127
|
+
purl += `${encodeURIComponent(namespace)}/`;
|
|
128
|
+
}
|
|
129
|
+
purl += `${name}@${pkg.version}`;
|
|
130
|
+
|
|
131
|
+
purlLookup.set(pkg.name, purl);
|
|
132
|
+
|
|
133
|
+
components.push({
|
|
134
|
+
group: namespace,
|
|
135
|
+
name: name,
|
|
136
|
+
version: pkg.version,
|
|
137
|
+
purl: purl,
|
|
138
|
+
_rawDeps: pkg.dependencies,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
} catch (e) {
|
|
142
|
+
// Ignore
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const dependencies: DependencyGraphEntry[] = [];
|
|
148
|
+
|
|
149
|
+
for (const comp of components) {
|
|
150
|
+
const childPurls: string[] = [];
|
|
151
|
+
if (comp._rawDeps) {
|
|
152
|
+
for (const depName of Object.keys(comp._rawDeps)) {
|
|
153
|
+
const resolvedPurl = purlLookup.get(depName);
|
|
154
|
+
if (resolvedPurl) {
|
|
155
|
+
childPurls.push(resolvedPurl);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
delete comp._rawDeps;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (childPurls.length > 0) {
|
|
162
|
+
dependencies.push({
|
|
163
|
+
ref: comp.purl,
|
|
164
|
+
dependsOn: childPurls,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
await fs.writeJson(
|
|
170
|
+
path.join(path.dirname(output), "binary-metadata.json"),
|
|
171
|
+
{
|
|
172
|
+
components,
|
|
173
|
+
dependencies,
|
|
174
|
+
},
|
|
175
|
+
{ spaces: 0 },
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const appendApplicationPayload = async (destination: string, prefix = "") => {
|
|
179
|
+
const archive = archiver("tar", {
|
|
180
|
+
gzip: true,
|
|
181
|
+
gzipOptions: { level: 6 },
|
|
182
|
+
});
|
|
183
|
+
const outputStream = fs.createWriteStream(destination, { flags: "a" });
|
|
184
|
+
archive.pipe(outputStream);
|
|
185
|
+
|
|
186
|
+
for (const file of files) {
|
|
187
|
+
const absPath = path.join(input, file);
|
|
188
|
+
let name = path.join(prefix, file);
|
|
189
|
+
if (process.platform === "win32") {
|
|
190
|
+
name = name.replace(/\\/g, "/");
|
|
191
|
+
}
|
|
192
|
+
archive.file(absPath, { name });
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (includeNode) {
|
|
196
|
+
const nodePath = process.execPath;
|
|
197
|
+
let nodeDest = path.join(
|
|
198
|
+
prefix,
|
|
199
|
+
"node_modules",
|
|
200
|
+
".bin",
|
|
201
|
+
path.basename(nodePath),
|
|
202
|
+
);
|
|
203
|
+
if (process.platform === "win32") {
|
|
204
|
+
nodeDest = nodeDest.replace(/\\/g, "/");
|
|
205
|
+
}
|
|
206
|
+
archive.file(nodePath, { name: nodeDest });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await archive.finalize();
|
|
210
|
+
await stream.finished(outputStream);
|
|
211
|
+
};
|
|
212
|
+
|
|
121
213
|
if (output.endsWith(".app")) {
|
|
122
214
|
if (process.platform !== "darwin")
|
|
123
215
|
throw new Error(
|
|
124
216
|
"macOS Application Bundles (.app) are supported in macOS only.",
|
|
125
217
|
);
|
|
126
|
-
|
|
127
|
-
await fs.move(
|
|
128
|
-
buildDirectory,
|
|
129
|
-
path.join(output, "Contents", "Resources", "application"),
|
|
130
|
-
);
|
|
218
|
+
|
|
131
219
|
await fs.ensureDir(path.join(output, "Contents", "MacOS"));
|
|
220
|
+
await fs.ensureDir(path.join(output, "Contents", "Resources"));
|
|
221
|
+
|
|
132
222
|
const name = path.basename(output, ".app");
|
|
223
|
+
|
|
133
224
|
await fs.writeFile(
|
|
134
225
|
path.join(output, "Contents", "MacOS", name),
|
|
135
226
|
bash`
|
|
@@ -138,202 +229,130 @@ export default async function caxa({
|
|
|
138
229
|
` + "\n",
|
|
139
230
|
{ mode: 0o755 },
|
|
140
231
|
);
|
|
232
|
+
|
|
141
233
|
await fs.writeFile(
|
|
142
234
|
path.join(output, "Contents", "Resources", name),
|
|
143
235
|
bash`
|
|
144
236
|
#!/usr/bin/env sh
|
|
145
237
|
${command
|
|
146
238
|
.map(
|
|
147
|
-
(
|
|
148
|
-
`"${
|
|
149
|
-
/\{\{\s*caxa\s*\}\}/g,
|
|
150
|
-
`$(dirname "$0")/application`,
|
|
151
|
-
)}"`,
|
|
239
|
+
(p) =>
|
|
240
|
+
`"${p.replace(/\{\{\s*caxa\s*}}/g, `$(dirname "$0")/application`)}"`,
|
|
152
241
|
)
|
|
153
242
|
.join(" ")}
|
|
154
243
|
` + "\n",
|
|
155
244
|
{ mode: 0o755 },
|
|
156
245
|
);
|
|
246
|
+
|
|
247
|
+
const appDest = path.join(output, "Contents", "Resources", "application");
|
|
248
|
+
await fs.ensureDir(appDest);
|
|
249
|
+
|
|
250
|
+
for (const file of files) {
|
|
251
|
+
const src = path.join(input, file);
|
|
252
|
+
const dest = path.join(appDest, file);
|
|
253
|
+
await fs.copy(src, dest);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (includeNode) {
|
|
257
|
+
const nodeDest = path.join(
|
|
258
|
+
appDest,
|
|
259
|
+
"node_modules",
|
|
260
|
+
".bin",
|
|
261
|
+
path.basename(process.execPath),
|
|
262
|
+
);
|
|
263
|
+
await fs.ensureDir(path.dirname(nodeDest));
|
|
264
|
+
await fs.copyFile(process.execPath, nodeDest);
|
|
265
|
+
}
|
|
157
266
|
} else if (output.endsWith(".sh")) {
|
|
158
267
|
if (process.platform === "win32")
|
|
159
268
|
throw new Error("The Shell Stub (.sh) isn’t supported in Windows.");
|
|
160
|
-
|
|
269
|
+
|
|
270
|
+
let shellStub =
|
|
161
271
|
bash`
|
|
162
272
|
#!/usr/bin/env sh
|
|
163
|
-
export
|
|
164
|
-
export
|
|
273
|
+
export CAXA_TMP="$(dirname $(mktemp))/caxa"
|
|
274
|
+
export CAXA_ID="${identifier}"
|
|
165
275
|
while true
|
|
166
276
|
do
|
|
167
|
-
export
|
|
168
|
-
export
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
then
|
|
172
|
-
if [ -d "$CAXA_LOCK" ]
|
|
173
|
-
then
|
|
174
|
-
continue
|
|
175
|
-
else
|
|
176
|
-
break
|
|
177
|
-
fi
|
|
178
|
-
else
|
|
179
|
-
${
|
|
180
|
-
uncompressionMessage === undefined
|
|
181
|
-
? bash``
|
|
182
|
-
: bash`echo "${uncompressionMessage}" >&2`
|
|
183
|
-
}
|
|
184
|
-
mkdir -p "$CAXA_LOCK"
|
|
185
|
-
mkdir -p "$CAXA_APPLICATION_DIRECTORY"
|
|
186
|
-
tail -n+{{caxa-number-of-lines}} "$0" | tar -xz -C "$CAXA_APPLICATION_DIRECTORY"
|
|
187
|
-
rmdir "$CAXA_LOCK"
|
|
188
|
-
break
|
|
277
|
+
export CAXA_LOCK="$CAXA_TMP/locks/$CAXA_ID"
|
|
278
|
+
export CAXA_APP="$CAXA_TMP/apps/$CAXA_ID"
|
|
279
|
+
if [ -d "$CAXA_APP" ] && [ ! -d "$CAXA_LOCK" ]; then
|
|
280
|
+
break
|
|
189
281
|
fi
|
|
282
|
+
|
|
283
|
+
${uncompressionMessage ? bash`echo "${uncompressionMessage}" >&2` : ""}
|
|
284
|
+
mkdir -p "$CAXA_LOCK" "$CAXA_APP"
|
|
285
|
+
|
|
286
|
+
# Use atomic extraction pattern
|
|
287
|
+
tail -n+{{lines}} "$0" | tar -xz -C "$CAXA_APP"
|
|
288
|
+
|
|
289
|
+
rmdir "$CAXA_LOCK"
|
|
290
|
+
break
|
|
190
291
|
done
|
|
191
292
|
exec ${command
|
|
192
|
-
.map(
|
|
193
|
-
(commandPart) =>
|
|
194
|
-
`"${commandPart.replace(
|
|
195
|
-
/\{\{\s*caxa\s*\}\}/g,
|
|
196
|
-
`"$CAXA_APPLICATION_DIRECTORY"`,
|
|
197
|
-
)}"`,
|
|
198
|
-
)
|
|
293
|
+
.map((p) => `"${p.replace(/\{\{\s*caxa\s*}}/g, `"$CAXA_APP"`)}"`)
|
|
199
294
|
.join(" ")} "$@"
|
|
200
295
|
` + "\n";
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
296
|
+
|
|
297
|
+
shellStub = shellStub.replace(
|
|
298
|
+
"{{lines}}",
|
|
299
|
+
String(shellStub.split("\n").length),
|
|
204
300
|
);
|
|
205
|
-
await fs.writeFile(output,
|
|
206
|
-
await
|
|
301
|
+
await fs.writeFile(output, shellStub, { mode: 0o755 });
|
|
302
|
+
await appendApplicationPayload(output);
|
|
207
303
|
} else {
|
|
208
304
|
if (!(await fs.pathExists(stub)))
|
|
209
305
|
throw new Error(
|
|
210
306
|
`Stub not found (your operating system / architecture may be unsupported): ‘${stub}’`,
|
|
211
307
|
);
|
|
308
|
+
|
|
212
309
|
await fs.copyFile(stub, output);
|
|
213
310
|
await fs.chmod(output, 0o755);
|
|
214
|
-
|
|
311
|
+
|
|
312
|
+
await appendApplicationPayload(output);
|
|
313
|
+
|
|
215
314
|
await fs.appendFile(
|
|
216
315
|
output,
|
|
217
316
|
"\n" + JSON.stringify({ identifier, command, uncompressionMessage }),
|
|
218
317
|
);
|
|
219
318
|
}
|
|
220
|
-
|
|
221
|
-
if (removeBuildDirectory) await fs.remove(buildDirectory);
|
|
222
|
-
|
|
223
|
-
async function appendTarballOfBuildDirectoryToOutput(): Promise<void> {
|
|
224
|
-
const archive = archiver("tar", { gzip: true });
|
|
225
|
-
const archiveStream = fs.createWriteStream(output, { flags: "a" });
|
|
226
|
-
archive.pipe(archiveStream);
|
|
227
|
-
archive.directory(buildDirectory, false);
|
|
228
|
-
await archive.finalize();
|
|
229
|
-
await stream.finished(archiveStream);
|
|
230
|
-
}
|
|
231
319
|
}
|
|
232
320
|
|
|
233
321
|
if (url.fileURLToPath(import.meta.url) === (await fs.realpath(process.argv[1])))
|
|
234
322
|
await commander.program
|
|
235
323
|
.name("caxa")
|
|
236
324
|
.description("Package Node.js applications into executable binaries")
|
|
237
|
-
.requiredOption(
|
|
238
|
-
"-i, --input <input>",
|
|
239
|
-
"[Required] The input directory to package.",
|
|
240
|
-
)
|
|
325
|
+
.requiredOption("-i, --input <input>", "Input directory to package.")
|
|
241
326
|
.requiredOption(
|
|
242
327
|
"-o, --output <output>",
|
|
243
|
-
"
|
|
244
|
-
)
|
|
245
|
-
.option("-F, --no-force", "[Advanced] Don’t overwrite output if it exists.")
|
|
246
|
-
.option(
|
|
247
|
-
"-e, --exclude <path...>",
|
|
248
|
-
`[Advanced] Paths to exclude from the build. The paths are passed to https://github.com/sindresorhus/globby and paths that match will be excluded. [Super-Advanced, Please don’t use] If you wish to emulate ‘--include’, you may use ‘--exclude "*" ".*" "!path-to-include" ...’. The problem with ‘--include’ is that if you change your project structure but forget to change the caxa invocation, then things will subtly fail only in the packaged version.`,
|
|
249
|
-
)
|
|
250
|
-
.option(
|
|
251
|
-
"-N, --no-include-node",
|
|
252
|
-
"[Advanced] Don’t copy the Node.js executable to ‘{{caxa}}/node_modules/.bin/node’.",
|
|
253
|
-
)
|
|
254
|
-
.option("-s, --stub <path>", "[Advanced] Path to the stub.")
|
|
255
|
-
.option(
|
|
256
|
-
"--identifier <identifier>",
|
|
257
|
-
"[Advanced] Build identifier, which is part of the path in which the application will be unpacked.",
|
|
328
|
+
"Path where the executable will be produced.",
|
|
258
329
|
)
|
|
330
|
+
.option("-F, --no-force", "Don’t overwrite output if it exists.")
|
|
331
|
+
.option("-e, --exclude <path...>", "Paths to exclude from the build.")
|
|
332
|
+
.option("-N, --no-include-node", "Don’t copy the Node.js executable.")
|
|
333
|
+
.option("-s, --stub <path>", "Path to the stub.")
|
|
334
|
+
.option("--identifier <id>", "Build identifier.")
|
|
259
335
|
.option(
|
|
260
336
|
"-B, --no-remove-build-directory",
|
|
261
|
-
"
|
|
337
|
+
"Ignored in v2 (streaming build).",
|
|
262
338
|
)
|
|
263
339
|
.option(
|
|
264
|
-
"-m, --uncompression-message <
|
|
265
|
-
"
|
|
266
|
-
)
|
|
267
|
-
.argument(
|
|
268
|
-
"<command...>",
|
|
269
|
-
"The command to run and optional arguments to pass to the command every time the executable is called. Paths must be absolute. The ‘{{caxa}}’ placeholder is substituted for the folder from which the package runs. The ‘node’ executable is available at ‘{{caxa}}/node_modules/.bin/node’. Use double quotes to delimit the command and each argument.",
|
|
340
|
+
"-m, --uncompression-message <msg>",
|
|
341
|
+
"Message to show during extraction.",
|
|
270
342
|
)
|
|
343
|
+
.argument("<command...>", "Command to run.")
|
|
271
344
|
.version(
|
|
272
345
|
JSON.parse(
|
|
273
346
|
await fs.readFile(new URL("../package.json", import.meta.url), "utf8"),
|
|
274
347
|
).version,
|
|
275
348
|
)
|
|
276
|
-
.
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
macOS/Linux:
|
|
285
|
-
$ caxa --input "examples/echo-command-line-parameters" --output "echo-command-line-parameters" -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/index.mjs" "some" "embedded arguments" "--an-option-thats-part-of-the-command"
|
|
286
|
-
|
|
287
|
-
macOS/Linux (Shell Stub):
|
|
288
|
-
$ caxa --input "examples/echo-command-line-parameters" --output "echo-command-line-parameters.sh" -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/index.mjs" "some" "embedded arguments" "--an-option-thats-part-of-the-command"
|
|
289
|
-
|
|
290
|
-
macOS (Application Bundle):
|
|
291
|
-
$ caxa --input "examples/echo-command-line-parameters" --output "Echo Command Line Parameters.app" -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/index.mjs" "some" "embedded arguments" "--an-option-thats-part-of-the-command"
|
|
292
|
-
`,
|
|
293
|
-
)
|
|
294
|
-
.action(
|
|
295
|
-
async (
|
|
296
|
-
command: string[],
|
|
297
|
-
{
|
|
298
|
-
input,
|
|
299
|
-
output,
|
|
300
|
-
force,
|
|
301
|
-
exclude,
|
|
302
|
-
includeNode,
|
|
303
|
-
stub,
|
|
304
|
-
identifier,
|
|
305
|
-
removeBuildDirectory,
|
|
306
|
-
uncompressionMessage,
|
|
307
|
-
}: {
|
|
308
|
-
input: string;
|
|
309
|
-
output: string;
|
|
310
|
-
force?: boolean;
|
|
311
|
-
exclude?: string[];
|
|
312
|
-
includeNode?: boolean;
|
|
313
|
-
stub?: string;
|
|
314
|
-
identifier?: string;
|
|
315
|
-
removeBuildDirectory?: boolean;
|
|
316
|
-
uncompressionMessage?: string;
|
|
317
|
-
},
|
|
318
|
-
) => {
|
|
319
|
-
try {
|
|
320
|
-
await caxa({
|
|
321
|
-
input,
|
|
322
|
-
output,
|
|
323
|
-
command,
|
|
324
|
-
force,
|
|
325
|
-
exclude,
|
|
326
|
-
includeNode,
|
|
327
|
-
stub,
|
|
328
|
-
identifier,
|
|
329
|
-
removeBuildDirectory,
|
|
330
|
-
uncompressionMessage,
|
|
331
|
-
});
|
|
332
|
-
} catch (error: any) {
|
|
333
|
-
console.error(error.message);
|
|
334
|
-
process.exit(1);
|
|
335
|
-
}
|
|
336
|
-
},
|
|
337
|
-
)
|
|
349
|
+
.action(async (command, opts) => {
|
|
350
|
+
try {
|
|
351
|
+
await caxa({ command, ...opts });
|
|
352
|
+
} catch (error: any) {
|
|
353
|
+
console.error(error.message);
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
})
|
|
338
357
|
.showHelpAfterError()
|
|
339
358
|
.parseAsync();
|
package/stubs/go.mod
ADDED
package/stubs/go.sum
ADDED
|
Binary file
|
package/stubs/stub--darwin--x64
CHANGED
|
Binary file
|
package/stubs/stub--linux--arm
CHANGED
|
Binary file
|
package/stubs/stub--linux--arm64
CHANGED
|
Binary file
|
package/stubs/stub--linux--x64
CHANGED
|
Binary file
|
package/stubs/stub--win32--arm64
CHANGED
|
Binary file
|
package/stubs/stub--win32--x64
CHANGED
|
Binary file
|