craft-native 0.0.92 → 0.0.94

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/dist/index.d.ts CHANGED
@@ -3,7 +3,27 @@
3
3
  * TypeScript SDK powered by Bun
4
4
  */
5
5
  import type { AppConfig, WindowOptions } from './types.js';
6
+ /**
7
+ * The version a `craft --version` first line reports, whichever form it takes:
8
+ * `craft version 0.0.92`, `craft/0.0.92 darwin-arm64 bun-v1.4.1`,
9
+ * `craft 0.0.92`, `v0.0.92`, or a bare `0.0.92`.
10
+ *
11
+ * The slash form is the CLI's own, and used to survive the strip intact, so
12
+ * the whole line was compared against a semver and never matched — two
13
+ * identical versions reported as drift, on the one path where the real fault
14
+ * was that PATH had resolved to the CLI at all (#236).
15
+ */
6
16
  export declare function parseCraftVersionOutput(output: string): string;
17
+ /**
18
+ * The rejection for a child that exited non-zero.
19
+ *
20
+ * Whatever the child managed to say comes first, because it is the only part
21
+ * that can name the actual fault. `quiet` used to map to `stdio: 'ignore'`,
22
+ * which threw that away and then told the caller to read output that no
23
+ * longer existed — leaving `exited with code 1` as the whole of the error
24
+ * (#236).
25
+ */
26
+ export declare function craftProcessFailedMessage(code: number | null, stderr: string, quiet: boolean): string;
7
27
  export { packageApp, pack, type PackageConfig, type PackageResult } from './package.js';
8
28
  export { craftBinaryNotFoundMessage, resolveCraftBinary } from './binary-resolver.js';
9
29
  export * from './utils/index.js';
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ var __require = import.meta.require;
17
17
 
18
18
  // src/index.ts
19
19
  import { execFile as execFile2, spawn as spawn4 } from "child_process";
20
- import { mkdtempSync as mkdtempSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
20
+ import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync3 } from "fs";
21
21
  import { tmpdir as tmpdir4 } from "os";
22
22
  import { join as join4 } from "path";
23
23
  import { promisify as promisify2 } from "util";
@@ -40,6 +40,7 @@ function resolveCraftBinary(explicit) {
40
40
  }
41
41
  return "craft";
42
42
  }
