@craft-native/ios 0.0.449 → 0.0.464

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
@@ -1,685 +1 @@
1
- /** Store large native source assets compressed; the host decodes each once on demand. */
2
- export declare function compressNativeSources(target: string): void;
3
- import { type CraftAppShortcut } from './app-shortcuts.js';
4
- /** Package custom fonts and their licenses; removed fonts cannot linger in the app. */
5
- export declare function syncNativeFonts(fonts: CraftConfig['nativeFonts'], output: string): string[];
6
- /** This package's version, which the app names in its user agent (`Craft/<version>`). */
7
- export declare function resolveCraftVersion(startDir?: string): string;
8
- export type CraftAppearance = 'light' | 'dark' | 'system';
9
- /** A declared command Craft runs after the native project has been generated. */
10
- export interface CraftPostGenerateHook {
11
- command: string;
12
- args?: string[];
13
- }
14
- export interface CraftTabBarConfig {
15
- selection?: {
16
- /** The selected tab indicator's corner radius in points; omitted keeps a capsule. */
17
- cornerRadius?: number;
18
- /** The selected tab indicator fill as #RRGGBB. */
19
- color?: string;
20
- };
21
- }
22
- export interface CraftConfig {
23
- appShortcuts?: CraftAppShortcut[];
24
- /** Bundled font files keyed by their PostScript font name, used as native fontFamily. */
25
- nativeFonts?: Record<string, {
26
- src: string;
27
- license?: string;
28
- }>;
29
- appName: string;
30
- bundleId: string;
31
- /** Opt in to UIKit + JavaScriptCore instead of the default WebView. */
32
- renderer?: 'web' | 'native';
33
- version?: string;
34
- buildNumber?: string;
35
- darkMode?: boolean;
36
- /**
37
- * Which interface style the app draws in. `system` follows the phone's
38
- * Light/Dark setting (and the page's `prefers-color-scheme` with it); `light`
39
- * and `dark` pin one. Unset keeps the older `darkMode` switch.
40
- */
41
- appearance?: CraftAppearance;
42
- /** Static native tab-bar styling applied before the page's own tabBar.set call. */
43
- tabBar?: CraftTabBarConfig;
44
- /** Runs from the generated project root after `craft ios build` writes it. */
45
- postGenerate?: CraftPostGenerateHook;
46
- backgroundColor?: string;
47
- /** Default tint for native controls and selected tabs, as #RRGGBB. */
48
- tintColor?: string;
49
- /**
50
- * CSS font stack for the native chrome's labels (tab bar, bar buttons); the
51
- * first family packaged in `nativeFonts` wins, a generic one keeps the system face.
52
- */
53
- fontFamily?: string;
54
- /** CSS font stack for navigation titles; `fontFamily` when unset. */
55
- headingFontFamily?: string;
56
- /** The launch and webview background while the phone is in Dark Mode. */
57
- backgroundColorDark?: string;
58
- /** Edge-swipe back and forward through the page's history, pushState entries included. */
59
- swipeNavigation?: boolean;
60
- enableSpeechRecognition?: boolean;
61
- enableHaptics?: boolean;
62
- enableShare?: boolean;
63
- enableCamera?: boolean;
64
- enableBiometric?: boolean;
65
- enablePushNotifications?: boolean;
66
- enableSecureStorage?: boolean;
67
- enableGeolocation?: boolean;
68
- enableClipboard?: boolean;
69
- enableContacts?: boolean;
70
- enableCalendar?: boolean;
71
- enableLocalNotifications?: boolean;
72
- enableInAppPurchase?: boolean;
73
- enableKeepAwake?: boolean;
74
- enableOrientationLock?: boolean;
75
- enableDeepLinks?: boolean;
76
- enableQRScanner?: boolean;
77
- /** Reach devices on the local network (a Mac on the same Wi-Fi); iOS asks first. */
78
- enableLocalNetwork?: boolean;
79
- enableFilePicker?: boolean;
80
- enableFileDownload?: boolean;
81
- enableSocialAuth?: boolean;
82
- /** Native passkeys; requires a matching `webcredentials:` associated domain. */
83
- enablePasskeys?: boolean;
84
- enableAudioRecording?: boolean;
85
- enableVideoRecording?: boolean;
86
- enableMotionSensors?: boolean;
87
- /** Core Motion relative altitude and pressure; includes the motion usage description. */
88
- enableBarometer?: boolean;
89
- /** Core Motion interval steps, cadence and seven-day device history. */
90
- enablePedometer?: boolean;
91
- /** Shaking the phone raises a `shake` event. Arms the accelerometer while the app is in front. */
92
- enableShakeGesture?: boolean;
93
- enableLocalDatabase?: boolean;
94
- enableBluetooth?: boolean;
95
- enableNFC?: boolean;
96
- enableHealthKit?: boolean;
97
- /** Observe declared HealthKit types on background wakes; requires enableHealthKit. */
98
- enableHealthKitBackground?: boolean;
99
- healthKitBackgroundTypes?: Array<'steps' | 'heartRate' | 'restingHeartRate' | 'heartRateVariability' | 'activeEnergy' | 'distance' | 'bodyMass' | 'sleep' | 'workouts'>;
100
- healthKitBackgroundFrequency?: 'immediate' | 'hourly' | 'daily' | 'weekly';
101
- /** Native Apple Wallet pass presentation and lookup for native screens. */
102
- enableWallet?: boolean;
103
- enableLiveActivities?: boolean;
104
- enableWatchApp?: boolean;
105
- enableBackgroundLocation?: boolean;
106
- enableBackgroundTasks?: boolean;
107
- enableScreenCapture?: boolean;
108
- enablePDFViewer?: boolean;
109
- enableAR?: boolean;
110
- enableMLKit?: boolean;
111
- /**
112
- * Show and control what the Music app is playing (`craft.music`, through
113
- * MPMusicPlayerController.systemMusicPlayer). Only Apple Music: iOS gives
114
- * no app the controls of another player such as Spotify. iOS asks the
115
- * person for media library access the first time the page calls
116
- * `craft.music.requestAuthorization()`, never at launch.
117
- */
118
- enableAppleMusic?: boolean;
119
- /**
120
- * Read a Bluetooth heart-rate strap, or a watch broadcasting its heart rate
121
- * (the standard Heart Rate Service), through `craft.heartRate`: scan,
122
- * connect, live readings with RR intervals, and a recording kept natively.
123
- * Adds the `bluetooth-central` background mode, so readings keep coming
124
- * during a workout with the screen locked. iOS asks for Bluetooth the first
125
- * time the page scans or connects.
126
- */
127
- enableHeartRate?: boolean;
128
- /**
129
- * Keep playing sound with the screen locked or the app in the background:
130
- * a sleep soundscape, a meditation timer's ambience. Adds the `audio`
131
- * background mode. iOS keeps the app running only while it plays, and App
132
- * Review expects audible content, so turn it on only for an app that plays
133
- * some (Web Audio on native screens and in the web view, which use the
134
- * playback session).
135
- */
136
- enableBackgroundAudio?: boolean;
137
- /**
138
- * Schedule structured workouts onto the paired Apple Watch through
139
- * `craft.scheduledWorkouts` (WorkoutKit's WorkoutScheduler, iOS 17+): each
140
- * appears in the watch's Workout app on its day, with its steps, goals and
141
- * alerts. Compiles CraftScheduledWorkouts.swift with the
142
- * `CRAFT_SCHEDULED_WORKOUTS` condition, so an app without it never links
143
- * WorkoutKit; below iOS 17 it is weak-linked and answers unsupported. iOS
144
- * asks the person the first time the page calls
145
- * `craft.scheduledWorkouts.requestAuthorization()`, never at launch.
146
- */
147
- enableScheduledWorkouts?: boolean;
148
- /**
149
- * Purpose strings in the app's own words, by Info.plist key
150
- * (`{ NSAppleMusicUsageDescription: 'Shows the song playing during a workout.' }`).
151
- * Each replaces the generic sentence Craft writes for that key.
152
- */
153
- usageDescriptions?: Record<string, string>;
154
- /**
155
- * The app's site. With `renderer: "web"` it is the page the web view loads.
156
- * With `renderer: "native"` and `nativeScreens` there is no web view: its
157
- * path is the path the app starts on (`/` when unset), and a path no native
158
- * screen draws (`craft.navigation.open('/terms')`, or a link to this host)
159
- * opens in the in-app browser against its origin. Native screens read it as
160
- * `__stxNativeBridge.appURL`.
161
- */
162
- devServerURL?: string;
163
- iosVersion?: string;
164
- watchosVersion?: string;
165
- teamId?: string;
166
- urlSchemes?: string[];
167
- trustedOrigins?: string[];
168
- /**
169
- * The domains the app's web view treats as its own (WKAppBoundDomains, at
170
- * most 10). Service workers only run in an iOS web view on these, so a site
171
- * that works offline in Safari works offline in the app. Unset, they are the
172
- * hosts of `trustedOrigins` and the dev server: the origins the bridge is
173
- * already injected into, and once any are declared iOS keeps script
174
- * injection to them. `[]` declares none.
175
- */
176
- appBoundDomains?: string[];
177
- /**
178
- * Also refuse to load anything but the app-bound domains in the web view
179
- * (WKWebViewConfiguration.limitsNavigationsToAppBoundDomains). Off by
180
- * default: links elsewhere already open in Safari. WebKit applies the limit
181
- * to the main frame only, so embedded players and maps in cross-origin
182
- * iframes (YouTube, Vimeo) keep loading with it on (checked in the iOS 26
183
- * simulator); WebKit only declines to inject user scripts into them, which
184
- * the bridge never does.
185
- */
186
- limitNavigationsToAppBoundDomains?: boolean;
187
- /**
188
- * Universal links and shared web credentials
189
- * (`com.apple.developer.associated-domains`). A bare host such as
190
- * `hq.training` is written as `applinks:hq.training`; an entry with its own
191
- * service (`webcredentials:`, `applinks:…?mode=developer`) is kept as given.
192
- * A universal link reaches the page the way a custom-scheme link does, as
193
- * `craftDeepLink`.
194
- */
195
- associatedDomains?: string[];
196
- /**
197
- * iOS's scheduled background refresh (BGAppRefreshTask). When enabled the
198
- * page gets `craftBackgroundRefresh` and answers with
199
- * `craft.background.complete(ok)`. The identifier defaults to
200
- * `<bundleId>.refresh` and is declared in BGTaskSchedulerPermittedIdentifiers,
201
- * with the `fetch` background mode.
202
- */
203
- backgroundRefresh?: CraftBackgroundRefresh;
204
- appGroups?: string[];
205
- appIconPath?: string;
206
- /**
207
- * The logo the launch screen shows on `backgroundColor`, and that stays on
208
- * screen until the page says it is ready (`splash.hide()`), so the app goes
209
- * from launch to content without a blank web view in between. PNG, PDF or
210
- * SVG, drawn at its own size in points: give an SVG the width and height it
211
- * should have on screen. A PNG with `@2x` and `@3x` files beside it
212
- * (`LaunchLogo.png`, `LaunchLogo@2x.png`, `LaunchLogo@3x.png`, as ts-images'
213
- * `generateSplashScreens` writes them) is sharp on every screen.
214
- */
215
- splashImagePath?: string;
216
- /** The splash logo in Dark Mode, on `backgroundColorDark`. The light one if unset. */
217
- splashImagePathDark?: string;
218
- /**
219
- * Whether the app uses encryption beyond the exempt kinds (HTTPS, the
220
- * system's own). Written as `ITSAppUsesNonExemptEncryption`, so App Store
221
- * Connect does not ask the export-compliance question on every build.
222
- * Default false: a WebView app that talks HTTPS is exempt.
223
- */
224
- usesNonExemptEncryption?: boolean;
225
- privacy?: CraftPrivacyManifest;
226
- /** Press-and-hold link previews, as in Safari. Default false. */
227
- allowsLinkPreview?: boolean;
228
- /**
229
- * WebKit's bar above the keyboard for a form field (previous, next, Done),
230
- * which no native app's keyboard has. Default false: hidden. A page can
231
- * change it with `craft.chrome.setKeyboardAccessory()`.
232
- */
233
- keyboardAccessory?: boolean;
234
- /** Pinch and double-tap zoom off, and the page's viewport pinned at scale 1. Default true. */
235
- disableZoom?: boolean;
236
- /**
237
- * The longest the launch splash stays up, in seconds, when the page neither
238
- * hides it (`splash.hide()`) nor paints. Default 3.
239
- */
240
- splashMaxSeconds?: number;
241
- /**
242
- * How long the app's own page may take to answer, in seconds, before the
243
- * load counts as unreachable and the bundled page stands in. Default 10.
244
- */
245
- requestTimeoutSeconds?: number;
246
- orientations?: Array<'portrait' | 'landscape-left' | 'landscape-right' | 'portrait-upside-down'>;
247
- deviceFamilies?: Array<'iphone' | 'ipad'>;
248
- /**
249
- * App paths drawn as native stx screens, each to the screen in the native
250
- * bundle that draws it, e.g. `{ "/m": "Today", "/m/calendar": "Calendar" }`.
251
- * A segment may be a parameter (`/m/workout/:id`) and the last one `*`.
252
- * Needs `nativeBundle`.
253
- *
254
- * With `renderer: "web"` (hybrid) every other path stays in the web view,
255
- * and a path whose screen is missing or throws falls back to it.
256
- *
257
- * With `renderer: "native"` the app is all native, with the same tabs and
258
- * path routing and no web view at all: every tab id and the start path (the
259
- * path of `devServerURL`) must be a native screen's, and any other path
260
- * opens in the in-app browser on the app's site.
261
- */
262
- nativeScreens?: Record<string, string>;
263
- /**
264
- * The bundle `stx native compile --format bundle` wrote, copied to
265
- * `dist/native-screen.js`; or a directory of route bundles (stx's
266
- * `routesDir`: `<Screen>.js` and `__app.js`), copied to
267
- * `dist/native-screens/`, so each screen evaluates only its own file.
268
- */
269
- nativeBundle?: string;
270
- /**
271
- * The bundle route of a screen-less script that runs once for the app's
272
- * whole life, beside the screens (Stacks names it `__app`). It hears the
273
- * app's events (`craftNotificationResponse`, `craftNotificationReceived`,
274
- * `craftSilentPush`, `craftBackgroundRefresh`, `craftShortcut`,
275
- * `craftSiriShortcut`) as `CRAFT_EVENT` messages instead of the page, every
276
- * `APP_STATE`, and can open paths with `craft.navigation.open`. Needs
277
- * `nativeScreens` or `renderer: "native"`, and the native bundle.
278
- */
279
- nativeApp?: string;
280
- /**
281
- * Where native screens run their JavaScript. `"main"` (the default) runs it
282
- * on the main thread; `"background"` gives screens a serial thread of their
283
- * own, so a screen's script, its timers and its renders never hold the
284
- * main thread while it scrolls or animates. UIKit still runs on main: the
285
- * shell hands each render to it, and a pushed screen waits for its first
286
- * render (at most 0.3 s) so it never slides in empty.
287
- */
288
- nativeScriptThread?: 'main' | 'background';
289
- /**
290
- * The native tab bar, shown from the first frame, before the page loads.
291
- * The page's own `tabBar.set` replaces it later. Each `id` is the tab's
292
- * root path, as the page's tab links name it.
293
- */
294
- tabs?: CraftTab[];
295
- /**
296
- * Hybrid: web-storage keys the page writes (localStorage or
297
- * sessionStorage) that native screens need, mirrored into the Keychain
298
- * under the name given, e.g. `{ "auth_token": "auth.token" }` for
299
- * `craft.secureStorage.getSync('auth.token')`. Turns on secure storage.
300
- */
301
- shareStorage?: Record<string, string>;
302
- /**
303
- * The secure-storage key the signed-in account's token lives under
304
- * (default `auth.token`). `craft.session` follows it: a change of it, made
305
- * by any native screen or by the page through a `shareStorage` key, is
306
- * `SESSION_CHANGED { key, token, previous }` on every native screen and a
307
- * `craftsession` event on the page.
308
- */
309
- sessionTokenKey?: string;
310
- /**
311
- * Crash and error reporting to bughq (CraftCrashReporter.swift): crashes
312
- * and hangs (signal handlers, NSException, MetricKit), uncaught JavaScript
313
- * errors in native screens and the app script, and what the page sends
314
- * through `craft.crashReporter`. Queued on disk and sent when online.
315
- */
316
- crashReporting?: CraftCrashReporting;
317
- }
318
- export interface CraftCrashReporting {
319
- /** The bughq project's public ingest key. Ships in the app; it is not a secret. */
320
- key: string;
321
- /** The bughq host. Default https://bughq.org. */
322
- host?: string;
323
- /** Default `production`. */
324
- environment?: string;
325
- /** The release every event names. Default `<version>+<build>`, e.g. `1.0.0+41`. */
326
- release?: string;
327
- /** One session per launch, for crash-free sessions per release. Default on. */
328
- sessions?: boolean;
329
- }
330
- export interface CraftTab {
331
- /** The tab's root path; comes back to the page in `craftTabSelect`. */
332
- id: string;
333
- title: string;
334
- /** An SF Symbol name. */
335
- symbol?: string;
336
- /** Native selected-tab icon overrides; retained pushed screens keep their owning tab's policy. */
337
- selectedSymbol?: string;
338
- selectedIconTint?: string;
339
- /** False suppresses the legacy pulse while selected; omission uses the legacy policy. */
340
- selectedIconPulse?: boolean;
341
- }
342
- /** `/a//b/?q#h` → `/a/b`, the way the shell and the page compare paths. Null for a relative path. */
343
- export declare function normalizeNativePath(raw: string): string | null;
344
- export interface NativePathMatch {
345
- path: string;
346
- screen: string;
347
- params: Record<string, string>;
348
- }
349
- /**
350
- * The native screen for a path, by the rules the shell (`CraftHybridRoutes`)
351
- * and the page script apply: static segments win over `:params`, which win
352
- * over a trailing `*`; query items become params under the path's own.
353
- */
354
- export declare function matchNativePath(nativeScreens: Record<string, string> | undefined, raw: string): NativePathMatch | null;
355
- /** Whether a config mixes native screens into its web page. */
356
- export declare function isHybrid(config: Pick<CraftConfig, 'renderer' | 'nativeScreens'>): boolean;
357
- /** Whether a config is an all-native app with routes: `renderer: "native"` and `nativeScreens`, tabs and paths with no web view. */
358
- export declare function hasNativeRoutes(config: Pick<CraftConfig, 'renderer' | 'nativeScreens'>): boolean;
359
- /** Whether a config draws any native screen, and so needs `dist/native-screen.js`. */
360
- export declare function usesNativeBundle(config: Pick<CraftConfig, 'renderer' | 'nativeScreens'>): boolean;
361
- /**
362
- * The path the app starts on: the path of `devServerURL` (with its query),
363
- * `/` when there is none. The shell reads it the same way
364
- * (`CraftHybridRoutes.appPath`).
365
- */
366
- export declare function nativeStartPath(config: Pick<CraftConfig, 'devServerURL'>): string;
367
- /** What is wrong with a config's hybrid and tab settings, one sentence each. */
368
- export declare function hybridConfigProblems(config: Pick<CraftConfig, 'renderer' | 'nativeScreens' | 'tabs' | 'shareStorage' | 'devServerURL' | 'nativeApp' | 'nativeScriptThread'>): string[];
369
- /**
370
- * The builder installs a directory of route bundles (stx's `routesDir`) as
371
- * well as the one-file bundle, and the app runs each screen from its own
372
- * route's file. Stacks asks for route bundles only when this is true.
373
- */
374
- /** Build-time proof for Stacks capability mappings, including unreleased source builds. */
375
- export declare const nativeSensorCapabilities: readonly ['barometer', 'pedometer', 'healthKitBackground'];
376
- export declare const nativeRouteBundles = true;
377
- /**
378
- * The app evaluates stx's shared runtime (`__runtime.js`, stx's
379
- * `sharedRuntime`) in each screen's context before the route's own file.
380
- * Stacks asks stx for it only when this is true: a route file built so
381
- * refuses to run without it.
382
- */
383
- export declare const nativeRouteRuntime = true;
384
- /**
385
- * The app gives a screen its messages a language at a time (stx's
386
- * `messages`, `native-screens/__messages/`): read when the screen first
387
- * looks inside them (`__stxNativeReadMessages`). Stacks leaves the languages
388
- * out of the screens' code only when this is true.
389
- */
390
- export declare const nativeMessages = true;
391
- export interface CraftBackgroundRefresh {
392
- enabled: boolean;
393
- /** The BGTaskScheduler identifier. Default `<bundleId>.refresh`. */
394
- identifier?: string;
395
- /** The soonest iOS may run it again, in minutes. Default 15. */
396
- minimumIntervalMinutes?: number;
397
- }
398
- export interface CraftPrivacyDataType {
399
- type: string;
400
- linked?: boolean;
401
- tracking?: boolean;
402
- purposes: string[];
403
- }
404
- export interface CraftPrivacyAccessedApiType {
405
- type: string;
406
- reasons: string[];
407
- }
408
- export interface CraftPrivacyManifest {
409
- tracking?: boolean;
410
- trackingDomains?: string[];
411
- collectedDataTypes?: CraftPrivacyDataType[];
412
- accessedApiTypes?: CraftPrivacyAccessedApiType[];
413
- }
414
- export interface InitOptions {
415
- name: string;
416
- bundleId?: string;
417
- teamId?: string;
418
- output: string;
419
- config?: Partial<CraftConfig>;
420
- /**
421
- * Where the Zig runtime archives live, overriding `CRAFT_IOS_RUNTIME`.
422
- *
423
- * `null` means "no runtime, whatever the environment says" — the shape
424
- * `AppConfig.craftPath` has for `CRAFT_BIN`, and the reason it exists here
425
- * is the same: a caller that does not opt in should not be steered by an
426
- * ambient variable. Without it this package's own tests inherited whatever
427
- * the developer's shell exported, and went from 12 passing to 8 passing and
428
- * 4 failing when `CRAFT_IOS_RUNTIME` happened to be set.
429
- *
430
- * Omitted (`undefined`) keeps the environment lookup, which is what the
431
- * monorepo dev loop uses.
432
- */
433
- runtimeDir?: string | null;
434
- /** Explicit Craft Zig source package for a per-app runtime build (or CRAFT_IOS_RUNTIME_SOURCE). */
435
- runtimeSource?: string | null;
436
- }
437
- export interface BuildOptions {
438
- htmlPath?: string;
439
- /** JavaScript bundle emitted by `stx native compile Screen.stx --format bundle`. */
440
- nativeBundlePath?: string;
441
- devServer?: string;
442
- output: string;
443
- generateProject?: boolean;
444
- /**
445
- * Where to re-read the Zig runtime archives from, overriding
446
- * `CRAFT_IOS_RUNTIME`. Same meaning as `InitOptions.runtimeDir`; `null`
447
- * leaves whatever `init` installed exactly as it is.
448
- */
449
- runtimeDir?: string | null;
450
- /** Rebuild the installed runtime from this source using the app's current feature flags. */
451
- runtimeSource?: string | null;
452
- }
453
- /**
454
- * Run the app's declared generator hook without invoking a shell.
455
- *
456
- * A hook gets the generated project as its cwd and explicit metadata so a
457
- * patch can target the right platform and phase without guessing from paths.
458
- */
459
- export declare function runPostGenerateHook(hook: CraftPostGenerateHook | undefined, output: string, phase?: 'build'): void;
460
- export interface OpenOptions {
461
- output: string;
462
- }
463
- export interface RunOptions {
464
- simulator: boolean;
465
- output: string;
466
- }
467
- export declare function renderDeviceFamilies(config: CraftConfig): string;
468
- /** `appearance` when set, otherwise what the older `darkMode` switch pinned. */
469
- export declare function resolveAppearance(config: Pick<CraftConfig, 'appearance' | 'darkMode'>): CraftAppearance;
470
- /**
471
- * The Info.plist interface style and the status bar that reads on it.
472
- *
473
- * The status bar used to be `LightContent` whatever the app looked like:
474
- * white text that vanished on a light page. It now follows the appearance —
475
- * dark text on a light app, light on a dark one, and the system's choice when
476
- * the app follows the system.
477
- */
478
- export declare function renderAppearance(config: Pick<CraftConfig, 'appearance' | 'darkMode'>): {
479
- interfaceStyle: string;
480
- statusBarStyle: string;
481
- };
482
- export declare function renderUsageDescriptions(config: CraftConfig): string;
483
- export declare function renderOrientations(config: CraftConfig): string;
484
- /** WKAppBoundDomains: the configured domains plus the dev server's host, at most 10. */
485
- export declare function renderAppBoundDomains(config: CraftConfig): string;
486
- export declare function renderUrlTypes(config: CraftConfig): string;
487
- export declare function renderBackgroundModes(config: CraftConfig): string;
488
- /** The background refresh task's identifier, or null when it is off. */
489
- export declare function backgroundRefreshIdentifier(config: Pick<CraftConfig, 'backgroundRefresh' | 'bundleId'>): string | null;
490
- /** BGTaskSchedulerPermittedIdentifiers: iOS runs no task it does not list. */
491
- export declare function renderBackgroundTaskIdentifiers(config: Pick<CraftConfig, 'backgroundRefresh' | 'bundleId'>): string;
492
- /**
493
- * The associated-domains entitlement's entries. Each needs a service prefix,
494
- * and a bare host (the easy thing to write) used to be signed as it was and
495
- * then matched nothing, so universal links silently never opened the app.
496
- */
497
- export declare function associatedDomainEntries(domains: string[] | undefined): string[];
498
- export declare function renderEntitlements(config: CraftConfig): string;
499
- export declare function renderWatchEntitlements(config: CraftConfig): string;
500
- /**
501
- * The build settings that link the Zig runtime into the app target.
502
- *
503
- * Two things are load-bearing here:
504
- *
505
- * `LIBRARY_SEARCH_PATHS` is written twice, once per SDK, so `-lcraft-ios`
506
- * resolves to the device archive for a device build and the simulator archive
507
- * for a simulator one without the flag itself changing. Xcode applies the
508
- * `[sdk=...]` condition; xcodegen passes these keys through verbatim.
509
- *
510
- * The four `-u` flags are the reason anything works at all. Nothing in the
511
- * Swift source *references* these symbols — `CraftZigRuntime` and
512
- * `CraftSwiftShim` both find them with `dlsym` at runtime — so a static
513
- * archive contributes no objects for them and the linker drops the entire
514
- * runtime as unreachable. `-u` names them as undefined so the objects are
515
- * pulled in and the symbols end up in the binary for `dlsym` to find.
516
- *
517
- * `-u` rather than `-force_load`: forcing the whole archive would pull in
518
- * every object whether reachable or not, and these four entry points already
519
- * reach everything the bridge actually uses.
520
- */
521
- export declare function renderRuntimeSettings(): string;
522
- /**
523
- * Build settings a feature adds to the app target. WorkoutKit is compiled in
524
- * only for `enableScheduledWorkouts`: CraftScheduledWorkouts.swift imports it
525
- * behind the `CRAFT_SCHEDULED_WORKOUTS` condition, so an app that does not
526
- * schedule workouts does not link it. `$(inherited)` keeps Debug's `DEBUG`.
527
- */
528
- export declare function renderFeatureSettings(config: Partial<CraftConfig>): string;
529
- export declare function renderPrivacyManifest(config: CraftConfig): string;
530
- /**
531
- * Whether a PNG carries an alpha channel, from its header: colour type 4
532
- * (grey + alpha) or 6 (RGB + alpha), or a tRNS chunk before the image data.
533
- */
534
- export declare function pngHasAlpha(bytes: Uint8Array): boolean;
535
- /** The asset the launch screen and the splash both draw, so one hands over to the other unseen. */
536
- export declare const LAUNCH_LOGO = "LaunchLogo";
537
- /**
538
- * A bitmap splash's `@2x` and `@3x` files beside it (`LaunchLogo.png`,
539
- * `LaunchLogo@2x.png`, `LaunchLogo@3x.png`, as ts-images'
540
- * `generateSplashScreens` writes them), by scale. A bitmap without them is
541
- * one image, drawn at its pixel size in points.
542
- */
543
- export declare function splashScales(source: string): Array<{
544
- scale: 1 | 2 | 3;
545
- path: string;
546
- }>;
547
- /** The launch screen: the background colour, and the splash logo on it when there is one. */
548
- export declare function renderLaunchScreen(config: Pick<CraftConfig, 'splashImagePath'>): string;
549
- /** Near-black or near-white, whichever reads on `background` (WCAG relative luminance). */
550
- export declare function readableTextOn(background: string | undefined): string;
551
- /**
552
- * The page the app shows when its own page cannot be reached: the generated
553
- * `dist/index.html` until the app's web assets replace it.
554
- *
555
- * An app whose page has a service worker normally opens from it offline, so
556
- * this only shows on a first launch without one, or when the remote fails
557
- * hard. It used to be a placeholder that said "Built with Craft iOS" in white
558
- * on whatever the background was (invisible on a light one) with a bridge
559
- * status line under it: debug output, in front of the person using the app.
560
- *
561
- * Now it says what happened in the app's own colours, light and dark, sized
562
- * with Dynamic Type, and Retry asks the shell to load the app's page again.
563
- * The shell also goes back to the app's page by itself when the connection
564
- * returns, so the page does not retry on `online` as well.
565
- */
566
- export declare function renderOfflinePage(config: Pick<CraftConfig, 'appName' | 'backgroundColor' | 'backgroundColorDark'>): string;
567
- /** Replace the bundled web application atomically so removed assets cannot linger. */
568
- export declare function syncWebAssets(source: string, output: string): void;
569
- /**
570
- * Initialize a new iOS project
571
- */
572
- /**
573
- * Where the Zig runtime archives live, or null when this build has none.
574
- *
575
- * `CRAFT_IOS_RUNTIME` points at a directory holding the archives `zig build
576
- * build-ios-all` produces. It is opt-in and there is deliberately no fallback
577
- * search: a generated project with no runtime is the shipping default today,
578
- * and it works — `CraftZigRuntime.offer` is a `dlsym` miss, every action
579
- * answers false, and the Swift switch serves the whole surface exactly as it
580
- * always has. Guessing at a path would turn "no runtime" into "some runtime,
581
- * from somewhere", which is the failure mode the pantry contract exists to
582
- * rule out.
583
- *
584
- * This is the same shape as `CRAFT_BIN`: an explicit override for the monorepo
585
- * dev loop, not a lookup path. Shipping the runtime to real apps means putting
586
- * these archives in the pantry package beside the `craft` binary, which is a
587
- * distribution decision this function does not make.
588
- *
589
- * `override` is what `InitOptions.runtimeDir` passes: a path to use instead of
590
- * the variable, or `null` to declare there is no runtime regardless of what the
591
- * environment says. `undefined` falls through to `CRAFT_IOS_RUNTIME`.
592
- */
593
- export declare function resolveRuntimeDir(override?: string | null): string | null;
594
- /**
595
- * Copy the Zig archives into the generated project as `Runtime/<sdk>/libcraft-ios.a`.
596
- *
597
- * One name for both SDKs, in two directories, because that is what lets a
598
- * single `-lcraft-ios` in OTHER_LDFLAGS work for device and simulator builds:
599
- * Xcode picks the directory by SDK and the flag never changes.
600
- *
601
- * Returns true when a runtime was installed.
602
- */
603
- export declare function installRuntime(output: string, runtimeDir: string, config?: CraftConfig): Promise<boolean>;
604
- /**
605
- * The identifier an app's display name becomes wherever Xcode or Swift needs
606
- * one: the project, the target, the product and the `@main` type.
607
- *
608
- * The display name goes in front of people and may say anything; an
609
- * identifier may not. "HQ.training" used to become `struct HQ.trainingApp`,
610
- * which does not compile. Words are joined in PascalCase ("HQTraining"), and
611
- * a name that starts with a digit or has no letters at all still yields a
612
- * valid Swift type.
613
- */
614
- export declare function productName(name: string): string;
615
- /** Restore package-owned Swift, retaining Xcode metadata and bundled screens.
616
- * Xcode Cloud assigns the distributed build number independently of the source
617
- * config; keep the packaged runtime identity in step with Apple's build.
618
- */
619
- export declare function restoreShell(output: string): void;
620
- export { assertNoApplicationSwiftSources, findApplicationSwiftSources } from './source-audit.js';
621
- export declare function init(options: InitOptions): Promise<void>;
622
- /**
623
- * Build web assets and generate Xcode project
624
- */
625
- export declare function build(options: BuildOptions): Promise<void>;
626
- /**
627
- * Open Xcode project
628
- */
629
- export declare function open(options: OpenOptions): Promise<void>;
630
- /**
631
- * Build and run on simulator or device
632
- */
633
- /** One bootable simulator, as `simctl list` describes it. */
634
- export interface SimulatorDevice {
635
- name: string;
636
- udid: string;
637
- state: string;
638
- runtime: string;
639
- }
640
- /**
641
- * Every available *iOS* simulator, newest runtime first, iPhones before iPads.
642
- *
643
- * Exported because the choice is worth testing without a simulator present -
644
- * `pickSimulator` is the policy and this is the data it reads.
645
- */
646
- export declare function orderSimulators(devices: SimulatorDevice[], sdkVersion?: string): SimulatorDevice[];
647
- /**
648
- * The device to run on.
649
- *
650
- * A booted one first - if the developer already has a simulator open, that is
651
- * the one they are looking at - then the newest iPhone.
652
- *
653
- * This used to be the string `iPhone 15`, hard-coded into the `-destination`
654
- * argument. On a machine whose Xcode ships iPhone 17 and no iPhone 15, that is
655
- * not a fallback, it is `xcodebuild: error: Unable to find a device named
656
- * 'iPhone 15'` - the command fails for a reason that has nothing to do with the
657
- * app being built, and the fix is invisible from the error.
658
- */
659
- export declare function pickSimulator(): Promise<SimulatorDevice | null>;
660
- /**
661
- * Boot it, and wait until it can actually do something.
662
- *
663
- * `simctl boot` returns as soon as the device starts booting, and a device
664
- * that reports `Booted` is minutes away from being able to install anything on
665
- * a cold runtime. `bootstatus` is the wait, and skipping it is why a first run
666
- * on a fresh machine fails where the second succeeds.
667
- */
668
- export declare function bootSimulator(device: SimulatorDevice): Promise<void>;
669
- /**
670
- * Bring the Simulator window to the front, if it can be found.
671
- *
672
- * `open -a Simulator` resolves through LaunchServices, and LaunchServices only
673
- * knows the name if a Simulator.app has been registered under it - which is not
674
- * true on a machine running Xcode-beta, where the answer is `Unable to find
675
- * application named 'Simulator'`. The app is always at a known path under the
676
- * *selected* developer directory, so that is tried first.
677
- *
678
- * Never throws. The window is a convenience: the app is installed and launched
679
- * either way, and failing the whole run because a window did not come to the
680
- * front would be reporting a cosmetic problem as a build failure.
681
- */
682
- export declare function showSimulator(): Promise<void>;
683
- export declare function run(options: RunOptions): Promise<void>;
684
- export { createNativeMutationValidator, initSimulatorDriver, serializeSimulatorSteps } from './testing.js';
685
- export type { NativeMutationValidator, NativeValidationResult, SimulatorDriverOptions, SimulatorStep, TimedTouchPoint } from './testing.js';
1
+ export * from './internal/ios/src/index.js'