@crustjs/crust 0.0.6 → 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 CHANGED
@@ -1,44 +1,18 @@
1
1
  # @crustjs/crust
2
2
 
3
- The all-in-one package for the [Crust](https://crustjs.com) CLI framework.
3
+ CLI tooling for the [Crust](https://crustjs.com) framework — build and distribute standalone executables.
4
4
 
5
- Re-exports everything from `@crustjs/core` and `@crustjs/plugins`, plus provides CLI tooling for building Crust-powered CLIs.
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
- When installed, the `crust` binary provides tooling for your project:
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 JS 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.
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 + JS resolver (default)
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` | `bun-darwin-arm64` | macOS Apple Silicon |
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
- my-cli.js # JS resolver (entry point for npm bin)
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 JS resolver as the bin entry:
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/my-cli.js"
93
+ "my-cli": "dist/cli"
118
94
  },
119
95
  "files": ["dist"]
120
96
  }
121
97
  ```
122
98
 
123
- The resolver uses `#!/usr/bin/env node` for maximum compatibility when installed globally via npm (works even when Bun is not installed on the end user's machine).
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.6",
15
- description: "A TypeScript-first, Bun-native CLI framework with composable modules.",
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
- "command",
31
- "framework",
32
- "parser",
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 entries = [];
137
+ const caseEntries = [];
145
138
  for (const target of targets) {
146
- const platformKey = TARGET_PLATFORM_MAP[target];
139
+ if (target.startsWith("bun-windows"))
140
+ continue;
141
+ const unameKey = TARGET_UNAME_MAP[target];
147
142
  const filename = getBinaryFilename(baseName, target);
148
- entries.push(` "${platformKey}": "${filename}"`);
143
+ caseEntries.push(` ${unameKey}) bin="${filename}" ;;`);
149
144
  }
150
- const mapBody = entries.join(`,
145
+ const caseBody = caseEntries.join(`
151
146
  `);
152
- return `#!/usr/bin/env node
153
- "use strict";
147
+ return `#!/bin/sh
148
+ # Auto-generated by crust build \u2014 do not edit
149
+ set -e
154
150
 
155
- const { execFileSync } = require("node:child_process");
156
- const { chmodSync, statSync } = require("node:fs");
157
- const path = require("node:path");
151
+ dir="$(cd "$(dirname "$0")" && pwd)"
152
+ platform="$(uname -s)-$(uname -m)"
158
153
 
159
- const PLATFORM_ARCH = \`\${process.platform}-\${process.arch}\`;
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
- const TARGET_MAP = {
162
- ${mapBody}
163
- };
164
-
165
- const binaryName = TARGET_MAP[PLATFORM_ARCH];
163
+ bin_path="$dir/$bin"
166
164
 
167
- if (!binaryName) {
168
- console.error(
169
- \`[${baseName}] Unsupported platform: \${PLATFORM_ARCH}. \` +
170
- "Please open an issue with your OS/CPU details."
171
- );
172
- process.exit(1);
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
- const binPath = path.join(__dirname, binaryName);
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
- try {
178
- statSync(binPath);
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 content = generateResolver(baseName, targets);
214
- writeFileSync(resolverPath, content, { mode: 493 });
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", `${baseName}.js`);
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.6",
4
- "description": "A TypeScript-first, Bun-native CLI framework with composable modules.",
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
- "command",
20
- "framework",
21
- "parser",
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
  },
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
@@ -1,2 +0,0 @@
1
- export * from "@crustjs/core";
2
- export * from "@crustjs/plugins";
package/dist/index.js DELETED
@@ -1,4 +0,0 @@
1
- // @bun
2
- // src/index.ts
3
- export * from "@crustjs/core";
4
- export * from "@crustjs/plugins";