@appthreat/caxa 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.
@@ -0,0 +1,46 @@
1
+ name: npm test and release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - release/*
8
+ tags:
9
+ - 'v*'
10
+ workflow_dispatch:
11
+
12
+ env:
13
+ REGISTRY: ghcr.io
14
+
15
+ jobs:
16
+ test:
17
+ strategy:
18
+ matrix:
19
+ os: [windows, macos, ubuntu]
20
+ node-version: [20, 21]
21
+ runs-on: ${{ matrix.os }}-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: actions/setup-node@v4
25
+ with:
26
+ node-version: ${{ matrix.node-version }}
27
+ - run: npm install-ci-test
28
+
29
+ npm-publish:
30
+ if: startsWith(github.ref, 'refs/tags/')
31
+ needs: test
32
+ runs-on: ubuntu-latest
33
+ permissions:
34
+ contents: read
35
+ packages: write
36
+ id-token: write
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+ - uses: actions/setup-node@v4
40
+ with:
41
+ node-version: 21.x
42
+ registry-url: https://registry.npmjs.org/
43
+ - run: npm ci && npm publish --access=public --@cyclonedx:registry='https://registry.npmjs.org'
44
+ env:
45
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
46
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Team AppThreat <cloud@appthreat.com>
4
+ Copyright (c) 2022 Leandro Facchinetti <license@leafac.com> (https://leafac.com)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ Forked from caxa [3.0.1](https://github.com/leafac/caxa/releases/tag/v3.0.1) with the following changes:
2
+
3
+ - Updated packages.
4
+ - Added default excludes to ignore .git and some test directories.
5
+ - Removed broken unit tests from source/index.mts.
6
+ - Excluded build and binary stubs using .gitignore. The published package would include binary stubs not present in this git repository.
7
+
8
+ Original README below:
9
+
10
+ <h1 align="center">caxa</h1>
11
+ <h3 align="center">šŸ“¦ Package Node.js applications into executable binaries šŸ“¦</h3>
12
+
13
+ ### Why Package Node.js Applications into Executable Binaries?
14
+
15
+ - Simple deploys. Transfer the binary into a machine and run it.
16
+ - Let users test an application even if they don’t have Node.js installed.
17
+ - Simple installation story for command-line applications.
18
+ - It’s like the much-praised distribution story of [Go](https://golang.org) programs but for Node.js.
19
+
20
+ ### Features
21
+
22
+ - Works on Windows, macOS (Intel & ARM), and Linux (Intel, ARM6, ARM7, ARM64).
23
+ - Simple to use. `npm install @appthreat/caxa` and call `caxa` from the command line. No need to declare which files to include; no need to bundle the application into a single file.
24
+ - Supports any kind of Node.js project, including those with native modules.
25
+ - Works with any Node.js version.
26
+ - Packages in seconds.
27
+ - Relatively small binaries. A ā€œHello World!ā€ application is ~30MB, which is terrible if compared to Go’s ~2MB, and worse still if compared to C’s ~50KB, but best-in-class if compared to other packaging solutions for Node.js.
28
+ - Produces `.exe`s for Windows, simple binaries for macOS/Linux, and macOS Application Bundles (`.app`).
29
+ - Based on a simple but powerful idea. Implemented in ~200 lines of code.
30
+ - No magic. No traversal of `require()`s trying to find which files to include; no patches to Node.js source.
31
+
32
+ ### Anti-Features
33
+
34
+ - Doesn’t patch the Node.js source code.
35
+ - Doesn’t build Node.js from source.
36
+ - Doesn’t support cross-compilation (for example, building a Windows executable from a macOS development machine).
37
+ - Doesn’t support packaging with a Node.js version different from the one that’s running caxa (for example, bundling Node.js 15 while running caxa with Node.js 14).
38
+ - Doesn’t hide your JavaScript source code in any way.
39
+
40
+ ### Installation
41
+
42
+ ```console
43
+ $ npm install --save-dev @appthreat/caxa
44
+ ```
45
+
46
+ ### Usage
47
+
48
+ #### Prepare the Project for Packaging
49
+
50
+ - Install any dependencies with `npm install` or `npm ci`.
51
+ - Build. For example, compile TypeScript with `tsc`, bundle with webpack, and whatever else you need to get the project ready to start. Typically this is the kind of thing that goes into an [npm `prepare` script](https://docs.npmjs.com/cli/v7/using-npm/scripts#prepare-and-prepublish), so the `npm ci` from the previous point may already have taken care of this.
52
+ - If there are files that shouldn’t be in the package, remove them from the directory. For example, you may wish to remove the `.git` directory.
53
+ - You don’t need to `npm dedupe --production`, because caxa will do that for you from within the build directory. (Otherwise, if you tried to `npm dedupe --production` you’d uninstall caxa, which should probably be in `devDependencies`.)
54
+ - It’s recommended that you run caxa on a Continuous Integration server. (GitHub Actions, for example, does a shallow fetch of the repository, so removing the `.git` directory becomes negligible—but you can always do that with the `--exclude` advanced option.)
55
+
56
+ #### Call caxa from the Command Line
57
+
58
+ ```console
59
+ $ npx caxa --help
60
+ Usage: caxa [options] <command...>
61
+
62
+ Package Node.js applications into executable binaries
63
+
64
+ Arguments:
65
+ command 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.
66
+
67
+ Options:
68
+ -i, --input <input> [Required] The input directory to package.
69
+ -o, --output <output> [Required] The path where the executable will be produced. On Windows, must end in ā€˜.exe’. In macOS and Linux, may have no extension to produce regular binary. In macOS and Linux, may end in ā€˜.sh’ to use the Shell Stub, which is a bit smaller, but depends on some tools being installed on the end-user machine, for example, ā€˜tar’, ā€˜tail’, and so forth. In macOS, may end in ā€˜.app’ to generate a macOS Application Bundle.
70
+ -F, --no-force [Advanced] Don’t overwrite output if it exists.
71
+ -e, --exclude <path...> [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.
72
+ -D, --no-dedupe [Advanced] Don’t run ā€˜npm dedupe --production’ on the build directory.
73
+ -p, --prepare-command <command> [Advanced] Command to run on the build directory after ā€˜npm dedupe --production’, before packaging.
74
+ -N, --no-include-node [Advanced] Don’t copy the Node.js executable to ā€˜{{caxa}}/node_modules/.bin/node’.
75
+ -s, --stub <path> [Advanced] Path to the stub.
76
+ --identifier <identifier> [Advanced] Build identifier, which is part of the path in which the application will be unpacked.
77
+ -B, --no-remove-build-directory [Advanced] Remove the build directory after the build.
78
+ -m, --uncompression-message <message> [Advanced] A message to show when uncompressing, for example, ā€˜This may take a while to run the first time, please wait...’.
79
+ -V, --version output the version number
80
+ -h, --help display help for command
81
+
82
+ Examples:
83
+ Windows:
84
+ > caxa --input "examples/echo-command-line-parameters" --output "echo-command-line-parameters.exe" -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/index.mjs" "some" "embedded arguments" "--an-option-thats-part-of-the-command"
85
+
86
+ macOS/Linux:
87
+ $ 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"
88
+
89
+ macOS/Linux (Shell Stub):
90
+ $ 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"
91
+
92
+ macOS (Application Bundle):
93
+ $ 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"
94
+ ```
95
+
96
+ Here’s [a real-world example of using caxa](https://github.com/courselore/courselore/blob/c0b541d63fc656986ebeab4af3f3dc9bc2909972/.github/workflows/main.yml). This example includes packaging for Windows, macOS, and Linux; distributing tags with GitHub Releases Assets; distributing Insiders Builds for every push with GitHub Actions Artifacts; and deploying a binary to a server with `rsync` (and publishing an npm package as well, but that’s beyond the scope of caxa).
97
+
98
+ #### Call caxa from TypeScript/JavaScript
99
+
100
+ Instead of calling caxa from the command line, you may prefer to write a program that builds your application, for example:
101
+
102
+ ```typescript
103
+ import caxa from "caxa";
104
+
105
+ (async () => {
106
+ await caxa({
107
+ input: "examples/echo-command-line-parameters",
108
+ output: "echo-command-line-parameters",
109
+ command: [
110
+ "{{caxa}}/node_modules/.bin/node",
111
+ "{{caxa}}/index.mjs",
112
+ "some",
113
+ "embedded arguments",
114
+ ],
115
+ });
116
+ })();
117
+ ```
118
+
119
+ You may need to inspect `process.platform` to determine which operating system you’re running and come up with the appropriate parameters.
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs-extra";
3
+ export default function caxa({ input, output, command, force, exclude, filter, dedupe, prepareCommand, prepare, includeNode, stub, identifier, removeBuildDirectory, uncompressionMessage, }: {
4
+ input: string;
5
+ output: string;
6
+ command: string[];
7
+ force?: boolean;
8
+ exclude?: string[];
9
+ filter?: fs.CopyFilterSync | fs.CopyFilterAsync;
10
+ dedupe?: boolean;
11
+ prepareCommand?: string;
12
+ prepare?: (buildDirectory: string) => Promise<void>;
13
+ includeNode?: boolean;
14
+ stub?: string;
15
+ identifier?: string;
16
+ removeBuildDirectory?: boolean;
17
+ uncompressionMessage?: string;
18
+ }): Promise<void>;
19
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../source/index.mts"],"names":[],"mappings":";AAMA,OAAO,EAAE,MAAM,UAAU,CAAC;AAoB1B,wBAA8B,IAAI,CAAC,EACjC,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAY,EACZ,OAAyB,EACzB,MAOI,EACJ,MAAa,EACb,cAAc,EACd,OAGC,EACD,WAAkB,EAClB,IAKC,EACD,UAGC,EACD,oBAA2B,EAC3B,oBAAoB,GACrB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,EAAE,CAAC,cAAc,GAAG,EAAE,CAAC,eAAe,CAAC;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GAAG,OAAO,CAAC,IAAI,CAAC,CA4IhB"}
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env node
2
+ import path from "node:path";
3
+ import url from "node:url";
4
+ import os from "node:os";
5
+ import stream from "node:stream/promises";
6
+ import fs from "fs-extra";
7
+ import { globbySync } from "globby";
8
+ import { execa, execaCommand } from "execa";
9
+ import cryptoRandomString from "crypto-random-string";
10
+ import bash from "dedent";
11
+ import archiver from "archiver";
12
+ import * as commander from "commander";
13
+ import dedent from "dedent";
14
+ import process from "node:process";
15
+ // Some default excludes
16
+ const defaultExcludes = [
17
+ ".*",
18
+ ".git/**",
19
+ ".vscode/**",
20
+ "**/*/*.env",
21
+ "docs/**",
22
+ "test/**",
23
+ ];
24
+ export default async function caxa({ input, output, command, force = true, exclude = defaultExcludes, filter = (() => {
25
+ const pathsToExclude = globbySync(exclude, {
26
+ expandDirectories: false,
27
+ onlyFiles: false,
28
+ }).map((pathToExclude) => path.normalize(pathToExclude));
29
+ return (pathToCopy) => !pathsToExclude.includes(path.normalize(pathToCopy));
30
+ })(), dedupe = true, prepareCommand, prepare = async (buildDirectory) => {
31
+ if (prepareCommand === undefined)
32
+ return;
33
+ await execaCommand(prepareCommand, { cwd: buildDirectory, shell: true });
34
+ }, includeNode = true, stub = url.fileURLToPath(new URL(`../stubs/stub--${process.platform}--${process.arch}`, import.meta.url)), identifier = path.join(path.basename(path.basename(path.basename(output, ".exe"), ".app"), ".sh"), cryptoRandomString({ length: 10, type: "alphanumeric" }).toLowerCase()), removeBuildDirectory = true, uncompressionMessage, }) {
35
+ if (!(await fs.pathExists(input)) || !(await fs.lstat(input)).isDirectory())
36
+ throw new Error(`Input isn’t a directory: ā€˜${input}’.`);
37
+ if ((await fs.pathExists(output)) && !force)
38
+ throw new Error(`Output already exists: ā€˜${output}’.`);
39
+ if (process.platform === "win32" && !output.endsWith(".exe"))
40
+ throw new Error("Windows executable must end in ā€˜.exe’.");
41
+ const buildDirectory = path.join(os.tmpdir(), "caxa/builds", cryptoRandomString({ length: 10, type: "alphanumeric" }).toLowerCase());
42
+ await fs.copy(input, buildDirectory, { filter });
43
+ if (dedupe)
44
+ await execa("npm", ["dedupe", "--production"], { cwd: buildDirectory });
45
+ await prepare(buildDirectory);
46
+ if (includeNode) {
47
+ const node = path.join(buildDirectory, "node_modules/.bin", path.basename(process.execPath));
48
+ await fs.ensureDir(path.dirname(node));
49
+ await fs.copyFile(process.execPath, node);
50
+ }
51
+ await fs.ensureDir(path.dirname(output));
52
+ await fs.remove(output);
53
+ if (output.endsWith(".app")) {
54
+ if (process.platform !== "darwin")
55
+ throw new Error("macOS Application Bundles (.app) are supported in macOS only.");
56
+ await fs.ensureDir(path.join(output, "Contents/Resources"));
57
+ await fs.move(buildDirectory, path.join(output, "Contents/Resources/application"));
58
+ await fs.ensureDir(path.join(output, "Contents/MacOS"));
59
+ const name = path.basename(output, ".app");
60
+ await fs.writeFile(path.join(output, "Contents/MacOS", name), bash `
61
+ #!/usr/bin/env sh
62
+ open "$(dirname "$0")/../Resources/${name}"
63
+ ` + "\n", { mode: 0o755 });
64
+ await fs.writeFile(path.join(output, "Contents/Resources", name), bash `
65
+ #!/usr/bin/env sh
66
+ ${command
67
+ .map((part) => `"${part.replace(/\{\{\s*caxa\s*\}\}/g, `$(dirname "$0")/application`)}"`)
68
+ .join(" ")}
69
+ ` + "\n", { mode: 0o755 });
70
+ }
71
+ else if (output.endsWith(".sh")) {
72
+ if (process.platform === "win32")
73
+ throw new Error("The Shell Stub (.sh) isn’t supported in Windows.");
74
+ let stub = bash `
75
+ #!/usr/bin/env sh
76
+ export CAXA_TEMPORARY_DIRECTORY="$(dirname $(mktemp))/caxa"
77
+ export CAXA_EXTRACTION_ATTEMPT=-1
78
+ while true
79
+ do
80
+ export CAXA_EXTRACTION_ATTEMPT=$(( CAXA_EXTRACTION_ATTEMPT + 1 ))
81
+ export CAXA_LOCK="$CAXA_TEMPORARY_DIRECTORY/locks/${identifier}/$CAXA_EXTRACTION_ATTEMPT"
82
+ export CAXA_APPLICATION_DIRECTORY="$CAXA_TEMPORARY_DIRECTORY/applications/${identifier}/$CAXA_EXTRACTION_ATTEMPT"
83
+ if [ -d "$CAXA_APPLICATION_DIRECTORY" ]
84
+ then
85
+ if [ -d "$CAXA_LOCK" ]
86
+ then
87
+ continue
88
+ else
89
+ break
90
+ fi
91
+ else
92
+ ${uncompressionMessage === undefined
93
+ ? bash ``
94
+ : bash `echo "${uncompressionMessage}" >&2`}
95
+ mkdir -p "$CAXA_LOCK"
96
+ mkdir -p "$CAXA_APPLICATION_DIRECTORY"
97
+ tail -n+{{caxa-number-of-lines}} "$0" | tar -xz -C "$CAXA_APPLICATION_DIRECTORY"
98
+ rmdir "$CAXA_LOCK"
99
+ break
100
+ fi
101
+ done
102
+ exec ${command
103
+ .map((commandPart) => `"${commandPart.replace(/\{\{\s*caxa\s*\}\}/g, `"$CAXA_APPLICATION_DIRECTORY"`)}"`)
104
+ .join(" ")} "$@"
105
+ ` + "\n";
106
+ stub = stub.replace("{{caxa-number-of-lines}}", String(stub.split("\n").length));
107
+ await fs.writeFile(output, stub, { mode: 0o755 });
108
+ await appendTarballOfBuildDirectoryToOutput();
109
+ }
110
+ else {
111
+ if (!(await fs.pathExists(stub)))
112
+ throw new Error(`Stub not found (your operating system / architecture may be unsupported): ā€˜${stub}’`);
113
+ await fs.copyFile(stub, output);
114
+ await fs.chmod(output, 0o755);
115
+ await appendTarballOfBuildDirectoryToOutput();
116
+ await fs.appendFile(output, "\n" + JSON.stringify({ identifier, command, uncompressionMessage }));
117
+ }
118
+ if (removeBuildDirectory)
119
+ await fs.remove(buildDirectory);
120
+ async function appendTarballOfBuildDirectoryToOutput() {
121
+ const archive = archiver("tar", { gzip: true });
122
+ const archiveStream = fs.createWriteStream(output, { flags: "a" });
123
+ archive.pipe(archiveStream);
124
+ archive.directory(buildDirectory, false);
125
+ await archive.finalize();
126
+ await stream.finished(archiveStream);
127
+ }
128
+ }
129
+ if (url.fileURLToPath(import.meta.url) === (await fs.realpath(process.argv[1])))
130
+ await commander.program
131
+ .name("caxa")
132
+ .description("Package Node.js applications into executable binaries")
133
+ .requiredOption("-i, --input <input>", "[Required] The input directory to package.")
134
+ .requiredOption("-o, --output <output>", "[Required] The path where the executable will be produced. On Windows, must end in ā€˜.exe’. In macOS and Linux, may have no extension to produce regular binary. In macOS and Linux, may end in ā€˜.sh’ to use the Shell Stub, which is a bit smaller, but depends on some tools being installed on the end-user machine, for example, ā€˜tar’, ā€˜tail’, and so forth. In macOS, may end in ā€˜.app’ to generate a macOS Application Bundle.")
135
+ .option("-F, --no-force", "[Advanced] Don’t overwrite output if it exists.")
136
+ .option("-e, --exclude <path...>", `[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.`)
137
+ .option("-D, --no-dedupe", "[Advanced] Don’t run ā€˜npm dedupe --production’ on the build directory.")
138
+ .option("-p, --prepare-command <command>", "[Advanced] Command to run on the build directory after ā€˜npm dedupe --production’, before packaging.")
139
+ .option("-N, --no-include-node", "[Advanced] Don’t copy the Node.js executable to ā€˜{{caxa}}/node_modules/.bin/node’.")
140
+ .option("-s, --stub <path>", "[Advanced] Path to the stub.")
141
+ .option("--identifier <identifier>", "[Advanced] Build identifier, which is part of the path in which the application will be unpacked.")
142
+ .option("-B, --no-remove-build-directory", "[Advanced] Remove the build directory after the build.")
143
+ .option("-m, --uncompression-message <message>", "[Advanced] A message to show when uncompressing, for example, ā€˜This may take a while to run the first time, please wait...’.")
144
+ .argument("<command...>", "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.")
145
+ .version(JSON.parse(await fs.readFile(new URL("../package.json", import.meta.url), "utf8")).version)
146
+ .addHelpText("after", "\n" +
147
+ dedent `
148
+ Examples:
149
+ Windows:
150
+ > caxa --input "examples/echo-command-line-parameters" --output "echo-command-line-parameters.exe" -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/index.mjs" "some" "embedded arguments" "--an-option-thats-part-of-the-command"
151
+
152
+ macOS/Linux:
153
+ $ 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"
154
+
155
+ macOS/Linux (Shell Stub):
156
+ $ 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"
157
+
158
+ macOS (Application Bundle):
159
+ $ 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"
160
+ `)
161
+ .action(async (command, { input, output, force, exclude = [], dedupe, prepareCommand, includeNode, stub, identifier, removeBuildDirectory, uncompressionMessage, }) => {
162
+ try {
163
+ await caxa({
164
+ input,
165
+ output,
166
+ command,
167
+ force,
168
+ exclude,
169
+ dedupe,
170
+ prepareCommand,
171
+ includeNode,
172
+ stub,
173
+ identifier,
174
+ removeBuildDirectory,
175
+ uncompressionMessage,
176
+ });
177
+ }
178
+ catch (error) {
179
+ console.error(error.message);
180
+ process.exit(1);
181
+ }
182
+ })
183
+ .showHelpAfterError()
184
+ .parseAsync();
185
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../source/index.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ console.log(JSON.stringify(process.argv.slice(2), undefined, 2));
@@ -0,0 +1 @@
1
+ process.exit(1);
@@ -0,0 +1,50 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ import fs from "fs-extra";
4
+ import cryptoRandomString from "crypto-random-string";
5
+ import { Database, sql } from "@leafac/sqlite";
6
+ import sharp from "sharp";
7
+
8
+ const temporaryDirectory = path.join(
9
+ os.tmpdir(),
10
+ "caxa/examples/native-modules",
11
+ cryptoRandomString({ length: 10, type: "alphanumeric" }).toLowerCase()
12
+ );
13
+ await fs.ensureDir(temporaryDirectory);
14
+
15
+ const database = new Database(path.join(temporaryDirectory, "database.db"));
16
+ database.migrate(
17
+ sql`CREATE TABLE "caxaExampleNativeModules" ("example" TEXT);`
18
+ );
19
+ database.run(
20
+ sql`INSERT INTO "caxaExampleNativeModules" ("example") VALUES (${"caxa native modules"})`
21
+ );
22
+ console.log(
23
+ "@leafac/sqlite:",
24
+ JSON.stringify(
25
+ database.get(
26
+ sql`
27
+ SELECT "example" FROM "caxaExampleNativeModules"
28
+ `
29
+ ),
30
+ undefined,
31
+ 2
32
+ )
33
+ );
34
+ database.close();
35
+
36
+ const imageFile = path.join(temporaryDirectory, "image.png");
37
+ await fs.writeFile(
38
+ imageFile,
39
+ await sharp({
40
+ create: {
41
+ width: 48,
42
+ height: 48,
43
+ channels: 4,
44
+ background: { r: 255, g: 0, b: 0, alpha: 0.5 },
45
+ },
46
+ })
47
+ .png()
48
+ .toBuffer()
49
+ );
50
+ console.log("sharp:", (await sharp(imageFile).metadata()).width);