@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.
- package/.github/workflows/main.yml +46 -0
- package/LICENSE +22 -0
- package/README.md +119 -0
- package/build/index.d.mts +19 -0
- package/build/index.d.mts.map +1 -0
- package/build/index.mjs +185 -0
- package/build/index.mjs.map +1 -0
- package/examples/echo-command-line-parameters/index.mjs +1 -0
- package/examples/false/index.mjs +1 -0
- package/examples/native-modules/index.mjs +50 -0
- package/examples/native-modules/package-lock.json +1028 -0
- package/examples/native-modules/package.json +8 -0
- package/examples/web-application/package-lock.json +1190 -0
- package/examples/web-application/package.json +14 -0
- package/examples/web-application/source/index.mts +11 -0
- package/examples/web-application/tsconfig.json +19 -0
- package/package.json +45 -0
- package/source/index.mts +337 -0
- package/source/tsconfig.json +19 -0
- package/stubs/stub.go +298 -0
|
@@ -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"}
|
package/build/index.mjs
ADDED
|
@@ -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":";AAEA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAC1C,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,IAAI,MAAM,QAAQ,CAAC;AAC1B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AACvC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,wBAAwB;AACxB,MAAM,eAAe,GAAG;IACtB,IAAI;IACJ,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,SAAS;IACT,SAAS;CACV,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,IAAI,CAAC,EACjC,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,GAAG,IAAI,EACZ,OAAO,GAAG,eAAe,EACzB,MAAM,GAAG,CAAC,GAAG,EAAE;IACb,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,EAAE;QACzC,iBAAiB,EAAE,KAAK;QACxB,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC,GAAG,CAAC,CAAC,aAAqB,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,UAAkB,EAAE,EAAE,CAC5B,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;AACzD,CAAC,CAAC,EAAE,EACJ,MAAM,GAAG,IAAI,EACb,cAAc,EACd,OAAO,GAAG,KAAK,EAAE,cAAsB,EAAE,EAAE;IACzC,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO;IACzC,MAAM,YAAY,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3E,CAAC,EACD,WAAW,GAAG,IAAI,EAClB,IAAI,GAAG,GAAG,CAAC,aAAa,CACtB,IAAI,GAAG,CACL,kBAAkB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,IAAI,EAAE,EACrD,MAAM,CAAC,IAAI,CAAC,GAAG,CAChB,CACF,EACD,UAAU,GAAG,IAAI,CAAC,IAAI,CACpB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAC1E,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,WAAW,EAAE,CACvE,EACD,oBAAoB,GAAG,IAAI,EAC3B,oBAAoB,GAgBrB;IACC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE;QACzE,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK;QACzC,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,IAAI,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAE5D,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAC9B,EAAE,CAAC,MAAM,EAAE,EACX,aAAa,EACb,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,WAAW,EAAE,CACvE,CAAC;IACF,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACjD,IAAI,MAAM;QACR,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;IAC1E,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9B,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,cAAc,EACd,mBAAmB,EACnB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAChC,CAAC;QACF,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAExB,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAC/B,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;QACJ,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;QAC5D,MAAM,EAAE,CAAC,IAAI,CACX,cAAc,EACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gCAAgC,CAAC,CACpD,CAAC;QACF,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,CAAC,EACzC,IAAI,CAAA;;6CAEmC,IAAI;OAC1C,GAAG,IAAI,EACR,EAAE,IAAI,EAAE,KAAK,EAAE,CAChB,CAAC;QACF,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,EAAE,IAAI,CAAC,EAC7C,IAAI,CAAA;;UAEA,OAAO;aACN,GAAG,CACF,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,IAAI,CAAC,OAAO,CACd,qBAAqB,EACrB,6BAA6B,CAC9B,GAAG,CACP;aACA,IAAI,CAAC,GAAG,CAAC;OACb,GAAG,IAAI,EACR,EAAE,IAAI,EAAE,KAAK,EAAE,CAChB,CAAC;IACJ,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC9B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,IAAI,IAAI,GACN,IAAI,CAAA;;;;;;;8DAOoD,UAAU;sFACc,UAAU;;;;;;;;;;cAWlF,oBAAoB,KAAK,SAAS;YAChC,CAAC,CAAC,IAAI,CAAA,EAAE;YACR,CAAC,CAAC,IAAI,CAAA,SAAS,oBAAoB,OACvC;;;;;;;;eAQG,OAAO;aACX,GAAG,CACF,CAAC,WAAW,EAAE,EAAE,CACd,IAAI,WAAW,CAAC,OAAO,CACrB,qBAAqB,EACrB,+BAA+B,CAChC,GAAG,CACP;aACA,IAAI,CAAC,GAAG,CAAC;OACb,GAAG,IAAI,CAAC;QACX,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,0BAA0B,EAC1B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAChC,CAAC;QACF,MAAM,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,MAAM,qCAAqC,EAAE,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,8EAA8E,IAAI,GAAG,CACtF,CAAC;QACJ,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChC,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC9B,MAAM,qCAAqC,EAAE,CAAC;QAC9C,MAAM,EAAE,CAAC,UAAU,CACjB,MAAM,EACN,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CACrE,CAAC;IACJ,CAAC;IAED,IAAI,oBAAoB;QAAE,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAE1D,KAAK,UAAU,qCAAqC;QAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5B,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACzC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,MAAM,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,IAAI,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,SAAS,CAAC,OAAO;SACpB,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,uDAAuD,CAAC;SACpE,cAAc,CACb,qBAAqB,EACrB,4CAA4C,CAC7C;SACA,cAAc,CACb,uBAAuB,EACvB,saAAsa,CACva;SACA,MAAM,CAAC,gBAAgB,EAAE,iDAAiD,CAAC;SAC3E,MAAM,CACL,yBAAyB,EACzB,kcAAkc,CACnc;SACA,MAAM,CACL,iBAAiB,EACjB,wEAAwE,CACzE;SACA,MAAM,CACL,iCAAiC,EACjC,qGAAqG,CACtG;SACA,MAAM,CACL,uBAAuB,EACvB,oFAAoF,CACrF;SACA,MAAM,CAAC,mBAAmB,EAAE,8BAA8B,CAAC;SAC3D,MAAM,CACL,2BAA2B,EAC3B,mGAAmG,CACpG;SACA,MAAM,CACL,iCAAiC,EACjC,wDAAwD,CACzD;SACA,MAAM,CACL,uCAAuC,EACvC,8HAA8H,CAC/H;SACA,QAAQ,CACP,cAAc,EACd,0VAA0V,CAC3V;SACA,OAAO,CACN,IAAI,CAAC,KAAK,CACR,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CACvE,CAAC,OAAO,CACV;SACA,WAAW,CACV,OAAO,EACP,IAAI;QACF,MAAM,CAAA;;;;;;;;;;;;;SAaL,CACJ;SACA,MAAM,CACL,KAAK,EACH,OAAiB,EACjB,EACE,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAO,GAAG,EAAE,EACZ,MAAM,EACN,cAAc,EACd,WAAW,EACX,IAAI,EACJ,UAAU,EACV,oBAAoB,EACpB,oBAAoB,GAarB,EACD,EAAE;QACF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC;gBACT,KAAK;gBACL,MAAM;gBACN,OAAO;gBACP,KAAK;gBACL,OAAO;gBACP,MAAM;gBACN,cAAc;gBACd,WAAW;gBACX,IAAI;gBACJ,UAAU;gBACV,oBAAoB;gBACpB,oBAAoB;aACrB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF;SACA,kBAAkB,EAAE;SACpB,UAAU,EAAE,CAAC"}
|
|
@@ -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);
|