craft-native 0.0.436 → 0.0.443
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/LICENSE.md +30 -0
- package/README.md +35 -0
- package/dist/android/src/index.d.ts +44 -0
- package/dist/android/src/index.js +82 -3
- package/dist/android/templates/AndroidManifest.xml.template +2 -1
- package/dist/android/templates/CraftHealthServices.kt.template +2 -0
- package/dist/android/templates/CraftNativeCapabilities.kt.template +42 -1
- package/dist/android/templates/CraftNativeMotion.kt.template +269 -0
- package/dist/android/templates/CraftNativeServices.kt.template +6 -1
- package/dist/android/templates/CraftPassiveSteps.kt.template +159 -0
- package/dist/android/templates/CraftRecordingPressure.kt.template +156 -0
- package/dist/android/templates/LocationRecordingService.kt.template +77 -9
- package/dist/android/templates/MainActivity.kt.template +3 -0
- package/dist/android/templates/MainActivityNative.kt.template +132 -1
- package/dist/cli.js +289 -108
- package/dist/components/index.d.ts +25 -0
- package/dist/index.cjs +207 -27
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +321 -140
- package/dist/installer-background.d.ts +2 -0
- package/dist/installer-layout.d.ts +1 -0
- package/dist/ios/src/index.d.ts +23 -1
- package/dist/ios/src/index.js +49 -9
- package/dist/ios/templates/CraftApp.swift +14 -0
- package/dist/ios/templates/CraftHealth.swift +2 -1
- package/dist/ios/templates/CraftHealthBackground.swift +308 -0
- package/dist/ios/templates/CraftNativeActions.swift +153 -0
- package/dist/ios/templates/CraftNativePedometer.swift +181 -0
- package/dist/ios/templates/CraftNativeScreen.swift +76 -0
- package/dist/macos/src/index.js +1 -1
- package/dist/macos/src/toolchain.d.ts +1 -1
- package/dist/macos/templates/CraftMacApplication.swift +124 -39
- package/dist/macos/templates/CraftMacRenderer.swift +111 -33
- package/dist/macos/templates/CraftMacRuntime.swift +270 -81
- package/dist/package.d.ts +40 -0
- package/dist/types.d.ts +26 -0
- package/package.json +1 -1
|
@@ -321,6 +321,22 @@ export interface BaseProps {
|
|
|
321
321
|
accessibilityValue?: string | number;
|
|
322
322
|
/** Accessibility state exposed to assistive technologies */
|
|
323
323
|
accessibilityState?: AccessibilityState;
|
|
324
|
+
/**
|
|
325
|
+
* Actions a screen reader can perform on this node, published to the
|
|
326
|
+
* VoiceOver rotor and TalkBack's actions menu.
|
|
327
|
+
*
|
|
328
|
+
* A long press announces nothing and cannot be performed by assistive
|
|
329
|
+
* technology, so anything reachable only by holding needs these to exist
|
|
330
|
+
* for a screen reader at all. Pair with `onAccessibilityAction`, which
|
|
331
|
+
* receives the `name` of whichever one ran.
|
|
332
|
+
*/
|
|
333
|
+
accessibilityActions?: AccessibilityAction[];
|
|
334
|
+
/** Fired when a screen reader performs one of `accessibilityActions`. */
|
|
335
|
+
onAccessibilityAction?: (event: {
|
|
336
|
+
nativeEvent: {
|
|
337
|
+
actionName: string;
|
|
338
|
+
};
|
|
339
|
+
}) => void;
|
|
324
340
|
/** Accessibility role */
|
|
325
341
|
accessibilityRole?: 'none' | 'button' | 'link' | 'image' | 'text' | 'header' | 'search' | 'adjustable' | 'menu' | 'summary' | 'alert' | 'checkbox' | 'combobox' | 'menuitem' | 'progressbar' | 'radio' | 'tablist' | 'radiogroup' | 'list' | 'menubar' | 'spinbutton' | 'switch' | 'tab' | 'timer' | 'toolbar' | 'scrollbar';
|
|
326
342
|
/** Native list chrome slot for keyed FlatList/SectionList children. */
|
|
@@ -335,6 +351,15 @@ export interface AccessibilityState {
|
|
|
335
351
|
selected?: boolean;
|
|
336
352
|
checked?: boolean;
|
|
337
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* One action a screen reader can perform on a node.
|
|
356
|
+
*/
|
|
357
|
+
export interface AccessibilityAction {
|
|
358
|
+
/** Identifies the action to `onAccessibilityAction`; never spoken. */
|
|
359
|
+
name: string;
|
|
360
|
+
/** What the person hears. Falls back to `name` when absent. */
|
|
361
|
+
label?: string;
|
|
362
|
+
}
|
|
338
363
|
/**
|
|
339
364
|
* View component props.
|
|
340
365
|
*/
|
package/dist/index.cjs
CHANGED
|
@@ -91,6 +91,7 @@ __export(exports_src, {
|
|
|
91
91
|
createApp: () => createApp,
|
|
92
92
|
createArcSidebar: () => createArcSidebar,
|
|
93
93
|
createClient: () => createClient,
|
|
94
|
+
createDiskImage: () => createDiskImage,
|
|
94
95
|
createFileBrowser: () => createFileBrowser,
|
|
95
96
|
createFileSidebar: () => createFileSidebar,
|
|
96
97
|
createMenubarApp: () => createMenubarApp,
|
|
@@ -334,9 +335,9 @@ __export(exports_updater, {
|
|
|
334
335
|
});
|
|
335
336
|
|
|
336
337
|
// src/index.ts
|
|
337
|
-
var
|
|
338
|
-
var
|
|
339
|
-
var
|
|
338
|
+
var import_node_child_process2 = require("node:child_process");
|
|
339
|
+
var import_node_fs4 = require("node:fs");
|
|
340
|
+
var import_node_path3 = require("node:path");
|
|
340
341
|
var import_node_util = require("node:util");
|
|
341
342
|
|
|
342
343
|
// src/binary-resolver.ts
|
|
@@ -375,7 +376,7 @@ function craftBinaryNotFoundMessage(triedPath) {
|
|
|
375
376
|
`);
|
|
376
377
|
}
|
|
377
378
|
// package.json
|
|
378
|
-
var version = "0.0.
|
|
379
|
+
var version = "0.0.443";
|
|
379
380
|
|
|
380
381
|
// src/sdk-version.ts
|
|
381
382
|
var SDK_VERSION = version;
|
|
@@ -494,6 +495,134 @@ function removeTempDir(dir) {
|
|
|
494
495
|
unhook();
|
|
495
496
|
}
|
|
496
497
|
|
|
498
|
+
// src/installer-layout.ts
|
|
499
|
+
var import_node_child_process = require("node:child_process");
|
|
500
|
+
var import_node_fs3 = require("node:fs");
|
|
501
|
+
var import_node_path2 = require("node:path");
|
|
502
|
+
/*!
|
|
503
|
+
* Format implementation adapted from MIT-licensed references:
|
|
504
|
+
* Copyright (c) 2020 Kenty Gwend
|
|
505
|
+
* Copyright (c) 2026 John Campion Jr
|
|
506
|
+
* Copyright (c) 2014 Alastair Houghton
|
|
507
|
+
* Copyright (c) 2022 Russell Keith-Magee
|
|
508
|
+
*
|
|
509
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
510
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
511
|
+
* in the Software without restriction, including without limitation the rights
|
|
512
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
513
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
514
|
+
* furnished to do so, subject to the following conditions:
|
|
515
|
+
* The above copyright notice and this permission notice shall be included in
|
|
516
|
+
* all copies or substantial portions of the Software.
|
|
517
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
518
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
519
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
520
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
521
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
522
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
523
|
+
* SOFTWARE.
|
|
524
|
+
*/
|
|
525
|
+
var number = (value, bytes = 4) => {
|
|
526
|
+
const out = Buffer.alloc(bytes);
|
|
527
|
+
out.writeUIntBE(value, 0, bytes);
|
|
528
|
+
return out;
|
|
529
|
+
};
|
|
530
|
+
var unicode = (value) => Buffer.from(value, "utf16le").swap16();
|
|
531
|
+
var pascal = (value, size) => {
|
|
532
|
+
const out = Buffer.alloc(size);
|
|
533
|
+
const bytes = Buffer.from(value).subarray(0, size - 1);
|
|
534
|
+
out[0] = bytes.length;
|
|
535
|
+
bytes.copy(out, 1);
|
|
536
|
+
return out;
|
|
537
|
+
};
|
|
538
|
+
var tag = (id, data) => Buffer.concat([number(id, 2), number(data.length, 2), data, Buffer.alloc(data.length % 2)]);
|
|
539
|
+
function backgroundAlias(mount, volume) {
|
|
540
|
+
const folder = ".background";
|
|
541
|
+
const filename = "installer.png";
|
|
542
|
+
const directory = import_node_fs3.statSync(import_node_path2.join(mount, folder));
|
|
543
|
+
const file = import_node_fs3.statSync(import_node_path2.join(mount, folder, filename));
|
|
544
|
+
const date = (ms) => Math.floor(ms / 1000) + 2082844800;
|
|
545
|
+
const volumeDate = date(import_node_fs3.statSync(mount).birthtimeMs);
|
|
546
|
+
const fileDate = date(file.birthtimeMs);
|
|
547
|
+
const preciseDate = (value) => {
|
|
548
|
+
const out = Buffer.alloc(8);
|
|
549
|
+
out.writeBigUInt64BE(BigInt(value) * 65536n);
|
|
550
|
+
return out;
|
|
551
|
+
};
|
|
552
|
+
const body = Buffer.concat([
|
|
553
|
+
number(0, 2),
|
|
554
|
+
pascal(volume, 28),
|
|
555
|
+
number(volumeDate),
|
|
556
|
+
Buffer.from("H+"),
|
|
557
|
+
number(0, 2),
|
|
558
|
+
number(directory.ino),
|
|
559
|
+
pascal(filename, 64),
|
|
560
|
+
number(file.ino),
|
|
561
|
+
number(fileDate),
|
|
562
|
+
Buffer.alloc(8),
|
|
563
|
+
number(65535, 2),
|
|
564
|
+
number(65535, 2),
|
|
565
|
+
Buffer.alloc(16),
|
|
566
|
+
tag(0, Buffer.from(folder)),
|
|
567
|
+
tag(16, preciseDate(volumeDate)),
|
|
568
|
+
tag(17, preciseDate(fileDate)),
|
|
569
|
+
tag(1, number(directory.ino)),
|
|
570
|
+
tag(2, Buffer.from(`${volume}:${folder}:\x00${filename}`)),
|
|
571
|
+
tag(14, Buffer.concat([number(filename.length, 2), unicode(filename)])),
|
|
572
|
+
tag(15, Buffer.concat([number(volume.length, 2), unicode(volume)])),
|
|
573
|
+
tag(18, Buffer.from(`/${folder}/${filename}`)),
|
|
574
|
+
tag(19, Buffer.from(`/Volumes/${volume}`)),
|
|
575
|
+
number(65535, 2),
|
|
576
|
+
number(0, 2)
|
|
577
|
+
]);
|
|
578
|
+
return Buffer.concat([Buffer.alloc(4), number(body.length + 8, 2), number(2, 2), body]);
|
|
579
|
+
}
|
|
580
|
+
function plist(values) {
|
|
581
|
+
const escape = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
582
|
+
const entries = Object.entries(values).map(([key, value]) => {
|
|
583
|
+
const data = Buffer.isBuffer(value) ? `<data>${value.toString("base64")}</data>` : typeof value === "boolean" ? `<${value}/>` : typeof value === "number" ? ["viewOptionsVersion", "backgroundType"].includes(key) ? `<integer>${value}</integer>` : `<real>${value}</real>` : `<string>${escape(value)}</string>`;
|
|
584
|
+
return `<key>${key}</key>${data}`;
|
|
585
|
+
}).join("");
|
|
586
|
+
return import_node_child_process.execFileSync("plutil", ["-convert", "binary1", "-o", "-", "-"], { input: `<?xml version="1.0"?><plist version="1.0"><dict>${entries}</dict></plist>` });
|
|
587
|
+
}
|
|
588
|
+
function writeInstallerLayout(mount, volume, appName) {
|
|
589
|
+
const records = [];
|
|
590
|
+
const blob = (name, code, data) => records.push({ name, code, type: "blob", data: Buffer.concat([number(data.length), data]) });
|
|
591
|
+
blob(".", "bwsp", plist({ ShowStatusBar: false, ShowToolbar: false, ShowTabView: false, ShowSidebar: false, ContainerShowSidebar: false, ShowPathbar: false, SidebarWidth: 0, PreviewPaneVisibility: false, WindowBounds: "{{100, 100}, {660, 460}}" }));
|
|
592
|
+
blob(".", "icvp", plist({ viewOptionsVersion: 1, backgroundType: 2, backgroundColorRed: 1, backgroundColorGreen: 1, backgroundColorBlue: 1, backgroundImageAlias: backgroundAlias(mount, volume), iconSize: 96, arrangeBy: "none", gridSpacing: 100, gridOffsetX: 0, gridOffsetY: 0, scrollPositionX: 0, scrollPositionY: 0, textSize: 13, labelOnBottom: true, showIconPreview: true, showItemInfo: false }));
|
|
593
|
+
records.push({ name: ".", code: "vSrn", type: "long", data: number(1) });
|
|
594
|
+
records.push({ name: ".", code: "icvl", type: "type", data: Buffer.from("icnv") });
|
|
595
|
+
records.push({ name: ".", code: "vstl", type: "type", data: Buffer.from("icnv") });
|
|
596
|
+
for (const [name, x, y] of [[appName, 160, 190], ["Applications", 500, 190], [".background", 500, 600]])
|
|
597
|
+
blob(name, "Iloc", Buffer.concat([number(x), number(y), Buffer.from("ffffffffffff0000", "hex")]));
|
|
598
|
+
records.sort((a, b) => {
|
|
599
|
+
const left = a.name.normalize("NFD").toLowerCase();
|
|
600
|
+
const right = b.name.normalize("NFD").toLowerCase();
|
|
601
|
+
return left < right ? -1 : left > right ? 1 : a.code < b.code ? -1 : 1;
|
|
602
|
+
});
|
|
603
|
+
const leaf = Buffer.concat([number(0), number(records.length), ...records.map((record) => {
|
|
604
|
+
const name = record.name.normalize("NFD");
|
|
605
|
+
return Buffer.concat([number(name.length), unicode(name), Buffer.from(record.code + record.type), record.data]);
|
|
606
|
+
})]);
|
|
607
|
+
if (leaf.length > 4096)
|
|
608
|
+
throw new Error("Installer layout exceeds the Finder store leaf capacity");
|
|
609
|
+
const offsets = Buffer.alloc(1024);
|
|
610
|
+
offsets.writeUInt32BE(2048 | 11, 0);
|
|
611
|
+
offsets.writeUInt32BE(32 | 5, 4);
|
|
612
|
+
offsets.writeUInt32BE(4096 | 12, 8);
|
|
613
|
+
const free = Array.from({ length: 32 }, (_, power) => power >= 6 && power <= 10 || power >= 13 && power <= 30 ? Buffer.concat([number(1), number(2 ** power)]) : number(0));
|
|
614
|
+
const root = Buffer.concat([number(3), number(0), offsets, number(1), Buffer.from([4]), Buffer.from("DSDB"), number(1), ...free]);
|
|
615
|
+
const out = Buffer.alloc(8196);
|
|
616
|
+
Buffer.concat([number(1), Buffer.from("Bud1"), number(2048), number(root.length), number(2048), Buffer.alloc(16)]).copy(out);
|
|
617
|
+
Buffer.concat([number(2), number(0), number(records.length), number(1), number(4096)]).copy(out, 36);
|
|
618
|
+
root.copy(out, 2052);
|
|
619
|
+
leaf.copy(out, 4100);
|
|
620
|
+
import_node_fs3.writeFileSync(import_node_path2.join(mount, ".DS_Store"), out);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// src/installer-background.ts
|
|
624
|
+
var installerBackground = Buffer.from("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vpDh4twyyyyT7S6//PKDdsOXbt/xkT2miF0Kvq200kqZDVsFuI4P6667buZw9913p5deeilnMWGz3nrr5euIqtEURBYCiPFjn20ASyyxRO4TW1wPYQkXGLz44ovZD67hB8v0d955Z3rllVeyYAs/iEnZD2wg5LDx+OOPp9dffz33AcsNN9wwLb744pnpaHwn0/3GG29k34kpMV5yySXTWmutlV+won/en3zyyfTCCy/ksWIbP5577rnclnHgcxT8wxbbF2DL+JZaaqlsk72v2IQZBdvcp9ShEKsVV1xx8F58880309JLL53jsvLKK4/5/ZI79R8JSGDMCSgoxxypBiUwPgT+4z/+I++vZLI+7LDD8uT9v//7v1l4cA6BxaR/zDHH5Ad5YkJHXCFK/u///i/NmjUrixrEAAVxggA44ogj0he+8IUsAv7xH/8x70ukTgjRc889N51//vlp2sADNFynHYIDMYHda6+9dj677INEeH7xi19MhxxyyKAA7ZYUfSJQ/vu//zuPhTEeeOCB6fd///fT7Nmz01/+5V/m6wjaP/7jP07w4fx7772XRSSiZ9ddd00nnHBCFjVwG64gnB544IFBO4gzxCNMEUGbb755OvbYY9P06dOzEKL+jTfemLcLYBcRiG//8z//k+65557sB+IMUfe5z30u/eqv/moW9REreLN/8Qc/+EG68MILs4B9//33Mz9ELAL2q1/9am6L77AYqmALGz/60Y/ylwj2qVLof4UVVsgcyPQi8Fjiht2jjz6a+6ct5aSTTsovxsfyN+Om/R133JHjzpgQ0PiCeMUu2xF+5Vd+JY8L/+j3r//6r7Mwhd3v/u7v5rrf/e53s4BlfGRF+YL05S9/Od8v9D3c2LhukYAEektAQdlb/vYugY4JkBlj4mdSv+KKK7JIJLvDZ15MwGSCeEocIcPeQiZwMkN/9Vd/la666qo8kSNeED7UZzJHRCAWOEaoIprIpCF6EHAURAHXEWq0Q3CQJeQp7VtvvTXbw274gRglE8o+TAQHomssCwIx9vlF5os+OUfhOEQMPuEv74zjvPPOy6LpL/7iL/L4hhIuCKRbbrkl/emf/mkW7Qip4hgZF0L63nvvzXUQqvBCEOIHx/CHPSzCD3zBjx//+MeZ5R/90R9ln6P+3//932chSH36o198ZMxkW//sz/4sx+jQQw/NfeXG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6gzXR1zrxA7jHS7u2B5NnfCh3XsnfrWz4zkJSKA3BOZf/+mND/YqAQlIQAINIsCXCwQqr5HEdoOwOFQJ1JqAGcpah0/nJSABCdSHAFlM9nEeddRR+WeMEJM8BER20iIBCdSbgHso6x0/vZeABCRQOwI8xBN7QclWKihrF0IdlsCnCJih/BQST0hAAhKQQJUE4in4KvvQtgQkML4E3EM5vrztTQISkIAEJCABCUw4AgrKCRdSByQBCUhAAhKQgATGl4CCcnx525sEJCABCUhAAhKYcAQUlBMupA5IAhKQgAQkIAEJjC8BBeX48rY3CUhAAhKQgAQkMOEIKCgnXEgdkAQkIAEJSEACEhhfAgrK8eVtbxKQgAQkIAEJSGDCEVBQTriQOiAJSEACEpCABCQwvgQUlOPL294kIAEJSEACEpDAhCOgoJxwIXVAEpCABCQgAQlIYHwJKCjHl7e9SUACEpCABCQggQlHQEE54ULqgCTQGwKTJk1KkydPTrxbekOgyH+hhRbK8ajSk/Hoo0r/tS0BCYwdAQXl2LHUkgQqIYBAY+IuvhAOU6ZM6al4w58Qj7zPmTMnPfvss+mDDz6ohMN4Gy2Obyz6jviNha12Nj788MPM/7333stxeemll/LndnU7ORf3YbTl84svvjimfYRt3yUggfoRmFI/l/VYAs0hgHB86KGH0u23355Fwrx583LWaamllkprr712Wn/99bOw/Pjjj8cVCv29/vrrabHFFkuLLrpo9umJJ55IF1xwQTriiCOybx999NG4+jSWneE741t88cXTIosskuDeTYHXFVdckebOnZv22muvHLNu7JXbIlZfffXV9MMf/jDtu+++afPNN0/nnXdeeuONN9Lxxx+fx9HNGBCPCNX3338/ce9xXzKWc889N73zzjvpG9/4Rr4XuumjPCY/S0AC9SJghrJe8dLbhhFAKLz88svprrvuSm+99Vae0N9888105513ptNPPz395Cc/Se++++58mUImf0o5w8Z5hADn25XydT6HrWJ9bCBeTjnllHTvvfemqVOn5suIJrKTvIetdu2pHNeH8qXY33D1sRM2hrI5mjrF/hjfK6+8kk4++eT0wAMPDI4v6hT74Xikgr3nn38+3XzzzemWW25JzzzzzKcEJXbCFuPhFZ/D/kjjRMzBHzFMn5tttlmaMWNGWnjhhQcFMTaH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SEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJSEACEpCABCRQHQEFZXVstSwBCUhAAhKQgAQaQUBB2YgwO0gJ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", "base64");
|
|
625
|
+
|
|
497
626
|
// src/package.ts
|
|
498
627
|
var import_child_process = require("child_process");
|
|
499
628
|
var import_crypto = require("crypto");
|
|
@@ -722,7 +851,7 @@ async function packageMacOS(config, outDir) {
|
|
|
722
851
|
results.push({ success: true, platform: "macos", format: "app", outputPath: appBundlePath });
|
|
723
852
|
if (opts.dmg !== false) {
|
|
724
853
|
const outputPath = import_path.join(outDir, `${name}-${version}.dmg`);
|
|
725
|
-
let dmgResult = await
|
|
854
|
+
let dmgResult = await createDiskImage({ appBundlePath, outputPath, volumeName: name });
|
|
726
855
|
if (dmgResult.success && opts.signIdentity) {
|
|
727
856
|
const signed = await runTool("codesign", codesignArguments({
|
|
728
857
|
path: outputPath,
|
|
@@ -1209,6 +1338,8 @@ function dmgCreateArguments(opts, contentBytes) {
|
|
|
1209
1338
|
opts.volumeName,
|
|
1210
1339
|
"-srcfolder",
|
|
1211
1340
|
opts.appBundlePath,
|
|
1341
|
+
"-fs",
|
|
1342
|
+
"HFS+",
|
|
1212
1343
|
"-size",
|
|
1213
1344
|
`${dmgCapacityMegabytes(contentBytes)}m`,
|
|
1214
1345
|
"-ov",
|
|
@@ -1244,24 +1375,70 @@ function runTool(tool, args) {
|
|
|
1244
1375
|
});
|
|
1245
1376
|
}
|
|
1246
1377
|
var runHdiutil = (args) => runTool("hdiutil", args);
|
|
1247
|
-
async function
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
for (let attempt = 1
|
|
1253
|
-
const
|
|
1378
|
+
async function detachDiskImage(mount, options = {}) {
|
|
1379
|
+
const run = options.run ?? runHdiutil;
|
|
1380
|
+
const wait = options.wait ?? ((ms) => new Promise((resolve) => {
|
|
1381
|
+
setTimeout(resolve, ms);
|
|
1382
|
+
}));
|
|
1383
|
+
for (let attempt = 1;; attempt++) {
|
|
1384
|
+
const forced = attempt >= HDIUTIL_MAX_ATTEMPTS;
|
|
1385
|
+
const result = await run(forced ? ["detach", mount, "-force"] : ["detach", mount]);
|
|
1254
1386
|
if (result.success)
|
|
1255
|
-
return { success: true
|
|
1256
|
-
failures.push(`attempt ${attempt}: ${result.error}`);
|
|
1387
|
+
return { success: true };
|
|
1257
1388
|
if (!shouldRetryHdiutil(result.error, attempt))
|
|
1258
|
-
return { success: false, error:
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1389
|
+
return { success: false, error: result.error };
|
|
1390
|
+
await wait(attempt * 2000);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
async function createDiskImage(opts) {
|
|
1394
|
+
if (!/^[^/:\n]{1,27}$/.test(opts.volumeName))
|
|
1395
|
+
return { success: false, error: `Invalid DMG volume name "${opts.volumeName}"; must be 1..27 chars without /, :, or newline` };
|
|
1396
|
+
const scratch = createTempDir("craft-installer-");
|
|
1397
|
+
const payload = import_path.join(scratch, "payload");
|
|
1398
|
+
const mount = import_path.join(scratch, "mount");
|
|
1399
|
+
const writable = import_path.join(scratch, "installer.dmg");
|
|
1400
|
+
let mounted = false;
|
|
1401
|
+
const run = async (tool, args) => {
|
|
1402
|
+
const result = await runTool(tool, args);
|
|
1403
|
+
if (!result.success)
|
|
1404
|
+
throw new Error(result.error);
|
|
1405
|
+
return result;
|
|
1406
|
+
};
|
|
1407
|
+
try {
|
|
1408
|
+
import_fs.mkdirSync(payload);
|
|
1409
|
+
import_fs.mkdirSync(mount);
|
|
1410
|
+
const bundleName = import_path.basename(opts.appBundlePath);
|
|
1411
|
+
await run("ditto", [opts.appBundlePath, import_path.join(payload, bundleName)]);
|
|
1412
|
+
import_fs.symlinkSync("/Applications", import_path.join(payload, "Applications"));
|
|
1413
|
+
import_fs.mkdirSync(import_path.join(payload, ".background"));
|
|
1414
|
+
import_fs.writeFileSync(import_path.join(payload, ".background", "installer.png"), installerBackground);
|
|
1415
|
+
const args = dmgCreateArguments({ ...opts, appBundlePath: payload, outputPath: writable }, pathContentBytes(payload));
|
|
1416
|
+
args[args.indexOf("ULMO")] = "UDRW";
|
|
1417
|
+
for (let attempt = 1;; attempt++) {
|
|
1418
|
+
const result = await runHdiutil(args);
|
|
1419
|
+
if (result.success)
|
|
1420
|
+
break;
|
|
1421
|
+
if (!shouldRetryHdiutil(result.error, attempt))
|
|
1422
|
+
throw new Error(result.error);
|
|
1423
|
+
import_fs.rmSync(writable, { force: true });
|
|
1424
|
+
await new Promise((resolve) => setTimeout(resolve, attempt * 2000));
|
|
1425
|
+
}
|
|
1426
|
+
await run("hdiutil", ["attach", writable, "-nobrowse", "-mountpoint", mount]);
|
|
1427
|
+
mounted = true;
|
|
1428
|
+
writeInstallerLayout(mount, opts.volumeName, bundleName);
|
|
1429
|
+
const detached = await detachDiskImage(mount);
|
|
1430
|
+
if (!detached.success)
|
|
1431
|
+
throw new Error(detached.error);
|
|
1432
|
+
mounted = false;
|
|
1433
|
+
await run("hdiutil", ["convert", writable, "-format", "ULMO", "-ov", "-o", opts.outputPath]);
|
|
1434
|
+
return { success: true, outputPath: opts.outputPath };
|
|
1435
|
+
} catch (error) {
|
|
1436
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1437
|
+
} finally {
|
|
1438
|
+
if (mounted)
|
|
1439
|
+
await runTool("hdiutil", ["detach", mount, "-force"]);
|
|
1440
|
+
removeTempDir(scratch);
|
|
1262
1441
|
}
|
|
1263
|
-
return { success: false, error: failures.join(`
|
|
1264
|
-
`) };
|
|
1265
1442
|
}
|
|
1266
1443
|
function pkgbuildComponentPlist(rootRelativeBundlePath) {
|
|
1267
1444
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -10889,9 +11066,12 @@ async function extractBundleFromZip(zipPath, stagingDir) {
|
|
|
10889
11066
|
try {
|
|
10890
11067
|
await execFileAsync("ditto", ["-x", "-k", zipPath, unpacked]);
|
|
10891
11068
|
const source = findTopLevelApp(unpacked);
|
|
10892
|
-
if (
|
|
10893
|
-
|
|
10894
|
-
|
|
11069
|
+
if (source)
|
|
11070
|
+
return { appPath: source, stagingDir: staging };
|
|
11071
|
+
const images = import_fs3.readdirSync(unpacked, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".dmg"));
|
|
11072
|
+
if (images.length !== 1)
|
|
11073
|
+
throw new Error(`Archive must contain one .app or one disk image: ${zipPath}`);
|
|
11074
|
+
return await extractBundleFromDmg(import_path2.join(unpacked, images[0].name), staging);
|
|
10895
11075
|
} catch (error) {
|
|
10896
11076
|
if (!stagingDir)
|
|
10897
11077
|
removeTempDir(staging);
|
|
@@ -11594,7 +11774,7 @@ Examples:
|
|
|
11594
11774
|
var updater_default = AutoUpdater;
|
|
11595
11775
|
|
|
11596
11776
|
// src/index.ts
|
|
11597
|
-
var execFileAsync2 = import_node_util.promisify(
|
|
11777
|
+
var execFileAsync2 = import_node_util.promisify(import_node_child_process2.execFile);
|
|
11598
11778
|
var versionMismatchWarned = false;
|
|
11599
11779
|
async function probeBinaryVersion(craftPath) {
|
|
11600
11780
|
if (versionMismatchWarned)
|
|
@@ -11704,7 +11884,7 @@ class CraftApp {
|
|
|
11704
11884
|
}
|
|
11705
11885
|
probeBinaryVersion(craftPath);
|
|
11706
11886
|
const quiet = this.config.quiet === true;
|
|
11707
|
-
this.process =
|
|
11887
|
+
this.process = import_node_child_process2.spawn(craftPath, args, {
|
|
11708
11888
|
stdio: quiet ? ["ignore", "ignore", "pipe"] : "inherit",
|
|
11709
11889
|
env: { ...process.env, [CRAFT_CLI_SPAWN_MARKER]: craftPath }
|
|
11710
11890
|
});
|
|
@@ -11856,8 +12036,8 @@ class CraftApp {
|
|
|
11856
12036
|
} else {
|
|
11857
12037
|
const dir = createTempDir("craft-sidebar-");
|
|
11858
12038
|
this.sidebarConfigDir = dir;
|
|
11859
|
-
const path =
|
|
11860
|
-
|
|
12039
|
+
const path = import_node_path3.join(dir, "sidebar-config.json");
|
|
12040
|
+
import_node_fs4.writeFileSync(path, json, "utf-8");
|
|
11861
12041
|
args.push("--sidebar-config-file", path);
|
|
11862
12042
|
}
|
|
11863
12043
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -24,7 +24,7 @@ export declare function parseCraftVersionOutput(output: string): string;
|
|
|
24
24
|
* (#236).
|
|
25
25
|
*/
|
|
26
26
|
export declare function craftProcessFailedMessage(code: number | null, stderr: string, quiet: boolean): string;
|
|
27
|
-
export { packageApp, pack, macOSRuntimeExecutablePath, type PackageConfig, type PackageResult } from './package.js';
|
|
27
|
+
export { createDiskImage, packageApp, pack, macOSRuntimeExecutablePath, type PackageConfig, type PackageResult } from './package.js';
|
|
28
28
|
export { craftBinaryNotFoundMessage, resolveCraftBinary } from './binary-resolver.js';
|
|
29
29
|
export * from './utils/index.js';
|
|
30
30
|
export * from './api/index.js';
|
|
@@ -85,4 +85,4 @@ export declare function show(html: string, options?: WindowOptions): Promise<voi
|
|
|
85
85
|
* Quick helper to load a URL
|
|
86
86
|
*/
|
|
87
87
|
export declare function loadURL(url: string, options?: WindowOptions): Promise<void>;
|
|
88
|
-
export type { WindowOptions, CraftSidebarAPI, CraftNativeUIAPI, CraftContextMenuItem, CraftContextMenuResult, AppConfig, CraftTrayAPI, CraftWindowAPI, CraftAppAPI, CraftBridgeAPI, MenubarState, MenubarInitOptions, CraftTimersAPI, Permission, HapticType, CraftHapticsAPI, CameraOptions, PhotoPickerOptions, CraftMobileAPI, CraftFileSystemAPI, CraftFsWatchEvent, CraftFsWatchHandle, CraftDatabaseAPI, CraftHttpAPI, CraftCryptoAPI, CraftCapabilities, CapabilityNamespace, CapabilityNamespaceStatus, CapabilityAction, CraftPreferencesAPI, CraftPreferencesInfo, CraftSettingsAPI, PreferenceValue, CraftEventType, CraftEventMap, CraftEventHandler, CraftEventEmitter, IOSConfig, AndroidConfig, MacOSConfig, WindowsConfig, LinuxConfig, CraftAppConfig, } from './types.js';
|
|
88
|
+
export type { WindowOptions, CraftSidebarAPI, CraftNativeUIAPI, CraftContextMenuItem, CraftContextMenuResult, AppConfig, CraftTrayAPI, CraftWindowAPI, CraftAppAPI, CraftBridgeAPI, CraftBindingsAPI, MenubarState, MenubarInitOptions, CraftTimersAPI, Permission, HapticType, CraftHapticsAPI, CameraOptions, PhotoPickerOptions, CraftMobileAPI, CraftFileSystemAPI, CraftFsWatchEvent, CraftFsWatchHandle, CraftDatabaseAPI, CraftHttpAPI, CraftCryptoAPI, CraftCapabilities, CapabilityNamespace, CapabilityNamespaceStatus, CapabilityAction, CraftPreferencesAPI, CraftPreferencesInfo, CraftSettingsAPI, PreferenceValue, CraftEventType, CraftEventMap, CraftEventHandler, CraftEventEmitter, IOSConfig, AndroidConfig, MacOSConfig, WindowsConfig, LinuxConfig, CraftAppConfig, } from './types.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare function parseCraftVersionOutput(output: string): string;
|
|
|
24
24
|
* (#236).
|
|
25
25
|
*/
|
|
26
26
|
export declare function craftProcessFailedMessage(code: number | null, stderr: string, quiet: boolean): string;
|
|
27
|
-
export { packageApp, pack, macOSRuntimeExecutablePath, type PackageConfig, type PackageResult } from './package.js';
|
|
27
|
+
export { createDiskImage, packageApp, pack, macOSRuntimeExecutablePath, type PackageConfig, type PackageResult } from './package.js';
|
|
28
28
|
export { craftBinaryNotFoundMessage, resolveCraftBinary } from './binary-resolver.js';
|
|
29
29
|
export * from './utils/index.js';
|
|
30
30
|
export * from './api/index.js';
|
|
@@ -85,4 +85,4 @@ export declare function show(html: string, options?: WindowOptions): Promise<voi
|
|
|
85
85
|
* Quick helper to load a URL
|
|
86
86
|
*/
|
|
87
87
|
export declare function loadURL(url: string, options?: WindowOptions): Promise<void>;
|
|
88
|
-
export type { WindowOptions, CraftSidebarAPI, CraftNativeUIAPI, CraftContextMenuItem, CraftContextMenuResult, AppConfig, CraftTrayAPI, CraftWindowAPI, CraftAppAPI, CraftBridgeAPI, MenubarState, MenubarInitOptions, CraftTimersAPI, Permission, HapticType, CraftHapticsAPI, CameraOptions, PhotoPickerOptions, CraftMobileAPI, CraftFileSystemAPI, CraftFsWatchEvent, CraftFsWatchHandle, CraftDatabaseAPI, CraftHttpAPI, CraftCryptoAPI, CraftCapabilities, CapabilityNamespace, CapabilityNamespaceStatus, CapabilityAction, CraftPreferencesAPI, CraftPreferencesInfo, CraftSettingsAPI, PreferenceValue, CraftEventType, CraftEventMap, CraftEventHandler, CraftEventEmitter, IOSConfig, AndroidConfig, MacOSConfig, WindowsConfig, LinuxConfig, CraftAppConfig, } from './types.js';
|
|
88
|
+
export type { WindowOptions, CraftSidebarAPI, CraftNativeUIAPI, CraftContextMenuItem, CraftContextMenuResult, AppConfig, CraftTrayAPI, CraftWindowAPI, CraftAppAPI, CraftBridgeAPI, CraftBindingsAPI, MenubarState, MenubarInitOptions, CraftTimersAPI, Permission, HapticType, CraftHapticsAPI, CameraOptions, PhotoPickerOptions, CraftMobileAPI, CraftFileSystemAPI, CraftFsWatchEvent, CraftFsWatchHandle, CraftDatabaseAPI, CraftHttpAPI, CraftCryptoAPI, CraftCapabilities, CapabilityNamespace, CapabilityNamespaceStatus, CapabilityAction, CraftPreferencesAPI, CraftPreferencesInfo, CraftSettingsAPI, PreferenceValue, CraftEventType, CraftEventMap, CraftEventHandler, CraftEventEmitter, IOSConfig, AndroidConfig, MacOSConfig, WindowsConfig, LinuxConfig, CraftAppConfig, } from './types.js';
|