@crustjs/crust 0.0.5 → 0.0.7
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 +13 -37
- package/dist/cli.js +80 -79
- package/package.json +8 -15
- package/dist/cli.d.ts +0 -12
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -4
package/README.md
CHANGED
|
@@ -1,44 +1,18 @@
|
|
|
1
1
|
# @crustjs/crust
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CLI tooling for the [Crust](https://crustjs.com) framework — build and distribute standalone executables.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> For the framework API (`defineCommand`, `runMain`, plugins, etc.), install [`@crustjs/core`](https://www.npmjs.com/package/@crustjs/core) and [`@crustjs/plugins`](https://www.npmjs.com/package/@crustjs/plugins).
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
bun add @crustjs/crust
|
|
10
|
+
bun add -d @crustjs/crust
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
## Framework API
|
|
14
|
-
|
|
15
|
-
The `@crustjs/crust` package gives you the full framework API in a single import:
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
import {
|
|
19
|
-
defineCommand,
|
|
20
|
-
runMain,
|
|
21
|
-
helpPlugin,
|
|
22
|
-
versionPlugin,
|
|
23
|
-
} from "@crustjs/crust";
|
|
24
|
-
|
|
25
|
-
const main = defineCommand({
|
|
26
|
-
meta: { name: "my-cli", description: "My CLI tool" },
|
|
27
|
-
run() {
|
|
28
|
-
console.log("Hello!");
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
runMain(main, {
|
|
33
|
-
plugins: [versionPlugin("1.0.0"), helpPlugin()],
|
|
34
|
-
});
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
> For granular control, you can install `@crustjs/core` and `@crustjs/plugins` separately.
|
|
38
|
-
|
|
39
13
|
## CLI Commands
|
|
40
14
|
|
|
41
|
-
|
|
15
|
+
The `crust` binary provides build tooling for your Crust-powered CLI:
|
|
42
16
|
|
|
43
17
|
| Command | Description |
|
|
44
18
|
| ------------- | ------------------------------------------------ |
|
|
@@ -48,10 +22,10 @@ When installed, the `crust` binary provides tooling for your project:
|
|
|
48
22
|
|
|
49
23
|
Compiles your CLI entry file to standalone Bun executables using `bun build --compile`.
|
|
50
24
|
|
|
51
|
-
**By default, builds for all 5 supported platforms** and generates a
|
|
25
|
+
**By default, builds for all 5 supported platforms** and generates a shell resolver script that detects the host platform at runtime and runs the correct binary. This makes it easy to distribute your CLI as a single npm package that works everywhere — no runtime (Node.js or Bun) required.
|
|
52
26
|
|
|
53
27
|
```sh
|
|
54
|
-
crust build # All platforms +
|
|
28
|
+
crust build # All platforms + shell resolver (default)
|
|
55
29
|
crust build --entry src/main.ts # Custom entry point
|
|
56
30
|
crust build --name my-tool # Set base binary name
|
|
57
31
|
crust build --no-minify # Disable minification
|
|
@@ -72,7 +46,7 @@ crust build --target linux-x64 --outfile ./my-cli # Custom output (single
|
|
|
72
46
|
| `linux-x64` | `bun-linux-x64-baseline` | Linux x86_64 |
|
|
73
47
|
| `linux-arm64` | `bun-linux-arm64` | Linux ARM64 |
|
|
74
48
|
| `darwin-x64` | `bun-darwin-x64` | macOS Intel |
|
|
75
|
-
| `darwin-arm64`
|
|
49
|
+
| `darwin-arm64` | `bun-darwin-arm64` | macOS Apple Silicon |
|
|
76
50
|
| `windows-x64` | `bun-windows-x64-baseline` | Windows x86_64 |
|
|
77
51
|
|
|
78
52
|
#### Flags
|
|
@@ -84,6 +58,7 @@ crust build --target linux-x64 --outfile ./my-cli # Custom output (single
|
|
|
84
58
|
| `--name` | `-n` | `"string"` | package.json `name` | Base binary name |
|
|
85
59
|
| `--minify` | — | `"boolean"` | `true` | Minify the output |
|
|
86
60
|
| `--target` | `-t` | `"string"` | _(all platforms)_ | Target platform(s); repeatable |
|
|
61
|
+
| `--resolver` | `-r` | `"string"` | `cli` | Resolver script filename (multi-target only, no extension) |
|
|
87
62
|
|
|
88
63
|
#### Output
|
|
89
64
|
|
|
@@ -91,7 +66,8 @@ crust build --target linux-x64 --outfile ./my-cli # Custom output (single
|
|
|
91
66
|
|
|
92
67
|
```
|
|
93
68
|
dist/
|
|
94
|
-
|
|
69
|
+
cli # Shell resolver (entry point for npm bin)
|
|
70
|
+
cli.cmd # Windows batch resolver
|
|
95
71
|
my-cli-bun-linux-x64-baseline # Linux x64 binary
|
|
96
72
|
my-cli-bun-linux-arm64 # Linux ARM64 binary
|
|
97
73
|
my-cli-bun-darwin-x64 # macOS Intel binary
|
|
@@ -108,19 +84,19 @@ dist/
|
|
|
108
84
|
|
|
109
85
|
#### Distributing via npm
|
|
110
86
|
|
|
111
|
-
After building for all platforms, configure your `package.json` to use the
|
|
87
|
+
After building for all platforms, configure your `package.json` to use the shell resolver as the bin entry:
|
|
112
88
|
|
|
113
89
|
```json
|
|
114
90
|
{
|
|
115
91
|
"name": "my-cli",
|
|
116
92
|
"bin": {
|
|
117
|
-
"my-cli": "dist/
|
|
93
|
+
"my-cli": "dist/cli"
|
|
118
94
|
},
|
|
119
95
|
"files": ["dist"]
|
|
120
96
|
}
|
|
121
97
|
```
|
|
122
98
|
|
|
123
|
-
The resolver
|
|
99
|
+
The resolver is a `#!/bin/sh` script (with a companion `.cmd` for Windows) that requires no runtime — it detects the platform and directly executes the correct prebuilt binary.
|
|
124
100
|
|
|
125
101
|
## Documentation
|
|
126
102
|
|
package/dist/cli.js
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
// package.json
|
|
12
12
|
var package_default = {
|
|
13
13
|
name: "@crustjs/crust",
|
|
14
|
-
version: "0.0.
|
|
15
|
-
description: "
|
|
14
|
+
version: "0.0.7",
|
|
15
|
+
description: "CLI tooling for the Crust framework \u2014 build and distribute standalone executables.",
|
|
16
16
|
type: "module",
|
|
17
17
|
license: "MIT",
|
|
18
18
|
author: "chenxin-yan",
|
|
@@ -27,22 +27,15 @@ var package_default = {
|
|
|
27
27
|
},
|
|
28
28
|
keywords: [
|
|
29
29
|
"cli",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
30
|
+
"build",
|
|
31
|
+
"compile",
|
|
32
|
+
"standalone",
|
|
33
33
|
"bun",
|
|
34
|
-
"typescript"
|
|
35
|
-
"plugin"
|
|
34
|
+
"typescript"
|
|
36
35
|
],
|
|
37
36
|
files: [
|
|
38
37
|
"dist"
|
|
39
38
|
],
|
|
40
|
-
exports: {
|
|
41
|
-
".": {
|
|
42
|
-
import: "./dist/index.js",
|
|
43
|
-
types: "./dist/index.d.ts"
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
39
|
publishConfig: {
|
|
47
40
|
access: "public"
|
|
48
41
|
},
|
|
@@ -86,13 +79,6 @@ var TARGET_ALIASES = {
|
|
|
86
79
|
"darwin-arm64": "bun-darwin-arm64",
|
|
87
80
|
"windows-x64": "bun-windows-x64-baseline"
|
|
88
81
|
};
|
|
89
|
-
var TARGET_PLATFORM_MAP = {
|
|
90
|
-
"bun-linux-x64-baseline": "linux-x64",
|
|
91
|
-
"bun-linux-arm64": "linux-arm64",
|
|
92
|
-
"bun-darwin-x64": "darwin-x64",
|
|
93
|
-
"bun-darwin-arm64": "darwin-arm64",
|
|
94
|
-
"bun-windows-x64-baseline": "win32-x64"
|
|
95
|
-
};
|
|
96
82
|
function resolveTarget(input) {
|
|
97
83
|
if (SUPPORTED_TARGETS.includes(input)) {
|
|
98
84
|
return input;
|
|
@@ -135,83 +121,92 @@ function resolveTargetOutfile(baseName, target, cwd) {
|
|
|
135
121
|
const ext = isWindows ? ".exe" : "";
|
|
136
122
|
return resolve(cwd, "dist", `${baseName}-${target}${ext}`);
|
|
137
123
|
}
|
|
124
|
+
var TARGET_UNAME_MAP = {
|
|
125
|
+
"bun-linux-x64-baseline": "Linux-x86_64",
|
|
126
|
+
"bun-linux-arm64": "Linux-aarch64",
|
|
127
|
+
"bun-darwin-x64": "Darwin-x86_64",
|
|
128
|
+
"bun-darwin-arm64": "Darwin-arm64",
|
|
129
|
+
"bun-windows-x64-baseline": "Windows-x64"
|
|
130
|
+
};
|
|
138
131
|
function getBinaryFilename(baseName, target) {
|
|
139
132
|
const isWindows = target.startsWith("bun-windows");
|
|
140
133
|
const ext = isWindows ? ".exe" : "";
|
|
141
134
|
return `${baseName}-${target}${ext}`;
|
|
142
135
|
}
|
|
143
136
|
function generateResolver(baseName, targets) {
|
|
144
|
-
const
|
|
137
|
+
const caseEntries = [];
|
|
145
138
|
for (const target of targets) {
|
|
146
|
-
|
|
139
|
+
if (target.startsWith("bun-windows"))
|
|
140
|
+
continue;
|
|
141
|
+
const unameKey = TARGET_UNAME_MAP[target];
|
|
147
142
|
const filename = getBinaryFilename(baseName, target);
|
|
148
|
-
|
|
143
|
+
caseEntries.push(` ${unameKey}) bin="${filename}" ;;`);
|
|
149
144
|
}
|
|
150
|
-
const
|
|
145
|
+
const caseBody = caseEntries.join(`
|
|
151
146
|
`);
|
|
152
|
-
return `#!/
|
|
153
|
-
|
|
147
|
+
return `#!/bin/sh
|
|
148
|
+
# Auto-generated by crust build \u2014 do not edit
|
|
149
|
+
set -e
|
|
154
150
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const path = require("node:path");
|
|
151
|
+
dir="$(cd "$(dirname "$0")" && pwd)"
|
|
152
|
+
platform="$(uname -s)-$(uname -m)"
|
|
158
153
|
|
|
159
|
-
|
|
154
|
+
case "$platform" in
|
|
155
|
+
${caseBody}
|
|
156
|
+
*)
|
|
157
|
+
echo "[${baseName}] Unsupported platform: $platform" >&2
|
|
158
|
+
echo "[${baseName}] Please open an issue with your OS/CPU details." >&2
|
|
159
|
+
exit 1
|
|
160
|
+
;;
|
|
161
|
+
esac
|
|
160
162
|
|
|
161
|
-
|
|
162
|
-
${mapBody}
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const binaryName = TARGET_MAP[PLATFORM_ARCH];
|
|
163
|
+
bin_path="$dir/$bin"
|
|
166
164
|
|
|
167
|
-
if
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
165
|
+
if [ ! -f "$bin_path" ]; then
|
|
166
|
+
echo "[${baseName}] Prebuilt binary not found: $bin_path" >&2
|
|
167
|
+
echo "[${baseName}] Expected binary for $platform: $bin" >&2
|
|
168
|
+
echo "[${baseName}] Try reinstalling the package." >&2
|
|
169
|
+
exit 1
|
|
170
|
+
fi
|
|
174
171
|
|
|
175
|
-
|
|
172
|
+
# Ensure the binary is executable
|
|
173
|
+
if [ ! -x "$bin_path" ]; then
|
|
174
|
+
chmod +x "$bin_path" 2>/dev/null || true
|
|
175
|
+
fi
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
} catch {
|
|
180
|
-
console.error(\`[${baseName}] Prebuilt binary not found: \${binPath}\`);
|
|
181
|
-
console.error(\`[${baseName}] Expected binary for \${PLATFORM_ARCH}: \${binaryName}\`);
|
|
182
|
-
console.error(\`[${baseName}] Try reinstalling the package.\`);
|
|
183
|
-
process.exit(1);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Ensure binary is executable on Unix
|
|
187
|
-
if (process.platform !== "win32") {
|
|
188
|
-
try {
|
|
189
|
-
const stats = statSync(binPath);
|
|
190
|
-
if ((stats.mode & 0o111) === 0) {
|
|
191
|
-
chmodSync(binPath, stats.mode | 0o111);
|
|
192
|
-
}
|
|
193
|
-
} catch {
|
|
194
|
-
try {
|
|
195
|
-
chmodSync(binPath, 0o755);
|
|
196
|
-
} catch {
|
|
197
|
-
// If chmod fails, continue and let execFileSync report the error
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
try {
|
|
203
|
-
execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
204
|
-
} catch (error) {
|
|
205
|
-
if (error && typeof error === "object" && "status" in error && typeof error.status === "number") {
|
|
206
|
-
process.exit(error.status);
|
|
207
|
-
}
|
|
208
|
-
process.exit(1);
|
|
177
|
+
exec "$bin_path" "$@"
|
|
178
|
+
`;
|
|
209
179
|
}
|
|
180
|
+
function generateCmdResolver(baseName, targets) {
|
|
181
|
+
const windowsTargets = targets.filter((t) => t.startsWith("bun-windows"));
|
|
182
|
+
if (windowsTargets.length === 0) {
|
|
183
|
+
return `@echo off\r
|
|
184
|
+
echo [${baseName}] No Windows binary was built for this package. >&2\r
|
|
185
|
+
exit /b 1\r
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
const filename = getBinaryFilename(baseName, windowsTargets[0]);
|
|
189
|
+
return `@echo off\r
|
|
190
|
+
rem Auto-generated by crust build -- do not edit\r
|
|
191
|
+
setlocal\r
|
|
192
|
+
set "dir=%~dp0"\r
|
|
193
|
+
set "bin=${filename}"\r
|
|
194
|
+
set "bin_path=%dir%%bin%"\r
|
|
195
|
+
\r
|
|
196
|
+
if not exist "%bin_path%" (\r
|
|
197
|
+
echo [${baseName}] Prebuilt binary not found: %bin_path% >&2\r
|
|
198
|
+
echo [${baseName}] Try reinstalling the package. >&2\r
|
|
199
|
+
exit /b 1\r
|
|
200
|
+
)\r
|
|
201
|
+
\r
|
|
202
|
+
"%bin_path%" %*\r
|
|
210
203
|
`;
|
|
211
204
|
}
|
|
212
205
|
function writeResolver(resolverPath, baseName, targets) {
|
|
213
|
-
const
|
|
214
|
-
writeFileSync(resolverPath,
|
|
206
|
+
const shellContent = generateResolver(baseName, targets);
|
|
207
|
+
writeFileSync(resolverPath, shellContent, { mode: 493 });
|
|
208
|
+
const cmdContent = generateCmdResolver(baseName, targets);
|
|
209
|
+
writeFileSync(`${resolverPath}.cmd`, cmdContent);
|
|
215
210
|
}
|
|
216
211
|
function buildBunArgs(entryPath, outfilePath, minify, target) {
|
|
217
212
|
const args = [
|
|
@@ -274,6 +269,12 @@ var buildCommand = defineCommand({
|
|
|
274
269
|
multiple: true,
|
|
275
270
|
description: "Target platform(s) to compile for (e.g. linux-x64, darwin-arm64). Omit to build all.",
|
|
276
271
|
alias: "t"
|
|
272
|
+
},
|
|
273
|
+
resolver: {
|
|
274
|
+
type: "string",
|
|
275
|
+
description: "Filename for the resolver script (multi-target builds, no extension)",
|
|
276
|
+
default: "cli",
|
|
277
|
+
alias: "r"
|
|
277
278
|
}
|
|
278
279
|
},
|
|
279
280
|
async run({ flags }) {
|
|
@@ -305,7 +306,7 @@ var buildCommand = defineCommand({
|
|
|
305
306
|
await execBuild(args, cwd, targetOutfile);
|
|
306
307
|
results.push(targetOutfile);
|
|
307
308
|
}
|
|
308
|
-
const resolverPath = resolve(cwd, "dist",
|
|
309
|
+
const resolverPath = resolve(cwd, "dist", flags.resolver);
|
|
309
310
|
writeResolver(resolverPath, baseName, targets);
|
|
310
311
|
console.log(`
|
|
311
312
|
Built ${results.length} target(s) successfully:`);
|
|
@@ -313,7 +314,7 @@ Built ${results.length} target(s) successfully:`);
|
|
|
313
314
|
console.log(` ${r}`);
|
|
314
315
|
}
|
|
315
316
|
console.log(`
|
|
316
|
-
Resolver: ${resolverPath}`);
|
|
317
|
+
Resolver: ${resolverPath} (+ ${resolverPath}.cmd)`);
|
|
317
318
|
}
|
|
318
319
|
}
|
|
319
320
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crustjs/crust",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.7",
|
|
4
|
+
"description": "CLI tooling for the Crust framework — build and distribute standalone executables.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "chenxin-yan",
|
|
@@ -16,22 +16,15 @@
|
|
|
16
16
|
},
|
|
17
17
|
"keywords": [
|
|
18
18
|
"cli",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
19
|
+
"build",
|
|
20
|
+
"compile",
|
|
21
|
+
"standalone",
|
|
22
22
|
"bun",
|
|
23
|
-
"typescript"
|
|
24
|
-
"plugin"
|
|
23
|
+
"typescript"
|
|
25
24
|
],
|
|
26
25
|
"files": [
|
|
27
26
|
"dist"
|
|
28
27
|
],
|
|
29
|
-
"exports": {
|
|
30
|
-
".": {
|
|
31
|
-
"import": "./dist/index.js",
|
|
32
|
-
"types": "./dist/index.d.ts"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
28
|
"publishConfig": {
|
|
36
29
|
"access": "public"
|
|
37
30
|
},
|
|
@@ -45,8 +38,8 @@
|
|
|
45
38
|
"test": "bun test"
|
|
46
39
|
},
|
|
47
40
|
"dependencies": {
|
|
48
|
-
"@crustjs/core": "0.0.
|
|
49
|
-
"@crustjs/plugins": "0.0.
|
|
41
|
+
"@crustjs/core": "0.0.6",
|
|
42
|
+
"@crustjs/plugins": "0.0.6"
|
|
50
43
|
},
|
|
51
44
|
"devDependencies": {
|
|
52
45
|
"@crustjs/config": "0.0.0",
|
package/dist/cli.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Command } from "@crustjs/core";
|
|
2
|
-
/**
|
|
3
|
-
* The root `crust` CLI command.
|
|
4
|
-
*
|
|
5
|
-
* Built entirely with `@crustjs/core`.
|
|
6
|
-
* When invoked without a subcommand, displays help listing available commands.
|
|
7
|
-
*
|
|
8
|
-
* Subcommands:
|
|
9
|
-
* - `crust build` - Compile your CLI to a standalone Bun executable
|
|
10
|
-
*/
|
|
11
|
-
declare const crustCommand: Command;
|
|
12
|
-
export { crustCommand };
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED