@stacksjs/desktop-build 0.75.408 → 0.75.409
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 +16 -0
- package/dist/index.js +2 -1
- package/package.json +9 -9
package/dist/index.d.ts
CHANGED
|
@@ -132,6 +132,8 @@ export declare function desktopAppVersion(options?: DesktopAppVersionOptions): s
|
|
|
132
132
|
* somebody typed is how a build becomes unpredictable.
|
|
133
133
|
*/
|
|
134
134
|
export declare function dmgVolumeName(options: DmgVolumeOptions): string;
|
|
135
|
+
/** The arguments that sign `notarytool` in. A key held as PEM text has to be written to `keyPath` first. */
|
|
136
|
+
export declare function notarytoolAuthArgs(credentials: { profile: string } | { keyId: string, issuerId: string, keyPath: string }): string[];
|
|
135
137
|
/**
|
|
136
138
|
* Everything `build:dmg` needs to name and sign a bundle, from flags first and
|
|
137
139
|
* the environment second.
|
|
@@ -301,6 +303,10 @@ export declare interface DmgPackagingFlags {
|
|
|
301
303
|
bundleId?: unknown
|
|
302
304
|
signingIdentity?: unknown
|
|
303
305
|
notaryProfile?: unknown
|
|
306
|
+
notarize?: unknown
|
|
307
|
+
apiKeyId?: unknown
|
|
308
|
+
apiIssuerId?: unknown
|
|
309
|
+
apiKeyPath?: unknown
|
|
304
310
|
volumeName?: unknown
|
|
305
311
|
[flag: string]: unknown
|
|
306
312
|
}
|
|
@@ -317,6 +323,7 @@ export declare interface DmgPackaging {
|
|
|
317
323
|
volumeName: string
|
|
318
324
|
signingIdentity?: string
|
|
319
325
|
notaryProfile?: string
|
|
326
|
+
notary?: NotaryCredentials
|
|
320
327
|
}
|
|
321
328
|
export declare interface CodesignOptions {
|
|
322
329
|
identity: string
|
|
@@ -325,6 +332,15 @@ export declare interface CodesignOptions {
|
|
|
325
332
|
}
|
|
326
333
|
export type CraftLauncher = (command: string[]) => void | Promise<void>;
|
|
327
334
|
export type CraftBinaryLocator = (binary: string) => string | null;
|
|
335
|
+
/**
|
|
336
|
+
* How `notarytool` signs in: a keychain profile saved by `xcrun notarytool
|
|
337
|
+
* store-credentials`, or an App Store Connect API key, which needs no keychain
|
|
338
|
+
* and is what CI and the Mac App Store path (`desktop:apple`) already hold.
|
|
339
|
+
* The key is a `.p8` file or, from an encrypted `.env.production`, its PEM text.
|
|
340
|
+
*/
|
|
341
|
+
export type NotaryCredentials = | { profile: string }
|
|
342
|
+
| { keyId: string, issuerId: string, keyPath: string }
|
|
343
|
+
| { keyId: string, issuerId: string, keyPem: string }
|
|
328
344
|
export * from './agent';
|
|
329
345
|
export * from './agent-launcher';
|
|
330
346
|
export * from './invites';
|
package/dist/index.js
CHANGED
|
@@ -36,4 +36,5 @@ ${kept.map(([key,value])=>` <key>${xmlEscape(key)}</key>${plistValue(value," "
|
|
|
36
36
|
${minimumSystem}${highResolution}${transportSecurity}${icon}${extra}
|
|
37
37
|
</dict>
|
|
38
38
|
</plist>
|
|
39
|
-
`,ignored}}export function resolveDevWindowUrl(port,options={}){if(!Number.isInteger(port)||port<1||port>65535)throw RangeError(`Invalid desktop development port: ${port}`);const configured=options.url||process.env.APP_URL;if(!configured)return"https://stacks.test";const withProtocol=/^https?:\/\//.test(configured)?configured:`https://${configured}`;return new URL(withProtocol).toString().replace(/\/$/,"")}export function craftDevCommand(port,options={}){const command=[resolveCraftBinary(options.craftBin),resolveDevWindowUrl(port,options),"--title",options.title||"Stacks","--width",String(options.width||1400),"--height",String(options.height||900)];if(options.hotReload!==!1)command.push("--hot-reload");if(options.devTools===!1)command.push("--no-devtools");if(options.darkMode)command.push("--dark");if(options.systemTray)command.push("--system-tray");if(options.hideDockIcon)command.push("--hide-dock-icon");if(options.menubarOnly)command.push("--menubar-only");return command}export function createUpdateManifestUrl(baseUrl,channel="stable"){if(!/^[a-z0-9-]+$/i.test(channel))throw Error("Update channel may only contain letters, numbers, and hyphens");return new URL(`/desktop/updates/${channel}.json`,/^https?:\/\//.test(baseUrl)?baseUrl:`https://${baseUrl}`).toString()}async function launchCraft(command){Bun.spawn(command,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).unref()}export async function openDevWindow(port,options={},launcher=launchCraft){await launcher(craftDevCommand(port,options));return!0}export const BUN_EXECUTABLE_MARKER="---- Bun!";const MARKER_SEARCH_BYTES=8388608,RUNTIME_SIZE_FLOOR=41943040,MACH_O_MAGIC=new Set([4277009102,3472551422,4277009103,3489328638,3405691582,3199925962]);export function isMachO(path){try{const fd=openSync(path,"r");try{const head=Buffer.alloc(4);if(readSync(fd,head,0,4,0)<4)return!1;return MACH_O_MAGIC.has(head.readUInt32BE(0))}finally{closeSync(fd)}}catch{return!1}}export function bundleDirectoryFor(path){return isMachO(path)?"MacOS":"Resources"}export function desktopAppVersion(options={}){const override=options.override?.trim();if(override)return override;return(typeof options.declared==="string"?options.declared.trim():"")||"0.0.0"}export function dmgVolumeName(options){const override=options.override?.trim();if(override)return override;const appName=options.appName.trim(),version=options.version?.trim();return version?`${appName} ${version}`:`${appName} Installer`}
|
|
39
|
+
`,ignored}}export function resolveDevWindowUrl(port,options={}){if(!Number.isInteger(port)||port<1||port>65535)throw RangeError(`Invalid desktop development port: ${port}`);const configured=options.url||process.env.APP_URL;if(!configured)return"https://stacks.test";const withProtocol=/^https?:\/\//.test(configured)?configured:`https://${configured}`;return new URL(withProtocol).toString().replace(/\/$/,"")}export function craftDevCommand(port,options={}){const command=[resolveCraftBinary(options.craftBin),resolveDevWindowUrl(port,options),"--title",options.title||"Stacks","--width",String(options.width||1400),"--height",String(options.height||900)];if(options.hotReload!==!1)command.push("--hot-reload");if(options.devTools===!1)command.push("--no-devtools");if(options.darkMode)command.push("--dark");if(options.systemTray)command.push("--system-tray");if(options.hideDockIcon)command.push("--hide-dock-icon");if(options.menubarOnly)command.push("--menubar-only");return command}export function createUpdateManifestUrl(baseUrl,channel="stable"){if(!/^[a-z0-9-]+$/i.test(channel))throw Error("Update channel may only contain letters, numbers, and hyphens");return new URL(`/desktop/updates/${channel}.json`,/^https?:\/\//.test(baseUrl)?baseUrl:`https://${baseUrl}`).toString()}async function launchCraft(command){Bun.spawn(command,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).unref()}export async function openDevWindow(port,options={},launcher=launchCraft){await launcher(craftDevCommand(port,options));return!0}export const BUN_EXECUTABLE_MARKER="---- Bun!";const MARKER_SEARCH_BYTES=8388608,RUNTIME_SIZE_FLOOR=41943040,MACH_O_MAGIC=new Set([4277009102,3472551422,4277009103,3489328638,3405691582,3199925962]);export function isMachO(path){try{const fd=openSync(path,"r");try{const head=Buffer.alloc(4);if(readSync(fd,head,0,4,0)<4)return!1;return MACH_O_MAGIC.has(head.readUInt32BE(0))}finally{closeSync(fd)}}catch{return!1}}export function bundleDirectoryFor(path){return isMachO(path)?"MacOS":"Resources"}export function desktopAppVersion(options={}){const override=options.override?.trim();if(override)return override;return(typeof options.declared==="string"?options.declared.trim():"")||"0.0.0"}export function dmgVolumeName(options){const override=options.override?.trim();if(override)return override;const appName=options.appName.trim(),version=options.version?.trim();return version?`${appName} ${version}`:`${appName} Installer`}export function notarytoolAuthArgs(credentials){return"profile"in credentials?["--keychain-profile",credentials.profile]:["--key",credentials.keyPath,"--key-id",credentials.keyId,"--issuer",credentials.issuerId]}function resolveNotary(flags,env){const profile=supplied(flags.notaryProfile)??supplied(env.DESKTOP_NOTARY_PROFILE);if(profile)return{profile};if(!(flags.notarize===!0||["1","true","yes"].includes(supplied(env.DESKTOP_NOTARIZE)?.toLowerCase()??"")))return;const keyId=supplied(flags.apiKeyId)??supplied(env.APP_STORE_CONNECT_API_KEY_ID),issuerId=supplied(flags.apiIssuerId)??supplied(env.APP_STORE_CONNECT_API_ISSUER_ID),keyPath=supplied(flags.apiKeyPath)??supplied(env.APP_STORE_CONNECT_API_KEY_PATH),keyPem=supplied(env.APP_STORE_CONNECT_API_KEY)?.replaceAll("\\n",`
|
|
40
|
+
`),missing=[!keyId&&"APP_STORE_CONNECT_API_KEY_ID (--api-key-id)",!issuerId&&"APP_STORE_CONNECT_API_ISSUER_ID (--api-issuer-id)",!keyPath&&!keyPem&&"APP_STORE_CONNECT_API_KEY_PATH (--api-key-path) or APP_STORE_CONNECT_API_KEY"].filter(Boolean);if(missing.length||!keyId||!issuerId)throw Error(`Notarizing needs a keychain profile (--notary-profile or DESKTOP_NOTARY_PROFILE) or an App Store Connect API key. Missing: ${missing.join(", ")}.`);if(keyPath)return{keyId,issuerId,keyPath};if(!keyPem.includes("-----BEGIN PRIVATE KEY-----"))throw Error("APP_STORE_CONNECT_API_KEY must hold the PEM text of the .p8 key.");return{keyId,issuerId,keyPem}}function supplied(value){if(typeof value!=="string")return;return value.trim()||void 0}export function resolveDmgPackaging(inputs={}){const flags=inputs.flags??{},env=inputs.env??{},appName=supplied(flags.appName)??supplied(env.DESKTOP_APP_NAME)??supplied(inputs.manifestTitle)??supplied(env.APP_NAME)??"Stacks",version=desktopAppVersion({override:supplied(flags.appVersion)??supplied(env.DESKTOP_APP_VERSION),declared:inputs.declaredVersion}),bundleId=supplied(flags.bundleId)??supplied(env.DESKTOP_BUNDLE_ID)??`sh.stacks.${appName.toLowerCase().replace(/[^a-z0-9]+/g,"-")}`;return{appName,bundleId,version,volumeName:dmgVolumeName({appName,version,override:supplied(flags.volumeName)??supplied(env.DESKTOP_VOLUME_NAME)}),signingIdentity:supplied(flags.signingIdentity)??supplied(env.DESKTOP_SIGNING_IDENTITY),notaryProfile:supplied(flags.notaryProfile)??supplied(env.DESKTOP_NOTARY_PROFILE),notary:resolveNotary(flags,env)}}export function codesignArgs(options){return["codesign","--force",options.identity==="-"?"--timestamp=none":"--timestamp","--options","runtime",...options.entitlements?["--entitlements",options.entitlements]:[],"--sign",options.identity,options.target]}export function looksLikeBunExecutable(path,read=readTail){const file=read(path);if(!file||file.size<RUNTIME_SIZE_FLOOR)return!1;return file.tail.includes(BUN_EXECUTABLE_MARKER)}function readTail(path){try{const{size}=statSync(path);if(size<RUNTIME_SIZE_FLOOR)return{size,tail:""};const fd=openSync(path,"r");try{const length=Math.min(MARKER_SEARCH_BYTES,size),buffer=Buffer.alloc(length);readSync(fd,buffer,0,length,size-length);return{size,tail:buffer.toString("latin1")}}finally{closeSync(fd)}}catch{return null}}export function describeRuntimeDuplication(runtimes){if(runtimes.length<2)return null;const sorted=[...runtimes].sort((a,b)=>b.bytes-a.bytes),wasted=sorted.slice(1).length*RUNTIME_SIZE_FLOOR,names=sorted.map((r)=>`${r.name} (${(r.bytes/1024/1024).toFixed(1)} MB)`).join(", ");return`This bundle ships ${runtimes.length} Bun-compiled executables: ${names}. Each embeds a full copy of the Bun runtime, so at least ${(wasted/1024/1024).toFixed(0)} MB of the bundle is the same runtime repeated. `+"Compiling one binary that dispatches on a subcommand \u2014 `MyApp agent`, `MyApp worker` \u2014 keeps the helpers as separate processes and pays for the runtime once."}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/desktop-build",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.409",
|
|
6
6
|
"description": "Build and launch Craft desktop applications for Stacks",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -73,15 +73,15 @@
|
|
|
73
73
|
"prepublishOnly": "bun run build"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@stacksjs/config": "0.75.
|
|
77
|
-
"@stacksjs/router": "0.75.
|
|
78
|
-
"@stacksjs/server": "0.75.
|
|
79
|
-
"craft-native": ">=0.0.
|
|
76
|
+
"@stacksjs/config": "0.75.409",
|
|
77
|
+
"@stacksjs/router": "0.75.409",
|
|
78
|
+
"@stacksjs/server": "0.75.409",
|
|
79
|
+
"craft-native": ">=0.0.420"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
|
-
"@stacksjs/config": "0.75.
|
|
83
|
-
"@stacksjs/router": "0.75.
|
|
84
|
-
"@stacksjs/server": "0.75.
|
|
82
|
+
"@stacksjs/config": "0.75.409",
|
|
83
|
+
"@stacksjs/router": "0.75.409",
|
|
84
|
+
"@stacksjs/server": "0.75.409"
|
|
85
85
|
},
|
|
86
86
|
"peerDependenciesMeta": {
|
|
87
87
|
"@stacksjs/config": {
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
|
-
"@stacksjs/build": "0.75.
|
|
98
|
+
"@stacksjs/build": "0.75.409",
|
|
99
99
|
"better-dx": "^0.2.24"
|
|
100
100
|
}
|
|
101
101
|
}
|