43
+ var CRAFT_CLI_SPAWN_MARKER = "CRAFT_CLI_SPAWNED_FROM";
43
44
  function craftBinaryNotFoundMessage(triedPath) {
44
45
  return [
45
46
  `Craft native binary not found (tried "${triedPath}").`,
@@ -56,6 +57,11 @@ function craftBinaryNotFoundMessage(triedPath) {
56
57
  ].join(`
57
58
  `);
58
59
  }
60
+ // package.json
61
+ var version = "0.0.94";
62
+
63
+ // src/sdk-version.ts
64
+ var SDK_VERSION = version;
59
65
 
60
66
  // src/package.ts
61
67
  import { spawn } from "child_process";
@@ -183,13 +189,13 @@ async function packageApp(config) {
183
189
  }
184
190
  async function packageMacOS(config, outDir) {
185
191
  const results = [];
186
- const { name, version, bundleId = `com.myapp.${name.toLowerCase()}` } = config;
192
+ const { name, version: version2, bundleId = `com.myapp.${name.toLowerCase()}` } = config;
187
193
  const opts = config.macos || {};
188
194
  const hardenedRuntime = !opts.appStore;
189
195
  const appBundlePath = join(outDir, `${name}.app`);
190
196
  const appBundle = createMacOSAppBundle({
191
197
  name,
192
- version,
198
+ version: version2,
193
199
  bundleId,
194
200
  buildNumber: opts.buildNumber,
195
201
  category: opts.category,
@@ -233,7 +239,7 @@ async function packageMacOS(config, outDir) {
233
239
  }
234
240
  results.push({ success: true, platform: "macos", format: "app", outputPath: appBundlePath });
235
241
  if (opts.dmg !== false) {
236
- const outputPath = join(outDir, `${name}-${version}.dmg`);
242
+ const outputPath = join(outDir, `${name}-${version2}.dmg`);
237
243
  const dmgResult = await createDMG({ appBundlePath, outputPath, volumeName: name });
238
244
  results.push({
239
245
  success: dmgResult.success,
@@ -246,12 +252,12 @@ async function packageMacOS(config, outDir) {
246
252
  results.push(...await notarizeIfRequested(opts, outputPath, "dmg"));
247
253
  }
248
254
  if (opts.pkg || opts.appStore) {
249
- const outputPath = join(outDir, `${name}-${version}.pkg`);
255
+ const outputPath = join(outDir, `${name}-${version2}.pkg`);
250
256
  const pkgResult = await createPKG({
251
257
  appBundlePath,
252
258
  outputPath,
253
259
  identifier: bundleId,
254
- version,
260
+ version: version2,
255
261
  appStore: opts.appStore === true,
256
262
  installerIdentity: opts.installerIdentity
257
263
  });
@@ -297,14 +303,14 @@ async function notarizeIfRequested(opts, artifactPath, format) {
297
303
  }
298
304
  async function packageWindows(config, outDir) {
299
305
  const results = [];
300
- const { name, version } = config;
306
+ const { name, version: version2 } = config;
301
307
  const opts = config.windows || {};
302
308
  if (opts.msi !== false) {
303
309
  const msiResult = await createMSI({
304
310
  name,
305
- version,
311
+ version: version2,
306
312
  binaryPath: config.binaryPath,
307
- outputPath: join(outDir, `${name}-${version}.msi`),
313
+ outputPath: join(outDir, `${name}-${version2}.msi`),
308
314
  manufacturer: config.author || "Unknown",
309
315
  architecture: opts.architecture || windowsArchitecture(process.arch),
310
316
  certificatePath: opts.certificatePath,
@@ -321,9 +327,9 @@ async function packageWindows(config, outDir) {
321
327
  if (opts.zip || opts.msi === false) {
322
328
  const zipResult = await createZIP({
323
329
  name,
324
- version,
330
+ version: version2,
325
331
  binaryPath: config.binaryPath,
326
- outputPath: join(outDir, `${name}-${version}-windows.zip`)
332
+ outputPath: join(outDir, `${name}-${version2}-windows.zip`)
327
333
  });
328
334
  results.push({
329
335
  success: zipResult.success,
@@ -337,14 +343,14 @@ async function packageWindows(config, outDir) {
337
343
  }
338
344
  async function packageLinux(config, outDir) {
339
345
  const results = [];
340
- const { name, version } = config;
346
+ const { name, version: version2 } = config;
341
347
  const opts = config.linux || {};
342
348
  if (opts.deb !== false) {
343
349
  const debResult = await createDEB({
344
350
  name,
345
- version,
351
+ version: version2,
346
352
  binaryPath: config.binaryPath,
347
- outputPath: join(outDir, `${name}_${version}_amd64.deb`),
353
+ outputPath: join(outDir, `${name}_${version2}_amd64.deb`),
348
354
  description: config.description || "",
349
355
  maintainer: config.author || "Unknown",
350
356
  dependencies: opts.debDependencies || ["libgtk-3-0", "libwebkit2gtk-4.1-37"]
@@ -360,9 +366,9 @@ async function packageLinux(config, outDir) {
360
366
  if (opts.rpm) {
361
367
  const rpmResult = await createRPM({
362
368
  name,
363
- version,
369
+ version: version2,
364
370
  binaryPath: config.binaryPath,
365
- outputPath: join(outDir, `${name}-${version}-1.x86_64.rpm`),
371
+ outputPath: join(outDir, `${name}-${version2}-1.x86_64.rpm`),
366
372
  description: config.description || "",
367
373
  requires: opts.rpmDependencies || ["gtk3", "webkit2gtk3"]
368
374
  });
@@ -377,9 +383,9 @@ async function packageLinux(config, outDir) {
377
383
  if (opts.appImage) {
378
384
  const appImageResult = await createAppImage({
379
385
  name,
380
- version,
386
+ version: version2,
381
387
  binaryPath: config.binaryPath,
382
- outputPath: join(outDir, `${name}-${version}-x86_64.AppImage`),
388
+ outputPath: join(outDir, `${name}-${version2}-x86_64.AppImage`),
383
389
  iconPath: config.iconPath
384
390
  });
385
391
  results.push({
@@ -2570,7 +2576,7 @@ class SystemTray {
2570
2576
  }
2571
2577
  async setIcon(icon) {
2572
2578
  this._options.icon = icon;
2573
- await this._call("setIcon", icon);
2579
+ await this._call("setIcon", JSON.stringify({ icon }));
2574
2580
  }
2575
2581
  async setTooltip(tooltip) {
2576
2582
  this._options.tooltip = tooltip;
@@ -2584,6 +2590,9 @@ class SystemTray {
2584
2590
  if (!processedItem.id && processedItem.label) {
2585
2591
  processedItem.id = `menu_${index}_${Date.now()}`;
2586
2592
  }
2593
+ if (!processedItem.action && processedItem.id && processedItem.type !== "separator") {
2594
+ processedItem.action = processedItem.id;
2595
+ }
2587
2596
  if (processedItem.submenu) {
2588
2597
  processedItem.submenu = processItems(processedItem.submenu);
2589
2598
  }
@@ -2646,9 +2655,9 @@ class SystemTray {
2646
2655
  return new Promise((resolve, reject) => {
2647
2656
  try {
2648
2657
  window.webkit.messageHandlers.craft.postMessage({
2649
- type: "tray",
2650
- action,
2651
- data: typeof data === "string" ? data : JSON.stringify(data)
2658
+ t: "tray",
2659
+ a: action,
2660
+ d: typeof data === "string" ? data : JSON.stringify(data)
2652
2661
  });
2653
2662
  resolve(undefined);
2654
2663
  } catch (error) {
@@ -3928,8 +3937,8 @@ var crypto = {
3928
3937
  if (combined.length < 1 + SALT_LEN + IV_LEN + TAG_LEN) {
3929
3938
  throw new CraftCryptoError("Ciphertext too short to be valid");
3930
3939
  }
3931
- const version = combined[0];
3932
- if (version !== FORMAT_VERSION) {
3940
+ const version2 = combined[0];
3941
+ if (version2 !== FORMAT_VERSION) {
3933
3942
  throw new LegacyCiphertextError;
3934
3943
  }
3935
3944
  const salt = combined.slice(1, 1 + SALT_LEN);
@@ -4894,6 +4903,13 @@ var lifecycle = {
4894
4903
  return () => document.removeEventListener("visibilitychange", handler);
4895
4904
  }
4896
4905
  };
4906
+ function bridgeNotification(options, now = Date.now()) {
4907
+ const { scheduleAt, ...rest } = options;
4908
+ if (scheduleAt === undefined)
4909
+ return rest;
4910
+ const wait = Math.ceil(scheduleAt - now);
4911
+ return wait > 0 ? { ...rest, delay: wait } : rest;
4912
+ }
4897
4913
  var notifications = {
4898
4914
  async show(options) {
4899
4915
  const craft = getCraftMobile();
@@ -4907,7 +4923,7 @@ var notifications = {
4907
4923
  async schedule(options) {
4908
4924
  const craft = getCraftMobile();
4909
4925
  if (typeof window !== "undefined" && craft?.notifications) {
4910
- return craft.notifications.schedule(options);
4926
+ return craft.notifications.schedule(bridgeNotification(options));
4911
4927
  }
4912
4928
  throw new Error("Scheduled notifications not available in web");
4913
4929
  },
@@ -10583,14 +10599,14 @@ async function updaterCommand(args) {
10583
10599
  switch (subcommand) {
10584
10600
  case "check": {
10585
10601
  const url = rest[0];
10586
- const version = rest[1] || "0.0.0";
10602
+ const version2 = rest[1] || "0.0.0";
10587
10603
  if (!url) {
10588
10604
  console.error("Usage: craft updater check <update-url> [current-version]");
10589
10605
  process.exit(1);
10590
10606
  }
10591
10607
  const updater = new AutoUpdater({
10592
10608
  updateUrl: url,
10593
- currentVersion: version,
10609
+ currentVersion: version2,
10594
10610
  appPath: process.cwd(),
10595
10611
  autoDownload: false
10596
10612
  });
@@ -10624,14 +10640,14 @@ ${update.releaseNotes}`);
10624
10640
  break;
10625
10641
  }
10626
10642
  case "generate-manifest": {
10627
- const version = rest[0];
10643
+ const version2 = rest[0];
10628
10644
  const outputPath = rest[1] || "update.json";
10629
- if (!version) {
10645
+ if (!version2) {
10630
10646
  console.error("Usage: craft updater generate-manifest <version> [output]");
10631
10647
  process.exit(1);
10632
10648
  }
10633
10649
  const manifest = {
10634
- version,
10650
+ version: version2,
10635
10651
  releaseDate: new Date().toISOString(),
10636
10652
  platforms: {}
10637
10653
  };
@@ -10663,21 +10679,13 @@ var updater_default = AutoUpdater;
10663
10679
  // src/index.ts
10664
10680
  var execFileAsync2 = promisify2(execFile2);
10665
10681
  var versionMismatchWarned = false;
10666
- function getSdkVersion() {
10667
- try {
10668
- const pkgPath = join4(import.meta.dir, "..", "package.json");
10669
- return JSON.parse(readFileSync3(pkgPath, "utf-8")).version ?? "unknown";
10670
- } catch {
10671
- return "unknown";
10672
- }
10673
- }
10674
10682
  async function probeBinaryVersion(craftPath) {
10675
10683
  if (versionMismatchWarned)
10676
10684
  return;
10677
10685
  try {
10678
10686
  const { stdout } = await execFileAsync2(craftPath, ["--version"], { timeout: 2000 });
10679
10687
  const nativeVersion = parseCraftVersionOutput(stdout);
10680
- const sdkVersion = getSdkVersion();
10688
+ const sdkVersion = SDK_VERSION;
10681
10689
  if (sdkVersion !== "unknown" && nativeVersion && nativeVersion !== sdkVersion) {
10682
10690
  versionMismatchWarned = true;
10683
10691
  console.warn(`\u26A0\uFE0F Craft binary/SDK version mismatch: SDK=${sdkVersion}, native=${nativeVersion}.
@@ -10687,7 +10695,27 @@ async function probeBinaryVersion(craftPath) {
10687
10695
  }
10688
10696
  function parseCraftVersionOutput(output) {
10689
10697
  const firstLine = output.trim().split(/\r?\n/, 1)[0] ?? "";
10690
- return firstLine.replace(/^craft version\s+/i, "").replace(/^v/, "").trim();
10698
+ const withoutName = firstLine.replace(/^craft(?:\s+version)?[\s/]+/i, "").trim();
10699
+ const firstToken = withoutName.split(/\s+/, 1)[0] ?? "";
10700
+ return firstToken.replace(/^v/, "").trim();
10701
+ }
10702
+ var STDERR_TAIL_LIMIT = 4000;
10703
+ function craftProcessFailedMessage(code, stderr, quiet) {
10704
+ const said = stderr.trim();
10705
+ const header = `\u274C Craft process exited with code ${code}`;
10706
+ if (said)
10707
+ return `${header}
10708
+
10709
+ ${said}`;
10710
+ const where = quiet ? "It wrote nothing to stderr. Re-run without `quiet` to see its full output." : "Check the console output above for more details.";
10711
+ return `${header}
10712
+
10713
+ ` + `This may indicate:
10714
+ ` + ` \u2022 Invalid window configuration
10715
+ ` + ` \u2022 Malformed HTML content
10716
+ ` + ` \u2022 System resource constraints
10717
+
10718
+ ` + where;
10691
10719
  }
10692
10720
  function detectDevMode() {
10693
10721
  if (typeof process === "undefined")
@@ -10750,8 +10778,14 @@ class CraftApp {
10750
10778
  const args = this.buildArgs();
10751
10779
  const craftPath = await this.findCraftBinary();
10752
10780
  probeBinaryVersion(craftPath);
10781
+ const quiet = this.config.quiet === true;
10753
10782
  this.process = spawn4(craftPath, args, {
10754
- stdio: this.config.quiet ? "ignore" : "inherit"
10783
+ stdio: quiet ? ["ignore", "ignore", "pipe"] : "inherit",
10784
+ env: { ...process.env, [CRAFT_CLI_SPAWN_MARKER]: craftPath }
10785
+ });
10786
+ let stderrTail = "";
10787
+ this.process.stderr?.on("data", (chunk) => {
10788
+ stderrTail = (stderrTail + chunk.toString()).slice(-STDERR_TAIL_LIMIT);
10755
10789
  });
10756
10790
  return new Promise((resolve, reject) => {
10757
10791
  this.process?.on("error", (error) => {
@@ -10771,18 +10805,11 @@ class CraftApp {
10771
10805
  ` + `For troubleshooting, visit:
10772
10806
  ` + " https://github.com/home-lang/craft/issues"));
10773
10807
  });
10774
- this.process?.on("exit", (code) => {
10808
+ this.process?.on("close", (code) => {
10775
10809
  if (code === 0 || code === null) {
10776
10810
  resolve();
10777
10811
  } else {
10778
- reject(new Error(`\u274C Craft process exited with code ${code}
10779
-
10780
- ` + `This may indicate:
10781
- ` + ` \u2022 Invalid window configuration
10782
- ` + ` \u2022 Malformed HTML content
10783
- ` + ` \u2022 System resource constraints
10784
-
10785
- ` + "Check the console output above for more details."));
10812
+ reject(new Error(craftProcessFailedMessage(code, stderrTail, quiet)));
10786
10813
  }
10787
10814
  });
10788
10815
  });
@@ -11098,6 +11125,7 @@ export {
11098
11125
  createArcSidebar,
11099
11126
  createApp,
11100
11127
  craftUnavailableMessage,
11128
+ craftProcessFailedMessage,
11101
11129
  craftBinaryNotFoundMessage,
11102
11130
  copy,
11103
11131
  exports_components as components,